From 5eca7175958a6340698f94e7b44db8248ed8ee2c Mon Sep 17 00:00:00 2001
From: Sonal Goyal <sonalgoyal4@gmail.com>
Date: Wed, 9 Oct 2024 14:49:56 +0530
Subject: [PATCH] pmd changes

---
 .github/workflows/pmd.yml                     |    2 +-
 .../net.sourceforge.pmd.lang.Language         |    1 +
 pmd/resources/category/java/bestpractices.xml | 2010 ++++++++++
 .../category/java/categories.properties       |   13 +
 pmd/resources/category/java/codestyle.xml     | 2101 +++++++++++
 pmd/resources/category/java/design.xml        | 1534 ++++++++
 pmd/resources/category/java/documentation.xml |  152 +
 pmd/resources/category/java/errorprone.xml    | 3235 +++++++++++++++++
 .../category/java/multithreading.xml          |  459 +++
 pmd/resources/category/java/performance.xml   |  925 +++++
 pmd/resources/category/java/security.xml      |   66 +
 .../rulesets/java/internal/diagnostics.xml    |   24 +
 pmd/resources/rulesets/java/quickstart.xml    |  322 ++
 13 files changed, 10843 insertions(+), 1 deletion(-)
 create mode 100644 pmd/resources/META-INF/services/net.sourceforge.pmd.lang.Language
 create mode 100644 pmd/resources/category/java/bestpractices.xml
 create mode 100644 pmd/resources/category/java/categories.properties
 create mode 100644 pmd/resources/category/java/codestyle.xml
 create mode 100644 pmd/resources/category/java/design.xml
 create mode 100644 pmd/resources/category/java/documentation.xml
 create mode 100644 pmd/resources/category/java/errorprone.xml
 create mode 100644 pmd/resources/category/java/multithreading.xml
 create mode 100644 pmd/resources/category/java/performance.xml
 create mode 100644 pmd/resources/category/java/security.xml
 create mode 100644 pmd/resources/rulesets/java/internal/diagnostics.xml
 create mode 100644 pmd/resources/rulesets/java/quickstart.xml

diff --git a/.github/workflows/pmd.yml b/.github/workflows/pmd.yml
index 77e980d75..d68e031b0 100644
--- a/.github/workflows/pmd.yml
+++ b/.github/workflows/pmd.yml
@@ -22,7 +22,7 @@ jobs:
           java-version: '11'
       - uses: pmd/pmd-github-action@v1
         with:
-          rulesets: 'ruleset.xml'
+          rulesets: 'pmd/resources/rulesets/java/quickstart.xml'
           analyzeModifiedFilesOnly: false
       - name: Upload SARIF file
         uses: github/codeql-action/upload-sarif@v1
diff --git a/pmd/resources/META-INF/services/net.sourceforge.pmd.lang.Language b/pmd/resources/META-INF/services/net.sourceforge.pmd.lang.Language
new file mode 100644
index 000000000..98ca0d58e
--- /dev/null
+++ b/pmd/resources/META-INF/services/net.sourceforge.pmd.lang.Language
@@ -0,0 +1 @@
+net.sourceforge.pmd.lang.java.JavaLanguageModule
diff --git a/pmd/resources/category/java/bestpractices.xml b/pmd/resources/category/java/bestpractices.xml
new file mode 100644
index 000000000..03b23ad1c
--- /dev/null
+++ b/pmd/resources/category/java/bestpractices.xml
@@ -0,0 +1,2010 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<ruleset name="Best Practices"
+    xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+    <description>
+Rules which enforce generally accepted best practices.
+    </description>
+
+    <rule name="AbstractClassWithoutAbstractMethod"
+          language="java"
+          since="3.0"
+          message="This abstract class does not have any abstract methods"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.AbstractClassWithoutAbstractMethodRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#abstractclasswithoutabstractmethod">
+        <description>
+The abstract class does not contain any abstract methods. An abstract class suggests
+an incomplete implementation, which is to be completed by subclasses implementing the
+abstract methods. If the class is intended to be used as a base class only (not to be instantiated
+directly) a protected constructor can be provided to prevent direct instantiation.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public abstract class Foo {
+  void int method1() { ... }
+  void int method2() { ... }
+  // consider using abstract methods or removing
+  // the abstract modifier and adding protected constructors
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AccessorClassGeneration"
+          language="java"
+          since="1.04"
+          maximumLanguageVersion="10"
+          message="Avoid instantiation through private constructors from outside of the constructor's class."
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.AccessorClassGenerationRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#accessorclassgeneration">
+        <description>
+Instantiation by way of private constructors from outside the constructor's class often causes the
+generation of an accessor. A factory method, or non-privatization of the constructor can eliminate this
+situation. The generated class file is actually an interface.  It gives the accessing class the ability
+to invoke a new hidden package scope constructor that takes the interface as a supplementary parameter.
+This turns a private constructor effectively into one with package scope, and is challenging to discern.
+
+_Note:_ This rule is only executed for Java 10 or lower.
+Since Java 11, [JEP 181: Nest-Based Access Control](https://openjdk.org/jeps/181) has been implemented. This
+means that in Java 11 and above accessor classes are not generated anymore.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Outer {
+ void method(){
+  Inner ic = new Inner();//Causes generation of accessor class
+ }
+ public class Inner {
+  private Inner(){}
+ }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AccessorMethodGeneration"
+          language="java"
+          since="5.5.4"
+          maximumLanguageVersion="10"
+          message="Consider giving this member package visibility to access it from {0} without a synthetic accessor method"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.AccessorMethodGenerationRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#accessormethodgeneration">
+        <description>
+When accessing private fields / methods from another class, the Java compiler will generate accessor methods
+with package-private visibility. This adds overhead, and to the dex method count on Android. This situation can
+be avoided by changing the visibility of the field / method from private to package-private.
+
+
+_Note:_ This rule is only executed for Java 10 or lower.
+Since Java 11, [JEP 181: Nest-Based Access Control](https://openjdk.org/jeps/181) has been implemented. This
+means that in Java 11 and above accessor classes are not generated anymore.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class OuterClass {
+    private int counter;
+    /* package */ int id;
+
+    public class InnerClass {
+        InnerClass() {
+            OuterClass.this.counter++; // wrong accessor method will be generated
+        }
+
+        public int getOuterClassId() {
+            return OuterClass.this.id; // id is package-private, no accessor method needed
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ArrayIsStoredDirectly"
+          language="java"
+          since="2.2"
+          message="The user-supplied array ''{0}'' is stored directly."
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.ArrayIsStoredDirectlyRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#arrayisstoreddirectly">
+        <description>
+Constructors and methods receiving arrays should clone objects and store the copy.
+This prevents future changes from the user from affecting the original array.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    private String [] x;
+        public void foo (String [] param) {
+        // Don't do this, make a copy of the array at least
+        this.x=param;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidMessageDigestField"
+          language="java"
+          since="6.18.0"
+          message="You shouldn't declare field of MessageDigest type, because unsynchronized access could cause problems"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidmessagedigestfield">
+        <description>
+            Declaring a MessageDigest instance as a field make this instance directly available to multiple threads.
+            Such sharing of MessageDigest instances should be avoided if possible since it leads to wrong results
+            if the access is not synchronized correctly.
+            Just create a new instance and use it locally, where you need it.
+            Creating a new instance is easier than synchronizing access to a shared instance.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//FieldDeclaration/ClassType[pmd-java:typeIs('java.security.MessageDigest')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+            <![CDATA[
+import java.security.MessageDigest;
+public class AvoidMessageDigestFieldExample {
+    private final MessageDigest sharedMd;
+    public AvoidMessageDigestFieldExample() throws Exception {
+        sharedMd = MessageDigest.getInstance("SHA-256");
+    }
+    public byte[] calculateHashShared(byte[] data) {
+        // sharing a MessageDigest like this without synchronizing access
+        // might lead to wrong results
+        sharedMd.reset();
+        sharedMd.update(data);
+        return sharedMd.digest();
+    }
+
+    // better
+    public byte[] calculateHash(byte[] data) throws Exception {
+        MessageDigest md = MessageDigest.getInstance("SHA-256");
+        md.update(data);
+        return md.digest();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidPrintStackTrace"
+          language="java"
+          since="3.2"
+          message="Avoid printStackTrace(); use a logger call instead."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidprintstacktrace">
+        <description>
+Avoid printStackTrace(); use a logger call instead.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall[ pmd-java:matchesSig("java.lang.Throwable#printStackTrace()") ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+class Foo {
+    void bar() {
+        try {
+            // do something
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidReassigningCatchVariables"
+          language="java"
+          since="6.27.0"
+          message="Avoid reassigning caught exception ''{0}''"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.AvoidReassigningCatchVariablesRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidreassigningcatchvariables">
+        <description>
+Reassigning exception variables caught in a catch statement should be avoided because of:
+
+1) If it is needed, multi catch can be easily added and code will still compile.
+
+2) Following the principle of least surprise we want to make sure that a variable caught in a catch statement
+is always the one thrown in a try block.
+        </description>
+        <priority>3</priority>
+        <example><![CDATA[
+public class Foo {
+    public void foo() {
+        try {
+            // do something
+        } catch (Exception e) {
+            e = new NullPointerException(); // not recommended
+        }
+
+        try {
+            // do something
+        } catch (MyException | ServerException e) {
+            e = new RuntimeException(); // won't compile
+        }
+    }
+}
+        ]]></example>
+    </rule>
+
+    <rule name="AvoidReassigningLoopVariables"
+          language="java"
+          since="6.11.0"
+          message="Avoid reassigning the loop control variable ''{0}''"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.AvoidReassigningLoopVariablesRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidreassigningloopvariables">
+        <description>
+Reassigning loop variables can lead to hard-to-find bugs. Prevent or limit how these variables can be changed.
+
+In foreach-loops, configured by the `foreachReassign` property:
+- `deny`: Report any reassignment of the loop variable in the loop body. _This is the default._
+- `allow`: Don't check the loop variable.
+- `firstOnly`: Report any reassignments of the loop variable, except as the first statement in the loop body.
+            _This is useful if some kind of normalization or clean-up of the value before using is permitted, but any other change of the variable is not._
+
+In for-loops, configured by the `forReassign` property:
+- `deny`: Report any reassignment of the control variable in the loop body. _This is the default._
+- `allow`: Don't check the control variable.
+- `skip`: Report any reassignments of the control variable, except conditional increments/decrements (`++`, `--`, `+=`, `-=`).
+            _This prevents accidental reassignments or unconditional increments of the control variable._
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+  private void foo() {
+    for (String s : listOfStrings()) {
+      s = s.trim(); // OK, when foreachReassign is "firstOnly" or "allow"
+      doSomethingWith(s);
+
+      s = s.toUpper(); // OK, when foreachReassign is "allow"
+      doSomethingElseWith(s);
+    }
+
+    for (int i=0; i < 10; i++) {
+      if (check(i)) {
+        i++; // OK, when forReassign is "skip" or "allow"
+      }
+
+      i = 5;  // OK, when forReassign is "allow"
+
+      doSomethingWith(i);
+    }
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidReassigningParameters"
+          language="java"
+          since="1.0"
+          message="Avoid reassigning parameters such as ''{0}''"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.AvoidReassigningParametersRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidreassigningparameters">
+        <description>
+Reassigning values to incoming parameters of a method or constructor is not recommended, as this can
+make the code more difficult to understand. The code is often read with the assumption that parameter values
+don't change and an assignment violates therefore the principle of least astonishment. This is especially a
+problem if the parameter is documented e.g. in the method's javadoc and the new content differs from the original
+documented content.
+
+Use temporary local variables instead. This allows you to assign a new name, which makes the code better
+understandable.
+
+Note that this rule considers both methods and constructors. If there are multiple assignments for a formal
+parameter, then only the first assignment is reported.
+        </description>
+        <priority>2</priority>
+        <example>
+<![CDATA[
+public class Hello {
+  private void greet(String name) {
+    name = name.trim();
+    System.out.println("Hello " + name);
+
+    // preferred
+    String trimmedName = name.trim();
+    System.out.println("Hello " + trimmedName);
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidStringBufferField"
+          language="java"
+          since="4.2"
+          message="StringBuffers can grow quite a lot, and so may become a source of memory leak (if the owning class has a long life time)."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidstringbufferfield">
+        <description>
+StringBuffers/StringBuilders can grow considerably, and so may become a source of memory leaks
+if held within objects with long lifetimes.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//FieldDeclaration/ClassType[pmd-java:typeIs('java.lang.StringBuffer') or pmd-java:typeIs('java.lang.StringBuilder')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    private StringBuffer buffer;    // potential memory leak as an instance variable;
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidUsingHardCodedIP"
+          language="java"
+          since="4.1"
+          message="Do not hard code the IP address ${variableName}"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.AvoidUsingHardCodedIPRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#avoidusinghardcodedip">
+        <description>
+Application with hard-coded IP addresses can become impossible to deploy in some cases.
+Externalizing IP adresses is preferable.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    private String ip = "127.0.0.1";     // not recommended
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CheckResultSet"
+          language="java"
+          since="4.1"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.CheckResultSetRule"
+          message="Always check the return of one of the navigation method (next,previous,first,last) of a ResultSet."
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#checkresultset">
+        <description>
+Always check the return values of navigation methods (next, previous, first, last) of a ResultSet.
+If the value return is 'false', it should be handled properly.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+Statement stat = conn.createStatement();
+ResultSet rst = stat.executeQuery("SELECT name FROM person");
+rst.next();     // what if it returns false? bad form
+String firstName = rst.getString(1);
+
+Statement stat = conn.createStatement();
+ResultSet rst = stat.executeQuery("SELECT name FROM person");
+if (rst.next()) {    // result is properly examined and used
+    String firstName = rst.getString(1);
+    } else  {
+        // handle missing data
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ConstantsInInterface"
+          language="java"
+          since="5.5"
+          message="Using constants in interfaces is a bad practice."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#constantsininterface">
+        <description>
+Using constants in interfaces is a bad practice. Interfaces define types, constants are implementation details better placed in classes or enums. If the constants are best viewed as members of an enumerated type, you should export them with an enum type.
+For other scenarios, consider using a utility class. See Effective Java's 'Use interfaces only to define types'.
+        </description>
+        <priority>3</priority>
+        <properties>
+        <property name="ignoreIfHasMethods" type="Boolean" description="Whether to ignore constants in interfaces if the interface defines any methods" value="true"/>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration[@Interface = true()][$ignoreIfHasMethods= false() or not(ClassBody/MethodDeclaration)]/ClassBody/FieldDeclaration
+ ]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public interface ConstantInterface {
+    public static final int CONST1 = 1; // violation, no fields allowed in interface!
+    static final int CONST2 = 1;        // violation, no fields allowed in interface!
+    final int CONST3 = 1;               // violation, no fields allowed in interface!
+    int CONST4 = 1;                     // violation, no fields allowed in interface!
+}
+
+// with ignoreIfHasMethods = false
+public interface AnotherConstantInterface {
+    public static final int CONST1 = 1; // violation, no fields allowed in interface!
+
+    int anyMethod();
+}
+
+// with ignoreIfHasMethods = true
+public interface YetAnotherConstantInterface {
+    public static final int CONST1 = 1; // no violation
+
+    int anyMethod();
+}
+ ]]>
+        </example>
+    </rule>
+
+    <rule name="DefaultLabelNotLastInSwitchStmt"
+          language="java"
+          since="1.5"
+          message="The default label should be the last label in a switch statement"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#defaultlabelnotlastinswitchstmt">
+        <description>
+By convention, the default label should be the last label in a switch statement.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//SwitchLabel[@Default = true() and not(.. is ../../*[last()])]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+  void bar(int a) {
+   switch (a) {
+    case 1:  // do something
+       break;
+    default:  // the default case should be last, by convention
+       break;
+    case 2:
+       break;
+   }
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="DoubleBraceInitialization"
+          language="java"
+          since="6.16.0"
+          message="Double-brace initialization should be avoided"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#doublebraceinitialization">
+        <description>
+            Double brace initialisation is a pattern to initialise eg collections concisely. But it implicitly
+            generates a new .class file, and the object holds a strong reference to the enclosing object. For those
+            reasons, it is preferable to initialize the object normally, even though it's verbose.
+
+            This rule counts any anonymous class which only has a single initializer as an instance of double-brace
+            initialization. There is currently no way to find out whether a method called in the initializer is not
+            accessible from outside the anonymous class, and those legit cases should be suppressed for the time being.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//ConstructorCall/AnonymousClassDeclaration/ClassBody[count(*)=1]/Initializer[@Static=false()]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example><![CDATA[
+// this is double-brace initialization
+return new ArrayList<String>(){{
+    add("a");
+    add("b");
+    add("c");
+}};
+
+// the better way is to not create an anonymous class:
+List<String> a = new ArrayList<>();
+a.add("a");
+a.add("b");
+a.add("c");
+return a;
+]]>
+        </example>
+    </rule>
+
+    <rule name="ForLoopCanBeForeach"
+          language="java"
+          since="6.0.0"
+          message="This 'for' loop can be replaced by a 'foreach' loop"
+          minimumLanguageVersion="1.5"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.ForLoopCanBeForeachRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#forloopcanbeforeach">
+        <description>
+Reports loops that can be safely replaced with the foreach syntax. The rule considers loops over
+lists, arrays and iterators. A loop is safe to replace if it only uses the index variable to
+access an element of the list or array, only has one update statement, and loops through *every*
+element of the list or array left to right.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class MyClass {
+  void loop(List<String> l) {
+    for (int i = 0; i < l.size(); i++) { // pre Java 1.5
+      System.out.println(l.get(i));
+    }
+
+    for (String s : l) {        // post Java 1.5
+      System.out.println(s);
+    }
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ForLoopVariableCount"
+          language="java"
+          since="6.11.0"
+          message="Too many control variables in the 'for' statement"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#forloopvariablecount">
+        <description>
+Having a lot of control variables in a 'for' loop makes it harder to see what range of values
+the loop iterates over. By default this rule allows a regular 'for' loop with only one variable.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="maximumVariables" type="Integer"
+                      description="A regular for statement will have 1 control variable" min="0" max="100" value="1"/>
+            <property name="xpath">
+                <value>//ForInit/LocalVariableDeclaration[count(VariableDeclarator) > $maximumVariables]</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+// this will be reported with the default setting of at most one control variable in a for loop
+for (int i = 0, j = 0; i < 10; i++, j += 2) {
+   foo();
+]]>
+        </example>
+    </rule>
+
+    <rule name="GuardLogStatement"
+          language="java"
+          since="5.1.0"
+          message="Logger calls should be surrounded by log level guards."
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.GuardLogStatementRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#guardlogstatement">
+        <description>
+Whenever using a log level, one should check if it is actually enabled, or
+otherwise skip the associate String creation and manipulation, as well as any method calls.
+
+An alternative to checking the log level are substituting parameters, formatters or lazy logging
+with lambdas. The available alternatives depend on the actual logging framework.
+        </description>
+        <priority>2</priority>
+        <example>
+<![CDATA[
+// Add this for performance - avoid manipulating strings if the logger may drop it
+if (log.isDebugEnabled()) {
+    log.debug("log something" + param1 + " and " + param2 + "concat strings");
+}
+
+// Avoid the guarding if statement with substituting parameters
+log.debug("log something {} and {}", param1, param2);
+
+// Avoid the guarding if statement with formatters
+log.debug("log something %s and %s", param1, param2);
+
+// This is still an issue, method invocations may be expensive / have side-effects
+log.debug("log something expensive: {}", calculateExpensiveLoggingText());
+
+// Avoid the guarding if statement with lazy logging and lambdas
+log.debug("log something expensive: {}", () -> calculateExpensiveLoggingText());
+
+// … alternatively use method references
+log.debug("log something expensive: {}", this::calculateExpensiveLoggingText);
+]]>
+        </example>
+    </rule>
+
+    <rule name="JUnit4SuitesShouldUseSuiteAnnotation"
+          language="java"
+          since="4.0"
+          message="JUnit 4 indicates test suites via annotations, not the suite method."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit4suitesshouldusesuiteannotation">
+        <description>
+In JUnit 3, test suites are indicated by the suite() method. In JUnit 4, suites are indicated
+through the @RunWith(Suite.class) annotation.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration[@Name='suite' and ClassType[pmd-java:typeIs('junit.framework.Test')]]
+                   [not(.//ReturnStatement/*[pmd-java:typeIs('junit.framework.JUnit4TestAdapter')])]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class BadExample extends TestCase{
+
+    public static Test suite(){
+        return new Suite();
+    }
+}
+
+@RunWith(Suite.class)
+@SuiteClasses( { TestOne.class, TestTwo.class })
+public class GoodTest {
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="JUnit4TestShouldUseAfterAnnotation" deprecated="true" ref="UnitTestShouldUseAfterAnnotation" />
+
+    <rule name="JUnit4TestShouldUseBeforeAnnotation" deprecated="true" ref="UnitTestShouldUseBeforeAnnotation"/>
+
+    <rule name="JUnit4TestShouldUseTestAnnotation" deprecated="true" ref="UnitTestShouldUseTestAnnotation" />
+
+    <rule name="JUnit5TestShouldBePackagePrivate"
+          language="java"
+          since="6.35.0"
+          message="JUnit 5 tests should be package-private."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junit5testshouldbepackageprivate">
+        <description><![CDATA[
+Reports JUnit 5 test classes and methods that are not package-private.
+Contrary to JUnit 4 tests, which required public visibility to be run by the engine,
+JUnit 5 tests can also be run if they're package-private. Marking them as such
+is a good practice to limit their visibility.
+
+Test methods are identified as those which use `@Test`, `@RepeatedTest`,
+`@TestFactory`, `@TestTemplate` or `@ParameterizedTest`.
+            ]]></description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration[
+    (: a Junit 5 test class, ie, it has methods with the annotation :)
+    @Interface = false() and
+    ClassBody/MethodDeclaration
+    [ModifierList/Annotation[
+               pmd-java:typeIs('org.junit.jupiter.api.Test')
+            or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+            or pmd-java:typeIs('org.junit.jupiter.api.TestFactory')
+            or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+            or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+    ]]
+]/(
+       self::*[@Abstract = false() and @Visibility = ("public", "protected")]
+|      ClassBody/MethodDeclaration
+       [@Visibility = ("public", "protected")]
+       [ModifierList/Annotation[
+               pmd-java:typeIs('org.junit.jupiter.api.Test')
+            or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+            or pmd-java:typeIs('org.junit.jupiter.api.TestFactory')
+            or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+            or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+       ]]
+)
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+            <![CDATA[
+class MyTest { // not public, that's fine
+    @Test
+    public void testBad() { } // should not have a public modifier
+
+    @Test
+    protected void testAlsoBad() { } // should not have a protected modifier
+
+    @Test
+    private void testNoRun() { } // should not have a private modifier
+
+    @Test
+    void testGood() { } // package private as expected
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="JUnitAssertionsShouldIncludeMessage" deprecated="true" ref="UnitTestAssertionsShouldIncludeMessage" />
+
+    <rule name="JUnitTestContainsTooManyAsserts" deprecated="true" ref="UnitTestContainsTooManyAsserts"/>
+
+    <rule name="JUnitTestsShouldIncludeAssert" deprecated="true" ref="UnitTestShouldIncludeAssert" />
+
+    <rule name="JUnitUseExpected"
+          language="java"
+          since="4.0"
+          message="In JUnit4, use the @Test(expected) annotation to denote tests that should throw exceptions"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.JUnitUseExpectedRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#junituseexpected">
+        <description>
+In JUnit4, use the @Test(expected) annotation to denote tests that should throw exceptions.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class MyTest {
+    @Test
+    public void testBad() {
+        try {
+            doSomething();
+            fail("should have thrown an exception");
+        } catch (Exception e) {
+        }
+    }
+
+    @Test(expected=Exception.class)
+    public void testGood() {
+        doSomething();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="LiteralsFirstInComparisons"
+          language="java"
+          since="6.24.0"
+          message="Position literals first in String comparisons"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.LiteralsFirstInComparisonsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#literalsfirstincomparisons">
+        <description>
+            Position literals first in all String comparisons, if the second argument is null then NullPointerExceptions
+            can be avoided, they will just return false. Note that switching literal positions for compareTo and
+            compareToIgnoreCase may change the result, see examples.
+        </description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+class Foo {
+    boolean bar(String x) {
+        return x.equals("2"); // should be "2".equals(x)
+    }
+    boolean bar(String x) {
+        return x.equalsIgnoreCase("2"); // should be "2".equalsIgnoreCase(x)
+    }
+    boolean bar(String x) {
+        return (x.compareTo("bar") > 0); // should be: "bar".compareTo(x) < 0
+    }
+    boolean bar(String x) {
+        return (x.compareToIgnoreCase("bar") > 0); // should be: "bar".compareToIgnoreCase(x) < 0
+    }
+    boolean bar(String x) {
+        return x.contentEquals("bar"); // should be "bar".contentEquals(x)
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="LooseCoupling"
+          language="java"
+          since="0.7"
+          message="Avoid using implementation types like ''{0}''; use the interface instead"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.LooseCouplingRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#loosecoupling">
+        <description>
+Excessive coupling to implementation types (e.g., `HashSet`) limits your ability to use alternate
+implementations in the future as requirements change. Whenever available, declare variables
+and parameters using a more general type (e.g, `Set`).
+
+This rule reports uses of concrete collection types. User-defined types that should be treated
+the same as interfaces can be configured with the property `allowedTypes`.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+import java.util.ArrayList;
+import java.util.HashSet;
+
+public class Bar {
+    // sub-optimal approach
+    private ArrayList<SomeType> list = new ArrayList<>();
+
+    public HashSet<SomeType> getFoo() {
+        return new HashSet<SomeType>();
+    }
+
+    // preferred approach
+    private List<SomeType> list = new ArrayList<>();
+
+    public Set<SomeType> getFoo() {
+        return new HashSet<SomeType>();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="MethodReturnsInternalArray"
+          language="java"
+          since="2.2"
+          message="Returning ''{0}'' may expose an internal array."
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.MethodReturnsInternalArrayRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#methodreturnsinternalarray">
+        <description>
+Exposing internal arrays to the caller violates object encapsulation since elements can be
+removed or replaced outside of the object that owns it. It is safer to return a copy of the array.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class SecureSystem {
+    UserData [] ud;
+    public UserData [] getUserData() {
+        // Don't return directly the internal array, return a copy
+        return ud;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+
+    <rule name="MissingOverride"
+          language="java"
+          since="6.2.0"
+          minimumLanguageVersion="1.5"
+          message="The method ''{0}'' is missing an @Override annotation."
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.MissingOverrideRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#missingoverride">
+        <description>
+            Annotating overridden methods with @Override ensures at compile time that
+            the method really overrides one, which helps refactoring and clarifies intent.
+        </description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+            public class Foo implements Runnable {
+                // This method is overridden, and should have an @Override annotation
+                public void run() {
+
+                }
+            }
+            ]]>
+        </example>
+    </rule>
+
+    <rule name="OneDeclarationPerLine"
+          language="java"
+          since="5.0"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="Use one line for each declaration, it enhances code readability."
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#onedeclarationperline">
+        <description>
+Java allows the use of several variables declaration of the same type on one line.
+However, it can lead to quite messy code. This rule looks for several declarations on the same line.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//LocalVariableDeclaration
+   [not(parent::ForInit)]
+   [count(VariableDeclarator) > 1]
+   [$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)]
+|
+//FieldDeclaration
+   [count(VariableDeclarator) > 1]
+   [$strictMode or count(distinct-values(VariableDeclarator/@BeginLine)) != count(VariableDeclarator)]
+]]>
+                </value>
+            </property>
+            <property name="strictMode" type="Boolean" value="false"
+                      description="If true, mark combined declaration even if the declarations are on separate lines."/>
+        </properties>
+        <example>
+<![CDATA[
+String name;            // separate declarations
+String lastname;
+
+String name, lastname;  // combined declaration, a violation
+
+String name,
+       lastname;        // combined declaration on multiple lines, no violation by default.
+                        // Set property strictMode to true to mark this as violation.
+]]>
+        </example>
+    </rule>
+
+    <rule name="PreserveStackTrace"
+          language="java"
+          since="3.7"
+          message="Thrown exception does not preserve the stack trace of exception ''{0}'' on all code paths"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.PreserveStackTraceRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#preservestacktrace">
+        <description>
+Reports exceptions that are thrown from within a catch block, yet don't refer to the
+exception parameter declared by that catch block. The stack trace of the original
+exception could be lost, which makes the thrown exception less informative.
+
+To preserve the stack trace, the original exception may be used as the cause of
+the new exception, using `Throwable#initCause`, or passed as a constructor argument
+to the new exception. It may also be preserved using `Throwable#addSuppressed`.
+The rule actually assumes that any method or constructor that takes the original
+exception as argument preserves the original stack trace.
+
+The rule allows `InvocationTargetException` and `PrivilegedActionException` to be
+replaced by their cause exception. The discarded part of the stack trace is in those
+cases only JDK-internal code, which is not very useful. The rule also ignores exceptions
+whose name starts with `ignored`.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    void good() {
+        try{
+            Integer.parseInt("a");
+        } catch (Exception e) {
+            throw new Exception(e); // Ok, this initializes the cause of the new exception
+        }
+        try {
+            Integer.parseInt("a");
+        } catch (Exception e) {
+            throw (IllegalStateException)new IllegalStateException().initCause(e); // second possibility to create exception chain.
+        }
+    }
+    void wrong() {
+        try{
+            Integer.parseInt("a");
+        } catch (Exception e) {
+            // Violation: this only preserves the message and not the stack trace
+            throw new Exception(e.getMessage());
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="PrimitiveWrapperInstantiation"
+          language="java"
+          since="6.37.0"
+          message="Do not use `new {0}(...)`, prefer `{0}.valueOf(...)`"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.PrimitiveWrapperInstantiationRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#primitivewrapperinstantiation">
+        <description>
+            Reports usages of primitive wrapper constructors. They are deprecated
+            since Java 9 and should not be used. Even before Java 9, they can
+            be replaced with usage of the corresponding static `valueOf` factory method
+            (which may be automatically inserted by the compiler since Java 1.5).
+            This has the advantage that it may reuse common instances instead of creating
+            a new instance each time.
+
+            Note that for `Boolean`, the named constants `Boolean.TRUE` and `Boolean.FALSE`
+            are preferred instead of `Boolean.valueOf`.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+            public class Foo {
+                private Integer ZERO = new Integer(0);      // violation
+                private Integer ZERO1 = Integer.valueOf(0); // better
+                private Integer ZERO1 = 0;                  // even better
+            }
+            ]]>
+        </example>
+    </rule>
+
+
+    <rule name="ReplaceEnumerationWithIterator"
+          language="java"
+          since="3.4"
+          message="Consider replacing this Enumeration with the newer java.util.Iterator"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#replaceenumerationwithiterator">
+        <description>
+Consider replacing Enumeration usages with the newer java.util.Iterator
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ImplementsList/ClassType[pmd-java:typeIsExactly('java.util.Enumeration')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo implements Enumeration {
+    private int x = 42;
+    public boolean hasMoreElements() {
+        return true;
+    }
+    public Object nextElement() {
+        return String.valueOf(i++);
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ReplaceHashtableWithMap"
+          language="java"
+          since="3.4"
+          message="Consider replacing this Hashtable with the newer java.util.Map"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#replacehashtablewithmap">
+        <description>
+Consider replacing Hashtable usage with the newer java.util.Map if thread safety is not required.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value><![CDATA[
+                //ClassType[pmd-java:typeIsExactly('java.util.Hashtable')]
+                ]]></value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    void bar() {
+        Hashtable h = new Hashtable();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ReplaceVectorWithList"
+          language="java"
+          since="3.4"
+          message="Consider replacing this Vector with the newer java.util.List"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#replacevectorwithlist">
+        <description>
+Consider replacing Vector usages with the newer java.util.ArrayList if expensive thread-safe operations are not required.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value><![CDATA[
+                //ClassType[pmd-java:typeIsExactly('java.util.Vector')]
+                ]]></value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+import java.util.Vector;
+public class Foo {
+    void bar() {
+        Vector v = new Vector();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="SimplifiableTestAssertion"
+          language="java"
+          since="6.37.0"
+          message="Assertion may be simplified using {0}"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.SimplifiableTestAssertionRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#simplifiabletestassertion">
+        <description>
+            Reports test assertions that may be simplified using a more specific
+            assertion method. This enables better error messages, and makes the
+            assertions more readable.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+import org.junit.Test;
+import static org.junit.Assert.*;
+
+class SomeTestClass {
+    Object a,b;
+    @Test
+    void testMethod() {
+        assertTrue(a.equals(b)); // could be assertEquals(a, b);
+        assertTrue(!a.equals(b)); // could be assertNotEquals(a, b);
+
+        assertTrue(!something); // could be assertFalse(something);
+        assertFalse(!something); // could be assertTrue(something);
+
+        assertTrue(a == b); // could be assertSame(a, b);
+        assertTrue(a != b); // could be assertNotSame(a, b);
+
+        assertTrue(a == null); // could be assertNull(a);
+        assertTrue(a != null); // could be assertNotNull(a);
+    }
+}
+            ]]>
+        </example>
+    </rule>
+
+    <rule name="SwitchStmtsShouldHaveDefault"
+          language="java"
+          since="1.0"
+          message="Switch statements should be exhaustive, add a default case (or missing enum branches)"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#switchstmtsshouldhavedefault">
+        <description>
+            Switch statements should be exhaustive, to make their control flow
+            easier to follow. This can be achieved by adding a `default` case, or,
+            if the switch is on an enum type, by ensuring there is one switch branch
+            for each enum constant.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value><![CDATA[
+                //SwitchStatement[@DefaultCase = false() and @ExhaustiveEnumSwitch = false()]
+            ]]></value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+class Foo {{
+    int x = 2;
+    switch (x) {
+      case 1: int j = 6;
+      case 2: int j = 8;
+      // missing default: here
+    }
+}}
+]]>
+        </example>
+    </rule>
+
+    <rule name="SystemPrintln"
+          language="java"
+          since="2.1"
+          message="Usage of System.out/err"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#systemprintln">
+        <description>
+References to System.(out|err).print are usually intended for debugging purposes and can remain in
+the codebase even in production code. By using a logger one can enable/disable this behaviour at
+will (and by priority) and avoid clogging the Standard out log.
+        </description>
+        <priority>2</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall[ starts-with(@MethodName, 'print') ]
+  /FieldAccess[ @Name = ('err', 'out') ]
+  /TypeExpression[ pmd-java:typeIsExactly('java.lang.System') ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+ <![CDATA[
+class Foo{
+    Logger log = Logger.getLogger(Foo.class.getName());
+    public void testA () {
+        System.out.println("Entering test");
+        // Better use this
+        log.fine("Entering test");
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnitTestAssertionsShouldIncludeMessage"
+          language="java"
+          since="1.04"
+          message="Unit test assertions should include a message"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnitTestAssertionsShouldIncludeMessageRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unittestassertionsshouldincludemessage">
+        <description>
+Unit assertions should include an informative message - i.e., use the three-argument version of
+`assertEquals()`, not the two-argument version.
+
+This rule supports tests using JUnit (3, 4 and 5) and TestNG.
+
+Note: This rule was named JUnitAssertionsShouldIncludeMessage before PMD 7.7.0.
+        </description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+public class Foo {
+    @Test
+    public void testSomething() {
+        assertEquals("foo", "bar");
+        // Use the form:
+        // assertEquals("Foo does not equals bar", "foo", "bar");
+        // instead
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnitTestContainsTooManyAsserts"
+          language="java"
+          since="5.0"
+          message="Unit tests should not contain more than ${maximumAsserts} assert(s)."
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnitTestContainsTooManyAssertsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unittestcontainstoomanyasserts">
+        <description>
+            Unit tests should not contain too many asserts. Many asserts are indicative of a complex test, for which
+            it is harder to verify correctness.  Consider breaking the test scenario into multiple, shorter test scenarios.
+            Customize the maximum number of assertions used by this Rule to suit your needs.
+
+            This rule checks for JUnit (3, 4 and 5) and TestNG Tests.
+
+            Note: This rule was named JUnitTestContainsTooManyAsserts before PMD 7.7.0.
+        </description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+public class MyTestCase {
+    // Ok
+    @Test
+    public void testMyCaseWithOneAssert() {
+        boolean myVar = false;
+        assertFalse("should be false", myVar);
+    }
+
+    // Bad, too many asserts (assuming max=1)
+    @Test
+    public void testMyCaseWithMoreAsserts() {
+        boolean myVar = false;
+        assertFalse("myVar should be false", myVar);
+        assertEquals("should equals false", false, myVar);
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnitTestShouldIncludeAssert"
+          language="java"
+          since="2.0"
+          message="This unit test should include assert() or fail()"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnitTestShouldIncludeAssertRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unittestshouldincludeassert">
+        <description>
+            Unit tests should include at least one assertion. This makes the tests more robust, and using assert
+            with messages provide the developer a clearer idea of what the test does.
+
+            This rule checks for JUnit (3, 4 and 5) and TestNG Tests.
+
+            Note: This rule was named JUnitTestsShouldIncludeAssert before PMD 7.7.0.
+        </description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+public class Foo {
+   @Test
+   public void testSomething() {
+      Bar b = findBar();
+      // This is better than having a NullPointerException
+      // assertNotNull("bar not found", b);
+      b.work();
+   }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnitTestShouldUseAfterAnnotation"
+          language="java"
+          since="4.0"
+          message="JUnit 4 tests that clean up tests should use the @After annotation, JUnit5 tests should use @AfterEach or @AfterAll"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unittestshoulduseafterannotation">
+        <description>
+            This rule detects methods called `tearDown()` that are not properly annotated as a cleanup method.
+            This is primarily intended to assist in upgrading from JUnit 3, where tear down methods were required to be called `tearDown()`.
+            To a lesser extent, this may help detect omissions under newer JUnit versions, as long as you are following this convention to name the methods.
+
+            JUnit 4 will only execute methods annotated with `@After` after running each test.
+            JUnit 5 introduced `@AfterEach` and `@AfterAll` annotations to execute methods after each test or after all tests in the class, respectively.
+
+            Note: This rule was named JUnit4TestShouldUseAfterAnnotation before PMD 7.7.0.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//MethodDeclaration[@Name='tearDown' and @Arity=0]
+    [not(ModifierList/Annotation[
+           pmd-java:typeIs('org.junit.After')
+        or pmd-java:typeIs('org.junit.jupiter.api.AfterEach')
+        or pmd-java:typeIs('org.junit.jupiter.api.AfterAll')
+        or pmd-java:typeIs('org.testng.annotations.AfterMethod')])]
+    (: Make sure this is a junit 4 class :)
+    [../MethodDeclaration[pmd-java:hasAnnotation('org.junit.Test')]]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+            <![CDATA[
+public class MyTest {
+    public void tearDown() {
+        bad();
+    }
+}
+public class MyTest2 {
+    @After public void tearDown() {
+        good();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnitTestShouldUseBeforeAnnotation"
+          language="java"
+          since="4.0"
+          message="JUnit 4 tests that set up tests should use the @Before annotation, JUnit5 tests should use @BeforeEach or @BeforeAll"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unittestshouldusebeforeannotation">
+        <description>
+            This rule detects methods called `setUp()` that are not properly annotated as a setup method.
+            This is primarily intended to assist in upgrading from JUnit 3, where setup methods were required to be called `setUp()`.
+            To a lesser extent, this may help detect omissions even under newer JUnit versions, as long as you are following this convention to name the methods.
+
+            JUnit 4 will only execute methods annotated with `@Before` before all tests.
+            JUnit 5 introduced `@BeforeEach` and `@BeforeAll` annotations to execute methods before each test or before all tests in the class, respectively.
+
+            Note: This rule was named JUnit4TestShouldUseBeforeAnnotation before PMD 7.7.0.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//MethodDeclaration[@Name='setUp' and @Arity=0]
+    [not(ModifierList/Annotation[
+           pmd-java:typeIs('org.junit.Before')
+        or pmd-java:typeIs('org.junit.jupiter.api.BeforeEach')
+        or pmd-java:typeIs('org.junit.jupiter.api.BeforeAll')
+        or pmd-java:typeIs('org.testng.annotations.BeforeMethod')])]
+    (: Make sure this is a junit 4 class :)
+    [../MethodDeclaration[pmd-java:hasAnnotation('org.junit.Test')]]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+            <![CDATA[
+public class MyTest {
+    public void setUp() {
+        bad();
+    }
+}
+public class MyTest2 {
+    @Before public void setUp() {
+        good();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnitTestShouldUseTestAnnotation"
+          language="java"
+          since="4.0"
+          message="Unit tests should use the @Test annotation or won't be run. In case of JUnit 5, test methods might use @RepeatedTest, @TestFactory, @TestTemplate or @ParameterizedTest annotations instead."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unittestshouldusetestannotation">
+        <description>
+            The rule will detect any test method starting with "test" that is not properly annotated, and will therefore not be run.
+
+            In JUnit 4, only methods annotated with the `@Test` annotation are executed.
+            In JUnit 5, one of the following annotations should be used for tests: `@Test`, `@RepeatedTest`, `@TestFactory`, `@TestTemplate` or `@ParameterizedTest`.
+            In TestNG, only methods annotated with the `@Test` annotation are executed.
+
+            Note: This rule was named JUnit4TestShouldUseTestAnnotation before PMD 7.7.0.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//ClassDeclaration[matches(@SimpleName, $testClassPattern) or pmd-java:typeIs('junit.framework.TestCase')]
+    (: a junit 3 method :)
+    /ClassBody/MethodDeclaration[
+        @Visibility="public"
+        and starts-with(@Name, 'test')
+        and not(ModifierList/Annotation[
+          pmd-java:typeIs('org.junit.Test')
+          or pmd-java:typeIs('org.junit.jupiter.api.Test')
+          or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+          or pmd-java:typeIs('org.junit.jupiter.api.TestFactory')
+          or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+          or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+          or pmd-java:typeIs('org.testng.annotations.Test')
+          ]
+        )
+    ]
+]]>
+                </value>
+            </property>
+            <property name="testClassPattern" type="Regex" description="The regex pattern used to identify test classes" value="Test" />
+        </properties>
+        <example>
+            <![CDATA[
+public class MyTest {
+    public void testBad() {
+        doSomething();
+    }
+
+    @Test
+    public void testGood() {
+        doSomething();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnnecessaryVarargsArrayCreation"
+          language="java"
+          since="7.1.0"
+          message="Unnecessary explicit array creation for varargs method call"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnnecessaryVarargsArrayCreationRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unnecessaryvarargsarraycreation">
+        <description>
+            Reports explicit array creation when a varargs is expected.
+            For instance:
+            ```java
+            Arrays.asList(new String[] { "foo", "bar", });
+            ```
+            can be replaced by:
+            ```java
+            Arrays.asList("foo", "bar");
+            ```
+        </description>
+        <priority>3</priority>
+        <example><![CDATA[
+import java.util.Arrays;
+
+class C {
+    static {
+        Arrays.asList(new String[]{"foo", "bar",});
+        // should be
+        Arrays.asList("foo", "bar");
+    }
+}
+            ]]></example>
+    </rule>
+
+
+    <rule name="UnusedAssignment"
+          language="java"
+          since="6.26.0"
+          message="The value assigned to this variable is never used or always overwritten"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedAssignmentRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedassignment">
+        <description>
+            Reports assignments to variables that are never used before the variable is overwritten,
+            or goes out of scope. Unused assignments are those for which
+            1. The variable is never read after the assignment, or
+            2. The assigned value is always overwritten by other assignments before the next read of
+            the variable.
+
+            The rule tracks assignements to fields of `this`, and static fields of the current class.
+            This may cause some false positives in timing-sensitive concurrent code, which the rule cannot detect.
+
+            The rule may be suppressed with the standard `@SuppressWarnings("unused")` tag.
+
+            The rule subsumes {% rule "UnusedLocalVariable" %}, and {% rule "UnusedFormalParameter" %}.
+            Those violations are filtered
+            out by default, in case you already have enabled those rules, but may be enabled with the property
+            `reportUnusedVariables`. Variables whose name starts with `ignored` or `unused` are filtered out, as
+            is standard practice for exceptions.
+
+            Limitations:
+            * The rule currently cannot know which method calls throw exceptions, or which exceptions they throw.
+            In the body of a try block, every method or constructor call is assumed to throw.  This may cause false-negatives.
+            The only other language construct that is assumed to throw is the `throw` statement, in particular,
+            things like `assert` statements, or NullPointerExceptions on dereference are ignored.
+            * The rule cannot resolve assignments across constructors, when they're called with the special
+            `this(...)` syntax. This may cause false-negatives.
+
+            Both of those limitations may be partly relaxed in PMD 7.
+        </description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+            class A {
+                // this field initializer is redundant,
+                // it is always overwritten in the constructor
+                int f = 1;
+
+                A(int f) {
+                    this.f = f;
+                }
+            }
+        ]]>
+        </example>
+        <example><![CDATA[
+class B {
+
+    int method(int i, int j) {
+        // this initializer is redundant,
+        // it is overwritten in all branches of the `if`
+        int k = 0;
+
+        // Both the assignments to k are unused, because k is
+        // not read after the if/else
+        // This may hide a bug: the programmer probably wanted to return k
+        if (i < j)
+            k = i;
+        else
+            k = j;
+
+        return j;
+    }
+
+}
+        ]]>
+
+        </example>
+        <example><![CDATA[
+class C {
+
+    int method() {
+        int i = 0;
+
+        checkSomething(++i);
+        checkSomething(++i);
+        checkSomething(++i);
+        checkSomething(++i);
+
+        // That last increment is not reported unless
+        // the property `checkUnusedPrefixIncrement` is
+        // set to `true`
+        // Technically it could be written (i+1), but it
+        // is not very important
+    }
+
+}
+        ]]>
+
+        </example>
+        <example><![CDATA[
+class C {
+
+    // variables that are truly unused (at most assigned to, but never accessed)
+    // are only reported if property `reportUnusedVariables` is true
+
+    void method(int param) { } // for example this method parameter
+
+    // even then, you can suppress the violation with an annotation:
+
+    void method(@SuppressWarning("unused") int param) { } // no violation, even if `reportUnusedVariables` is true
+
+    // For catch parameters, or for resources which don't need to be used explicitly,
+    // you can give a name that starts with "ignored" to ignore such warnings
+
+    {
+        try (Something ignored = Something.create()) {
+            // even if ignored is unused, it won't be flagged
+            // its purpose might be to side-effect in the create/close routines
+
+        } catch (Exception e) { // this is unused and will cause a warning if `reportUnusedVariables` is true
+            // you should choose a name that starts with "ignored"
+            return;
+        }
+    }
+
+}
+        ]]>
+
+        </example>
+    </rule>
+
+    <rule name="UnusedFormalParameter"
+          language="java"
+          since="0.8"
+          message="Avoid unused {0} parameters such as ''{1}''."
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedFormalParameterRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedformalparameter">
+        <description>
+Reports parameters of methods and constructors that are not referenced them in the method body.
+Parameters whose name starts with `ignored` or `unused` are filtered out.
+
+Removing unused formal parameters from public methods could cause a ripple effect through the code base.
+Hence, by default, this rule only considers private methods. To include non-private methods, set the
+`checkAll` property to `true`.
+
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    private void bar(String howdy) {
+        // howdy is not used
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnusedLocalVariable"
+          language="java"
+          since="0.1"
+          message="Avoid unused local variables such as ''{0}''."
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedLocalVariableRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedlocalvariable">
+        <description>
+Detects when a local variable is declared and/or assigned, but not used.
+Variables whose name starts with `ignored` or `unused` are filtered out.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    public void doSomething() {
+        int i = 5; // Unused
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnusedPrivateField"
+          since="0.1"
+          language="java"
+          message="Avoid unused private fields such as ''{0}''."
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedPrivateFieldRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedprivatefield">
+        <description>
+Detects when a private field is declared and/or assigned a value, but not used.
+
+Since PMD 6.50.0 private fields are ignored, if the fields are annotated with any annotation or the
+enclosing class has any annotation. Annotations often enable a framework (such as dependency injection, mocking
+or e.g. Lombok) which use the fields by reflection or other means. This usage can't be detected by static code analysis.
+Previously these frameworks where explicitly allowed by listing their annotations in the property
+"ignoredAnnotations", but that turned out to be prone of false positive for any not explicitly considered framework.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Something {
+    private static int FOO = 2; // Unused
+    private int i = 5; // Unused
+    private int j = 6;
+    public int addOne() {
+        return j++;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnusedPrivateMethod"
+          language="java"
+          since="0.7"
+          message="Avoid unused private methods such as ''{0}''."
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.UnusedPrivateMethodRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#unusedprivatemethod">
+        <description>
+Unused Private Method detects when a private method is declared but is unused.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Something {
+    private void foo() {} // unused
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseCollectionIsEmpty"
+          language="java"
+          since="3.9"
+          message="Substitute calls to size() == 0 (or size() != 0, size() &gt; 0, size() &lt; 1) with calls to isEmpty()"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.UseCollectionIsEmptyRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#usecollectionisempty">
+        <description>
+The isEmpty() method on java.util.Collection is provided to determine if a collection has any elements.
+Comparing the value of size() to 0 does not convey intent as well as the isEmpty() method.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    void good() {
+        List foo = getList();
+        if (foo.isEmpty()) {
+            // blah
+        }
+    }
+
+    void bad() {
+        List foo = getList();
+        if (foo.size() == 0) {
+            // blah
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+
+    <rule name="UseEnumCollections"
+          language="java"
+          since="7.3.0"
+          message="This collection could be an {0}"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.UseEnumCollectionsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#useenumcollections">
+        <description>
+            Wherever possible, use `EnumSet` or `EnumMap` instead of `HashSet` and `HashMap` when the keys
+            are of an enum type. The specialized enum collections are more space- and time-efficient.
+            This rule reports constructor expressions for hash sets or maps whose key
+            type is an enum type.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+            import java.util.EnumMap;
+            import java.util.HashSet;
+
+            enum Example {
+                A, B, C;
+
+                public static Set<Example> newSet() {
+                    return new HashSet<>(); // Could be EnumSet.noneOf(Example.class)
+                }
+
+                public static <V> Map<Example, V> newMap() {
+                    return new HashMap<>(); // Could be new EnumMap<>(Example.class)
+                }
+            }
+            ]]>
+        </example>
+    </rule>
+
+    <rule name="UseStandardCharsets"
+          language="java"
+          since="6.34.0"
+          minimumLanguageVersion="1.7"
+          message="Please use StandardCharsets constants"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#usestandardcharsets">
+        <description>
+Starting with Java 7, StandardCharsets provides constants for common Charset objects, such as UTF-8.
+Using the constants is less error prone, and can provide a small performance advantage compared to `Charset.forName(...)`
+since no scan across the internal `Charset` caches is needed.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall[@MethodName = 'forName'][pmd-java:typeIs('java.nio.charset.Charset')]
+    [
+        ArgumentList/StringLiteral
+            [@Image = ('"US-ASCII"', '"ISO-8859-1"', '"UTF-8"', '"UTF-16BE"', '"UTF-16LE"', '"UTF-16"')]
+    ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class UseStandardCharsets {
+    public void run() {
+
+        // looking up the charset dynamically
+        try (OutputStreamWriter osw = new OutputStreamWriter(out, Charset.forName("UTF-8"))) {
+            osw.write("test");
+        }
+
+        // best to use StandardCharsets
+        try (OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8)) {
+            osw.write("test");
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseTryWithResources"
+          language="java"
+          minimumLanguageVersion="1.7"
+          since="6.12.0"
+          message="Consider using a try-with-resources statement instead of explicitly closing the resource"
+          class="net.sourceforge.pmd.lang.java.rule.bestpractices.UseTryWithResourcesRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#usetrywithresources">
+        <description>
+Java 7 introduced the try-with-resources statement. This statement ensures that each resource is closed at the end
+of the statement. It avoids the need of explicitly closing the resources in a finally block. Additionally exceptions
+are better handled: If an exception occurred both in the `try` block and `finally` block, then the exception from
+the try block was suppressed. With the `try`-with-resources statement, the exception thrown from the try-block is
+preserved.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class TryWithResources {
+    public void run() {
+        InputStream in = null;
+        try {
+            in = openInputStream();
+            int i = in.read();
+        } catch (IOException e) {
+            e.printStackTrace();
+        } finally {
+            try {
+                if (in != null) in.close();
+            } catch (IOException ignored) {
+                // ignored
+            }
+        }
+
+        // better use try-with-resources
+        try (InputStream in2 = openInputStream()) {
+            int i = in2.read();
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseVarargs"
+          language="java"
+          minimumLanguageVersion="1.5"
+          since="5.0"
+          message="Consider using varargs for methods or constructors which take an array the last parameter."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#usevarargs">
+        <description>
+Java 5 introduced the varargs parameter declaration for methods and constructors. This syntactic
+sugar provides flexibility for users of these methods and constructors, allowing them to avoid
+having to deal with the creation of an array.
+
+Byte arrays in any method and String arrays in `public static void main(String[])` methods are ignored.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//FormalParameters[not(parent::MethodDeclaration[@Overridden=true() or @MainMethod=true()])]
+  /FormalParameter[position()=last()]
+   [@Varargs=false()]
+   [ArrayType[not(PrimitiveType[@Kind = "byte"] or ClassType[pmd-java:typeIs('java.lang.Byte')])]
+    or VariableId[ArrayDimensions] and (PrimitiveType[not(@Kind="byte")] or ClassType[not(pmd-java:typeIs('java.lang.Byte'))])]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    public void foo(String s, Object[] args) {
+        // Do something here...
+    }
+
+    public void bar(String s, Object... args) {
+        // Ahh, varargs tastes much better...
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="WhileLoopWithLiteralBoolean"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          language="java"
+          since="6.13.0"
+          message="The loop can be simplified."
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_bestpractices.html#whileloopwithliteralboolean">
+        <description>
+`do {} while (true);` requires reading the end of the statement before it is
+apparent that it loops forever, whereas `while (true) {}` is easier to understand.
+
+`do {} while (false);` is redundant, and if an inner variable scope is required,
+a block `{}` is sufficient.
+
+`while (false) {}` will never execute the block and can be removed in its entirety.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value><![CDATA[
+(: while loops with single boolean literal 'false', maybe parenthesized :)
+//WhileStatement/BooleanLiteral[@True = false()]
+|
+(: do-while loops with single boolean literal ('false' or 'true'), maybe parenthesized :)
+//DoStatement/BooleanLiteral
+|
+(: while loops with conditional or'ed boolean literals, maybe parenthesized :)
+//WhileStatement[(InfixExpression[@Operator = ('|', '||')])
+    (: no var access :)
+    [count(VariableAccess) = 0]
+    (: at least one false literal :)
+    [count(BooleanLiteral[@True = false()]) >= 1]]
+|
+(: while loops with conditional and'ed boolean literals, maybe parenthesized :)
+//WhileStatement[(InfixExpression[@Operator = ('&', '&&')])
+    (: at least one false literal :)
+    [count(BooleanLiteral[@True = false()]) >= 1]]
+|
+(: do-while loops with conditional or'ed boolean literals, maybe parenthesized :)
+//DoStatement[(InfixExpression[@Operator = ('|', '||')])
+    (: at least one true literal :)
+    [count(BooleanLiteral[@True = true()]) >= 1
+      (: or only boolean literal and no no var access :)
+      or count(BooleanLiteral) >= 1
+      and count(VariableAccess) = 0
+    ]]
+|
+(: do-while loops with conditional and'ed boolean literals, maybe parenthesized :)
+//DoStatement[(InfixExpression[@Operator = ('&', '&&')])
+    (: at least one false literal :)
+    [count(BooleanLiteral[@True = false()]) >= 1
+      (: or only boolean literal and no no var access :)
+      or count(BooleanLiteral) >= 1
+      and count(VariableAccess) = 0
+    ]]
+                ]]></value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Example {
+  {
+    while (true) { } // allowed
+    while (false) { } // disallowed
+    do { } while (true); // disallowed
+    do { } while (false); // disallowed
+    do { } while (false | false); // disallowed
+    do { } while (false || false); // disallowed
+  }
+}
+]]>
+        </example>
+    </rule>
+
+</ruleset>
diff --git a/pmd/resources/category/java/categories.properties b/pmd/resources/category/java/categories.properties
new file mode 100644
index 000000000..3189fd3ad
--- /dev/null
+++ b/pmd/resources/category/java/categories.properties
@@ -0,0 +1,13 @@
+#
+# BSD-style license; for more info see http://pmd.sourceforge.net/license.html
+#
+
+rulesets.filenames=\
+    category/java/bestpractices.xml,\
+    category/java/codestyle.xml,\
+    category/java/design.xml,\
+    category/java/documentation.xml,\
+    category/java/errorprone.xml,\
+    category/java/multithreading.xml,\
+    category/java/performance.xml,\
+    category/java/security.xml
diff --git a/pmd/resources/category/java/codestyle.xml b/pmd/resources/category/java/codestyle.xml
new file mode 100644
index 000000000..d525b0df9
--- /dev/null
+++ b/pmd/resources/category/java/codestyle.xml
@@ -0,0 +1,2101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<ruleset name="Code Style"
+         xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+    <description>
+        Rules which enforce a specific coding style.
+    </description>
+
+    <rule name="AtLeastOneConstructor"
+          language="java"
+          since="1.04"
+          message="Each class should declare at least one constructor"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.AtLeastOneConstructorRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#atleastoneconstructor">
+        <description>
+<![CDATA[
+Each non-static class should declare at least one constructor.
+Classes with solely static members are ignored, refer to [UseUtilityClassRule](pmd_rules_java_design.html#useutilityclass) to detect those.
+]]>
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+   // missing constructor
+  public void doSomething() { ... }
+  public void doOtherThing { ... }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidDollarSigns"
+          language="java"
+          since="1.5"
+          message="Avoid using dollar signs in variable/method/class/interface names"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#avoiddollarsigns">
+        <description>
+Avoid using dollar signs in variable/method/class/interface names.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+      //ClassDeclaration           [contains(@SimpleName, '$')]
+    | //EnumDeclaration            [contains(@SimpleName, '$')]
+    | //AnnotationTypeDeclaration  [contains(@SimpleName, '$')]
+    | //RecordDeclaration          [contains(@SimpleName, '$')]
+    | //VariableId                 [contains(@Name, '$')]
+    | //MethodDeclaration          [contains(@Name, '$')]
+
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Fo$o {  // not a recommended name
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidProtectedFieldInFinalClass"
+          language="java"
+          since="2.1"
+          message="Avoid protected fields in a final class.  Change to private or package access."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#avoidprotectedfieldinfinalclass">
+        <description>
+Do not use protected fields in final classes since they cannot be subclassed.
+Clarify your intent by using private or package access modifiers instead.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration[@Final = true()]
+/ClassBody
+/FieldDeclaration[@Visibility = "protected"]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public final class Bar {
+  private int x;
+  protected int y;  // bar cannot be subclassed, so is y really private or package visible?
+  Bar() {}
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidProtectedMethodInFinalClassNotExtending"
+          language="java"
+          since="5.1"
+          message="Avoid protected methods in a final class that doesn't extend anything other than Object.  Change to private or package access."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#avoidprotectedmethodinfinalclassnotextending">
+        <description>
+Do not use protected methods in most final classes since they cannot be subclassed. This should
+only be allowed in final classes that extend other classes with protected methods (whose
+visibility cannot be reduced). Clarify your intent by using private or package access modifiers instead.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration[@Final= true() and not(ExtendsList)]
+/ClassBody
+/MethodDeclaration[@Visibility="protected" and @Name != 'finalize']
+ ]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public final class Foo {
+  private int bar() {}
+  protected int baz() {} // Foo cannot be subclassed, and doesn't extend anything, so is baz() really private or package visible?
+}
+ ]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidUsingNativeCode"
+          language="java"
+          since="4.1"
+          message="The use of native code is not recommended."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#avoidusingnativecode">
+        <description>
+Unnecessary reliance on Java Native Interface (JNI) calls directly reduces application portability
+and increases the maintenance burden.
+        </description>
+        <priority>2</priority>
+        <properties>
+            <property name="xpath">
+                <value>//MethodCall[TypeExpression/ClassType[pmd-java:typeIs('java.lang.System')]
+                                    and @MethodName = 'loadLibrary']</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class SomeJNIClass {
+
+     public SomeJNIClass() {
+         System.loadLibrary("nativelib");
+     }
+
+     static {
+         System.loadLibrary("nativelib");
+     }
+
+     public void invalidCallsInMethod() throws SecurityException, NoSuchMethodException {
+         System.loadLibrary("nativelib");
+     }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="BooleanGetMethodName"
+          language="java"
+          since="4.0"
+          message="A 'getX()' method which returns a boolean should be named 'isX()'"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#booleangetmethodname">
+        <description>
+Methods that return boolean results should be named as predicate statements to denote this.
+I.e, 'isReady()', 'hasValues()', 'canCommit()', 'willFail()', etc.   Avoid the use of the 'get'
+prefix for these methods.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration
+    [starts-with(@Name, 'get')]
+    [@Arity = 0 or $checkParameterizedMethods = true()]
+    [ PrimitiveType[@Kind = 'boolean'] and @Overridden = false() ]
+]]>
+                </value>
+            </property>
+            <property name="checkParameterizedMethods" type="Boolean" description="Check parameterized methods" value="false"/>
+        </properties>
+        <example>
+<![CDATA[
+public boolean getFoo();            // bad
+public boolean isFoo();             // ok
+public boolean getFoo(boolean bar); // ok, unless checkParameterizedMethods=true
+]]>
+        </example>
+    </rule>
+
+    <rule name="CallSuperInConstructor"
+          language="java"
+          since="3.0"
+          message="It is a good practice to call super() in a constructor"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#callsuperinconstructor">
+        <description>
+It is a good practice to call super() in a constructor. If super() is not called but
+another constructor (such as an overloaded constructor) is called, this rule will not report it.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration[ExtendsList/*]
+  /ClassBody
+  /ConstructorDeclaration[ not(Block/ExplicitConstructorInvocation) ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo extends Bar{
+  public Foo() {
+   // call the constructor of Bar
+   super();
+  }
+ public Foo(int code) {
+  // do something with code
+   this();
+   // no problem with this
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ClassNamingConventions"
+          language="java"
+          since="1.2"
+          message="The {0} name ''{1}'' doesn''t match ''{2}''"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.ClassNamingConventionsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#classnamingconventions">
+        <description>
+            Configurable naming conventions for type declarations. This rule reports
+            type declarations which do not match the regex that applies to their
+            specific kind (e.g. enum or interface). Each regex can be configured through
+            properties.
+
+            By default, this rule uses the standard Java naming convention (Pascal case).
+            
+            The rule can detect utility classes and enforce a different naming convention
+            on those. E.g. setting the property `utilityClassPattern` to
+            `[A-Z][a-zA-Z0-9]+(Utils?|Helper|Constants)` reports any utility class, whose name
+            does not end in "Util(s)", "Helper" or "Constants".
+            
+            For this rule, a utility class is defined as: a concrete class that does not
+            inherit from a super class or implement any interface and only has static fields
+            or methods.
+
+            This rule detects test classes using the following convention: Test classes are top-level classes, that
+            either inherit from JUnit 3 TestCase or have at least one method annotated with the Test annotations from
+            JUnit4/5 or TestNG.
+        </description>
+        <priority>1</priority>
+        <example>
+<![CDATA[
+// This is Pascal case, the recommended naming convention in Java
+// Note that the default values of this rule don't allow underscores
+// or accented characters in type names
+public class FooBar {}
+
+// You may want abstract classes to be named 'AbstractXXX',
+// in which case you can customize the regex for abstract
+// classes to 'Abstract[A-Z]\w+'
+public abstract class Thing {}
+
+// This class doesn't respect the convention, and will be flagged
+public class Éléphant {}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CommentDefaultAccessModifier"
+          language="java"
+          since="5.4.0"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.CommentDefaultAccessModifierRule"
+          message="Missing commented default access modifier on {0} ''{1}''"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#commentdefaultaccessmodifier">
+        <description>
+To avoid mistakes if we want that an Annotation, Class, Enum, Method, Constructor or Field have a default access modifier
+we must add a comment at the beginning of its declaration.
+By default, the comment must be `/* default */` or `/* package */`, if you want another, you have to provide a regular expression.
+
+This rule ignores by default all cases that have a `@VisibleForTesting` annotation or any JUnit5/TestNG annotation. Use the
+property "ignoredAnnotations" to customize the recognized annotations.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    final String stringValue = "some string";
+    String getString() {
+       return stringValue;
+    }
+
+    class NestedFoo {
+    }
+}
+
+// should be
+public class Foo {
+    /* default */ final String stringValue = "some string";
+    /* default */ String getString() {
+       return stringValue;
+    }
+
+    /* default */ class NestedFoo {
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ConfusingTernary"
+          language="java"
+          since="1.9"
+          message="Avoid if (x != y) ..; else ..;"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.ConfusingTernaryRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#confusingternary">
+        <description>
+Avoid negation within an "if" expression with an "else" clause.  For example, rephrase:
+`if (x != y) diff(); else same();` as: `if (x == y) same(); else diff();`.
+
+Most "if (x != y)" cases without an "else" are often return cases, so consistent use of this
+rule makes the code easier to read.  Also, this resolves trivial ordering problems, such
+as "does the error case go first?" or "does the common case go first?".
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+boolean bar(int x, int y) {
+    return (x != y) ? diff : same;
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ControlStatementBraces"
+          language="java"
+          since="6.2.0"
+          message="This statement should have braces"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#controlstatementbraces">
+        <description>
+            Enforce a policy for braces on control statements. It is recommended to use braces on 'if ... else'
+            statements and loop statements, even if they are optional. This usually makes the code clearer, and
+            helps prepare the future when you need to add another statement. That said, this rule lets you control
+            which statements are required to have braces via properties.
+
+            From 6.2.0 on, this rule supersedes WhileLoopMustUseBraces, ForLoopMustUseBraces, IfStmtMustUseBraces,
+            and IfElseStmtMustUseBraces.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="checkIfElseStmt" type="Boolean" value="true" description="Require that 'if ... else' statements use braces" />
+            <property name="checkSingleIfStmt" type="Boolean" value="true" description="Require that 'if' statements with a single branch use braces" />
+            <property name="checkWhileStmt" type="Boolean" value="true" description="Require that 'while' loops use braces" />
+            <property name="checkForStmt" type="Boolean" value="true" description="Require that 'for' loops should use braces" />
+            <property name="checkDoWhileStmt" type="Boolean" value="true" description="Require that 'do ... while' loops use braces" />
+            <property name="checkCaseStmt" type="Boolean" value="false" description="Require that cases of a switch have braces"/>
+
+            <property name="allowEmptyLoop" type="Boolean" value="false" description="Allow loops with an empty statement, e.g. 'while(true);'" />
+            <property name="xpath">
+                <value><![CDATA[
+                //WhileStatement[$checkWhileStmt and not(Block) and not($allowEmptyLoop and EmptyStatement)]
+                |
+                //ForStatement[$checkForStmt and not(Block) and not($allowEmptyLoop and EmptyStatement)]
+                |
+                //ForeachStatement[$checkForStmt and not(Block) and not($allowEmptyLoop and EmptyStatement)]
+                |
+                //DoStatement[$checkDoWhileStmt and not(Block) and not($allowEmptyLoop and EmptyStatement)]
+                |
+                (: The violation is reported on the sub statement -- not the if statement :)
+                //IfStatement[$checkIfElseStmt]
+                    /*[position() > 1 and not(self::Block or self::IfStatement)]
+                      [ $checkSingleIfStmt
+                            (: Inside this (...) is the definition of a "single if statement" :)
+                            or not(parent::*/@Else = false() (: No else stmt :)
+                                   (: Not the last branch of an 'if ... else if' chain :)
+                                   and not(parent::IfStatement[parent::IfStatement]))]
+
+                |
+                (: Reports case labels if one of their subordinate statements is not braced :)
+                //SwitchFallthroughBranch[$checkCaseStmt]
+                             [count(*) > 1 and (count(*) > 2 or not(child::*[2]/self::Block))]
+                ]]></value>
+            </property>
+        </properties>
+        <example>
+            <![CDATA[
+while (true)    // not recommended
+  x++;
+
+while (true) {  // preferred approach
+  x++;
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="EmptyMethodInAbstractClassShouldBeAbstract"
+          language="java"
+          since="4.1"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="An empty method in an abstract class should be abstract instead"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#emptymethodinabstractclassshouldbeabstract">
+        <description>
+Empty or auto-generated methods in an abstract class should be tagged as abstract. This helps to remove their inapproprate
+usage by developers who should be implementing their own versions in the concrete subclasses.
+        </description>
+        <priority>1</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration[@RegularClass = true() and pmd-java:modifiers() = "abstract"]
+    /ClassBody
+    /MethodDeclaration
+    [Block[
+      let $size := count(*[not(self::EmptyStatement)])
+      return $size = 0
+             or $size = 1 and ReturnStatement[ NullLiteral or NumericLiteral[@ValueAsInt = 0] or StringLiteral[@Empty = true()]]
+    ]]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public abstract class ShouldBeAbstract {
+    public Object couldBeAbstract() {
+        // Should be abstract method ?
+        return null;
+    }
+
+    public void couldBeAbstract() {
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="EmptyControlStatement"
+          language="java"
+          since="6.46.0"
+          message="This control statement has an empty branch"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.EmptyControlStatementRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#emptycontrolstatement">
+        <!-- Note about naming: EmptyCodeBlock does not work because the rule flags `if(true);`  -->
+        <!-- EmptyControlStatement is weird because `{}` is not a control statement, and we also flag initializers. -->
+        <!-- EmptyStatement does not work because `;` is called an "empty statement" and is not flagged by this rule, rather, by UnnecessarySemicolon. -->
+        <!-- EmptyCodeConstruct would work but sounds a bit odd (right?). -->
+        <description><![CDATA[
+            Reports control statements whose body is empty, as well as empty initializers.
+
+            The checked code constructs are the following:
+            - bodies of `try` statements
+            - `finally` clauses of `try` statements
+            - `switch` statements
+            - `synchronized` statements
+            - `if` statements
+            - loop statements: `while`, `for`, `do .. while`
+            - initializers
+            - blocks used as statements (for scoping)
+
+            This rule replaces the rules EmptyFinallyBlock, 
+            EmptyIfStmt, EmptyInitializer, EmptyStatementBlock, 
+            EmptySwitchStatements, EmptySynchronizedBlock, EmptyTryBlock, and EmptyWhileStmt.
+
+            Notice that {% rule java/errorprone/EmptyCatchBlock %} is still an independent rule.
+
+            EmptyStatementNotInLoop is replaced by {% rule java/codestyle/UnnecessarySemicolon %}.
+        ]]></description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+class Foo {
+    {
+        if (true); // empty if statement
+        if (true) { // empty as well
+        }
+    }
+
+    {} // empty initializer
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ExtendsObject"
+          language="java"
+          since="5.0"
+          message="No need to explicitly extend Object."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#extendsobject">
+        <description>No need to explicitly extend Object.</description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ExtendsList/ClassType[pmd-java:typeIsExactly('java.lang.Object')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo extends Object {     // not required
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="FieldDeclarationsShouldBeAtStartOfClass"
+          language="java"
+          since="5.0"
+          message="Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes."
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.FieldDeclarationsShouldBeAtStartOfClassRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#fielddeclarationsshouldbeatstartofclass">
+        <description>
+Fields should be declared at the top of the class, before any method declarations, constructors, initializers or inner classes.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class HelloWorldBean {
+
+  // Field declared before methods / inner classes - OK
+  private String _thing;
+
+  public String getMessage() {
+    return "Hello World!";
+  }
+
+  // Field declared after methods / inner classes - avoid this
+  private String _fieldInWrongLocation;
+}
+]]>
+        </example>
+    </rule>
+
+
+    <rule name="FieldNamingConventions"
+          language="java"
+          since="6.7.0"
+          message="The {0} name ''{1}'' doesn''t match ''{2}''"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.FieldNamingConventionsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#fieldnamingconventions">
+        <description>
+            Configurable naming conventions for field declarations. This rule reports variable declarations
+            which do not match the regex that applies to their specific kind ---e.g. constants (static final),
+            enum constant, final field. Each regex can be configured through properties.
+
+            By default this rule uses the standard Java naming convention (Camel case), and uses the ALL_UPPER
+            convention for constants and enum constants.
+        </description>
+        <priority>1</priority>
+        <example>
+            <![CDATA[
+            class Foo {
+                int myField = 1; // This is in camel case, so it's ok
+                int my_Field = 1; // This contains an underscore, it's not ok by default
+                                  // but you may allow it, or even require the "my_" prefix
+
+                final int FinalField = 1; // you may configure a different convention for final fields,
+                                          // e.g. here PascalCase: [A-Z][a-zA-Z0-9]*
+
+                interface Interface {
+                    double PI = 3.14; // interface "fields" use the constantPattern property
+                }
+
+                enum AnEnum {
+                    ORG, NET, COM; // These use a separate property but are set to ALL_UPPER by default
+                }
+            }
+            ]]>
+        </example>
+    </rule>
+
+    <rule name="FinalParameterInAbstractMethod"
+          language="java"
+          since="6.42.0"
+          message="Final parameter in abstract method"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          typeResolution="true"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#finalparameterinabstractmethod">
+        <description>
+            Declaring a method parameter as final for an interface method is useless because the implementation may choose to not respect it.
+        </description>
+        <priority>1</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//MethodDeclaration
+    [FormalParameters/FormalParameter[@Final = true()]]
+    [not(Block)]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+            <![CDATA[
+public interface MyInterface {
+  void process(final Object arg); // Avoid using final here
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ForLoopShouldBeWhileLoop"
+          language="java"
+          since="1.02"
+          message="This for loop could be simplified to a while loop"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#forloopshouldbewhileloop">
+        <description>
+Some for loops can be simplified to while loops, this makes them more concise.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ForStatement[not(ForInit | ForUpdate) and count(*) = 2]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    void bar() {
+        for (;true;) true; // No Init or Update part, may as well be: while (true)
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="FormalParameterNamingConventions"
+          language="java"
+          since="6.6.0"
+          message="The {0} name ''{1}'' doesn''t match ''{2}''"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.FormalParameterNamingConventionsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#formalparameternamingconventions">
+        <description>
+            Configurable naming conventions for formal parameters of methods and lambdas.
+            This rule reports formal parameters which do not match the regex that applies to their
+            specific kind (e.g. lambda parameter, or final formal parameter). Each regex can be
+            configured through properties.
+
+            By default this rule uses the standard Java naming convention (Camel case).
+        </description>
+        <priority>1</priority>
+        <example>
+            <![CDATA[
+            class Foo {
+
+                abstract void bar(int myInt); // This is Camel case, so it's ok
+
+                void bar(int my_i) { // this will be reported
+
+                }
+
+                void lambdas() {
+
+                    // lambdas parameters can be configured separately
+                    Consumer<String> lambda1 = s_str -> { };
+
+                    // lambda parameters with an explicit type can be configured separately
+                    Consumer<String> lambda1 = (String str) -> { };
+
+                }
+
+            }
+            ]]>
+        </example>
+    </rule>
+
+    <rule name="GenericsNaming"
+          language="java"
+          since="4.2.6"
+          message="Generics names should be a one letter long and upper case."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#genericsnaming">
+        <description>
+Names for references to generic values should be limited to a single uppercase letter.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//TypeParameter[
+  string-length(@Name) > 1
+  or
+  upper-case(@Name) != @Name
+]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public interface GenericDao<E extends BaseModel, K extends Serializable> extends BaseDao {
+    // This is ok...
+}
+
+public interface GenericDao<E extends BaseModel, K extends Serializable> {
+    // Also this
+}
+
+public interface GenericDao<e extends BaseModel, K extends Serializable> {
+    // 'e' should be an 'E'
+}
+
+public interface GenericDao<EF extends BaseModel, K extends Serializable> {
+   // 'EF' is not ok.
+}
+]]>
+        </example>
+    </rule>
+
+
+    <rule name="IdenticalCatchBranches"
+          language="java"
+          since="6.4.0"
+          minimumLanguageVersion="1.7"
+          message="''catch'' branch identical to ''{0}'' branch"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.IdenticalCatchBranchesRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#identicalcatchbranches">
+        <description>
+            Identical `catch` branches use up vertical space and increase the complexity of code without
+            adding functionality. It's better style to collapse identical branches into a single multi-catch
+            branch.
+        </description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+try {
+    // do something
+} catch (IllegalArgumentException e) {
+    throw e;
+} catch (IllegalStateException e) { // Can be collapsed into the previous block
+    throw e;
+}
+
+try {
+    // do something
+} catch (IllegalArgumentException | IllegalStateException e) { // This is better
+    throw e;
+}
+            ]]>
+        </example>
+    </rule>
+
+
+    <rule name="LambdaCanBeMethodReference"
+          language="java"
+          since="7.1.0"
+          message="Lambda expression could be written as a method reference: `{0}`"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.LambdaCanBeMethodReferenceRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#lambdacanbemethodreference">
+        <description>
+            This rule reports lambda expressions that can be written more succinctly as a method reference. This is the case if the lambda is an expression lambda that only calls one method, passing the entire lambda parameter list in order to the method. For instance:
+            ```java
+                x -> Foo.call(x) // can be Foo::call
+                x -> call(x)     // can be this::call, if call is an instance method
+                (x, y, z) -> call(x, y, z) // can be this::call
+                () -> foo.get() // can be foo::get
+                x -> x.foo()    // can be XType::foo (where XType is the type of x)
+            ```
+
+            In some cases rewriting a lambda to a method reference can change the semantics of the code. For instance in `(x) -> someVar.call(x)`, the invocation of the lambda may produce a NullPointerException (NPE) if `someVar` is null. The method reference `someVar::call` will also NPE if `someVar` is null, but it will do so at the point the method reference is created, while the lambda is created without error and its NPE is only thrown if the lambda is invoked (which may be never). Code should probably not rely on this subtle semantic difference, therefore these potentially problematic lambdas are also reported by default. This behavior can be disabled by setting the property `ignoreIfMayNPE` to `true`.
+
+            The property `ignoreIfMayNPE` is true by default. By default, calls whose receiver is itself a method call are ignored, because they could cause side effects. This may be changed by setting the property `ignoreIfReceiverIsMethod` to `false`.
+
+            Scope limitations:
+            - This rule will not report lambdas of the form `x -> new CtorCall().something(x)`, because the semantics of the method reference would be to create a single new object, while the lambda creates one object per invocation.
+            - The rule cannot know if the qualifier of a method call performs side effects. This means `(x) -> sideEffectingMethod().foo(x)` will be reported. Suppress the warning in this case.
+        </description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+            import java.util.stream.Stream;
+
+            public class LambdaCanBeMethodReference {
+                static {
+                    Stream.of("abc", "d")
+                            .mapToInt(s -> s.length()) // could be String::length
+                            .reduce((x, y) -> Integer.sum(x, y)) // could be Integer::sum
+                            .getAsInt();
+                }
+            }
+            ]]>
+        </example>
+    </rule>
+
+    <rule name="LinguisticNaming"
+          language="java"
+          since="6.7.0"
+          message="Linguistics Antipattern - Method name and return type is inconsistent linguistically"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.LinguisticNamingRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#linguisticnaming">
+        <description>
+            This rule finds Linguistic Naming Antipatterns. It checks for fields, that are named, as if they should
+            be boolean but have a different type. It also checks for methods, that according to their name, should
+            return a boolean, but don't. Further, it checks, that getters return something and setters won't.
+            Finally, it checks that methods, that start with "to" - so called transform methods - actually return
+            something, since according to their name, they should convert or transform one object into another.
+            There is additionally an option, to check for methods that contain "To" in their name - which are
+            also transform methods. However, this is disabled by default, since this detection is prone to
+            false positives.
+
+            For more information, see [Linguistic Antipatterns - What They Are and How
+Developers Perceive Them](https://doi.org/10.1007/s10664-014-9350-8).
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class LinguisticNaming {
+    int isValid;    // the field name indicates a boolean, but it is an int.
+    boolean isTrue; // correct type of the field
+
+    void myMethod() {
+        int hasMoneyLocal;      // the local variable name indicates a boolean, but it is an int.
+        boolean hasSalaryLocal; // correct naming and type
+    }
+
+    // the name of the method indicates, it is a boolean, but the method returns an int.
+    int isValid() {
+        return 1;
+    }
+    // correct naming and return type
+    boolean isSmall() {
+        return true;
+    }
+
+    // the name indicates, this is a setter, but it returns something
+    int setName() {
+        return 1;
+    }
+
+    // the name indicates, this is a getter, but it doesn't return anything
+    void getName() {
+        // nothing to return?
+    }
+
+    // the name indicates, it transforms an object and should return the result
+    void toDataType() {
+        // nothing to return?
+    }
+    // the name indicates, it transforms an object and should return the result
+    void grapeToWine() {
+        // nothing to return?
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="LocalHomeNamingConvention"
+          language="java"
+          since="4.0"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="The Local Home interface of a Session EJB should be suffixed by 'LocalHome'"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#localhomenamingconvention">
+        <description>
+The Local Home interface of a Session EJB should be suffixed by 'LocalHome'.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration
+[
+    pmd-java:typeIs('javax.ejb.EJBLocalHome')
+    and not(ends-with(@SimpleName, 'LocalHome'))
+]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public interface MyBeautifulLocalHome extends javax.ejb.EJBLocalHome {} // proper name
+
+public interface MissingProperSuffix extends javax.ejb.EJBLocalHome {}  // non-standard name
+]]>
+        </example>
+    </rule>
+
+    <rule name="LocalInterfaceSessionNamingConvention"
+          language="java"
+          since="4.0"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="The Local Interface of a Session EJB should be suffixed by 'Local'"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#localinterfacesessionnamingconvention">
+        <description>
+The Local Interface of a Session EJB should be suffixed by 'Local'.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration
+[
+    pmd-java:typeIs('javax.ejb.EJBLocalObject')
+    and not(ends-with(@SimpleName, 'Local'))
+]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public interface MyLocal extends javax.ejb.EJBLocalObject {}                // proper name
+
+public interface MissingProperSuffix extends javax.ejb.EJBLocalObject {}    // non-standard name
+]]>
+        </example>
+    </rule>
+
+    <rule name="LocalVariableCouldBeFinal"
+          language="java"
+          since="2.2"
+          message="Local variable ''{0}'' could be declared final"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.LocalVariableCouldBeFinalRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#localvariablecouldbefinal">
+        <description>
+A local variable assigned only once can be declared final.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Bar {
+    public void foo () {
+    String txtA = "a";          // if txtA will not be assigned again it is better to do this:
+    final String txtB = "b";
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="LocalVariableNamingConventions"
+          language="java"
+          since="6.6.0"
+          message="The {0} name ''{1}'' doesn''t match ''{2}''"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.LocalVariableNamingConventionsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#localvariablenamingconventions">
+        <description>
+            Configurable naming conventions for local variable declarations and other locally-scoped
+            variables. This rule reports variable declarations which do not match the regex that applies to their
+            specific kind (e.g. final variable, or catch-clause parameter). Each regex can be configured through
+            properties.
+
+            By default this rule uses the standard Java naming convention (Camel case).
+        </description>
+        <priority>1</priority>
+        <example>
+            <![CDATA[
+            class Foo {
+                void bar() {
+                    int localVariable = 1; // This is in camel case, so it's ok
+                    int local_variable = 1; // This will be reported unless you change the regex
+
+                    final int i_var = 1; // final local variables can be configured separately
+
+                    try {
+                        foo();
+                    } catch (IllegalArgumentException e_illegal) {
+                        // exception block parameters can be configured separately
+                    }
+
+                }
+            }
+            ]]>
+        </example>
+    </rule>
+
+    <rule name="LongVariable"
+          language="java"
+          since="0.3"
+          message="Avoid excessively long variable names like {0}"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#longvariable">
+        <description>
+Fields, formal arguments, or local variable names that are too long can make the code difficult to follow.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="minimum" type="Integer" description="The variable length reporting threshold" min="1" max="100" value="17"/>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//VariableId[string-length(@Name) > $minimum]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Something {
+    int reallyLongIntName = -3;             // VIOLATION - Field
+    public static void main( String argumentsList[] ) { // VIOLATION - Formal
+        int otherReallyLongName = -5;       // VIOLATION - Local
+        for (int interestingIntIndex = 0;   // VIOLATION - For
+             interestingIntIndex < 10;
+             interestingIntIndex ++ ) {
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="MDBAndSessionBeanNamingConvention"
+          language="java"
+          since="4.0"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="SessionBean or MessageBean should be suffixed by Bean"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#mdbandsessionbeannamingconvention">
+        <description>
+The EJB Specification states that any MessageDrivenBean or SessionBean should be suffixed by 'Bean'.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration
+[
+    (pmd-java:typeIs('javax.ejb.SessionBean')
+     or pmd-java:typeIs('javax.ejb.MessageDrivenBean'))
+    and not(ends-with(@SimpleName, 'Bean'))
+]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class SomeBean implements SessionBean{}                  // proper name
+
+public class MissingTheProperSuffix implements SessionBean {}   // non-standard name
+]]>
+        </example>
+    </rule>
+
+    <rule name="MethodArgumentCouldBeFinal"
+          language="java"
+          since="2.2"
+          message="Parameter ''{0}'' is not assigned and could be declared final"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.MethodArgumentCouldBeFinalRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#methodargumentcouldbefinal">
+        <description>
+            Reports method and constructor parameters that can be made final because they are never reassigned within the body of the method.
+
+            This rule ignores unused parameters so as not to overlap with the rule {% rule java/bestpractices/UnusedFormalParameter %}.
+            It will also ignore the parameters of abstract methods.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+class Foo {
+    // reported, parameter can be declared final
+    public String foo1(String param) {
+        return param;
+    }
+    // not reported, parameter is declared final
+    public String foo2(final String param) {
+        return param.trim();
+    }
+    // not reported because param is unused
+    public String unusedParam(String param) {
+        return "abc";
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="MethodNamingConventions"
+          language="java"
+          since="1.2"
+          message="The {0} name ''{1}'' doesn''t match ''{2}''"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.MethodNamingConventionsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#methodnamingconventions">
+        <description>
+            Configurable naming conventions for method declarations. This rule reports
+            method declarations which do not match the regex that applies to their
+            specific kind (e.g. JUnit test or native method). Each regex can be
+            configured through properties.
+
+            By default this rule uses the standard Java naming convention (Camel case).
+        </description>
+        <priority>1</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    public void fooStuff() {
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="NoPackage"
+          language="java"
+          since="3.3"
+          message="All classes, interfaces, enums and annotations must belong to a named package"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#nopackage">
+        <description>
+Detects when a class, interface, enum or annotation does not have a package definition.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>/CompilationUnit[not(PackageDeclaration)]/*[pmd-java:nodeIs("TypeDeclaration")][1]</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+// no package declaration
+public class ClassInDefaultPackage {
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseUnderscoresInNumericLiterals"
+          language="java"
+          since="6.10.0"
+          minimumLanguageVersion="1.7"
+          message="Number {0} should separate every third digit with an underscore"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#useunderscoresinnumericliterals">
+        <description>
+            Since Java 1.7, numeric literals can use underscores to separate digits. This rule enforces that
+            numeric literals above a certain length use these underscores to increase readability.
+
+            The rule only supports decimal (base 10) literals for now. The acceptable length under which literals
+            are not required to have underscores is configurable via a property. Even under that length, underscores
+            that are misplaced (not making groups of 3 digits) are reported.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="acceptableDecimalLength" type="Integer" value="4" min="3" max="1000"
+                      description="Length under which literals in base 10 are not required to have underscores"/>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//NumericLiteral
+ (: Filter out literals in base other than 10 :)
+ [@Base = 10]
+ (: Filter out ignored field name :)
+ [not(ancestor::VariableDeclarator[1][@Name = 'serialVersionUID'])]
+ [
+   some $num in tokenize(@Image, "[dDfFlLeE+\-]")
+   satisfies not(
+                  ( contains($num, ".")
+                    and string-length(substring-before($num, ".")) <= $acceptableDecimalLength
+                    and string-length(substring-after($num, ".")) <= $acceptableDecimalLength
+                    or string-length($num) <= $acceptableDecimalLength
+                  )
+                  and not(contains($num,"_"))
+                  or matches($num, "^[0-9]{1,3}(_[0-9]{3})*(\.([0-9]{3}_)*[0-9]{1,3})?$")
+                )
+ ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+            <![CDATA[
+public class Foo {
+    private int num = 1000000; // should be 1_000_000
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="OnlyOneReturn"
+          language="java"
+          since="1.0"
+          message="A method should have only one exit point, and that should be the last statement in the method"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.OnlyOneReturnRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#onlyonereturn">
+        <description>
+A method should have only one exit point, and that should be the last statement in the method.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class OneReturnOnly1 {
+  public String foo(int x) {
+    if (x > 0) {
+      return "hey";   // first exit
+    }
+    return "hi";    // second exit
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="PackageCase"
+          language="java"
+          since="3.3"
+          message="Package name contains upper case characters"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#packagecase">
+        <description>
+Detects when a package definition contains uppercase characters.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>//PackageDeclaration[lower-case(@Name) != @Name]</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+package com.MyCompany;  // should be lowercase name
+
+public class SomeClass {
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="PrematureDeclaration"
+          language="java"
+          since="5.0"
+          message="Declaration of ''{0}'' can be moved closer to its usages"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.PrematureDeclarationRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#prematuredeclaration">
+        <description>
+Checks for variables that are defined before they might be used. A declaration is
+deemed to be premature if there are some statements that may return or throw an
+exception between the time the variable is declared and the time it is first read.
+
+Some variables cannot be declared close to their first usage because of side-effects
+occurring before they're first used. We try to avoid reporting those by considering
+most method and constructor invocations to be impure. See the second example.
+
+Note that this rule is meant to improve code readability but is not an optimization.
+A smart JIT will not care whether the variable is declared prematurely or not, as it
+can reorder code.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public int getLength(String[] strings) {
+
+    int length = 0; // could be moved closer to the loop
+
+    if (strings == null || strings.length == 0) return 0;
+
+    for (String str : strings) {
+        length += str.length();
+    }
+
+    return length;
+}
+]]>
+        </example>
+        <example>
+<![CDATA[
+public int getLength(String[] strings) {
+
+    int startTime = System.nanoTime(); // cannot be moved because initializer is impure
+
+    if (strings == null || strings.length == 0) {
+        // some error logic
+        throw new SomeException(...);
+    }
+
+    for (String str : strings) {
+        length += str.length();
+    }
+
+    return System.nanoTime() - startTime;
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="RemoteInterfaceNamingConvention"
+          language="java"
+          since="4.0"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="Remote Interface of a Session EJB should NOT be suffixed"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#remoteinterfacenamingconvention">
+        <description>
+Remote Interface of a Session EJB should not have a suffix.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration
+[
+    pmd-java:typeIs('javax.ejb.EJBObject')
+    and matches(@SimpleName, '.*(Session|EJB|Bean)$')
+]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+/* Poor Session suffix */
+public interface BadSuffixSession extends javax.ejb.EJBObject {}
+
+/* Poor EJB suffix */
+public interface BadSuffixEJB extends javax.ejb.EJBObject {}
+
+/* Poor Bean suffix */
+public interface BadSuffixBean extends javax.ejb.EJBObject {}
+]]>
+        </example>
+    </rule>
+
+    <rule name="RemoteSessionInterfaceNamingConvention"
+          language="java"
+          since="4.0"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="Remote Home interface of a Session EJB should be suffixed by 'Home'"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#remotesessioninterfacenamingconvention">
+        <description>
+A Remote Home interface type of a Session EJB should be suffixed by 'Home'.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration
+[
+    pmd-java:typeIs('javax.ejb.EJBHome')
+    and not(ends-with(@SimpleName, 'Home'))
+]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public interface MyBeautifulHome extends javax.ejb.EJBHome {}       // proper name
+
+public interface MissingProperSuffix extends javax.ejb.EJBHome {}   // non-standard name
+]]>
+        </example>
+    </rule>
+
+    <rule name="ShortClassName"
+          language="java"
+          since="5.0"
+          message="Avoid short class names like {0}"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#shortclassname">
+        <description>
+Short Classnames with fewer than e.g. five characters are not recommended.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="minimum" type="Integer" value="5" min="1" max="100" description="Number of characters that are required as a minimum for a class name."/>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration[string-length(@SimpleName) < $minimum]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ShortMethodName"
+          language="java"
+          since="0.3"
+          message="Avoid using short method names"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#shortmethodname">
+        <description>
+Method names that are very short are not helpful to the reader.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="minimum" type="Integer" value="3" min="1" max="100" description="Number of characters that are required as a minimum for a method name."/>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration[string-length(@Name) < $minimum]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class ShortMethod {
+    public void a( int i ) { // Violation
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ShortVariable"
+          language="java"
+          since="0.3"
+          message="Avoid variables with short names like {0}"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#shortvariable">
+        <description>
+Fields, local variables, enum constant names or parameter names that are very short are not helpful to the reader.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="minimum" type="Integer" value="3" min="1" max="100" description="Number of characters that are required as a minimum for a variable name."/>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//VariableId[string-length(@Name) < $minimum]
+ (: ForStatement :)
+ [not(../../parent::ForInit)]
+ (: Foreach statement :)
+ [not(../../parent::ForeachStatement)]
+ (: Catch statement parameter :)
+ [not(parent::CatchParameter)]
+ (: Lambda expression parameter :)
+ [not(parent::LambdaParameter)]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Something {
+    private int q = 15;                         // field - too short
+    public static void main( String as[] ) {    // formal arg - too short
+        int r = 20 + q;                         // local var - too short
+        for (int i = 0; i < 10; i++) {          // not a violation (inside 'for' loop)
+            r += q;
+        }
+        for (Integer i : numbers) {             // not a violation (inside 'for-each' loop)
+            r += q;
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="TooManyStaticImports"
+          language="java"
+          since="4.1"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="Too many static imports may lead to messy code"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#toomanystaticimports">
+        <description>
+If you overuse the static import feature, it can make your program unreadable and
+unmaintainable, polluting its namespace with all the static members you import.
+Readers of your code (including you, a few months after you wrote it) will not know
+which class a static member comes from (Sun 1.5 Language Guide).
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="maximumStaticImports" type="Integer"
+                      description="All static imports can be disallowed by setting this to 0" min="0" max="100" value="4"/>
+            <property name="xpath">
+                <value>
+<![CDATA[
+.[count(ImportDeclaration[@Static = true()]) > $maximumStaticImports]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+import static Lennon;
+import static Ringo;
+import static George;
+import static Paul;
+import static Yoko; // Too much !
+]]>
+        </example>
+    </rule>
+
+
+    <rule name="UnnecessaryAnnotationValueElement"
+          language="java"
+          since="6.2.0"
+          message="Avoid the use of value in annotations when it's the only element"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessaryannotationvalueelement">
+        <description>
+            Avoid the use of value in annotations when it's the only element.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//Annotation/AnnotationMemberList[count(*) = 1 and MemberValuePair[@Shorthand = false() and @Name = 'value']]
+]]>
+                </value>
+            </property>
+            <property name="java7Compatibility" type="Boolean" description="If disabled, the rule shows also violations that are applicable for java8+" value="false" />
+        </properties>
+        <example>
+            <![CDATA[
+@TestClassAnnotation(value = "TEST")
+public class Foo {
+
+    @TestMemberAnnotation(value = "TEST")
+    private String y;
+
+    @TestMethodAnnotation(value = "TEST")
+    public void bar() {
+        int x = 42;
+        return;
+    }
+}
+
+// should be
+
+@TestClassAnnotation("TEST")
+public class Foo {
+
+    @TestMemberAnnotation("TEST")
+    private String y;
+
+    @TestMethodAnnotation("TEST")
+    public void bar() {
+        int x = 42;
+        return;
+    }
+}
+
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnnecessaryBoxing"
+          language="java"
+          since="7.0.0"
+          minimumLanguageVersion="1.5"
+          message="Unnecessary {0}"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryBoxingRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessaryboxing">
+        <description>
+            Reports explicit boxing and unboxing conversions that may safely be removed,
+            either because they would be inserted by the compiler automatically,
+            or because they're semantically a noop (eg unboxing a value to rebox it immediately).
+
+            Note that this only handles boxing and unboxing conversions occurring through
+            calls to `valueOf` or one of the `intValue`, `byteValue`, etc. methods. Casts
+            that command a conversion are reported by {% rule UnnecessaryCast %} instead.
+        </description>
+        <priority>3</priority>
+        <example><![CDATA[
+{
+        // Instead of
+        Integer integer = Integer.valueOf(2);
+        // you may just write
+        Integer integer = 2;
+
+        int i = integer.intValue(); // similarly for unboxing
+
+        // Instead of
+        int x = Integer.valueOf("42");
+        // you may just write
+        int x = Integer.parseInt("42");
+}
+            ]]>
+        </example>
+    </rule>
+
+    <!-- This is only restricted to java 5+ because the rule doesn't support
+         the type system pre-java5, where there were no autoboxing conversions. -->
+    <rule name="UnnecessaryCast"
+          language="java"
+          minimumLanguageVersion="1.5"
+          since="6.24.0"
+          message="Unnecessary cast ({0})"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryCastRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessarycast">
+        <description><![CDATA[
+Detects casts which could be removed as the operand of the cast is already suitable
+for the context type. For instance, in the following:
+```
+Object context = (Comparable) "o";
+```
+The cast is unnecessary. This is because `String` already is a subtype of both
+`Comparable` and `Object`.
+
+This will also flag casts that can be avoided because of the autoboxing feature of Java 5.
+```
+Integer integer = (Integer) 1;
+```
+The literal would be autoboxed to `Integer` anyway.
+            ]]></description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+import java.util.function.Function;
+class SomeClass {
+   static {
+      Object o; long l; int i; Integer boxedInt;
+
+      // reference conversions
+
+      o = (Object) new SomeClass();      // unnecessary
+      o = (SomeClass) o;                 // necessary (narrowing cast)
+      o = (Comparable<String>) "string"; // unnecessary
+
+      // primitive conversions
+
+      l = (long) 2;   // unnecessary
+      l = (long) 2.0; // necessary (narrowing cast)
+      l = (byte) i;   // necessary (narrowing cast)
+
+      // boxing/unboxing casts (since java 5)
+
+      o = (Integer) 3;    // unnecessary (autoboxing would apply)
+      o = (long) 3;       // necessary (would be boxed to Long)
+      l = (int) boxedInt; // necessary (cannot cast Integer to long)
+
+      // casts that give a target type to a lambda/ method ref are necessary
+
+      o = (Function<Integer, String>) Integer::toString; // necessary (no target type)
+   }
+}
+]]>
+        </example>
+        <example>
+<![CDATA[
+import java.util.*;
+class SomeClass {
+   static {
+       /* Casts involving access to collections were common before Java 5, because collections
+        * were not generic. This rule may hence be useful when converting from using a raw
+        * type like `List` to a parameterized type like `List<String>`.
+        */
+       List<String> stringList = Arrays.asList("a", "b");
+       String element = (String) stringList.get(0); // this cast is unnecessary
+   }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnnecessaryConstructor"
+          language="java"
+          since="1.0"
+          message="Avoid unnecessary constructors - the compiler will generate these for you"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryConstructorRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessaryconstructor">
+        <description>
+This rule detects when a constructor is not necessary; i.e., when there is only one constructor and the
+constructor is identical to the default constructor. The default constructor should has same access
+modifier as the declaring class. In an enum type, the default constructor is implicitly private.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+  public Foo() {}
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnnecessaryFullyQualifiedName"
+          language="java"
+          since="5.0"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryFullyQualifiedNameRule"
+          message="Unnecessary qualifier ''{0}'': ''{1}'' is already in scope{2}"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessaryfullyqualifiedname">
+        <description>
+Import statements allow the use of non-fully qualified names.  The use of a fully qualified name
+which is covered by an import statement is redundant.  Consider using the non-fully qualified name.
+        </description>
+        <priority>4</priority>
+        <example>
+<![CDATA[
+import java.util.List;
+
+public class Foo {
+    private java.util.List list1;   // Unnecessary FQN
+    private List list2;             // More appropriate given import of 'java.util.List'
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnnecessaryImport"
+          language="java"
+          since="6.34.0"
+          message="Unnecessary import ''{0}''"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryImportRule"
+          typeResolution="true"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessaryimport">
+        <description>
+            Reports import statements that can be removed. They are either unused,
+            duplicated, or the members they import are already implicitly in scope,
+            because they're in java.lang, or the current package.
+
+            If some imports cannot be resolved, for instance because you run PMD with
+            an incomplete auxiliary classpath, some imports may be conservatively marked
+            as used even if they're not to avoid false positives.
+        </description>
+        <priority>4</priority>
+        <example>
+<![CDATA[
+            import java.io.File;            // not used, can be removed
+            import java.util.Collections;   // used below
+            import java.util.*;             // so this one is not used
+
+            import java.lang.Object;        // imports from java.lang, unnecessary
+            import java.lang.Object;        // duplicate, unnecessary
+
+            public class Foo {
+                static Object emptyList() {
+                    return Collections.emptyList();
+                }
+            }
+            ]]>
+        </example>
+    </rule>
+
+    <rule name="UnnecessaryLocalBeforeReturn"
+          language="java"
+          since="3.3"
+          message="Consider simply returning the value vs storing it in local variable ''{0}''"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryLocalBeforeReturnRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessarylocalbeforereturn">
+        <description>
+Avoid the creation of unnecessary local variables
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+   public int foo() {
+     int x = doSomething();
+     return x;  // instead, just 'return doSomething();'
+   }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnnecessaryModifier"
+          language="java"
+          since="1.02"
+          message="Unnecessary modifier{0} on {1} ''{2}''{3}"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryModifierRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessarymodifier">
+        <description>
+Fields in interfaces and annotations are automatically `public static final`, and methods are `public abstract`.
+Classes, interfaces or annotations nested in an interface or annotation are automatically `public static`
+(all nested interfaces and annotations are automatically static).
+Nested enums are automatically `static`.
+For historical reasons, modifiers which are implied by the context are accepted by the compiler, but are superfluous.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public @interface Annotation {
+    public abstract void bar();     // both abstract and public are ignored by the compiler
+    public static final int X = 0;  // public, static, and final all ignored
+    public static class Bar {}      // public, static ignored
+    public static interface Baz {}  // ditto
+}
+public interface Foo {
+    public abstract void bar();     // both abstract and public are ignored by the compiler
+    public static final int X = 0;  // public, static, and final all ignored
+    public static class Bar {}      // public, static ignored
+    public static interface Baz {}  // ditto
+}
+public class Bar {
+    public static interface Baz {}  // static ignored
+    public static enum FoorBar {    // static ignored
+        FOO;
+    }
+}
+public class FooClass {
+    static record BarRecord() {}     // static ignored
+}
+public interface FooInterface {
+    static record BarRecord() {}     // static ignored
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnnecessaryReturn"
+          language="java"
+          since="1.3"
+          message="Unnecessary return statement"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.UnnecessaryReturnRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessaryreturn">
+        <description>
+Avoid the use of unnecessary return statements. A return is unnecessary when no
+instructions follow anyway.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    public void bar() {
+        int x = 42;
+        return;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnnecessarySemicolon"
+          language="java"
+          since="6.46.0"
+          message="Unnecessary semicolon"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#unnecessarysemicolon">
+        <description>
+            Reports unnecessary semicolons (so called "empty statements" and "empty declarations").
+            These can be removed without changing the program. The Java grammar
+            allows them for historical reasons, but they should be avoided.
+            
+            This rule will not report empty statements that are syntactically 
+            required, for instance, because they are the body of a control statement.
+
+            This rule replaces EmptyStatementNotInLoop.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value><![CDATA[
+      (: empty declarations :)
+      //EmptyDeclaration
+      (: empty statements :)
+    | //Block/EmptyStatement
+
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+class Foo {
+    {
+        toString();; // one of these semicolons is unnecessary
+        if (true); // this semicolon is not unnecessary, but it could be an empty block instead (not reported)
+    }
+}; // this semicolon is unnecessary
+
+]]>
+        </example>
+    </rule>
+
+
+    <rule name="UseDiamondOperator"
+          language="java"
+          since="6.11.0"
+          message="Explicit type arguments can be replaced by a diamond: `{0}`"
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.UseDiamondOperatorRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#usediamondoperator"
+          minimumLanguageVersion="1.7">
+        <description><![CDATA[
+In some cases, explicit type arguments in a constructor call for a generic type
+may be replaced by diamond type arguments (`<>`), and be inferred by the compiler.
+This rule recommends that you use diamond type arguments anywhere possible, since
+it avoids duplication of the type arguments, and makes the code more concise and readable.
+
+This rule is useful when upgrading a codebase to Java 1.7, Java 1.8, or Java 9.
+The diamond syntax was first introduced in Java 1.7. In Java 8, improvements in Java's
+type inference made more type arguments redundant. In Java 9, type arguments inference
+was made possible for anonymous class constructors.
+            ]]></description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+            import java.util.*;
+            class Foo {
+                static {
+                    List<String> strings;
+                    strings = new ArrayList<String>(); // unnecessary duplication of type parameters
+                    strings = new ArrayList<>();       // using diamond type arguments is more concise
+
+                    strings = new ArrayList(); // accidental use of a raw type, you can use ArrayList<> instead
+
+                    strings = new ArrayList<>() {
+                        // for anonymous classes, this is possible since Java 9 only
+                    };
+                }
+            }
+            ]]>
+        </example>
+    </rule>
+
+    <rule name="UseExplicitTypes"
+          language="java"
+          minimumLanguageVersion="10"
+          since="7.0.0"
+          message="Use Explicit Types"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#useexplicittypes">
+        <description>
+Java 10 introduced the `var` keyword. This reduces the amount of code written because java can infer the type
+from the initializer of the variable declaration.
+
+This is essentially a trade-off: On the one hand, it can make code more readable by eliminating redundant
+information. On the other hand, it can make code less readable by eliding useful information. There is no
+blanket rule for when `var` should be used or shouldn't.
+
+It may make sense to use `var` when the type is inherently clear upon reading the statement
+(ie: assignment to either a literal value or a constructor call). Those use cases
+can be enabled through properties.
+
+Notice that lambda parameters are allowed, as they are already inferred  by default (the `var` keyword
+is completely optional).
+
+See also [Local Variable Type Inference Style Guidelines](https://openjdk.org/projects/amber/guides/lvti-style-guide).
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="allowLiterals" type="Boolean" value="false" description="Allow when variables are directly initialized with literals"/>
+            <property name="allowCtors" type="Boolean" value="false" description="Allow when variables are directly initialized with a constructor call"/>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//LocalVariableDeclaration[@TypeInferred = true()]
+    [not(VariableDeclarator[*[pmd-java:nodeIs("Literal")]]) or $allowLiterals = false()]
+    [not(VariableDeclarator[ConstructorCall]) or $allowCtors = false()]
+]]>
+                </value>
+            </property>
+        </properties>
+    </rule>
+
+    <rule name="UselessParentheses"
+          language="java"
+          since="5.0"
+          message="Useless parentheses."
+          class="net.sourceforge.pmd.lang.java.rule.codestyle.UselessParenthesesRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#uselessparentheses">
+        <description>
+            Parenthesized expressions are used to override the default operator precedence
+            rules. Parentheses whose removal would not change the relative nesting of operators
+            are unnecessary, because they don't change the semantics of the enclosing expression.
+
+            Some parentheses that strictly speaking are unnecessary, may still be considered useful
+            for readability. This rule allows to ignore violations on two kinds of unnecessary parentheses:
+            - "Clarifying" parentheses, which separate operators of difference precedence. While
+            unnecessary, they make precedence rules explicit, which may be useful for rarely used
+            operators. For example:
+            ```java
+                (a + b) &amp; c // is equivalent to `a + b &amp; c`, but probably clearer
+            ```
+            Unset the property `ignoreClarifying` to report them.
+
+            - "Balancing" parentheses, which are unnecessary but visually balance out another pair
+            of parentheses around an equality operator. For example, those two expressions are equivalent:
+            ```java
+                (a == null) != (b == null)
+                a == null != (b == null)
+            ```
+            The parentheses on the right are required, and the parentheses on the left are
+            just more visually pleasing. Unset the property `ignoreBalancing` to report them.
+
+        </description>
+        <priority>4</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    {
+        int n = 0;
+        n = (n);         // here
+        n = (n * 2) * 3; // and here
+        n = n * (2 * 3); // and here
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UselessQualifiedThis"
+          language="java"
+          since="5.4.0"
+          message="Useless qualified this usage in the same class."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#uselessqualifiedthis">
+        <description>
+            Reports qualified this usages in the same class.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ThisExpression/ClassType
+[ ancestor::*[pmd-java:nodeIs('TypeDeclaration')][1]/@SimpleName = ./@SimpleName ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    final Foo otherFoo = Foo.this;  // use "this" directly
+
+    public void doSomething() {
+         final Foo anotherFoo = Foo.this;  // use "this" directly
+    }
+
+    private ActionListener returnListener() {
+        return new ActionListener() {
+            @Override
+            public void actionPerformed(ActionEvent e) {
+                doSomethingWithQualifiedThis(Foo.this);  // This is fine
+            }
+        };
+    }
+
+    private class Foo3 {
+        final Foo myFoo = Foo.this;  // This is fine
+    }
+
+    private class Foo2 {
+        final Foo2 myFoo2 = Foo2.this;  // Use "this" direclty
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseShortArrayInitializer"
+        language="java"
+        since="6.15.0"
+        message="Array initialization can be written shorter"
+        class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+        externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_codestyle.html#useshortarrayinitializer">
+        <description>
+<![CDATA[
+When declaring and initializing array fields or variables, it is not necessary to explicitly create a new array
+using `new`. Instead one can simply define the initial content of the array as a expression in curly braces.
+
+E.g. `int[] x = new int[] { 1, 2, 3 };` can be written as `int[] x = { 1, 2, 3 };`.
+]]>
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value><![CDATA[
+//VariableDeclarator
+    [VariableId[@TypeInferred = false() and @ArrayType = true()]]
+    [ArrayAllocation/ArrayInitializer]
+                ]]></value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+Foo[] x = new Foo[] { ... }; // Overly verbose
+Foo[] x = { ... }; //Equivalent to above line
+]]>
+        </example>
+    </rule>
+</ruleset>
diff --git a/pmd/resources/category/java/design.xml b/pmd/resources/category/java/design.xml
new file mode 100644
index 000000000..37ca5dc3c
--- /dev/null
+++ b/pmd/resources/category/java/design.xml
@@ -0,0 +1,1534 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<ruleset name="Design"
+    xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+    <description>
+Rules that help you discover design issues.
+    </description>
+
+    <rule name="AbstractClassWithoutAnyMethod"
+          language="java"
+          since="4.2"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="No abstract method which means that the keyword is most likely used to prevent instantiation. Use a private or protected constructor instead."
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#abstractclasswithoutanymethod">
+        <description>
+If an abstract class does not provide any methods, it may be acting as a simple data container
+that is not meant to be instantiated. In this case, it is probably better to use a private or
+protected constructor in order to prevent instantiation than make the class misleadingly abstract.
+        </description>
+        <priority>1</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration
+    [@Abstract = true() and @Interface = false()]
+    [ClassBody[not(ConstructorDeclaration | MethodDeclaration)]]
+    [not(pmd-java:hasAnnotation('com.google.auto.value.AutoValue')
+         or pmd-java:hasAnnotation('lombok.AllArgsConstructor')
+         or pmd-java:hasAnnotation('lombok.NoArgsConstructor')
+         or pmd-java:hasAnnotation('lombok.RequiredArgsConstructor'))
+    ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public abstract class Example {
+    String field;
+    int otherField;
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidCatchingGenericException"
+          since="4.2.6"
+          language="java"
+          message="Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoidcatchinggenericexception">
+        <description>
+Avoid catching generic exceptions such as NullPointerException, RuntimeException, Exception in try-catch block.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//CatchParameter//ClassType[
+        pmd-java:typeIsExactly('java.lang.NullPointerException') or
+        pmd-java:typeIsExactly('java.lang.Exception') or
+        pmd-java:typeIsExactly('java.lang.RuntimeException')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+package com.igate.primitive;
+
+public class PrimitiveType {
+
+    public void downCastPrimitiveType() {
+        try {
+            System.out.println(" i [" + i + "]");
+        } catch(Exception e) {
+            e.printStackTrace();
+        } catch(RuntimeException e) {
+            e.printStackTrace();
+        } catch(NullPointerException e) {
+            e.printStackTrace();
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidDeeplyNestedIfStmts"
+          language="java"
+          since="1.0"
+          message="Deeply nested if..then statements are hard to read"
+          class="net.sourceforge.pmd.lang.java.rule.design.AvoidDeeplyNestedIfStmtsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoiddeeplynestedifstmts">
+        <description>
+Avoid creating deeply nested if-then statements since they are harder to read and error-prone to maintain.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+  public void bar(int x, int y, int z) {
+    if (x>y) {
+      if (y>z) {
+        if (z==x) {
+         // !! too deep
+        }
+      }
+    }
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidRethrowingException"
+          language="java"
+          since="3.8"
+          message="A catch statement that catches an exception only to rethrow it should be avoided."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoidrethrowingexception">
+        <description>
+Catch blocks that merely rethrow a caught exception only add to code size and runtime complexity.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//CatchClause[
+  CatchParameter/VariableId/@Name
+= Block[@Size = 1]/ThrowStatement/VariableAccess/@Name]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public void bar() {
+    try {
+        // do something
+    }  catch (SomeException se) {
+       throw se;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidThrowingNewInstanceOfSameException"
+          since="4.2.5"
+          language="java"
+          message="A catch statement that catches an exception only to wrap it in a new instance of the same type of exception and throw it should be avoided"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoidthrowingnewinstanceofsameexception">
+        <description>
+Catch blocks that merely rethrow a caught exception wrapped inside a new instance of the same type only add to
+code size and runtime complexity.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//CatchClause
+    [count(Block/*) = 1]
+    [CatchParameter/ClassType/@SimpleName = Block/ThrowStatement/ConstructorCall/ClassType/@SimpleName]
+    [Block/ThrowStatement/ConstructorCall/ArgumentList/@Size = 1]
+    /Block/ThrowStatement/ConstructorCall
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public void bar() {
+    try {
+        // do something
+    } catch (SomeException se) {
+        // harmless comment
+        throw new SomeException(se);
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidThrowingNullPointerException"
+          language="java"
+          since="1.8"
+          message="Avoid throwing null pointer exceptions."
+          class="net.sourceforge.pmd.lang.java.rule.design.AvoidThrowingNullPointerExceptionRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoidthrowingnullpointerexception">
+        <description>
+<![CDATA[
+Avoid throwing NullPointerExceptions manually. These are confusing because most people will assume that the
+virtual machine threw it.  To avoid a method being called with a null parameter, you may consider
+using an IllegalArgumentException instead, making it clearly seen as a programmer-initiated exception.
+However, there are better ways to handle this:
+
+>*Effective Java, 3rd Edition, Item 72: Favor the use of standard exceptions*
+>
+>Arguably, every erroneous method invocation boils down to an illegal argument or state,
+but other exceptions are standardly used for certain kinds of illegal arguments and states.
+If a caller passes null in some parameter for which null values are prohibited, convention dictates that
+NullPointerException be thrown rather than IllegalArgumentException.
+
+To implement that, you are encouraged to use `java.util.Objects.requireNonNull()`
+(introduced in Java 1.7). This method is designed primarily for doing parameter
+validation in methods and constructors with multiple parameters.
+
+Your parameter validation could thus look like the following:
+```
+public class Foo {
+    private String exampleValue;
+
+    void setExampleValue(String exampleValue) {
+      // check, throw and assignment in a single standard call
+      this.exampleValue = Objects.requireNonNull(exampleValue, "exampleValue must not be null!");
+    }
+  }
+```
+]]>
+        </description>
+        <priority>1</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    void bar() {
+        throw new NullPointerException();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidThrowingRawExceptionTypes"
+          language="java"
+          since="1.8"
+          message="Avoid throwing raw exception types."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoidthrowingrawexceptiontypes">
+        <description>
+Avoid throwing certain exception types. Rather than throw a raw RuntimeException, Throwable,
+Exception, or Error, use a subclassed exception or error instead.
+        </description>
+        <priority>1</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ThrowStatement//ConstructorCall
+ /ClassType[
+ pmd-java:typeIsExactly('java.lang.Throwable')
+or
+ pmd-java:typeIsExactly('java.lang.Exception')
+or
+ pmd-java:typeIsExactly('java.lang.Error')
+or
+ pmd-java:typeIsExactly('java.lang.RuntimeException')
+]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    public void bar() throws Exception {
+        throw new Exception();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidUncheckedExceptionsInSignatures"
+          since="6.13.0"
+          language="java"
+          message="A method or constructor should not explicitly declare unchecked exceptions in its ''throws'' clause"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#avoiduncheckedexceptionsinsignatures">
+        <description>
+Reports unchecked exceptions in the `throws` clause of a method or constructor.
+Java doesn't force the caller to handle an unchecked exception,
+so it's unnecessary except for documentation. A better practice is to document the
+exceptional cases with a `@throws` Javadoc tag, which allows being more descriptive.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ThrowsList/ClassType[pmd-java:typeIs('java.lang.RuntimeException')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public void foo() throws RuntimeException {
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ClassWithOnlyPrivateConstructorsShouldBeFinal"
+          language="java"
+          since="4.1"
+          class="net.sourceforge.pmd.lang.java.rule.design.ClassWithOnlyPrivateConstructorsShouldBeFinalRule"
+          message="This class has only private constructors and may be final"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#classwithonlyprivateconstructorsshouldbefinal">
+        <description>
+Reports classes that may be made final because they cannot be extended from outside
+their compilation unit anyway. This is because all their constructors are private,
+so a subclass could not call the super constructor.
+        </description>
+        <priority>1</priority>
+        <example>
+<![CDATA[
+public class Foo {  //Should be final
+    private Foo() { }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CollapsibleIfStatements"
+          language="java"
+          since="3.1"
+          message="This if statement could be combined with its parent"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#collapsibleifstatements">
+        <description><![CDATA[
+Reports nested 'if' statements that can be merged together by joining their
+conditions with a boolean `&&` operator in between.
+        ]]></description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//IfStatement[@Else = false()]/IfStatement[@Else = false()]
+|
+//IfStatement[@Else = false()]/Block[count(*) = 1]/IfStatement[@Else = false()]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+class Foo {
+
+    void bar() {
+        if (x) {            // original implementation
+            if (y) {
+                // do stuff
+            }
+        }
+    }
+
+    void bar() {
+        if (x && y) {        // clearer implementation
+            // do stuff
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CouplingBetweenObjects"
+          language="java"
+          since="1.04"
+          message="High amount of different objects as members denotes a high coupling"
+          class="net.sourceforge.pmd.lang.java.rule.design.CouplingBetweenObjectsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#couplingbetweenobjects">
+        <description>
+This rule counts the number of unique attributes, local variables, and return types within an object.
+A number higher than the specified threshold can indicate a high degree of coupling.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+import com.Blah;
+import org.Bar;
+import org.Bardo;
+
+public class Foo {
+    private Blah var1;
+    private Bar var2;
+
+    //followed by many imports of unique objects
+    ObjectC doWork() {
+        Bardo var55;
+        ObjectA var44;
+        ObjectZ var93;
+        return something();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CognitiveComplexity"
+        language="java"
+        message="The {0} ''{1}'' has a cognitive complexity of {2}, current threshold is {3}"
+        since="6.35.0"
+        class="net.sourceforge.pmd.lang.java.rule.design.CognitiveComplexityRule"
+        externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#cognitivecomplexity">
+        <description><![CDATA[
+            Methods that are highly complex are difficult to read and more costly to maintain. If you include too much decisional
+            logic within a single method, you make its behavior hard to understand and more difficult to modify.
+
+            Cognitive complexity is a measure of how difficult it is for humans to read and understand a method. Code that contains
+            a break in the control flow is more complex, whereas the use of language shorthands doesn't increase the level of
+            complexity. Nested control flows can make a method more difficult to understand, with each additional nesting of the
+            control flow leading to an increase in cognitive complexity.
+
+            Information about Cognitive complexity can be found in the original paper here:
+            <https://www.sonarsource.com/docs/CognitiveComplexity.pdf>
+
+            By default, this rule reports methods with a complexity of 15 or more. Reported methods should be broken down into less
+            complex components.
+        ]]></description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+public class Foo {
+  // Has a cognitive complexity of 0
+  public void createAccount() {
+    Account account = new Account("PMD");
+    // save account
+  }
+
+  // Has a cognitive complexity of 1
+  public Boolean setPhoneNumberIfNotExisting(Account a, String phone) {
+    if (a.phone == null) {                          // +1
+      a.phone = phone;
+      return true;
+    }
+
+    return false;
+  }
+
+  // Has a cognitive complexity of 4
+  public void updateContacts(List<Contact> contacts) {
+    List<Contact> contactsToUpdate = new ArrayList<Contact>();
+
+    for (Contact contact : contacts) {                           // +1
+      if (contact.department.equals("Finance")) {                // +2 (nesting = 1)
+        contact.title = "Finance Specialist";
+        contactsToUpdate.add(contact);
+      } else if (contact.department.equals("Sales")) {           // +1
+        contact.title = "Sales Specialist";
+        contactsToUpdate.add(contact);
+      }
+    }
+    // save contacts
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CyclomaticComplexity"
+          language="java"
+          message="The {0} ''{1}'' has a{2} cyclomatic complexity of {3}."
+          since="1.03"
+          class="net.sourceforge.pmd.lang.java.rule.design.CyclomaticComplexityRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#cyclomaticcomplexity">
+        <description><![CDATA[
+The complexity of methods directly affects maintenance costs and readability. Concentrating too much decisional logic
+in a single method makes its behaviour hard to read and change.
+
+Cyclomatic complexity assesses the complexity of a method by counting the number of decision points in a method,
+plus one for the method entry. Decision points are places where the control flow jumps to another place in the
+program. As such, they include all control flow statements, such as `if`, `while`, `for`, and `case`. For more
+details on the calculation, see the documentation {% jdoc java::lang.java.metrics.JavaMetrics#CYCLO %}.
+
+Generally, numbers ranging from 1-4 denote low complexity, 5-7 denote moderate complexity, 8-10 denote
+high complexity, and 11+ is very high complexity. By default, this rule reports methods with a complexity >= 10.
+Additionally, classes with many methods of moderate complexity get reported as well once the total of their
+methods' complexities reaches 80, even if none of the methods was directly reported.
+
+Reported methods should be broken down into several smaller methods. Reported classes should probably be broken down
+into subcomponents.]]>
+        </description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+class Foo {
+  void baseCyclo() {                // Cyclo = 1
+    highCyclo();
+  }
+
+  void highCyclo() {                // Cyclo = 10: reported!
+    int x = 0, y = 2;
+    boolean a = false, b = true;
+
+    if (a && (y == 1 ? b : true)) { // +3
+      if (y == x) {                 // +1
+        while (true) {              // +1
+          if (x++ < 20) {           // +1
+            break;                  // +1
+          }
+        }
+      } else if (y == t && !d) {    // +2
+        x = a ? y : x;              // +1
+      } else {
+        x = 2;
+      }
+    }
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="DataClass"
+          language="java"
+          since="6.0.0"
+          message="The class ''{0}'' is suspected to be a Data Class (WOC={1}, NOPA={2}, NOAM={3}, WMC={4})"
+          class="net.sourceforge.pmd.lang.java.rule.design.DataClassRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#dataclass">
+        <description>
+Data Classes are simple data holders, which reveal most of their state, and
+without complex functionality. The lack of functionality may indicate that
+their behaviour is defined elsewhere, which is a sign of poor data-behaviour
+proximity. By directly exposing their internals, Data Classes break encapsulation,
+and therefore reduce the system's maintainability and understandability. Moreover,
+classes tend to strongly rely on their data representation, which makes for a brittle
+design.
+
+Refactoring a Data Class should focus on restoring a good data-behaviour proximity. In
+most cases, that means moving the operations defined on the data back into the class.
+In some other cases it may make sense to remove entirely the class and move the data
+into the former client classes.
+
+The rule uses metrics to implement its detection strategy. The violation message
+gives information about the values of these metrics:
+* WMC: a class complexity measure for a class, see {% jdoc java::lang.java.metrics.JavaMetrics#WEIGHED_METHOD_COUNT %}
+* WOC: a 'non-triviality' measure for a class, see {% jdoc java::lang.java.metrics.JavaMetrics#WEIGHT_OF_CLASS %}
+* NOPA: number of public attributes, see {% jdoc java::lang.java.metrics.JavaMetrics#NUMBER_OF_PUBLIC_FIELDS %}
+* NOAM: number of public accessor methods, see {% jdoc java::lang.java.metrics.JavaMetrics#NUMBER_OF_ACCESSORS %}
+
+The rule identifies a god class by looking for classes which have all of the following properties:
+* High NOPA + NOAM
+* Low WOC
+* Low WMC
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class DataClass {
+
+  // class exposes public attributes
+  public String name = "";
+  public int bar = 0;
+  public int na = 0;
+
+  private int bee = 0;
+
+  // and private ones through getters
+  public void setBee(int n) {
+    bee = n;
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="DoNotExtendJavaLangError"
+          language="java"
+          since="4.0"
+          message="Exceptions should not extend java.lang.Error"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#donotextendjavalangerror">
+        <description>
+Errors are system exceptions. Do not extend them.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration/ExtendsList/ClassType[pmd-java:typeIs('java.lang.Error')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo extends Error { }
+]]>
+        </example>
+    </rule>
+
+    <rule name="ExceptionAsFlowControl"
+          language="java"
+          since="1.8"
+          message="Exception thrown at line {0} is caught in this block."
+          class="net.sourceforge.pmd.lang.java.rule.design.ExceptionAsFlowControlRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#exceptionasflowcontrol">
+        <description>
+This rule reports exceptions thrown and caught in an enclosing try statement.
+This use of exceptions as a form of `goto` statement is discouraged, as that may
+hide actual exceptions, and obscures control flow, especially when debugging.
+To fix a violation, add the necessary validation or use an alternate control structure.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public void bar() {
+    try {
+        try {
+        } catch (Exception e) {
+            throw new WrapperException(e);
+            // this is essentially a GOTO to the WrapperException catch block
+        }
+    } catch (WrapperException e) {
+        // do some more stuff
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ExcessiveImports"
+          language="java"
+          since="1.04"
+          message="A high number of imports can indicate a high degree of coupling within an object."
+          class="net.sourceforge.pmd.lang.java.rule.design.ExcessiveImportsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#excessiveimports">
+        <description>
+A high number of imports can indicate a high degree of coupling within an object. This rule
+counts the number of unique imports and reports a violation if the count is above the
+user-specified threshold.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+import blah.blah.Baz;
+import blah.blah.Bif;
+// 28 others from the same package elided
+public class Foo {
+    public void doWork() {}
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ExcessiveParameterList"
+          language="java"
+          since="0.9"
+          message="Avoid long parameter lists."
+          class="net.sourceforge.pmd.lang.java.rule.design.ExcessiveParameterListRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#excessiveparameterlist">
+        <description>
+Methods with numerous parameters are a challenge to maintain, especially if most of them share the
+same datatype. These situations usually denote the need for new objects to wrap the numerous parameters.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public void addPerson(      // too many arguments liable to be mixed up
+    int birthYear, int birthMonth, int birthDate, int height, int weight, int ssn) {
+
+    . . . .
+}
+
+public void addPerson(      // preferred approach
+    Date birthdate, BodyMeasurements measurements, int ssn) {
+
+    . . . .
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ExcessivePublicCount"
+          language="java"
+          since="1.04"
+          message="This class has a bunch of public methods and attributes"
+          class="net.sourceforge.pmd.lang.java.rule.design.ExcessivePublicCountRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#excessivepubliccount">
+        <description>
+Classes with large numbers of public methods and attributes require disproportionate testing efforts
+since combinational side effects grow rapidly and increase risk. Refactoring these classes into
+smaller ones not only increases testability and reliability but also allows new variations to be
+developed easily.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    public String value;
+    public Bar something;
+    public Variable var;
+    // [... more more public attributes ...]
+
+    public void doWork() {}
+    public void doMoreWork() {}
+    public void doWorkAgain() {}
+    // [... more more public methods ...]
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="FinalFieldCouldBeStatic"
+          language="java"
+          since="1.1"
+          message="This final field could be made static"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#finalfieldcouldbestatic">
+        <description>
+If a final field is assigned to a compile-time constant, it could be made static, thus saving overhead
+in each object at runtime.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//FieldDeclaration
+    [pmd-java:modifiers() = 'final']
+    [not(pmd-java:modifiers() = 'static')]
+    [not(./ancestor::ClassDeclaration[1][pmd-java:hasAnnotation('lombok.experimental.UtilityClass')])]
+    [not(.//Annotation[pmd-java:typeIs('lombok.Builder.Default')])]
+    /VariableDeclarator[*[last()][@CompileTimeConstant = true()
+         or self::NullLiteral
+         or self::VariableAccess[@Name = //FieldDeclaration[pmd-java:modifiers() = 'static']/VariableDeclarator/VariableId/@Name]
+         or self::FieldAccess
+         or self::ArrayAllocation/ArrayType/ArrayDimensions/ArrayDimExpr/NumericLiteral[@IntLiteral = true()][@Image = "0"]]]
+    /VariableId
+        [not(@Name = //MethodDeclaration[not(pmd-java:modifiers() = 'static')]
+            //SynchronizedStatement/(VariableAccess|FieldAccess[ThisExpression])/@Name)]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+  public final int BAR = 42; // this could be static and save some space
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="GodClass"
+          language="java"
+          since="5.0"
+          message="Possible God Class (WMC={0}, ATFD={2}, TCC={1})"
+          class="net.sourceforge.pmd.lang.java.rule.design.GodClassRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#godclass">
+        <description>
+The God Class rule detects the God Class design flaw using metrics. God classes do too many things,
+are very big and overly complex. They should be split apart to be more object-oriented.
+The rule uses the detection strategy described in "Object-Oriented Metrics in Practice".
+The violations are reported against the entire class.
+
+The rule uses metrics to implement its detection strategy. The violation message
+gives information about the values of these metrics:
+* WMC: a class complexity measure, see {% jdoc java::lang.java.metrics.JavaMetrics#WEIGHED_METHOD_COUNT %}
+* ATFD: a measure of how much data external data the class uses, see {% jdoc java::lang.java.metrics.JavaMetrics#ACCESS_TO_FOREIGN_DATA %}
+* TCC: a measure of how tightly related the methods are, see {% jdoc java::lang.java.metrics.JavaMetrics#TIGHT_CLASS_COHESION %}
+
+The rule identifies a god class by looking for classes which have all of the following properties:
+* High WMC
+* High ATFD
+* Low TCC
+
+See also the reference:
+
+Michele Lanza and Radu Marinescu. *Object-Oriented Metrics in Practice:
+Using Software Metrics to Characterize, Evaluate, and Improve the Design
+of Object-Oriented Systems.* Springer, Berlin, 1 edition, October 2006. Page 80.
+        </description>
+        <priority>3</priority>
+    </rule>
+
+    <rule name="ImmutableField"
+          language="java"
+          since="2.0"
+          message="Field ''{0}'' may be declared final"
+          class="net.sourceforge.pmd.lang.java.rule.design.ImmutableFieldRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#immutablefield">
+        <description>
+Reports non-final fields whose value never changes once object initialization ends,
+and hence may be marked final.
+
+Note that this rule does not enforce that the field value be deeply immutable itself.
+An object can still have mutable state, even if all its member fields are declared final.
+This is referred to as shallow immutability. For more information on mutability,
+see *Effective Java, 3rd Edition, Item 17: Minimize mutability*.
+
+Limitations: We can only check private fields for now.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+  private int x; // could be final
+  public Foo() {
+      x = 7;
+  }
+  public void foo() {
+     int a = x + 2;
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="InvalidJavaBean"
+          language="java"
+          since="6.52.0"
+          message="The bean ''{0}'' is missing a getter for property ''{1}''."
+          class="net.sourceforge.pmd.lang.java.rule.design.InvalidJavaBeanRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#invalidjavabean">
+        <description>
+Identifies beans, that don't follow the [JavaBeans API specification](https://download.oracle.com/otndocs/jcp/7224-javabeans-1.01-fr-spec-oth-JSpec/).
+
+Each non-static field should have both a getter and a setter method. If the field is just used internally and is not
+a bean property, then the field should be marked as `transient`.
+
+The rule verifies that the type of the field is the same as the result type of the getter. And that this type matches
+the type used in the setter.
+
+The rule also checks, that there is a no-arg or default constructor available.
+
+Optionally the rule also verifies, that the bean implements `java.io.Serializable`. While this is a requirement for the
+original JavaBeans specification, frameworks nowadays don't strictly require this anymore.
+
+In order to avoid many false positives in classes that are not beans, the rule needs to be explicitly
+enabled by configuring the property `packages`.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+package org.example.beans;
+public class MyBean {        // <-- bean is not serializable, missing "implements Serializable"
+    private String label;    // <-- missing setter for property "label"
+
+    public String getLabel() {
+        return label;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="LawOfDemeter"
+          language="java"
+          since="5.0"
+          message="Potential violation of the law of Demeter ({0})"
+          class="net.sourceforge.pmd.lang.java.rule.design.LawOfDemeterRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#lawofdemeter">
+        <description>
+The law of Demeter is a simple rule that says "only talk to friends". It forbids
+fetching data from "too far away", for some definition of distance, in order to
+reduce coupling between classes or objects of different levels of abstraction.
+
+The rule uses a notion of "degree", that quantifies how "far" an object is.
+Expressions with too high degree can only be used in certain ways. The degree of
+an expression is defined inductively:
+- The degree of `this` is 0
+- The degree of a method parameter is 1
+- The degree of a new object created in a method is 1
+- The degree of a static variable is 1
+- The degree of a field access expression like `expr.field` is the degree of `expr` plus 1
+- The degree of a "getter expression" like `expr.getFoo()` is the degree of `expr` plus 1
+- The degree of a "transformation expression" like `expr.withFoo("")` is the degree of `expr`
+- The degree of a variable is the maximum degree of all the assignments that reach it
+
+Intuitively, the more you call getters, the more the degree increases. Eventually
+the degree reaches the report threshold (property `trustRadius`) and the expression
+is reported. The details of the calculation are more involved and make room for common
+patterns, like usage of collections (objects that are in a list or array have the
+same degree as their container), the builder pattern, and getters that do not appear
+to break a boundary of abstraction.
+
+Be aware that this rule is prone to many false-positives and low-priority warnings.
+You can increase the `trustRadius` property to reduce them drastically. The default
+`trustRadius` of 1 corresponds to the original law of Demeter (you're only allowed
+one getter call on untrusted values). Given some `trustRadius` value:
+- expressions of degree lower or equal to `trustRadius` are not reported
+- expressions of degree exactly `trustRadius + 1` are reported, unless they are only returned
+from the current method, or passed as argument to another method. Without this exception it
+would not be possible to extract any information from e.g. method parameters.
+- values of degree strictly greater than `trustRadius + 1` are not reported. The
+intuition is that to obtain a value of degree `n > 1` then you must use an expression
+of degree `n - 1`, so if you have `n > trustRadius + 1`, there you're using some value
+of degree `trustRadius + 1` that will be reported.
+
+See also the references:
+
+*   Andrew Hunt, David Thomas, and Ward Cunningham. The Pragmatic Programmer. From Journeyman to Master. Addison-Wesley Longman, Amsterdam, October 1999.;
+*   K.J. Lieberherr and I.M. Holland. Assuring good style for object-oriented programs. Software, IEEE, 6(5):38–48, 1989.;
+*   &lt;http://www.ccs.neu.edu/home/lieber/LoD.html>
+*   &lt;http://en.wikipedia.org/wiki/Law_of_Demeter>
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    /**
+     * This example will result in one violation.
+     */
+    public void example(Bar b) { // b has degree 1
+        // `b.getC()` has degree 2, it's breaking a boundary of abstraction and so is reported.
+        b.getC().doIt();
+        // To respect the law of Demeter, Bar should encapsulate its
+        // C member more properly, eg by exposing a method like this:
+        b.callDoItOnC();
+
+        // a constructor call, not a method call.
+        D d = new D();
+        // this method call is ok, because we have create the new
+        // instance of D locally.
+        d.doSomethingElse();
+    }
+}
+            ]]>
+        </example>
+    </rule>
+
+    <rule name="LogicInversion"
+          language="java"
+          since="5.0"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="Use opposite operator instead of the logic complement operator."
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#logicinversion">
+        <description>
+Use opposite operator instead of negating the whole expression with a logic complement operator.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//UnaryExpression[@Operator='!']/InfixExpression[@Operator = ('==', '!=', '<', '>', '<=', '>=')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public boolean bar(int a, int b) {
+
+    if (!(a == b)) { // use !=
+         return false;
+     }
+
+    if (!(a < b)) { // use >=
+         return false;
+    }
+
+    return true;
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="LoosePackageCoupling"
+          language="java"
+          since="5.0"
+          message="Use of ''{0}'' outside of package hierarchy ''{1}'' is not recommended; use recommended classes instead"
+          class="net.sourceforge.pmd.lang.java.rule.design.LoosePackageCouplingRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#loosepackagecoupling">
+        <description>
+Avoid using classes from the configured package hierarchy outside of the package hierarchy,
+except when using one of the configured allowed classes.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+package some.package;
+
+import some.other.package.subpackage.subsubpackage.DontUseThisClass;
+
+public class Bar {
+    DontUseThisClass boo = new DontUseThisClass();
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="NcssCount"
+          language="java"
+          message="The {0} ''{1}'' has a NCSS line count of {2}."
+          since="6.0.0"
+          class="net.sourceforge.pmd.lang.java.rule.design.NcssCountRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#ncsscount">
+        <description>
+This rule uses the NCSS (Non-Commenting Source Statements) metric to determine the number of lines
+of code in a class, method or constructor. NCSS ignores comments, blank lines, and only counts actual
+statements. For more details on the calculation, see the documentation
+{% jdoc java::lang.java.metrics.JavaMetrics#NCSS %}.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+import java.util.Collections;       // +0
+import java.io.IOException;         // +0
+
+class Foo {                         // +1, total Ncss = 12
+
+  public void bigMethod()           // +1
+      throws IOException {
+    int x = 0, y = 2;               // +1
+    boolean a = false, b = true;    // +1
+
+    if (a || b) {                   // +1
+      try {                         // +1
+        do {                        // +1
+          x += 2;                   // +1
+        } while (x < 12);
+
+        System.exit(0);             // +1
+      } catch (IOException ioe) {   // +1
+        throw new PatheticFailException(ioe); // +1
+      }
+    } else {
+      assert false;                 // +1
+    }
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="NPathComplexity"
+          language="java"
+          since="3.9"
+          message="The {0} ''{1}'' has an NPath complexity of {2}, current threshold is {3}"
+          class="net.sourceforge.pmd.lang.java.rule.design.NPathComplexityRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#npathcomplexity">
+        <description>
+The NPath complexity of a method is the number of acyclic execution paths through that method.
+While cyclomatic complexity counts the number of decision points in a method, NPath counts the number of
+full paths from the beginning to the end of the block of the method. That metric grows exponentially, as
+it multiplies the complexity of statements in the same block. For more details on the calculation, see the
+documentation {% jdoc java::lang.java.metrics.JavaMetrics#NPATH %}.
+
+A threshold of 200 is generally considered the point where measures should be taken to reduce
+complexity and increase readability.
+        </description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+public class Foo {
+  public static void bar() { // Ncss = 252: reported!
+    boolean a, b = true;
+    try { // 2 * 2 + 2 = 6
+      if (true) { // 2
+        List buz = new ArrayList();
+      }
+
+      for(int i = 0; i < 19; i++) { // * 2
+        List buz = new ArrayList();
+      }
+    } catch(Exception e) {
+      if (true) { // 2
+        e.printStackTrace();
+      }
+    }
+
+    while (j++ < 20) { //  * 2
+      List buz = new ArrayList();
+    }
+
+    switch(j) { // * 7
+      case 1:
+      case 2: break;
+      case 3: j = 5; break;
+      case 4: if (b && a) { bar(); } break;
+      default: break;
+    }
+
+    do { // * 3
+        List buz = new ArrayList();
+    } while (a && j++ < 30);
+  }
+}
+ ]]>
+        </example>
+    </rule>
+
+    <rule name="SignatureDeclareThrowsException"
+          language="java"
+          since="1.2"
+          message="A method/constructor should not explicitly throw java.lang.Exception"
+          class="net.sourceforge.pmd.lang.java.rule.design.SignatureDeclareThrowsExceptionRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#signaturedeclarethrowsexception">
+        <description>
+A method/constructor shouldn't explicitly throw the generic java.lang.Exception, since it
+is unclear which exceptions that can be thrown from the methods. It might be
+difficult to document and understand such vague interfaces. Use either a class
+derived from RuntimeException or a checked exception.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public void foo() throws Exception {
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="SimplifiedTernary"
+          language="java"
+          since="5.4.0"
+          message="This conditional expression can be simplified with || or &amp;&amp;"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#simplifiedternary">
+        <description>
+<![CDATA[
+Reports ternary expression with the form `condition ? literalBoolean : foo`
+or `condition ? foo : literalBoolean`.
+
+These expressions can be simplified as follows:
+* `condition ? true : expr` simplifies to `condition || expr`
+* `condition ? false : expr` simplifies to `!condition && expr`
+* `condition ? expr : true` simplifies to `!condition || expr`
+* `condition ? expr : false` simplifies to `condition && expr`
+]]>
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ConditionalExpression[BooleanLiteral and not(NullLiteral)]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    public boolean test() {
+        return condition ? true : something(); // can be as simple as return condition || something();
+    }
+
+    public void test2() {
+        final boolean value = condition ? false : something(); // can be as simple as value = !condition && something();
+    }
+
+    public boolean test3() {
+        return condition ? something() : true; // can be as simple as return !condition || something();
+    }
+
+    public void test4() {
+        final boolean otherValue = condition ? something() : false; // can be as simple as condition && something();
+    }
+
+    public boolean test5() {
+        return condition ? true : false; // can be as simple as return condition;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+
+    <rule name="SimplifyBooleanExpressions"
+          language="java"
+          since="1.05"
+          message="Avoid unnecessary comparisons in boolean expressions"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#simplifybooleanexpressions">
+        <description>
+Avoid unnecessary comparisons in boolean expressions, they serve no purpose and impacts readability.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//InfixExpression[@Operator = ("==", "!=")]/BooleanLiteral
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Bar {
+  // can be simplified to
+  // bar = isFoo();
+  private boolean bar = (isFoo() == true);
+
+  public isFoo() { return false;}
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="SimplifyBooleanReturns"
+          language="java"
+          since="0.9"
+          message="This if statement can be replaced by `{0}`"
+          class="net.sourceforge.pmd.lang.java.rule.design.SimplifyBooleanReturnsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#simplifybooleanreturns">
+        <description>
+Avoid unnecessary if-then-else statements when returning a boolean. The result of
+the conditional test can be returned instead.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public boolean isBarEqualTo(int x) {
+    if (bar == x) {      // this bit of code...
+        return true;
+    } else {
+        return false;
+    }
+}
+
+public boolean isBarEqualTo(int x) {
+    return bar == x;    // can be replaced with this
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="SimplifyConditional"
+          language="java"
+          since="3.1"
+          message="No need to check for null before an instanceof"
+          class="net.sourceforge.pmd.lang.java.rule.design.SimplifyConditionalRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#simplifyconditional">
+        <description>
+No need to check for null before an instanceof; the instanceof keyword returns false when given a null argument.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+class Foo {
+  void bar(Object x) {
+    if (x != null && x instanceof Bar) {
+      // just drop the "x != null" check
+    }
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="SingularField"
+          language="java"
+          since="3.1"
+          message="Perhaps ''{0}'' could be replaced by a local variable."
+          class="net.sourceforge.pmd.lang.java.rule.design.SingularFieldRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#singularfield">
+        <description>
+Reports fields which may be converted to a local variable. This is so because
+in every method where the field is used, it is assigned before it is first read.
+Hence, the value that the field had before the method call may not be observed,
+so it might as well not be stored in the enclosing object.
+
+Limitations:
+* We can only check private fields for now.
+* The rule is not aware of threading, so it may cause false positives in concurrent code.
+Such FPs are best handled by suppression (see also the `ignoredAnnotations` property).
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    private int x; // this will be reported
+
+    public int foo(int y) {
+       x = y + 5; // assigned before any read
+       return x;
+    }
+
+    public int fooOk(int y) {
+       int z = y + 5; // might as well be a local like here
+       return z;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="SwitchDensity"
+          language="java"
+          since="1.02"
+          message="A high ratio of statements to labels in a switch statement.  Consider refactoring."
+          class="net.sourceforge.pmd.lang.java.rule.design.SwitchDensityRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#switchdensity">
+        <description>
+A high ratio of statements to labels in a switch statement implies that the switch statement
+is overloaded.  Consider moving the statements into new methods or creating subclasses based
+on the switch variable.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+  public void bar(int x) {
+    switch (x) {
+      case 1: {
+        // lots of statements
+        break;
+      } case 2: {
+        // lots of statements
+        break;
+      }
+    }
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="TooManyFields"
+          language="java"
+          since="3.0"
+          message="Too many fields"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#toomanyfields">
+        <description>
+Classes that have too many fields can become unwieldy and could be redesigned to have fewer fields,
+possibly through grouping related fields in new objects.  For example, a class with individual
+city/state/zip fields could park them within a single Address field.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="maxfields" type="Integer" description="Max allowable fields" min="1" max="1000" value="15"/>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration/ClassBody
+  [count(FieldDeclaration
+            [not(pmd-java:modifiers() = 'final')]
+            [not(pmd-java:modifiers() = 'static')]
+        ) > $maxfields]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Person {   // too many separate fields
+   int birthYear;
+   int birthMonth;
+   int birthDate;
+   float height;
+   float weight;
+}
+
+public class Person {   // this is more manageable
+   Date birthDate;
+   BodyMeasurements measurements;
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="TooManyMethods"
+          language="java"
+          since="4.2"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="This class has too many methods, consider refactoring it."
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#toomanymethods">
+        <description>
+A class with too many methods is probably a good suspect for refactoring, in order to reduce its
+complexity and find a way to have more fine grained objects.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="maxmethods" type="Integer" description="The method count reporting threshold" min="1" max="1000" value="10"/>
+            <property name="xpath">
+                <value>
+<![CDATA[
+ //ClassDeclaration/ClassBody
+     [
+      count(MethodDeclaration[
+         not (
+                (starts-with(@Name,'get') or starts-with(@Name,'set') or starts-with(@Name,'is'))
+                and
+                count(Block/*) <= 1
+            )
+      ]) > $maxmethods
+   ]
+]]>
+                </value>
+            </property>
+        </properties>
+    </rule>
+
+    <rule name="UselessOverridingMethod"
+          language="java"
+          since="3.3"
+          message="Overriding method merely calls super"
+          class="net.sourceforge.pmd.lang.java.rule.design.UselessOverridingMethodRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#uselessoverridingmethod">
+        <description>
+The overriding method merely calls the same method defined in a superclass.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public void foo(String bar) {
+    super.foo(bar);      // why bother overriding?
+}
+
+public String foo() {
+    return super.foo();  // why bother overriding?
+}
+
+@Id
+public Long getId() {
+    return super.getId();  // OK if 'ignoreAnnotations' is false, which is the default behavior
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseObjectForClearerAPI"
+          language="java"
+          since="4.2.6"
+          message="Rather than using a lot of String arguments, consider using a container object for those values."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#useobjectforclearerapi">
+        <description>
+When you write a public method, you should be thinking in terms of an API. If your method is public, it means other class
+will use it, therefore, you want (or need) to offer a comprehensive and evolutive API. If you pass a lot of information
+as a simple series of Strings, you may think of using an Object to represent all those information. You'll get a simpler
+API (such as doWork(Workload workload), rather than a tedious series of Strings) and more importantly, if you need at some
+point to pass extra data, you'll be able to do so by simply modifying or extending Workload without any modification to
+your API.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration[pmd-java:modifiers() = 'public']
+    [count(FormalParameters/FormalParameter[pmd-java:typeIs('java.lang.String')]) > 3]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class MyClass {
+    public void connect(String username,
+        String pssd,
+        String databaseName,
+        String databaseAdress)
+        // Instead of those parameters object
+        // would ensure a cleaner API and permit
+        // to add extra data transparently (no code change):
+        // void connect(UserData data);
+    {
+
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseUtilityClass"
+          language="java"
+          since="0.3"
+          message="All methods are static.  Consider using a utility class instead. Alternatively, you could add a private constructor or make the class abstract to silence this warning."
+          class="net.sourceforge.pmd.lang.java.rule.design.UseUtilityClassRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#useutilityclass">
+        <description>
+For classes that only have static methods, consider making them utility classes.
+Note that this doesn't apply to abstract classes, since their subclasses may
+well include non-static methods.  Also, if you want this class to be a utility class,
+remember to add a private constructor to prevent instantiation.
+(Note, that this use was known before PMD 5.1.0 as UseSingleton).
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class MaybeAUtility {
+  public static void foo() {}
+  public static void bar() {}
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="MutableStaticState"
+          language="java"
+          since="6.35.0"
+          message="Do not use non-final non-private static fields"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_design.html#mutablestaticstate">
+        <description>
+Non-private static fields should be made constants (or immutable references) by
+declaring them final.
+
+Non-private non-final static fields break encapsulation and can lead to hard to find
+bugs, since these fields can be modified from anywhere within the program.
+Callers can trivially access and modify non-private non-final static fields. Neither
+accesses nor modifications can be guarded against, and newly set values cannot
+be validated.
+
+If you are using this rule, then you don't need this
+rule {% rule java/errorprone/AssignmentToNonFinalStatic %}.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//FieldDeclaration[pmd-java:modifiers() = "static"][not(pmd-java:modifiers() = ("private", "final"))]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+            <![CDATA[
+public class Greeter { public static Foo foo = new Foo(); ... }       // avoid this
+public class Greeter { public static final Foo FOO = new Foo(); ... } // use this instead
+]]>
+        </example>
+    </rule>
+
+</ruleset>
diff --git a/pmd/resources/category/java/documentation.xml b/pmd/resources/category/java/documentation.xml
new file mode 100644
index 000000000..8b5138850
--- /dev/null
+++ b/pmd/resources/category/java/documentation.xml
@@ -0,0 +1,152 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<ruleset name="Documentation"
+    xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+    <description>
+Rules that are related to code documentation.
+    </description>
+
+    <rule name="CommentContent"
+          language="java"
+          since="5.0"
+          message="Invalid words or phrases found"
+          class="net.sourceforge.pmd.lang.java.rule.documentation.CommentContentRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#commentcontent">
+        <description>
+A rule for the politically correct... we don't want to offend anyone.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+//OMG, this is horrible, Bob is an idiot !!!
+]]>
+        </example>
+    </rule>
+
+    <rule name="CommentRequired"
+          language="java"
+          since="5.1"
+          message="Comment is required"
+          class="net.sourceforge.pmd.lang.java.rule.documentation.CommentRequiredRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#commentrequired">
+        <description>
+Denotes whether javadoc (formal) comments are required (or unwanted) for specific language elements.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+/**
+*
+*
+* @author Jon Doe
+*/
+]]>
+        </example>
+    </rule>
+
+    <rule name="CommentSize"
+          language="java"
+          since="5.0"
+          message="Comment is too large"
+          class="net.sourceforge.pmd.lang.java.rule.documentation.CommentSizeRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#commentsize">
+        <description>
+Determines whether the dimensions of non-header comments found are within the specified limits.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+/**
+*
+*   too many lines!
+*
+*
+*
+*
+*
+*
+*
+*
+*
+*
+*
+*
+*/
+]]>
+        </example>
+    </rule>
+
+    <rule name="UncommentedEmptyConstructor"
+          language="java"
+          since="3.4"
+          message="Document empty constructor"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#uncommentedemptyconstructor">
+        <description>
+Uncommented Empty Constructor finds instances where a constructor does not
+contain statements, but there is no comment. By explicitly commenting empty
+constructors it is easier to distinguish between intentional (commented)
+and unintentional empty constructors.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ConstructorDeclaration[@Visibility != "private"]
+                        [not(
+                               pmd-java:hasAnnotation('javax.inject.Inject')
+                            or pmd-java:hasAnnotation('org.springframework.beans.factory.annotation.Autowired')
+                        )]
+                        [Block[
+                            @containsComment = false()
+                            and (count(*) = 0 or ($ignoreExplicitConstructorInvocation = true() and count(*) = 1 and ExplicitConstructorInvocation))
+                        ]]
+]]>
+                </value>
+            </property>
+            <property name="ignoreExplicitConstructorInvocation" type="Boolean" description="Ignore explicit constructor invocation when deciding whether constructor is empty or not" value="false"/>
+        </properties>
+        <example>
+<![CDATA[
+public Foo() {
+  // This constructor is intentionally empty. Nothing special is needed here.
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UncommentedEmptyMethodBody"
+          language="java"
+          since="3.4"
+          message="Document empty method body"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_documentation.html#uncommentedemptymethodbody">
+        <description>
+Uncommented Empty Method Body finds instances where a method body does not contain
+statements, but there is no comment. By explicitly commenting empty method bodies
+it is easier to distinguish between intentional (commented) and unintentional
+empty methods.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration/Block[count(*) = 0 and @containsComment = false()]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public void doSomething() {
+}
+]]>
+        </example>
+    </rule>
+
+</ruleset>
diff --git a/pmd/resources/category/java/errorprone.xml b/pmd/resources/category/java/errorprone.xml
new file mode 100644
index 000000000..1f9ed3776
--- /dev/null
+++ b/pmd/resources/category/java/errorprone.xml
@@ -0,0 +1,3235 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<ruleset name="Error Prone"
+    xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+    <description>
+Rules to detect constructs that are either broken, extremely confusing or prone to runtime errors.
+    </description>
+
+    <rule name="AssignmentInOperand"
+          language="java"
+          since="1.03"
+          message="Avoid assignments in operands"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.AssignmentInOperandRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#assignmentinoperand">
+        <description>
+Avoid assignments in operands; this can make code more complicated and harder to read.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public void bar() {
+    int x = 2;
+    if ((x = getX()) == 3) {
+      System.out.println("3!");
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AssignmentToNonFinalStatic"
+          language="java"
+          since="2.2"
+          message="Possible unsafe assignment to non-final static field ''{0}'' in a constructor."
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.AssignmentToNonFinalStaticRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#assignmenttononfinalstatic">
+        <description>
+Identifies a possible unsafe usage of a static field.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class StaticField {
+   static int x;
+   public FinalFields(int y) {
+    x = y; // unsafe
+   }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidAccessibilityAlteration"
+          language="java"
+          since="4.1"
+          message="You should not modify visibility of constructors, methods or fields using setAccessible()"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidaccessibilityalteration">
+        <description>
+Methods such as `getDeclaredConstructors()`, `getDeclaredMethods()`, and `getDeclaredFields()` also
+return private constructors, methods and fields. These can be made accessible by calling `setAccessible(true)`.
+This gives access to normally protected data which violates the principle of encapsulation.
+
+This rule detects calls to `setAccessible` and finds possible accessibility alterations.
+If the call to `setAccessible` is wrapped within a `PrivilegedAction`, then the access alteration
+is assumed to be deliberate and is not reported.
+
+Note that with Java 17 the Security Manager, which is used for `PrivilegedAction` execution,
+is deprecated: [JEP 411: Deprecate the Security Manager for Removal](https://openjdk.org/jeps/411).
+For future-proof code, deliberate access alteration should be suppressed using the usual
+suppression methods (e.g. by using `@SuppressWarnings` annotation).
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall[
+          pmd-java:matchesSig("java.lang.reflect.AccessibleObject#setAccessible(boolean)")
+       or pmd-java:matchesSig("_#setAccessible(java.lang.reflect.AccessibleObject[],boolean)")
+    ]
+    [not(ArgumentList/BooleanLiteral[@True = false()])]
+    (: exclude anonymous privileged action classes :)
+    [not(ancestor::ConstructorCall[1][pmd-java:typeIs('java.security.PrivilegedAction')]/AnonymousClassDeclaration)]
+    (: exclude inner privileged action classes :)
+    [not(ancestor::ClassDeclaration[1][pmd-java:typeIs('java.security.PrivilegedAction')])]
+    (: exclude privileged action lambdas :)
+    [not(ancestor::LambdaExpression[pmd-java:typeIs('java.security.PrivilegedAction')])]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+public class Violation {
+    private void invalidSetAccessCalls() throws NoSuchMethodException, SecurityException {
+        Constructor<?> constructor = this.getClass().getDeclaredConstructor(String.class);
+        // call to forbidden setAccessible
+        constructor.setAccessible(true);
+
+        Method privateMethod = this.getClass().getDeclaredMethod("aPrivateMethod");
+        // call to forbidden setAccessible
+        privateMethod.setAccessible(true);
+
+        // deliberate accessibility alteration
+        String privateField = AccessController.doPrivileged(new PrivilegedAction<String>() {
+            @Override
+            public String run() {
+                try {
+                    Field field = Violation.class.getDeclaredField("aPrivateField");
+                    field.setAccessible(true);
+                    return (String) field.get(null);
+                } catch (ReflectiveOperationException | SecurityException e) {
+                    throw new RuntimeException(e);
+                }
+            }
+        });
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidAssertAsIdentifier"
+          language="java"
+          maximumLanguageVersion="1.3"
+          since="3.4"
+          message="Avoid using assert as an identifier; it became a reserved word in JDK 1.4"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidassertasidentifier">
+        <description>
+Use of the term `assert` will conflict with newer versions of Java since it is a reserved word.
+
+Since Java 1.4, the token `assert` became a reserved word and using it as an identifier will
+result in a compilation failure for Java 1.4 and later. This rule is therefore only useful
+for old Java code before Java 1.4. It can be used to identify problematic code prior to a Java update.
+        </description>
+        <priority>2</priority>
+        <properties>
+            <property name="xpath">
+                <value>//VariableId[@Name='assert']</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class A {
+    public class Foo {
+        String assert = "foo";
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidBranchingStatementAsLastInLoop"
+          language="java"
+          since="5.0"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidBranchingStatementAsLastInLoopRule"
+          message="Avoid using a branching statement as the last in a loop."
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidbranchingstatementaslastinloop">
+        <description>
+Using a branching statement as the last part of a loop may be a bug, and/or is confusing.
+Ensure that the usage is not a bug, or consider using another approach.
+        </description>
+        <priority>2</priority>
+        <example>
+<![CDATA[
+// unusual use of branching statement in a loop
+for (int i = 0; i < 10; i++) {
+    if (i*i <= 25) {
+        continue;
+    }
+    break;
+}
+
+// this makes more sense...
+for (int i = 0; i < 10; i++) {
+    if (i*i > 25) {
+        break;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidCallingFinalize"
+          language="java"
+          since="3.0"
+          message="Avoid calling finalize() explicitly"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidcallingfinalize">
+        <description>
+The method Object.finalize() is called by the garbage collector on an object when garbage collection determines
+that there are no more references to the object. It should not be invoked by application logic.
+
+Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall[pmd-java:matchesSig("java.lang.Object#finalize()")]
+    (: it's ok inside finalize :)
+    [not(SuperExpression and ancestor::*[self::MethodDeclaration or self::Initializer][1][@Name = 'finalize'][@Arity = 0][VoidType])]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+void foo() {
+    Bar b = new Bar();
+    b.finalize();
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidCatchingNPE"
+          language="java"
+          since="1.8"
+          message="Avoid catching NullPointerException; consider removing the cause of the NPE."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidcatchingnpe">
+        <description>
+Code should never throw NullPointerExceptions under normal circumstances.  A catch block may hide the
+original error, causing other, more subtle problems later on.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//CatchClause/CatchParameter/ClassType[pmd-java:typeIsExactly('java.lang.NullPointerException')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    void bar() {
+        try {
+            // do something
+        } catch (NullPointerException npe) {
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidCatchingThrowable"
+          language="java"
+          since="1.2"
+          message="A catch statement should never catch throwable since it includes errors."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidcatchingthrowable">
+        <description>
+Catching Throwable errors is not recommended since its scope is very broad. It includes runtime issues such as
+OutOfMemoryError that should be exposed and managed separately.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value><![CDATA[
+                //CatchParameter[ClassType[pmd-java:typeIsExactly('java.lang.Throwable')]]/VariableId
+                ]]></value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public void bar() {
+    try {
+        // do something
+    } catch (Throwable th) {  // should not catch Throwable
+        th.printStackTrace();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidDecimalLiteralsInBigDecimalConstructor"
+          language="java"
+          since="3.4"
+          message="Avoid creating BigDecimal with a decimal (float/double) literal. Use a String literal"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoiddecimalliteralsinbigdecimalconstructor">
+        <description>
+One might assume that the result of "new BigDecimal(0.1)" is exactly equal to 0.1, but it is actually
+equal to .1000000000000000055511151231257827021181583404541015625.
+This is because 0.1 cannot be represented exactly as a double (or as a binary fraction of any finite
+length). Thus, the long value that is being passed in to the constructor is not exactly equal to 0.1,
+appearances notwithstanding.
+
+The (String) constructor, on the other hand, is perfectly predictable: 'new BigDecimal("0.1")' is
+exactly equal to 0.1, as one would expect.  Therefore, it is generally recommended that the
+(String) constructor be used in preference to this one.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ConstructorCall[pmd-java:matchesSig('java.math.BigDecimal#new(double)')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+BigDecimal bd = new BigDecimal(1.123);       // loss of precision, this would trigger the rule
+
+BigDecimal bd = new BigDecimal("1.123");     // preferred approach
+
+BigDecimal bd = new BigDecimal(12);          // preferred approach, ok for integer values
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidDuplicateLiterals"
+          language="java"
+          since="1.0"
+          message="The String literal {0} appears {1} times in this file; the first occurrence is on line {2}"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidDuplicateLiteralsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidduplicateliterals">
+        <description>
+Code containing duplicate String literals can usually be improved by declaring the String as a constant field.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+private void bar() {
+     buz("Howdy");
+     buz("Howdy");
+     buz("Howdy");
+     buz("Howdy");
+}
+private void buz(String x) {}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidEnumAsIdentifier"
+          language="java"
+          maximumLanguageVersion="1.4"
+          since="3.4"
+          message="Avoid using enum as an identifier; it's a reserved word in JDK 1.5"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidenumasidentifier">
+        <description>
+Use of the term `enum` will conflict with newer versions of Java since it is a reserved word.
+
+Since Java 1.5, the token `enum` became a reserved word and using it as an identifier will
+result in a compilation failure for Java 1.5 and later. This rule is therefore only useful
+for old Java code before Java 1.5. It can be used to identify problematic code prior to a Java update.
+        </description>
+        <priority>2</priority>
+        <properties>
+            <property name="xpath">
+                <value>//VariableId[@Name='enum']</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class A {
+    public class Foo {
+        String enum = "foo";
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidFieldNameMatchingMethodName"
+          language="java"
+          since="3.0"
+          message="Field {0} has the same name as a method"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidfieldnamematchingmethodname">
+        <description>
+It can be confusing to have a field name with the same name as a method. While this is permitted,
+having information (field) and actions (method) is not clear naming. Developers versed in
+Smalltalk often prefer this approach as the methods denote accessor methods.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//FieldDeclaration/VariableDeclarator/VariableId
+    [some $method in ../../..[self::ClassBody or self::EnumBody]/MethodDeclaration
+     satisfies lower-case(@Name) = lower-case($method/@Name)]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    Object bar;
+    // bar is data or an action or both?
+    void bar() {
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidFieldNameMatchingTypeName"
+          language="java"
+          since="3.0"
+          message="It is somewhat confusing to have a field name matching the declaring class name"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidfieldnamematchingtypename">
+        <description>
+It is somewhat confusing to have a field name matching the declaring type name.
+This probably means that type and/or field names should be chosen more carefully.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//FieldDeclaration/VariableDeclarator/VariableId
+    [lower-case(@Name) = lower-case(ancestor::ClassDeclaration[1]/@SimpleName)]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo extends Bar {
+    int foo;    // There is probably a better name that can be used
+}
+public interface Operation {
+    int OPERATION = 1; // There is probably a better name that can be used
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidInstanceofChecksInCatchClause"
+          language="java"
+          since="3.0"
+          message="An instanceof check is being performed on the caught exception.  Create a separate catch clause for this exception type."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidinstanceofchecksincatchclause">
+        <description>
+Each caught exception type should be handled in its own catch clause.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//CatchParameter
+    /following-sibling::Block//InfixExpression[@Operator = 'instanceof']
+        /VariableAccess[@Name = ./ancestor::Block/preceding-sibling::CatchParameter/@Name]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+try { // Avoid this
+    // do something
+} catch (Exception ee) {
+    if (ee instanceof IOException) {
+        cleanup();
+    }
+}
+
+try {  // Prefer this:
+    // do something
+} catch (IOException ee) {
+    cleanup();
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidLiteralsInIfCondition"
+          language="java"
+          since="4.2.6"
+          message="Avoid using literals in if statements"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidliteralsinifcondition">
+        <description>
+Avoid using hard-coded literals in conditional statements. By declaring them as static variables
+or private members with descriptive names maintainability is enhanced. By default, the literals "-1" and "0" are ignored.
+More exceptions can be defined with the property "ignoreMagicNumbers".
+
+The rule doesn't consider deeper expressions by default, but this can be enabled via the property `ignoreExpressions`.
+With this property set to false, if-conditions like `i == 1 + 5` are reported as well. Note that in that case,
+the property ignoreMagicNumbers is not taken into account, if there are multiple literals involved in such an expression.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="ignoreMagicNumbers"
+                      description="Comma-separated list of magic numbers, that should be ignored"
+                      type="String" value="-1,0"/>
+            <property name="ignoreExpressions"
+                      description="If true, only literals in simple if conditions are considered. Otherwise literals in expressions are checked, too."
+                      type="Boolean" value="true"/>
+            <property name="xpath">
+                <value>
+<![CDATA[
+(: simple case - no deep expressions - this is always executed :)
+//IfStatement/*[1]/*[pmd-java:nodeIs('Literal')]
+    [not(pmd-java:nodeIs('NullLiteral'))]
+    [not(pmd-java:nodeIs('BooleanLiteral'))]
+    [empty(index-of(tokenize($ignoreMagicNumbers, '\s*,\s*'), @Image))]
+|
+(: consider also deeper expressions :)
+//IfStatement[$ignoreExpressions = false()]/*[1]//*[not(self::UnaryExpression[@Operator = '-'])]/*[pmd-java:nodeIs('Literal')]
+    [not(pmd-java:nodeIs('NullLiteral'))]
+    [not(pmd-java:nodeIs('BooleanLiteral'))]
+    [empty(index-of(tokenize($ignoreMagicNumbers, '\s*,\s*'), @Image))]
+|
+(: consider negative literals :)
+//IfStatement[$ignoreExpressions = false()]/*[1]//UnaryExpression[@Operator = '-']/*[pmd-java:nodeIs('Literal')]
+    [not(pmd-java:nodeIs('NullLiteral'))]
+    [not(pmd-java:nodeIs('BooleanLiteral'))]
+    [empty(index-of(tokenize($ignoreMagicNumbers, '\s*,\s*'), concat('-', @Image)))]
+|
+(: consider multiple literals in expressions :)
+//IfStatement[$ignoreExpressions = false()]/*[1][count(*[pmd-java:nodeIs('Literal')]
+    [not(pmd-java:nodeIs('NullLiteral'))]
+    [not(pmd-java:nodeIs('BooleanLiteral'))]) > 1]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+private static final int MAX_NUMBER_OF_REQUESTS = 10;
+
+public void checkRequests() {
+
+    if (i == 10) {                        // magic number, buried in a method
+      doSomething();
+    }
+
+    if (i == MAX_NUMBER_OF_REQUESTS) {    // preferred approach
+      doSomething();
+    }
+
+    if (aString.indexOf('.') != -1) {}     // magic number -1, by default ignored
+    if (aString.indexOf('.') >= 0) { }     // alternative approach
+
+    if (aDouble > 0.0) {}                  // magic number 0.0
+    if (aDouble >= Double.MIN_VALUE) {}    // preferred approach
+
+    // with rule property "ignoreExpressions" set to "false"
+    if (i == pos + 5) {}  // violation: magic number 5 within an (additive) expression
+    if (i == pos + SUFFIX_LENGTH) {} // preferred approach
+    if (i == 5 && "none".equals(aString)) {} // 2 violations: magic number 5 and literal "none"
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidLosingExceptionInformation"
+          since="4.2.6"
+          language="java"
+          message="Avoid statements in a catch block that invoke accessors on the exception without using the information"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidlosingexceptioninformation">
+        <description>
+Statements in a catch block that invoke accessors on the exception without using the information
+only add to code size.  Either remove the invocation, or use the return result.
+        </description>
+        <priority>2</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//CatchClause/Block/ExpressionStatement/MethodCall[
+    pmd-java:matchesSig("java.lang.Throwable#getMessage()")
+    or pmd-java:matchesSig("java.lang.Throwable#getLocalizedMessage()")
+    or pmd-java:matchesSig("java.lang.Throwable#getCause()")
+    or pmd-java:matchesSig("java.lang.Throwable#getStackTrace()")
+    or pmd-java:matchesSig("java.lang.Object#toString()")
+]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public void bar() {
+    try {
+        // do something
+    } catch (SomeException se) {
+        se.getMessage();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidMultipleUnaryOperators"
+          language="java"
+          since="4.2"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="Using multiple unary operators may be a bug, and/or is confusing."
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidmultipleunaryoperators">
+        <description>
+The use of multiple unary operators may be problematic, and/or confusing.
+Ensure that the intended usage is not a bug, or consider simplifying the expression.
+        </description>
+        <priority>2</priority>
+        <properties>
+            <property name="xpath">
+                <value><![CDATA[
+                    (: Only report on the toplevel one :)
+                    //UnaryExpression[UnaryExpression and not(parent::UnaryExpression)]
+                ]]></value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+// These are typo bugs, or at best needlessly complex and confusing:
+int i = - -1;
+int j = + - +1;
+int z = ~~2;
+boolean b = !!true;
+boolean c = !!!true;
+
+// These are better:
+int i = 1;
+int j = -1;
+int z = 2;
+boolean b = true;
+boolean c = false;
+
+// And these just make your brain hurt:
+int i = ~-2;
+int j = -~7;
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidUsingOctalValues"
+          language="java"
+          since="3.9"
+          message="Do not start a literal by 0 unless it's an octal value"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.AvoidUsingOctalValuesRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#avoidusingoctalvalues">
+        <description>
+Integer literals should not start with zero since this denotes that the rest of literal will be
+interpreted as an octal value.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+int i = 012;    // set i with 10 not 12
+int j = 010;    // set j with 8 not 10
+k = i * j;      // set k with 80 not 120
+]]>
+        </example>
+    </rule>
+
+    <rule name="BrokenNullCheck"
+          language="java"
+          since="3.8"
+          message="This expression will throw a NullPointerException"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.BrokenNullCheckRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#brokennullcheck">
+        <description>
+The null check is broken since it will throw a NullPointerException itself.
+It is likely that you used || instead of &amp;&amp; or vice versa.
+        </description>
+        <priority>2</priority>
+        <example>
+<![CDATA[
+public String bar(String string) {
+  // should be &&
+    if (string!=null || !string.equals(""))
+        return string;
+  // should be ||
+    if (string==null && string.equals(""))
+        return string;
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CallSuperFirst"
+          since="4.2.5"
+          language="java"
+          message="super should be called at the start of the method"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#callsuperfirst">
+        <description>Super should be called at the start of the method</description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration
+    [
+      pmd-java:typeIs('android.app.Activity') or
+      pmd-java:typeIs('android.app.Application') or
+      pmd-java:typeIs('android.app.Service')
+    ]
+    //MethodDeclaration
+    [
+      @Name=('onCreate', 'onConfigurationChanged', 'onPostCreate', 'onPostResume', 'onRestart',
+             'onRestoreInstanceState', 'onResume', 'onStart')
+    ]
+    [not(Block/*[1]/MethodCall[SuperExpression][@MethodName = ancestor::MethodDeclaration/@Name])]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+import android.app.Activity;
+import android.os.Bundle;
+
+public class DummyActivity extends Activity {
+    public void onCreate(Bundle bundle) {
+        // missing call to super.onCreate(bundle)
+        foo();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CallSuperLast"
+          since="4.2.5"
+          language="java"
+          message="super should be called at the end of the method"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#callsuperlast">
+        <description>
+Super should be called at the end of the method
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration
+    [
+      pmd-java:typeIs('android.app.Activity') or
+      pmd-java:typeIs('android.app.Application') or
+      pmd-java:typeIs('android.app.Service')
+    ]
+    //MethodDeclaration
+    [
+      @Name=('finish', 'onDestroy', 'onPause', 'onSaveInstanceState', 'onStop', 'onTerminate')
+    ]
+    [not(Block/*[last()]/MethodCall[SuperExpression][@MethodName = ancestor::MethodDeclaration/@Name])]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+import android.app.Activity;
+
+public class DummyActivity extends Activity {
+    public void onPause() {
+        foo();
+        // missing call to super.onPause()
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CheckSkipResult"
+          language="java"
+          since="5.0"
+          message="Check the value returned by the skip() method of an InputStream to see if the requested number of bytes has been skipped."
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.CheckSkipResultRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#checkskipresult">
+        <description>
+The skip() method may skip a smaller number of bytes than requested. Check the returned value to find out if it was the case or not.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+
+   private FileInputStream _s = new FileInputStream("file");
+
+   public void skip(int n) throws IOException {
+      _s.skip(n); // You are not sure that exactly n bytes are skipped
+   }
+
+   public void skipExactly(int n) throws IOException {
+      while (n != 0) {
+         long skipped = _s.skip(n);
+         if (skipped == 0)
+            throw new EOFException();
+         n -= skipped;
+      }
+   }
+]]>
+        </example>
+    </rule>
+
+    <rule name="ClassCastExceptionWithToArray"
+          language="java"
+          since="3.4"
+          message="This usage of the Collection.toArray() method will throw a ClassCastException."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#classcastexceptionwithtoarray">
+        <description>
+When deriving an array of a specific class from your Collection, one should provide an array of
+the same class as the parameter of the `toArray()` method. Doing otherwise will result
+in a `ClassCastException`.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//CastExpression[ArrayType/ClassType[not(pmd-java:typeIsExactly('java.lang.Object'))]]
+    /MethodCall[pmd-java:matchesSig("java.util.Collection#toArray()")]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+Collection c = new ArrayList();
+Integer obj = new Integer(1);
+c.add(obj);
+
+    // this would trigger the rule (and throw a ClassCastException if executed)
+Integer[] a = (Integer [])c.toArray();
+
+   // this is fine and will not trigger the rule
+Integer[] b = (Integer [])c.toArray(new Integer[0]);
+]]>
+        </example>
+    </rule>
+
+    <rule name="CloneMethodMustBePublic"
+          language="java"
+          since="5.4.0"
+          message="clone() method must be public if the class implements Cloneable"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#clonemethodmustbepublic">
+        <description>
+The java manual says "By convention, classes that implement this interface should override
+Object.clone (which is protected) with a public method."
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration[not(pmd-java:modifiers() = "public")]
+    [@Name = 'clone']
+    [@Arity = 0]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo implements Cloneable {
+    @Override
+    protected Object clone() throws CloneNotSupportedException { // Violation, must be public
+    }
+}
+
+public class Foo implements Cloneable {
+    @Override
+    protected Foo clone() { // Violation, must be public
+    }
+}
+
+public class Foo implements Cloneable {
+    @Override
+    public Object clone() // Ok
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CloneMethodMustImplementCloneable"
+          language="java"
+          since="1.9"
+          message="clone() method should be implemented only if implementing Cloneable interface"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.CloneMethodMustImplementCloneableRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#clonemethodmustimplementcloneable">
+        <description>
+The method clone() should only be implemented if the class implements the Cloneable interface with the exception of
+a final method that only throws CloneNotSupportedException.
+
+The rule can also detect, if the class implements or extends a Cloneable class.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class MyClass {
+ public Object clone() throws CloneNotSupportedException {
+  return foo;
+ }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CloneMethodReturnTypeMustMatchClassName"
+          language="java"
+          minimumLanguageVersion="1.5"
+          since="5.4.0"
+          message="The return type of the clone() method must be the class name when implements Cloneable"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#clonemethodreturntypemustmatchclassname">
+        <description>
+If a class implements `Cloneable` the return type of the method `clone()` must be the class name. That way, the caller
+of the clone method doesn't need to cast the returned clone to the correct type.
+
+Note: Such a covariant return type is only possible with Java 1.5 or higher.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration
+    [@Name = 'clone']
+    [@Arity = 0]
+    [ClassType[1]/@SimpleName != ancestor::ClassDeclaration[1]/@SimpleName]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo implements Cloneable {
+    @Override
+    protected Object clone() { // Violation, Object must be Foo
+    }
+}
+
+public class Foo implements Cloneable {
+    @Override
+    public Foo clone() { //Ok
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CloseResource"
+          language="java"
+          since="1.2.2"
+          message="Ensure that resources like this {0} object are closed after use"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.CloseResourceRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#closeresource">
+        <description>
+Ensure that resources (like `java.sql.Connection`, `java.sql.Statement`, and `java.sql.ResultSet` objects
+and any subtype of `java.lang.AutoCloseable`) are always closed after use.
+Failing to do so might result in resource leaks.
+
+Note: It suffices to configure the super type, e.g. `java.lang.AutoCloseable`, so that this rule automatically triggers
+on any subtype (e.g. `java.io.FileInputStream`). Additionally specifying `java.sql.Connection` helps in detecting
+the types, if the type resolution / auxclasspath is not correctly setup.
+
+Note: Since PMD 6.16.0 the default value for the property `types` contains `java.lang.AutoCloseable` and detects
+now cases where the standard `java.io.*Stream` classes are involved. In order to restore the old behaviour,
+just remove "AutoCloseable" from the types.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Bar {
+    public void withSQL() {
+        Connection c = pool.getConnection();
+        try {
+            // do stuff
+        } catch (SQLException ex) {
+           // handle exception
+        } finally {
+            // oops, should close the connection using 'close'!
+            // c.close();
+        }
+    }
+
+    public void withFile() {
+        InputStream file = new FileInputStream(new File("/tmp/foo"));
+        try {
+            int c = file.in();
+        } catch (IOException e) {
+            // handle exception
+        } finally {
+            // TODO: close file
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="CompareObjectsWithEquals"
+          language="java"
+          since="3.2"
+          message="Use equals() to compare object references."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#compareobjectswithequals">
+        <description>
+Use `equals()` to compare object references; avoid comparing them with `==`.
+
+Since comparing objects with named constants is useful in some cases (eg, when
+defining constants for sentinel values), the rule ignores comparisons against
+fields with all-caps name (eg `this == SENTINEL`), which is a common naming
+convention for constant fields.
+
+You may allow some types to be compared by reference by listing the exceptions
+in the `typesThatCompareByReference` property.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="typesThatCompareByReference" type="List[String]" description="List of canonical type names for which reference comparison is allowed.">
+                <value>java.lang.Enum,java.lang.Class</value>
+            </property>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//InfixExpression
+    [@Operator = ("==", "!=")]
+    [count(*
+        [not(self::NullLiteral)]
+        [pmd-java:typeIs('java.lang.Object')]
+        [not(some $t in $typesThatCompareByReference satisfies pmd-java:typeIs($t))]
+      ) = 2
+    ]
+    [not(ancestor::MethodDeclaration[1][@Name = "equals"])]
+    (: Is not a field access with an all-caps identifier :)
+    [not(FieldAccess[upper-case(@Name)=@Name]
+     or VariableAccess[upper-case(@Name)=@Name])]
+]]>
+        </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+class Foo {
+  boolean bar(String a, String b) {
+    return a == b;
+  }
+}
+
+]]>
+        </example>
+    </rule>
+
+    <rule name="ComparisonWithNaN"
+          language="java"
+          since="6.36.0"
+          message="Comparisons with NaN always return false"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#comparisonwithnan">
+        <description><![CDATA[
+            Reports comparisons with double and float `NaN` (Not-a-Number) values.
+            These are [specified](https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.21.1)
+            to have unintuitive behavior: NaN is considered unequal to itself.
+            This means a check like `someDouble == Double.NaN` will always return
+            false, even if `someDouble` is really the NaN value. To test whether a
+            value is the NaN value, one should instead use `Double.isNaN(someDouble)`
+            (or `Float.isNaN`). The `!=` operator should be treated similarly.
+            Finally, comparisons like `someDouble <= Double.NaN` are nonsensical
+            and will always evaluate to false.
+            
+            This rule has been renamed from "BadComparison" in PMD 6.36.0.
+        ]]></description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//InfixExpression[@Operator = ("==", "!=", "<=", ">=", "<", ">")]/FieldAccess[@Name='NaN' and (pmd-java:typeIs('double') or pmd-java:typeIs('float'))]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+            <![CDATA[
+boolean x = (y == Double.NaN);
+]]>
+        </example>
+    </rule>
+
+    <rule name="ConfusingArgumentToVarargsMethod"
+          language="java"
+          since="7.1.0"
+          message="Unclear if a varargs or non-varargs call is intended. Cast to {0} or {0}[], or pass varargs parameters separately to clarify intent."
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.ConfusingArgumentToVarargsMethodRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#confusingargumenttovarargsmethod">
+        <description>
+            Reports a confusing argument passed to a varargs method.
+
+            This can occur when an array is passed as a single varargs argument, when the array type is not exactly the
+            type of array that the varargs method expects. If, that array is a subtype of the component type of the expected
+            array type, then it might not be clear what value the called varargs method will receive.
+            For instance if you have:
+            ```java
+            void varargs(Object... parm);
+            ```
+            and call it like so:
+            ```java
+            varargs(new String[]{"a"});
+            ```
+            it is not clear whether you intended the method to receive the value `new Object[]{ new String[] {"a"} }` or
+            just `new String[] {"a"}` (the latter happens). This confusion occurs because `String[]` is both a subtype
+            of `Object[]` and of `Object`. To clarify your intent in this case, use a cast or pass individual elements like so:
+            ```java
+            // varargs call
+            // parm will be `new Object[] { "a" }`
+            varargs("a");
+
+            // non-varargs call
+            // parm will be `new String[] { "a" }`
+            varargs((Object[]) new String[]{"a"});
+
+            // varargs call
+            // parm will be `new Object[] { new String[] { "a" } }`
+            varargs((Object) new String[]{"a"});
+            ```
+
+            Another confusing case is when you pass `null` as the varargs argument. Here it is not clear whether you intended
+            to pass an array with a single null element, or a null array (the latter happens). This can similarly be clarified
+            with a cast.
+        </description>
+        <priority>3</priority>
+        <example><![CDATA[
+            import java.util.Arrays;
+
+            abstract class C {
+                abstract void varargs(Object... args);
+                static {
+                    varargs(new String[] { "a" });
+                    varargs(null);
+                }
+            }
+            ]]></example>
+    </rule>
+
+    <rule name="ConstructorCallsOverridableMethod"
+          language="java"
+          since="1.04"
+          message="Overridable {0} called during object construction{1}"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.ConstructorCallsOverridableMethodRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#constructorcallsoverridablemethod">
+        <description>
+Reports calls to overridable methods on `this` during object initialization. These
+are invoked on an incompletely constructed object and can be difficult to debug if overridden.
+This is because the subclass usually assumes that the superclass is completely initialized
+in all methods. If that is not the case, bugs can appear in the constructor, for instance,
+some fields that are still null may cause a NullPointerException or be stored somewhere
+else to blow up later.
+
+To avoid this problem, only use methods that are static, private, or final in constructors.
+Note that those methods also must not call overridable methods transitively to be safe.
+        </description>
+        <priority>1</priority>
+        <example>
+<![CDATA[
+public class SeniorClass {
+  public SeniorClass(){
+      toString(); //may throw NullPointerException if overridden
+  }
+  public String toString(){
+    return "IAmSeniorClass";
+  }
+}
+public class JuniorClass extends SeniorClass {
+  private String name;
+  public JuniorClass(){
+    super(); //Automatic call leads to NullPointerException
+    name = "JuniorClass";
+  }
+  public String toString(){
+    return name.toUpperCase();
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="DetachedTestCase"
+          language="java"
+          since="6.13.0"
+          message="Probable detached JUnit test case."
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.DetachedTestCaseRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#detachedtestcase">
+        <description>
+The method appears to be a test case since it has public or default visibility,
+non-static access, no arguments, no return value, has no annotations, but is a
+member of a class that has one or more JUnit test cases. If it is a utility
+method, it should likely have private visibility. If it is an ignored test, it
+should be annotated with @Test and @Ignore.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class MyTest {
+    @Test
+    public void someTest() {
+    }
+
+    // violation: Not annotated
+    public void someOtherTest () {
+    }
+
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="DoNotCallGarbageCollectionExplicitly"
+          language="java"
+          since="4.2"
+          message="Do not explicitly trigger a garbage collection."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#donotcallgarbagecollectionexplicitly">
+        <description>
+Calls to `System.gc()`, `Runtime.getRuntime().gc()`, and `System.runFinalization()` are not advised.
+Code should have the same behavior whether the garbage collection is disabled using the option
+`-Xdisableexplicitgc` or not.
+
+Moreover, "modern" JVMs do a very good job handling garbage collections. If memory usage issues unrelated to memory
+leaks develop within an application, it should be dealt with JVM options rather than within the code itself.
+        </description>
+        <priority>2</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall[
+       pmd-java:matchesSig("java.lang.System#gc()")
+    or pmd-java:matchesSig("java.lang.Runtime#gc()")
+    or pmd-java:matchesSig("java.lang.System#runFinalization()")
+    or pmd-java:matchesSig("java.lang.Runtime#runFinalization()")
+]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class GCCall {
+    public GCCall() {
+        // Explicit gc call !
+        System.gc();
+    }
+
+    public void doSomething() {
+        // Explicit gc call !
+        Runtime.getRuntime().gc();
+    }
+
+    public explicitGCcall() {
+        // Explicit gc call !
+        System.gc();
+    }
+
+    public void doSomething() {
+        // Explicit gc call !
+        Runtime.getRuntime().gc();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="DoNotExtendJavaLangThrowable"
+          language="java"
+          since="6.0.0"
+          message="Exceptions should not extend java.lang.Throwable"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#donotextendjavalangthrowable">
+        <description>
+Extend Exception or RuntimeException instead of Throwable.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration/ExtendsList/ClassType
+  [pmd-java:typeIsExactly('java.lang.Throwable')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo extends Throwable { }
+]]>
+        </example>
+    </rule>
+
+    <rule name="DoNotHardCodeSDCard"
+          since="4.2.6"
+          language="java"
+          message="Do not hardcode /sdcard."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#donothardcodesdcard">
+        <description>
+Use Environment.getExternalStorageDirectory() instead of "/sdcard"
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>//StringLiteral[starts-with(@Image,'"/sdcard')]</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class MyActivity extends Activity {
+    protected void foo() {
+        String storageLocation = "/sdcard/mypackage";   // hard-coded, poor approach
+
+       storageLocation = Environment.getExternalStorageDirectory() + "/mypackage"; // preferred approach
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="DoNotTerminateVM"
+          language="java"
+          since="4.1"
+          message="System.exit() should not be used in J2EE/JEE apps"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#donotterminatevm">
+        <description>
+Web applications should not call `System.exit()`, since only the web container or the
+application server should stop the JVM. Otherwise a web application would terminate all other applications
+running on the same application server.
+
+This rule also checks for the equivalent calls `Runtime.getRuntime().exit()` and `Runtime.getRuntime().halt()`.
+
+This rule has been renamed from "DoNotCallSystemExit" in PMD 6.29.0.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//(MethodDeclaration[@MainMethod = false()] | Initializer)//MethodCall[
+    pmd-java:matchesSig("java.lang.System#exit(int)")
+    or pmd-java:matchesSig("java.lang.Runtime#exit(int)")
+    or pmd-java:matchesSig("java.lang.Runtime#halt(int)")
+]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public void bar() {
+    System.exit(0);                 // never call this when running in an application server!
+}
+public void foo() {
+    Runtime.getRuntime().exit(0);   // never stop the JVM manually, the container will do this.
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="DoNotThrowExceptionInFinally"
+          language="java"
+          since="4.2"
+          message="A throw statement in a finally block makes the control flow hard to understand."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#donotthrowexceptioninfinally">
+        <description>
+Throwing exceptions within a 'finally' block is confusing since they may mask other exceptions
+or code defects.
+Note: This is a PMD implementation of the Lint4j rule "A throw in a finally block"
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>//FinallyClause[descendant::ThrowStatement]</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    public void bar() {
+        try {
+            // Here do some stuff
+        } catch( Exception e) {
+            // Handling the issue
+        } finally {
+            // is this really a good idea ?
+            throw new Exception();
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="DontImportSun"
+          language="java"
+          since="1.5"
+          message="Avoid importing anything from the 'sun.*' packages"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#dontimportsun">
+        <description>
+Avoid importing anything from the 'sun.*' packages. These packages are not portable
+and are likely to change.
+
+If you find yourself having to depend on Sun APIs, confine this dependency to as
+small a scope as possible, for instance by writing a stable wrapper class around
+the unstable API. You can then suppress this rule in the implementation of the wrapper.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//ImportDeclaration[starts-with(@ImportedName, 'sun.')]
+]]>
+                </value>
+            </property>
+
+        </properties>
+        <example>
+<![CDATA[
+import sun.misc.foo;
+public class Foo {}
+]]>
+        </example>
+    </rule>
+
+    <rule name="DontUseFloatTypeForLoopIndices"
+          language="java"
+          since="4.3"
+          message="Don't use floating point for loop indices. If you must use floating point, use double."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#dontusefloattypeforloopindices">
+        <description>
+Don't use floating point for loop indices. If you must use floating point, use double
+unless you're certain that float provides enough precision and you have a compelling
+performance need (space or time).
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ForStatement/ForInit//VariableId[pmd-java:typeIs('float')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Count {
+  public static void main(String[] args) {
+    final int START = 2000000000;
+    int count = 0;
+    for (float f = START; f < START + 50; f++)
+      count++;
+      //Prints 0 because (float) START == (float) (START + 50).
+      System.out.println(count);
+      //The termination test misbehaves due to floating point granularity.
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="EmptyCatchBlock"
+          language="java"
+          since="0.1"
+          message="Avoid empty catch blocks"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptycatchblock">
+        <description>
+Empty Catch Block finds instances where an exception is caught, but nothing is done.
+In most circumstances, this swallows an exception which should either be acted on
+or reported.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//CatchClause[
+  Block[
+      count(*) = 0
+      and ($allowCommentedBlocks = false() or @containsComment = false())
+  ]
+  and CatchParameter/VariableId[not(matches(@Name, $allowExceptionNameRegex))]
+]
+]]>
+                </value>
+            </property>
+            <property name="allowCommentedBlocks" type="Boolean" description="Empty blocks containing comments will be skipped" value="false"/>
+            <property name="allowExceptionNameRegex" type="Regex" description="Empty blocks catching exceptions with names matching this regular expression will be skipped" value="^(ignored|expected)$"/>
+        </properties>
+        <example>
+<![CDATA[
+public void doSomething() {
+    try {
+        FileInputStream fis = new FileInputStream("/tmp/bugger");
+    } catch (IOException ioe) {
+        // not good
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="EmptyFinalizer"
+          language="java"
+          since="1.5"
+          message="Avoid empty finalize methods"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#emptyfinalizer">
+        <description>
+Empty finalize methods serve no purpose and should be removed. Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration[@Name='finalize'][@Arity = 0]
+  /Block[not(*)]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+   protected void finalize() {}
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="EqualsNull"
+          language="java"
+          since="1.9"
+          message="Avoid using equals() to compare against null"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#equalsnull">
+        <description>
+Tests for null should not use the equals() method. The '==' operator should be used instead.
+        </description>
+        <priority>1</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall[@MethodName = "equals" and ArgumentList[count(*) = 1 and NullLiteral]]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+String x = "foo";
+
+if (x.equals(null)) {   // bad form
+    doSomething();
+}
+
+if (x == null) {        // preferred
+    doSomething();
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="FinalizeDoesNotCallSuperFinalize"
+          language="java"
+          since="1.5"
+          message="Last statement in finalize method should be a call to super.finalize()"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#finalizedoesnotcallsuperfinalize">
+        <description>
+If the finalize() is implemented, its last action should be to call super.finalize. Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<!-- in English: a method declaration of finalize(), with no arguments, containing
+a block whose last statement is NOT a call to super.finalize -->
+<![CDATA[
+//MethodDeclaration[@Name = "finalize"][@Arity = 0]
+   /Block/*[last()]
+      [not(MethodCall[@MethodName = "finalize"]/SuperExpression)]
+      [not(FinallyClause/Block/ExpressionStatement/
+          MethodCall[@MethodName = "finalize"]/SuperExpression)]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+protected void finalize() {
+    something();
+    // neglected to call super.finalize()
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="FinalizeOnlyCallsSuperFinalize"
+          language="java"
+          since="1.5"
+          message="Finalize should do something besides just calling super.finalize()"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#finalizeonlycallssuperfinalize">
+        <description>
+If the finalize() is implemented, it should do something besides just calling super.finalize(). Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration[@Name='finalize'][@Arity = 0]
+   [Block[@Size=1]/ExpressionStatement/MethodCall[@MethodName = "finalize"][SuperExpression]]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+protected void finalize() {
+    super.finalize();
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="FinalizeOverloaded"
+          language="java"
+          since="1.5"
+          message="Finalize methods should not be overloaded"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#finalizeoverloaded">
+        <description>
+Methods named finalize() should not have parameters.  It is confusing and most likely an attempt to
+overload Object.finalize(). It will not be called by the VM.
+
+Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration[@Name='finalize'][@Arity > 0]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    // this is confusing and probably a bug
+    protected void finalize(int a) {
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="FinalizeShouldBeProtected"
+          language="java"
+          since="1.1"
+          message="If you override finalize(), make it protected"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#finalizeshouldbeprotected">
+        <description>
+When overriding the finalize(), the new method should be set as protected.  If made public,
+other classes may invoke it at inappropriate times.
+
+Note that Oracle has declared Object.finalize() as deprecated since JDK 9.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration[@Visibility != "protected"][@Name='finalize'][@Arity = 0]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public void finalize() {
+    // do something
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="IdempotentOperations"
+          language="java"
+          since="2.0"
+          message="Avoid idempotent operations (like assigning a variable to itself)."
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.IdempotentOperationsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#idempotentoperations">
+        <description>
+Avoid idempotent operations - they have no effect.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+ public void bar() {
+  int x = 2;
+  x = x;
+ }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ImplicitSwitchFallThrough"
+          language="java"
+          since="3.0"
+          message="This switch case may be reached by fallthrough from the previous case"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.ImplicitSwitchFallThroughRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#implicitswitchfallthrough">
+        <description>
+Switch statements without break or return statements for each case option
+may indicate problematic behaviour. Empty cases are ignored as these indicate
+an intentional fall-through.
+
+You can ignore a violation by commenting `// fallthrough` before the case label
+which is reached by fallthrough, or with `@SuppressWarnings("fallthrough")`.
+
+This rule has been renamed from "MissingBreakInSwitch" in PMD 6.37.0.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public void bar(int status) {
+    switch(status) {
+      case CANCELLED:
+        doCancelled();
+        // break; hm, should this be commented out?
+      case NEW:
+        doNew();
+        // is this really a fall-through?
+        // what happens if you add another case after this one?
+      case REMOVED:
+        doRemoved();
+        // fallthrough - this comment just clarifies that you want a fallthrough
+      case OTHER: // empty case - this is interpreted as an intentional fall-through
+      case ERROR:
+        doErrorHandling();
+        break;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="InstantiationToGetClass"
+          language="java"
+          since="2.0"
+          message="Avoid instantiating an object just to call getClass() on it; use the .class public member instead"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#instantiationtogetclass">
+        <description>
+Avoid instantiating an object just to call getClass() on it; use the .class public member instead.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall
+ [@MethodName='getClass']
+ [ConstructorCall]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+// replace this
+Class c = new String().getClass();
+
+// with this:
+Class c = String.class;
+]]>
+        </example>
+    </rule>
+
+    <rule name="InvalidLogMessageFormat"
+          language="java"
+          since="5.5.0"
+          message="Invalid message format"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.InvalidLogMessageFormatRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#invalidlogmessageformat">
+        <description>
+Check for messages in slf4j and log4j2 (since 6.19.0) loggers with non matching number of arguments and placeholders.
+
+Since 6.32.0 in addition to parameterized message placeholders (`{}`) also format specifiers of string formatted
+messages are supported (`%s`).
+
+This rule has been renamed from "InvalidSlf4jMessageFormat" in PMD 6.19.0.
+        </description>
+        <priority>5</priority>
+        <example>
+<![CDATA[
+LOGGER.error("forget the arg {}");
+LOGGER.error("forget the arg %s");
+LOGGER.error("too many args {}", "arg1", "arg2");
+LOGGER.error("param {}", "arg1", new IllegalStateException("arg")); //The exception is shown separately, so is correct.
+]]>
+        </example>
+    </rule>
+
+    <rule name="JumbledIncrementer"
+          language="java"
+          since="1.0"
+          message="Avoid modifying an outer loop incrementer in an inner loop for update expression"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#jumbledincrementer">
+        <description>
+Avoid jumbled loop incrementers - it's usually a mistake, and is confusing even if intentional.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value><![CDATA[
+//ForStatement
+    [not(ForInit) or ForInit//VariableId/@Name != ForUpdate//VariableAccess/@Name]
+    [ForUpdate//VariableAccess[@AccessType = 'WRITE']/@Name
+     =
+     ancestor::ForStatement/ForInit//VariableId/@Name
+    ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+ <![CDATA[
+public class JumbledIncrementerRule1 {
+    public void foo() {
+        for (int i = 0; i < 10; i++) {          // only references 'i'
+            for (int k = 0; k < 20; i++) {      // references both 'i' and 'k'
+                System.out.println("Hello");
+            }
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="JUnitSpelling"
+          language="java"
+          since="1.0"
+          message="You may have misspelled a JUnit framework method (setUp or tearDown)"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.JUnitSpellingRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#junitspelling">
+        <description>
+            In JUnit 3, the setUp method is used to set up all data entities required in running tests.
+            The tearDown method is used to clean up all data entities required in running tests.
+            You should not misspell method name if you want your test to set up and clean up everything correctly.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+import junit.framework.*;
+
+public class Foo extends TestCase {
+    public void setup() {}    // oops, should be setUp
+    public void TearDown() {} // oops, should be tearDown
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="JUnitStaticSuite"
+          language="java"
+          since="1.0"
+          message="You have a suite() method that is not both public and static, so JUnit won't call it to get your TestSuite.  Is that what you wanted to do?"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.JUnitStaticSuiteRule"
+          typeResolution="true"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#junitstaticsuite">
+        <description>
+The suite() method in a JUnit test needs to be both public and static.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+import junit.framework.*;
+
+public class Foo extends TestCase {
+    public void suite() {}         // oops, should be static
+}
+]]>
+        </example>
+        <example>
+<![CDATA[
+import junit.framework.*;
+
+public class Foo extends TestCase {
+    private static void suite() {} // oops, should be public
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="MethodWithSameNameAsEnclosingClass"
+          language="java"
+          since="1.5"
+          message="A method should not have the same name as its containing class"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#methodwithsamenameasenclosingclass">
+        <description>
+A method should not have the same name as its containing class.
+This would be confusing as it would look like a constructor. 
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration[@Name = ancestor::ClassDeclaration/@SimpleName]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class MyClass {
+
+    public MyClass() {}         // this is OK because it is a constructor
+
+    public void MyClass() {}    // this is bad because it is a method
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="MisplacedNullCheck"
+          language="java"
+          since="3.5"
+          message="The null check here is misplaced; if the variable ''{0}'' is null there will be a NullPointerException"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#misplacednullcheck">
+        <description>
+The null check here is misplaced. If the variable is null a `NullPointerException` will be thrown.
+Either the check is useless (the variable will never be `null`) or it is incorrect.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//InfixExpression[@Operator = '&&']
+    /InfixExpression[@Operator = '!=']
+        (: one side is null :)
+        [NullLiteral]
+        (: other side checks for the variable used somewhere in the first child of conditional and expression :)
+        [VariableAccess]
+        [some $var in preceding-sibling::*//VariableAccess
+            [parent::MethodCall or parent::FieldAccess]
+            [not(ancestor::InfixExpression[@Operator = '||'])]
+            /@Name
+            satisfies $var = VariableAccess/@Name
+        ]
+    /VariableAccess
+|
+//InfixExpression[@Operator = '||']
+    /InfixExpression[@Operator = '==']
+        (: one side is null :)
+        [NullLiteral]
+        (: other side checks for the variable used somewhere in the first child of conditional or expression :)
+        [VariableAccess]
+        [some $var in preceding-sibling::*//VariableAccess
+            [parent::MethodCall or parent::FieldAccess]
+            [not(ancestor::InfixExpression[@Operator = '&&'])]
+            /@Name
+            satisfies $var = VariableAccess/@Name
+        ]
+    /VariableAccess
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    void bar() {
+        if (a.equals(baz) && a != null) {} // a could be null, misplaced null check
+
+        if (a != null && a.equals(baz)) {} // correct null check
+    }
+}
+]]>
+        </example>
+        <example>
+<![CDATA[
+public class Foo {
+    void bar() {
+        if (a.equals(baz) || a == null) {} // a could be null, misplaced null check
+
+        if (a == null || a.equals(baz)) {} // correct null check
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="MissingSerialVersionUID"
+          language="java"
+          since="3.0"
+          message="Classes implementing Serializable should set a serialVersionUID"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#missingserialversionuid">
+        <description>
+Serializable classes should provide a serialVersionUID field.
+The serialVersionUID field is also needed for abstract base classes. Each individual class in the inheritance
+chain needs an own serialVersionUID field. See also [Should an abstract class have a serialVersionUID](https://stackoverflow.com/questions/893259/should-an-abstract-class-have-a-serialversionuid).
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration
+    [@Interface = false()]
+    [count(ClassBody/FieldDeclaration/VariableDeclarator/VariableId[@Name='serialVersionUID']) = 0]
+    [(ImplementsList | ExtendsList)/ClassType[pmd-java:typeIs('java.io.Serializable')]]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo implements java.io.Serializable {
+    String name;
+    // Define serialization id to avoid serialization related bugs
+    // i.e., public static final long serialVersionUID = 4328743;
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="MissingStaticMethodInNonInstantiatableClass"
+          language="java"
+          since="3.0"
+          message="Class cannot be instantiated and does not provide any static methods or fields"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#missingstaticmethodinnoninstantiatableclass">
+        <description>
+A class that has private constructors and does not have any static methods or fields cannot be used.
+
+When one of the private constructors is annotated with one of the annotations, then the class is not considered
+non-instantiatable anymore and no violation will be reported.
+See the property `annotations`.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="annotations" type="List[String]" value="org.springframework.beans.factory.annotation.Autowired,javax.inject.Inject,com.google.inject.Inject,lombok.Builder" description="If a constructor is annotated with one of these annotations, then the class is ignored."/>
+            <property name="xpath">
+                <value>
+<![CDATA[
+let $topLevelClass := /*/ClassDeclaration return
+let $isLombokUtility := exists($topLevelClass[pmd-java:hasAnnotation('lombok.experimental.UtilityClass')]) return
+$topLevelClass[
+        (: non-instantiable :)
+        $isLombokUtility or
+        (
+            (: no lombok produced constructors :)
+            not(pmd-java:hasAnnotation('lombok.NoArgsConstructor') or
+                pmd-java:hasAnnotation('lombok.RequiredArgsConstructor') or
+                pmd-java:hasAnnotation('lombok.AllArgsConstructor') or
+                pmd-java:hasAnnotation('lombok.Builder')) and
+            (: or has non-default constructors … :)
+            ClassBody/ConstructorDeclaration and
+                (: … but only private … :)
+                not(ClassBody/ConstructorDeclaration[@Visibility != "private"]) and
+                (: … and none annotated … :)
+                (every $x in $annotations satisfies
+                      not(ClassBody/ConstructorDeclaration/ModifierList/Annotation[pmd-java:typeIs($x)]))
+        )
+    ]
+    [
+        (: With no visible static methods … :)
+        not(ClassBody/MethodDeclaration[($isLombokUtility or pmd-java:modifiers() = "static") and @Visibility != "private"]) and
+        (: … nor fields … :)
+        not(ClassBody/FieldDeclaration[($isLombokUtility or pmd-java:modifiers() = "static") and @Visibility != "private"]) and
+        (: … no nested classes, that are non-private and static … :)
+        not(ClassBody/ClassDeclaration
+            [pmd-java:modifiers() = "static" and @Visibility != "private"]
+            (: … and a non-private method returning the outer class type … :)
+            [(ClassBody/MethodDeclaration
+                [@Visibility != "private"]
+                [descendant::ReturnStatement/*[1][pmd-java:typeIs(ancestor::ClassDeclaration[@Nested = false()]/@BinaryName)]]
+            ) or (
+                (: … or the inner class extends the outer class :)
+                ExtendsList/ClassType[@SimpleName = ancestor::ClassDeclaration[@Nested = false()]/@SimpleName]
+            )]
+    )]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+// This class is unusable, since it cannot be
+// instantiated (private constructor),
+// and no static method can be called.
+
+public class Foo {
+  private Foo() {}
+  void foo() {}
+}
+
+]]>
+        </example>
+    </rule>
+
+    <rule name="MoreThanOneLogger"
+          language="java"
+          since="2.0"
+          message="Class contains more than one logger."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#morethanonelogger">
+        <description>
+Normally only one logger is used in each class. This rule supports slf4j, log4j, Java Util Logging and
+log4j2 (since 6.19.0).
+        </description>
+        <priority>2</priority>
+        <properties>
+            <property name="xpath">
+                <value><![CDATA[
+//ClassDeclaration[
+  count(
+    ClassBody/FieldDeclaration/ClassType[
+      pmd-java:typeIs("org.apache.log4j.Logger") or
+      pmd-java:typeIs("org.apache.logging.log4j.Logger") or
+      pmd-java:typeIs("java.util.logging.Logger") or
+      pmd-java:typeIs("org.slf4j.Logger")
+    ]
+  ) > 1
+]
+                ]]></value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    Logger log = Logger.getLogger(Foo.class.getName());
+    // It is very rare to see two loggers on a class, normally
+    // log information is multiplexed by levels
+    Logger log2= Logger.getLogger(Foo.class.getName());
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="NonCaseLabelInSwitchStatement"
+          language="java"
+          since="1.5"
+          message="A non-case label was present in a switch statement"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#noncaselabelinswitchstatement">
+        <description>
+A non-case label (e.g. a named break/continue label) was present in a switch statement.
+This is legal, but confusing. It is easy to mix up the case labels and the non-case labels.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>//SwitchStatement//LabeledStatement</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+  void bar(int a) {
+   switch (a) {
+     case 1:
+       // do something
+       break;
+     mylabel: // this is legal, but confusing!
+       break;
+     default:
+       break;
+    }
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="NonSerializableClass"
+          language="java"
+          since="1.1"
+          message="The field ''{0}'' of serializable class ''{1}'' is of non-serializable type ''{2}''."
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.NonSerializableClassRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#nonserializableclass">
+        <description>
+If a class is marked as `Serializable`, then all fields need to be serializable as well. In order to exclude
+a field, it can be marked as transient. Static fields are not considered.
+
+This rule reports all fields, that are not serializable.
+
+If a class implements the methods to perform manual serialization (`writeObject`, `readObject`) or uses
+a replacement object (`writeReplace`, `readResolve`) then this class is ignored.
+
+Note: This rule has been revamped with PMD 6.52.0. It was previously called "BeanMembersShouldSerialize".
+The property `prefix` has been deprecated, since in a serializable class all fields have to be
+serializable regardless of the name.
+        </description>
+        <priority>3</priority>
+        <example>
+            <![CDATA[
+class Buzz implements java.io.Serializable {
+    private static final long serialVersionUID = 1L;
+
+    private transient int someFoo;          // good, it's transient
+    private static int otherFoo;            // also OK, it's static
+    private java.io.FileInputStream stream; // bad - FileInputStream is not serializable
+
+    public void setStream(FileInputStream stream) {
+        this.stream = stream;
+    }
+
+    public int getSomeFoo() {
+          return this.someFoo;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="NonStaticInitializer"
+          language="java"
+          since="1.5"
+          message="Non-static initializers are confusing"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#nonstaticinitializer">
+        <description>
+A non-static initializer block will be called any time a constructor is invoked (just prior to
+invoking the constructor).  While this is a valid language construct, it is rarely used and is
+confusing.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//Initializer[@Static=false()][not(ancestor::*[3][self::ConstructorCall or self::EnumConstant])]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class MyClass {
+  // this block gets run before any call to a constructor
+  {
+    System.out.println("I am about to construct myself");
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="NullAssignment"
+          language="java"
+          since="1.02"
+          message="Assigning an Object to null is a code smell.  Consider refactoring."
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.NullAssignmentRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#nullassignment">
+        <description>
+Assigning a "null" to a variable (outside of its declaration) is usually bad form.  Sometimes, this type
+of assignment is an indication that the programmer doesn't completely understand what is going on in the code.
+
+NOTE: This sort of assignment may used in some cases to dereference objects and encourage garbage collection.
+        </description>
+        <priority>3</priority>
+        <example>
+ <![CDATA[
+public void bar() {
+  Object x = null; // this is OK
+  x = new Object();
+     // big, complex piece of code here
+  x = null; // this is not required
+     // big, complex piece of code here
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="OverrideBothEqualsAndHashcode"
+          language="java"
+          since="0.4"
+          message="Ensure you override both equals() and hashCode()"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.OverrideBothEqualsAndHashcodeRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#overridebothequalsandhashcode">
+        <description>
+Override both public boolean Object.equals(Object other), and public int Object.hashCode(), or override neither.  Even if you are inheriting a hashCode() from a parent class, consider implementing hashCode and explicitly delegating to your superclass.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Bar {        // poor, missing a hashcode() method
+    public boolean equals(Object o) {
+      // do some comparison
+    }
+}
+
+public class Baz {        // poor, missing an equals() method
+    public int hashCode() {
+      // return some hash value
+    }
+}
+
+public class Foo {        // perfect, both methods provided
+    public boolean equals(Object other) {
+      // do some comparison
+    }
+    public int hashCode() {
+      // return some hash value
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ProperCloneImplementation"
+          language="java"
+          since="1.4"
+          message="Object clone() should be implemented with super.clone()"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.ProperCloneImplementationRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#propercloneimplementation">
+        <description>
+Object clone() should be implemented with super.clone().
+        </description>
+        <priority>2</priority>
+        <example>
+<![CDATA[
+class Foo{
+    public Object clone(){
+        return new Foo(); // This is bad
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ProperLogger"
+          language="java"
+          since="3.3"
+          message="Logger should be defined private static final and have the correct class"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#properlogger">
+        <description>
+A logger should normally be defined private static final and be associated with the correct class.
+`private final Log log;` is also allowed for rare cases where loggers need to be passed around,
+with the restriction that the logger needs to be passed into the constructor.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//FieldDeclaration
+    [ClassType[pmd-java:typeIs($loggerClass)]]
+    [
+        (: check modifiers :)
+        (not(pmd-java:modifiers() = 'private') or not(pmd-java:modifiers() = 'final'))
+        (: check logger name :)
+        or (pmd-java:modifiers() = 'static' and VariableDeclarator/VariableId/@Name != $staticLoggerName)
+        or (not(pmd-java:modifiers() = 'static') and VariableDeclarator/VariableId/@Name != $loggerName)
+        (: check logger argument type matches class or enum name :)
+        or .//ArgumentList/ClassLiteral/ClassType/@SimpleName != ancestor::ClassDeclaration/@SimpleName
+        or .//ArgumentList/ClassLiteral/ClassType/@SimpleName != ancestor::EnumDeclaration/@SimpleName
+
+        (: special case - final logger initialized inside constructor :)
+        or (VariableDeclarator/@Initializer = false()
+            and not(pmd-java:modifiers() = 'static')
+            and not(ancestor::ClassBody/ConstructorDeclaration
+                //AssignmentExpression[@Operator = '=']
+                    [FieldAccess[1]/@Name = $loggerName or VariableAccess[1]/@Name = $loggerName]
+                    [*[2][@Name = ancestor::ConstructorDeclaration//FormalParameter/VariableId/@Name]])
+        )
+    ]
+]]>
+                </value>
+            </property>
+            <property name="staticLoggerName" type="String" description="Name of the static Logger variable" value="LOG"/>
+            <property name="loggerName" type="String" description="Name of the Logger instance variable" value="log"/>
+            <property name="loggerClass" type="String" description="Class name of the logger" value="org.apache.commons.logging.Log"/>
+        </properties>
+        <example>
+ <![CDATA[
+public class Foo {
+
+    private static final Log LOG = LogFactory.getLog(Foo.class);    // proper way
+
+    protected Log LOG = LogFactory.getLog(Testclass.class);         // wrong approach
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ReturnEmptyCollectionRatherThanNull"
+          language="java"
+          since="6.37.0"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="Return an empty collection rather than 'null'."
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#returnemptycollectionratherthannull">
+        <description>
+For any method that returns an collection (such as an array, Collection or Map), it is better to return
+an empty one rather than a null reference. This removes the need for null checking all results and avoids
+inadvertent NullPointerExceptions.
+
+See Effective Java, 3rd Edition, Item 54: Return empty collections or arrays instead of null
+        </description>
+        <priority>1</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ReturnStatement/NullLiteral
+[ancestor::MethodDeclaration[1]
+    [ArrayType
+     or ClassType[pmd-java:typeIs('java.util.Collection')
+        or pmd-java:typeIs('java.util.Map')]]
+]
+[not(./ancestor::LambdaExpression)]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Example {
+    // Not a good idea...
+    public int[] badBehavior() {
+        // ...
+        return null;
+    }
+
+    // Good behavior
+    public String[] bonnePratique() {
+        //...
+        return new String[0];
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="ReturnFromFinallyBlock"
+          language="java"
+          since="1.05"
+          message="Avoid returning from a finally block"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#returnfromfinallyblock">
+        <description>
+Avoid returning from a finally block, this can discard exceptions.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>//FinallyClause//ReturnStatement except //FinallyClause//(MethodDeclaration|LambdaExpression)//ReturnStatement</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Bar {
+    public String foo() {
+        try {
+            throw new Exception( "My Exception" );
+        } catch (Exception e) {
+            throw e;
+        } finally {
+            return "A. O. K."; // return not recommended here
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="SimpleDateFormatNeedsLocale"
+          language="java"
+          since="2.0"
+          message="When instantiating a SimpleDateFormat object, specify a Locale"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#simpledateformatneedslocale">
+        <description>
+Be sure to specify a Locale when creating SimpleDateFormat instances to ensure that locale-appropriate
+formatting is used.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ConstructorCall
+    [pmd-java:typeIs('java.text.SimpleDateFormat')]
+    [ArgumentList/@Size = 1]
+]]>
+                    </value>
+                </property>
+            </properties>
+        <example>
+<![CDATA[
+public class Foo {
+  // Should specify Locale.US (or whatever)
+  private SimpleDateFormat sdf = new SimpleDateFormat("pattern");
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="SingleMethodSingleton"
+          language="java"
+          since="5.4"
+          message="Class contains multiple getInstance methods. Please review."
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.SingleMethodSingletonRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#singlemethodsingleton">
+        <description>
+Some classes contain overloaded getInstance. The problem with overloaded getInstance methods
+is that the instance created using the overloaded method is not cached and so,
+for each call and new objects will be created for every invocation.
+        </description>
+        <priority>2</priority>
+        <example>
+<![CDATA[
+public class Singleton {
+
+    private static Singleton singleton = new Singleton( );
+
+    private Singleton(){ }
+
+    public static Singleton getInstance( ) {
+        return singleton;
+    }
+
+    public static Singleton getInstance(Object obj){
+        Singleton singleton = (Singleton) obj;
+        return singleton;           //violation
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="SingletonClassReturningNewInstance"
+          language="java"
+          since="5.4"
+          message="getInstance method always creates a new object and hence does not comply to Singleton Design Pattern behaviour. Please review"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.SingletonClassReturningNewInstanceRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#singletonclassreturningnewinstance">
+        <description>
+            A singleton class should only ever have one instance. Failure to check
+            whether an instance has already been created may result in multiple
+            instances being created.
+        </description>
+        <priority>2</priority>
+        <example>
+<![CDATA[
+class Singleton {
+    private static Singleton instance = null;
+    public static Singleton getInstance() {
+        synchronized(Singleton.class) {
+            return new Singleton(); // this should be assigned to the field
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="StaticEJBFieldShouldBeFinal"
+          language="java"
+          since="4.1"
+          message="EJB's shouldn't have non-final static fields"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#staticejbfieldshouldbefinal">
+        <description>
+According to the J2EE specification, an EJB should not have any static fields
+with write access. However, static read-only fields are allowed. This ensures proper
+behavior especially when instances are distributed by the container on several JREs.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration[ImplementsList/ClassType[
+        pmd-java:typeIs('javax.ejb.SessionBean')
+     or pmd-java:typeIs('javax.ejb.EJBHome')
+     or pmd-java:typeIs('javax.ejb.EJBLocalObject')
+     or pmd-java:typeIs('javax.ejb.EJBLocalHome')
+     or pmd-java:typeIs('javax.ejb.EJBObject')
+    ]]
+    /ClassBody/FieldDeclaration
+        [pmd-java:modifiers() = 'static']
+        [not(pmd-java:modifiers() = 'final')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class SomeEJB extends EJBObject implements EJBLocalHome {
+
+    private static int CountA;          // poor, field can be edited
+
+    private static final int CountB;    // preferred, read-only access
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="StringBufferInstantiationWithChar"
+          language="java"
+          since="3.9"
+          message="Argument to `new StringBuilder()` or `new StringBuffer()` is implicitly converted from char to int"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#stringbufferinstantiationwithchar">
+        <description>
+Individual character values provided as initialization arguments will be converted into integers.
+This can lead to internal buffer sizes that are larger than expected. Some examples:
+
+```
+new StringBuffer()      //  16
+new StringBuffer(6)     //  6
+new StringBuffer("hello world")  // 11 + 16 = 27
+new StringBuffer('A')   //  chr(A) = 65
+new StringBuffer("A")   //  1 + 16 = 17
+
+new StringBuilder()     //  16
+new StringBuilder(6)    //  6
+new StringBuilder("hello world")  // 11 + 16 = 27
+new StringBuilder('C')   //  chr(C) = 67
+new StringBuilder("A")   //  1 + 16 = 17
+```
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ConstructorCall[ArgumentList/*[pmd-java:typeIsExactly('char')]]
+    [pmd-java:matchesSig('java.lang.StringBuilder#new(int)')
+     or pmd-java:matchesSig('java.lang.StringBuffer#new(int)')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+// misleading instantiation, these buffers
+// are actually sized to 99 characters long
+StringBuffer  sb1 = new StringBuffer('c');
+StringBuilder sb2 = new StringBuilder('c');
+
+// in these forms, just single characters are allocated
+StringBuffer  sb3 = new StringBuffer("c");
+StringBuilder sb4 = new StringBuilder("c");
+]]>
+        </example>
+    </rule>
+
+    <rule name="SuspiciousEqualsMethodName"
+          language="java"
+          since="2.0"
+          message="The method name and parameter number are suspiciously close to equals(Object)"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#suspiciousequalsmethodname">
+        <description>
+The method name and parameter number are suspiciously close to `Object.equals`, which can denote an
+intention to override it. However, the method does not override `Object.equals`, but overloads it instead.
+Overloading `Object.equals` method is confusing for other programmers, error-prone and hard to maintain,
+especially when using inheritance, because `@Override` annotations used in subclasses can provide a false
+sense of security. For more information on `Object.equals` method, see Effective Java, 3rd Edition,
+Item 10: Obey the general contract when overriding equals.
+        </description>
+        <priority>2</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodDeclaration[@Name = 'equals'][
+    (@Arity = 1
+     and not(FormalParameters/FormalParameter[pmd-java:typeIsExactly('java.lang.Object')])
+     or not(PrimitiveType[@Kind = 'boolean'])
+    ) or (
+     @Arity = 2
+     and PrimitiveType[@Kind = 'boolean']
+     and FormalParameters/FormalParameter[pmd-java:typeIsExactly('java.lang.Object')]
+     and not(pmd-java:hasAnnotation('java.lang.Override'))
+    )
+]
+| //MethodDeclaration[@Name = 'equal'][
+    @Arity = 1
+    and FormalParameters/FormalParameter[pmd-java:typeIsExactly('java.lang.Object')]
+]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+   public int equals(Object o) {
+     // oops, this probably was supposed to be boolean equals
+   }
+   public boolean equals(String s) {
+     // oops, this probably was supposed to be equals(Object)
+   }
+   public boolean equals(Object o1, Object o2) {
+     // oops, this probably was supposed to be equals(Object)
+   }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="SuspiciousHashcodeMethodName"
+          language="java"
+          since="1.5"
+          message="The method name and return type are suspiciously close to hashCode()"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#suspicioushashcodemethodname">
+        <description>
+The method name and return type are suspiciously close to hashCode(), which may denote an intention
+to override the hashCode() method.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//MethodDeclaration[
+        lower-case(@Name) = 'hashcode'
+    and @Name != 'hashCode'
+    and @Arity = 0
+    and PrimitiveType[@Kind = 'int']
+]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    public int hashcode() { // oops, this probably was supposed to be 'hashCode'
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="SuspiciousOctalEscape"
+          language="java"
+          since="1.5"
+          message="Suspicious decimal characters following octal escape in string literal: {0}"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.SuspiciousOctalEscapeRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#suspiciousoctalescape">
+        <description>
+A suspicious octal escape sequence was found inside a String literal.
+The Java language specification (section 3.10.6) says an octal
+escape sequence inside a literal String shall consist of a backslash
+followed by:
+
+    OctalDigit | OctalDigit OctalDigit | ZeroToThree OctalDigit OctalDigit
+
+Any octal escape sequence followed by non-octal digits can be confusing,
+e.g. "\038" is interpreted as the octal escape sequence "\03" followed by
+the literal character "8".
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public void foo() {
+  // interpreted as octal 12, followed by character '8'
+  System.out.println("suspicious: \128");
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="TestClassWithoutTestCases"
+          language="java"
+          since="3.0"
+          message="The class ''{0}'' might be a test class, but it contains no test cases."
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.TestClassWithoutTestCasesRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#testclasswithouttestcases">
+        <description>
+Test classes typically end with the suffix "Test", "Tests" or "TestCase". Having a non-test class with that name
+is not a good practice, since most people will assume it is a test case. Test classes have test methods
+named "testXXX" (JUnit3) or use annotations (e.g. `@Test`).
+
+The suffix can be configured using the property `testClassPattern`. To disable the detection of possible test classes
+by name, set this property to an empty string.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+//Consider changing the name of the class if it is not a test
+//Consider adding test methods if it is a test
+public class CarTest {
+   public static void main(String[] args) {
+    // do something
+   }
+   // code
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnconditionalIfStatement"
+          language="java"
+          since="1.5"
+          message="Do not use 'if' statements that are always true or always false"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#unconditionalifstatement">
+        <description>
+Do not use "if" statements whose conditionals are always true or always false.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+ <![CDATA[
+//IfStatement[BooleanLiteral[1]]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    public void close() {
+        if (true) {        // fixed conditional, not recommended
+            // ...
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnnecessaryBooleanAssertion"
+          language="java"
+          since="3.0"
+          message="assertTrue(true) or similar statements are unnecessary"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#unnecessarybooleanassertion">
+        <description>
+A JUnit test assertion with a boolean literal is unnecessary since it always will evaluate to the same thing.
+Consider using flow control (in case of `assertTrue(false)` or similar) or simply removing
+statements like `assertTrue(true)` and `assertFalse(false)`. If you just want a test to halt after finding
+an error, use the `fail()` method and provide an indication message of why it did.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassDeclaration
+    [pmd-java:typeIs('junit.framework.TestCase')
+     or .//Annotation[pmd-java:typeIs('org.junit.Test')
+                   or pmd-java:typeIs('org.junit.jupiter.api.Test')
+                   or pmd-java:typeIs('org.junit.jupiter.api.RepeatedTest')
+                   or pmd-java:typeIs('org.junit.jupiter.api.TestFactory')
+                   or pmd-java:typeIs('org.junit.jupiter.api.TestTemplate')
+                   or pmd-java:typeIs('org.junit.jupiter.params.ParameterizedTest')
+     ]
+    ]
+    //MethodCall[@MethodName = ('assertTrue', 'assertFalse')]
+        [ArgumentList
+            [
+                BooleanLiteral or
+                UnaryExpression[@Operator = '!'][BooleanLiteral]
+            ]
+        ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class SimpleTest extends TestCase {
+    public void testX() {
+        assertTrue(true);            // serves no real purpose - remove it
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnnecessaryCaseChange"
+          language="java"
+          since="3.3"
+          message="Using equalsIgnoreCase() is cleaner than using toUpperCase/toLowerCase().equals()."
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.UnnecessaryCaseChangeRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#unnecessarycasechange">
+        <description>
+Using equalsIgnoreCase() is faster than using toUpperCase/toLowerCase().equals()
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+boolean answer1 = buz.toUpperCase().equals("BAZ");              // should be buz.equalsIgnoreCase("BAZ")
+
+boolean answer2 = buz.toUpperCase().equalsIgnoreCase("BAZ");    // another unnecessary toUpperCase()
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnnecessaryConversionTemporary"
+          language="java"
+          since="0.1"
+          message="Avoid unnecessary temporaries when converting primitives to Strings"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#unnecessaryconversiontemporary">
+        <description>
+Avoid the use temporary objects when converting primitives to Strings. Use the static conversion methods
+on the wrapper classes instead.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall[@MethodName = 'toString']
+    [ConstructorCall[position() = 1]
+        [
+            pmd-java:typeIs('java.lang.Integer')
+         or pmd-java:typeIs('java.lang.Long')
+         or pmd-java:typeIs('java.lang.Float')
+         or pmd-java:typeIs('java.lang.Byte')
+         or pmd-java:typeIs('java.lang.Double')
+         or pmd-java:typeIs('java.lang.Short')
+        ]
+    ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public String convert(int x) {
+    String foo = new Integer(x).toString(); // this wastes an object
+
+    return Integer.toString(x);             // preferred approach
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnusedNullCheckInEquals"
+          language="java"
+          since="3.5"
+          message="Invoke equals() on the object you''ve already ensured is not null"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#unusednullcheckinequals">
+        <description>
+After checking an object reference for null, you should invoke equals() on that object rather than passing
+it to another object's equals() method.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//InfixExpression[@Operator = '&&']
+  /MethodCall[pmd-java:matchesSig("java.lang.Object#equals(java.lang.Object)")]
+             [not(StringLiteral)]
+             [not(VariableAccess[@CompileTimeConstant = true()])]
+             [ArgumentList/VariableAccess/@Name = ..//InfixExpression[@Operator = '!='][NullLiteral]/VariableAccess/@Name]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Test {
+
+    public String method1() { return "ok";}
+    public String method2() { return null;}
+
+    public void method(String a) {
+        String b;
+        // I don't know it method1() can be "null"
+        // but I know "a" is not null..
+        // I'd better write a.equals(method1())
+
+        if (a!=null && method1().equals(a)) { // will trigger the rule
+            //whatever
+        }
+
+        if (method1().equals(a) && a != null) { // won't trigger the rule
+            //whatever
+        }
+
+        if (a!=null && method1().equals(b)) { // won't trigger the rule
+            //whatever
+        }
+
+        if (a!=null && "LITERAL".equals(a)) { // won't trigger the rule
+            //whatever
+        }
+
+        if (a!=null && !a.equals("go")) { // won't trigger the rule
+            a=method2();
+            if (method1().equals(a)) {
+                //whatever
+            }
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseCorrectExceptionLogging"
+          language="java"
+          since="3.2"
+          message="Use the correct logging statement for logging exceptions"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#usecorrectexceptionlogging">
+        <description>
+To make sure the full stacktrace is printed out, use the logging statement with two arguments: a String and a Throwable.
+
+This rule only applies to [Apache Commons Logging](https://commons.apache.org/proper/commons-logging/).
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//CatchClause/Block//MethodCall
+    [pmd-java:matchesSig('org.apache.commons.logging.Log#_(java.lang.Object)')]
+    [ArgumentList[not(MethodCall)]//VariableAccess/@Name = ancestor::CatchClause/CatchParameter/@Name]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Main {
+    private static final Log _LOG = LogFactory.getLog( Main.class );
+    void bar() {
+        try {
+        } catch( Exception e ) {
+            _LOG.error( e ); //Wrong!
+        } catch( OtherException oe ) {
+            _LOG.error( oe.getMessage(), oe ); //Correct
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseEqualsToCompareStrings"
+          language="java"
+          since="4.1"
+          message="Use equals() to compare strings instead of ''=='' or ''!=''"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#useequalstocomparestrings">
+        <description>
+Using '==' or '!=' to compare strings is only reliable if the interned string (`String#intern()`)
+is used on both sides.
+
+Use the `equals()` method instead.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//InfixExpression[@Operator = ('==', '!=')]
+                 [count(*[pmd-java:typeIsExactly('java.lang.String')]) = 2]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public boolean test(String s) {
+    if (s == "one") return true;        // unreliable
+    if ("two".equals(s)) return true;   // better
+    return false;
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UselessOperationOnImmutable"
+          language="java"
+          since="3.5"
+          message="An operation on an Immutable object (String, BigDecimal or BigInteger) won't change the object itself"
+          class="net.sourceforge.pmd.lang.java.rule.errorprone.UselessOperationOnImmutableRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#uselessoperationonimmutable">
+        <description>
+An operation on an Immutable object (String, BigDecimal or BigInteger) won't change the object itself
+since the result of the operation is a new object. Therefore, ignoring the operation result is an error.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+import java.math.*;
+
+class Test {
+    void method1() {
+        BigDecimal bd=new BigDecimal(10);
+        bd.add(new BigDecimal(5));      // this will trigger the rule
+    }
+    void method2() {
+        BigDecimal bd=new BigDecimal(10);
+        bd = bd.add(new BigDecimal(5)); // this won't trigger the rule
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseLocaleWithCaseConversions"
+          language="java"
+          since="2.0"
+          message="When doing a String.toLowerCase()/toUpperCase() call, use a Locale"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#uselocalewithcaseconversions">
+        <description>
+When doing `String::toLowerCase()/toUpperCase()` conversions, use an explicit locale argument to specify the case
+transformation rules.
+
+Using `String::toLowerCase()` without arguments implicitly uses `Locale::getDefault()`.
+The problem is that the default locale depends on the current JVM setup (and usually on the system in which
+it is running). Using the system default may be exactly what you want (e.g. if you are manipulating strings
+you got through standard input), but it may as well not be the case (e.g. if you are getting the string over
+the network or a file, and the encoding is well-defined and independent of the environment). In the latter case,
+using the default locale makes the case transformation brittle, as it may yield unexpected results on a machine
+whose locale has other case translation rules. For example, in Turkish, the uppercase form of `i` is `İ` (U+0130,
+not ASCII) and not `I` (U+0049) as in English.
+
+The rule is intended to *force* developers to think about locales when dealing with strings. By taking a
+conscious decision about the choice of locale at the time of writing, you reduce the risk of surprising
+behaviour down the line, and communicate your intent to future readers.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall[pmd-java:matchesSig("java.lang.String#toLowerCase()") or pmd-java:matchesSig("java.lang.String#toUpperCase()")]
+            [not(MethodCall[@MethodName = "toHexString"])]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+// violation - implicitly system-dependent conversion
+if (x.toLowerCase().equals("list")) {}
+
+// The above will not match "LIST" on a system with a Turkish locale.
+// It could be replaced with
+if (x.toLowerCase(Locale.US).equals("list")) { }
+// or simply
+if (x.equalsIgnoreCase("list")) { }
+
+// ok - system independent conversion
+String z = a.toLowerCase(Locale.ROOT);
+
+// ok - explicit system-dependent conversion
+String z2 = a.toLowerCase(Locale.getDefault());
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseProperClassLoader"
+          language="java"
+          since="3.7"
+          message="In J2EE, getClassLoader() might not work as expected.  Use Thread.currentThread().getContextClassLoader() instead."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_errorprone.html#useproperclassloader">
+        <description>
+In J2EE, the getClassLoader() method might not work as expected. Use
+Thread.currentThread().getContextClassLoader() instead.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>//MethodCall[pmd-java:matchesSig("java.lang.Class#getClassLoader()")]</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    ClassLoader cl = Bar.class.getClassLoader();
+}
+]]>
+        </example>
+    </rule>
+
+</ruleset>
diff --git a/pmd/resources/category/java/multithreading.xml b/pmd/resources/category/java/multithreading.xml
new file mode 100644
index 000000000..605829ce6
--- /dev/null
+++ b/pmd/resources/category/java/multithreading.xml
@@ -0,0 +1,459 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<ruleset name="Multithreading"
+    xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+    <description>
+Rules that flag issues when dealing with multiple threads of execution.
+    </description>
+
+    <rule name="AvoidSynchronizedAtMethodLevel"
+          language="java"
+          since="3.0"
+          message="Use block level locking rather than method level synchronization"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidsynchronizedatmethodlevel">
+        <description>
+Method-level synchronization will pin virtual threads and can cause performance problems. Additionally, it can cause
+problems when new code is added to the method.  Block-level ReentrantLock helps to ensure that only the code that
+needs mutual exclusion will be locked.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>//MethodDeclaration[pmd-java:modifiers() = "synchronized"]</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Foo {
+    // Try to avoid this:
+    synchronized void foo() {
+        // code, that doesn't need synchronization
+        // ...
+        // code, that requires synchronization
+        if (!sharedData.has("bar")) {
+            sharedData.add("bar");
+        }
+        // more code, that doesn't need synchronization
+        // ...
+    }
+    // Prefer this:
+    Lock instanceLock = new ReentrantLock();
+
+    void bar() {
+        // code, that doesn't need synchronization
+        // ...
+        try {
+            instanceLock.lock();  // or instanceLock.tryLock(long time, TimeUnit unit)
+            if (!sharedData.has("bar")) {
+                sharedData.add("bar");
+            }
+        } finally {
+            instanceLock.unlock();
+        }
+        // more code, that doesn't need synchronization
+        // ...
+    }
+
+    // Try to avoid this for static methods:
+    static synchronized void fooStatic() {
+    }
+
+    // Prefer this:
+    private static Lock CLASS_LOCK = new ReentrantLock();
+
+    static void barStatic() {
+        // code, that doesn't need synchronization
+        // ...
+        try {
+            CLS_LOCK.lock();
+            // code, that requires synchronization
+        } finally {
+            CLS_LOCK.unlock();
+        }
+        // more code, that doesn't need synchronization
+        // ...
+    }
+}
+]]>
+        </example>
+    </rule>
+
+  <rule name="AvoidSynchronizedStatement"
+        language="java"
+        since="7.5.0"
+        message="Use ReentrantLock rather than synchronization"
+        class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+        externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidsynchronizedstatement">
+    <description>
+      Synchronization will pin virtual threads and can cause performance problems.
+    </description>
+    <priority>3</priority>
+    <properties>
+      <property name="xpath">
+        <value>//SynchronizedStatement</value>
+      </property>
+    </properties>
+    <example>
+      <![CDATA[
+public class Foo {
+    // Try to avoid this:
+    void foo() {
+        // code that doesn't need mutual exclusion
+        synchronized(this) {
+            // code that requires mutual exclusion
+        }
+        // more code that doesn't need mutual exclusion
+    }
+    // Prefer this:
+    Lock instanceLock = new ReentrantLock();
+
+    void foo() {
+        // code that doesn't need mutual exclusion
+        try {
+            instanceLock.lock();  // or instanceLock.tryLock(long time, TimeUnit unit)
+            // code that requires mutual exclusion
+        } finally {
+            instanceLock.unlock();
+        }
+        // more code that doesn't need mutual exclusion
+    }
+}
+]]>
+    </example>
+  </rule>
+
+    <rule name="AvoidThreadGroup"
+          language="java"
+          since="3.6"
+          message="Avoid using java.lang.ThreadGroup; it is not thread safe"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidthreadgroup">
+        <description>
+Avoid using java.lang.ThreadGroup; although it is intended to be used in a threaded environment
+it contains methods that are not thread-safe.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+  //ConstructorCall/ClassType[pmd-java:typeIs('java.lang.ThreadGroup')]
+| //MethodCall[@MethodName = 'getThreadGroup']
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Bar {
+    void buz() {
+        ThreadGroup tg = new ThreadGroup("My threadgroup");
+        tg = new ThreadGroup(tg, "my thread group");
+        tg = Thread.currentThread().getThreadGroup();
+        tg = System.getSecurityManager().getThreadGroup();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidUsingVolatile"
+          language="java"
+          since="4.1"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="Use of modifier volatile is not recommended."
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#avoidusingvolatile">
+        <description>
+Use of the keyword 'volatile' is generally used to fine tune a Java application, and therefore, requires
+a good expertise of the Java Memory Model. Moreover, its range of action is somewhat misknown. Therefore,
+the volatile keyword should not be used for maintenance purpose and portability.
+        </description>
+        <priority>2</priority>
+        <properties>
+            <property name="xpath">
+                <value>//FieldDeclaration[pmd-java:modifiers() = "volatile"]</value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class ThrDeux {
+  private volatile String var1; // not suggested
+  private          String var2; // preferred
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="DoNotUseThreads"
+          language="java"
+          since="4.1"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="To be compliant to J2EE, a webapp should not use any thread."
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#donotusethreads">
+        <description>
+The J2EE specification explicitly forbids the use of threads. Threads are resources, that should be managed and monitored by the J2EE server.
+If the application creates threads on its own or uses own custom thread pools, then these threads are not managed, which could lead to resource exhaustion.
+Also, EJBs might be moved between machines in a cluster and only managed resources can be moved along.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ClassType
+[pmd-java:typeIs('java.lang.Thread') or pmd-java:typeIs('java.util.concurrent.ExecutorService')]
+(: allow Thread.currentThread().getContextClassLoader() :)
+[not(parent::TypeExpression[parent::MethodCall[pmd-java:matchesSig('_#currentThread()')
+                                               and parent::MethodCall[pmd-java:matchesSig('_#getContextClassLoader()')]
+                                              ]
+                           ]
+)]
+(: exclude duplicated types on the same line :)
+ [not((parent::FieldDeclaration|parent::LocalVariableDeclaration)/VariableDeclarator/*[2][pmd-java:typeIs('java.lang.Thread') or pmd-java:typeIs('java.util.concurrent.ExecutorService')])
+ or
+  @BeginLine != (parent::FieldDeclaration|parent::LocalVariableDeclaration)/VariableDeclarator/ConstructorCall/ClassType/@BeginLine]
+|
+//MethodCall[*[1][not(pmd-java:nodeIs('MethodCall'))][pmd-java:nodeIs('Expression') and (pmd-java:typeIs('java.util.concurrent.Executors')
+   or pmd-java:typeIs('java.util.concurrent.ExecutorService'))]]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+// This is not allowed
+public class UsingThread extends Thread {
+
+}
+
+// Neither this,
+public class UsingExecutorService {
+
+    public void methodX() {
+        ExecutorService executorService = Executors.newFixedThreadPool(5);
+    }
+}
+
+// Nor this,
+public class Example implements ExecutorService {
+
+}
+
+// Nor this,
+public class Example extends AbstractExecutorService {
+
+}
+
+// Nor this
+public class UsingExecutors {
+
+    public void methodX() {
+        Executors.newSingleThreadExecutor().submit(() -> System.out.println("Hello!"));
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="DontCallThreadRun"
+          language="java"
+          since="4.3"
+          message="Don't call Thread.run() explicitly, use Thread.start()"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#dontcallthreadrun">
+        <description>
+Explicitly calling Thread.run() method will execute in the caller's thread of control.  Instead, call Thread.start() for the intended behavior.
+        </description>
+        <priority>4</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall[ pmd-java:matchesSig("java.lang.Thread#run()") ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+Thread t = new Thread();
+t.run();            // use t.start() instead
+new Thread().run(); // same violation
+]]>
+        </example>
+    </rule>
+
+    <rule name="DoubleCheckedLocking"
+          language="java"
+          since="1.04"
+          message="Double checked locking is not thread safe in Java."
+          class="net.sourceforge.pmd.lang.java.rule.multithreading.DoubleCheckedLockingRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#doublecheckedlocking">
+        <description>
+Partially created objects can be returned by the Double Checked Locking pattern when used in Java.
+An optimizing JRE may assign a reference to the baz variable before it calls the constructor of the object the
+reference points to.
+
+Note: With Java 5, you can make Double checked locking work, if you declare the variable to be `volatile`.
+
+For more details refer to: &lt;http://www.javaworld.com/javaworld/jw-02-2001/jw-0209-double.html>
+or &lt;http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html>
+        </description>
+        <priority>1</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    /*volatile */ Object baz = null; // fix for Java5 and later: volatile
+    Object bar() {
+        if (baz == null) { // baz may be non-null yet not fully created
+            synchronized(this) {
+                if (baz == null) {
+                    baz = new Object();
+                }
+              }
+        }
+        return baz;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="NonThreadSafeSingleton"
+          language="java"
+          since="3.4"
+          message="Singleton is not thread safe"
+          class="net.sourceforge.pmd.lang.java.rule.multithreading.NonThreadSafeSingletonRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#nonthreadsafesingleton">
+        <description>
+Non-thread safe singletons can result in bad state changes. Eliminate
+static singletons if possible by instantiating the object directly. Static
+singletons are usually not needed as only a single instance exists anyway.
+Other possible fixes are to synchronize the entire method or to use an
+[initialize-on-demand holder class](https://en.wikipedia.org/wiki/Initialization-on-demand_holder_idiom).
+
+Refrain from using the double-checked locking pattern. The Java Memory Model doesn't
+guarantee it to work unless the variable is declared as `volatile`, adding an uneeded
+performance penalty. [Reference](http://www.cs.umd.edu/~pugh/java/memoryModel/DoubleCheckedLocking.html)
+
+See Effective Java, item 48.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+private static Foo foo = null;
+
+//multiple simultaneous callers may see partially initialized objects
+public static Foo getFoo() {
+    if (foo==null) {
+        foo = new Foo();
+    }
+    return foo;
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UnsynchronizedStaticFormatter"
+          language="java"
+          since="6.11.0"
+          message="Static Formatter objects should be accessed in a synchronized manner"
+          class="net.sourceforge.pmd.lang.java.rule.multithreading.UnsynchronizedStaticFormatterRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#unsynchronizedstaticformatter">
+        <description>
+Instances of `java.text.Format` are generally not synchronized.
+Sun recommends using separate format instances for each thread.
+If multiple threads must access a static formatter, the formatter must be
+synchronized on block level.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    private static final SimpleDateFormat sdf = new SimpleDateFormat();
+    void bar() {
+        sdf.format(); // poor, no thread-safety
+    }
+    void foo() {
+        synchronized (sdf) { // preferred
+            sdf.format();
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseConcurrentHashMap"
+          language="java"
+          minimumLanguageVersion="1.5"
+          since="4.2.6"
+          message="If you run in Java5 or newer and have concurrent access, you should use the ConcurrentHashMap implementation"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#useconcurrenthashmap">
+        <description>
+Since Java5 brought a new implementation of the Map designed for multi-threaded access, you can
+perform efficient map reads without blocking other threads.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//VariableDeclarator[VariableId[pmd-java:typeIsExactly('java.util.Map')] and *[2][self::ConstructorCall and not(pmd-java:typeIs('java.util.concurrent.ConcurrentHashMap'))]]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class ConcurrentApp {
+  public void getMyInstance() {
+    Map map1 = new HashMap();           // fine for single-threaded access
+    Map map2 = new ConcurrentHashMap(); // preferred for use with multiple threads
+
+    // the following case will be ignored by this rule
+    Map map3 = someModule.methodThatReturnMap(); // might be OK, if the returned map is already thread-safe
+  }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseNotifyAllInsteadOfNotify"
+          language="java"
+          since="3.0"
+          message="Call Thread.notifyAll() rather than Thread.notify()"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_multithreading.html#usenotifyallinsteadofnotify">
+        <description>
+Thread.notify() awakens a thread monitoring the object. If more than one thread is monitoring, then only
+one is chosen.  The thread chosen is arbitrary; thus its usually safer to call notifyAll() instead.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall[@MethodName="notify" and ArgumentList[count(*) = 0]]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+  void bar() {
+    x.notify();
+    // If many threads are monitoring x, only one (and you won't know which) will be notified.
+    // use instead:
+    x.notifyAll();
+  }
+]]>
+        </example>
+    </rule>
+
+</ruleset>
diff --git a/pmd/resources/category/java/performance.xml b/pmd/resources/category/java/performance.xml
new file mode 100644
index 000000000..376b53649
--- /dev/null
+++ b/pmd/resources/category/java/performance.xml
@@ -0,0 +1,925 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<ruleset name="Performance"
+    xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+    <description>
+Rules that flag suboptimal code.
+    </description>
+
+    <rule name="AddEmptyString"
+          language="java"
+          since="4.0"
+          message="Do not add empty strings"
+          class="net.sourceforge.pmd.lang.java.rule.performance.AddEmptyStringRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#addemptystring">
+        <description>
+The conversion of literals to strings by concatenating them with empty strings is inefficient.
+It is much better to use one of the type-specific `toString()` methods instead or `String.valueOf()`.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+String s = "" + 123;                // inefficient
+String t = Integer.toString(456);   // preferred approach
+]]>
+        </example>
+    </rule>
+
+    <rule name="AppendCharacterWithChar"
+          language="java"
+          since="3.5"
+          message="Avoid appending characters as strings in StringBuffer.append."
+          class="net.sourceforge.pmd.lang.java.rule.performance.AppendCharacterWithCharRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#appendcharacterwithchar">
+        <description>
+Avoid concatenating characters as strings in StringBuffer/StringBuilder.append methods.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+StringBuffer sb = new StringBuffer();
+sb.append("a");     // avoid this
+
+StringBuffer sb = new StringBuffer();
+sb.append('a');     // use this instead
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidArrayLoops"
+          language="java"
+          since="3.5"
+          message="Arrays.copyOf or System.arraycopy are more efficient"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#avoidarrayloops">
+        <description>
+Instead of manually copying data between two arrays, use the more efficient `Arrays.copyOf`
+or `System.arraycopy` method instead.
+
+To copy only part of the array, use `Arrays.copyOfRange` or `System.arraycopy`.
+
+If you want to copy/move elements inside the _same_ array (e.g. shift the elements), use `System.arraycopy`.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//(ForStatement[ForUpdate//(UnaryExpression[@Operator=('++','--')] | AssignmentExpression[@Operator = ('+=', '-=')][NumericLiteral[@Image = '1']])]
+ | WhileStatement | DoStatement)
+    [not(.//ContinueStatement)]
+    [not(.//BreakStatement)]
+    [not(.//ThrowStatement)]
+    [not(.//ReturnStatement)]
+    [count(Block//AssignmentExpression[@Operator='=']
+                                      (: no nested arrays or method calls as array index :)
+                                      [count(ArrayAccess[not(.//ArrayAccess)]
+                                                        [not(.//MethodCall)])=2]
+                                      (: array access indexes must be same (excluding constants) :)
+                                      [deep-equal(
+                                        sort(distinct-values(ArrayAccess[1]/(VariableAccess[2]|InfixExpression//VariableAccess)
+                                            (: don't consider array length accesses :)
+                                            [not(parent::FieldAccess[@Name='length'])]
+                                            [
+                                               (: exclude referenced constants :)
+                                               not(@Name = (ancestor::MethodDeclaration|//FieldDeclaration)//VariableDeclarator[NumericLiteral][not(../../../parent::ForInit)]/VariableId/@Name)
+                                               or
+                                               (: include loop variable :)
+                                               @Name = ancestor::ForStatement/ForInit/LocalVariableDeclaration/VariableDeclarator/VariableId/@Name
+                                            ]
+                                            /@Name)),
+                                        sort(distinct-values(ArrayAccess[2]/(VariableAccess[2]|InfixExpression//VariableAccess)
+                                            (: don't consider array length accesses :)
+                                            [not(parent::FieldAccess[@Name='length'])]
+                                            [
+                                               (: exclude referenced constants :)
+                                               not(@Name = (ancestor::MethodDeclaration|//FieldDeclaration)//VariableDeclarator[NumericLiteral][not(../../../parent::ForInit)]/VariableId/@Name)
+                                               or
+                                               (: include loop variable :)
+                                               @Name = ancestor::ForStatement/ForInit/LocalVariableDeclaration/VariableDeclarator/VariableId/@Name
+                                            ]
+                                            /@Name))
+                                      )]
+     )=1]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+class Scratch {
+    void copy_a_to_b() {
+        int[] a = new int[10];
+        int[] b = new int[10];
+        for (int i = 0; i < a.length; i++) {
+            b[i] = a[i];
+        }
+        // equivalent
+        b = Arrays.copyOf(a, a.length);
+        // equivalent
+        System.arraycopy(a, 0, b, 0, a.length);
+
+        int[] c = new int[10];
+        // this will not trigger the rule
+        for (int i = 0; i < c.length; i++) {
+            b[i] = a[c[i]];
+        }
+    }
+}
+]]>
+        </example>
+        <example>
+<![CDATA[
+class Scratch {
+    void shift_left(int[] a) {
+        for (int i = 0; i < a.length - 1; i++) {
+            a[i] = a[i + 1];
+        }
+        // equivalent
+        System.arraycopy(a, 1, a, 0, a.length - 1);
+    }
+    void shift_right(int[] a) {
+        for (int i = a.length - 1; i > 0; i--) {
+            a[i] = a[i - 1];
+        }
+        // equivalent
+        System.arraycopy(a, 0, a, 1, a.length - 1);
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidCalendarDateCreation"
+          since="6.25.0"
+          language="java"
+          message="A Calendar is used to get the current time, this is expensive."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          typeResolution="true"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#avoidcalendardatecreation">
+        <description>
+Problem: `java.util.Calendar` is a heavyweight object and expensive to create. It should only be used, if
+calendar calculations are needed.
+
+Solution: Use `new Date()`, Java 8+ `java.time.LocalDateTime.now()` or `ZonedDateTime.now()`.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value><![CDATA[
+//MethodCall[pmd-java:matchesSig("java.util.Calendar#getTime()") or pmd-java:matchesSig("java.util.Calendar#getTimeInMillis()")]
+  [*[1][local-name() = ('MethodCall', 'ConstructorCall')]
+                               [pmd-java:matchesSig("java.util.Calendar#getInstance()")
+                             or pmd-java:matchesSig("java.util.GregorianCalendar#getInstance()")
+                             or pmd-java:matchesSig("java.util.GregorianCalendar#new()")]
+  ]
+|
+//MethodCall[pmd-java:matchesSig("java.util.Calendar#getTime()") or pmd-java:matchesSig("java.util.Calendar#getTimeInMillis()")]
+   [*[1][local-name() = 'VariableAccess']]
+  (: ignore if .set* or .add or .clear or .roll is called on the variable :)
+  [not(VariableAccess/@Name = ancestor::Block//MethodCall[starts-with(@MethodName, "set") or @MethodName = ("add", "clear", "roll")]/VariableAccess/@Name)]
+  (: variable must be initialized with getInstance :)
+  [VariableAccess/@Name = ancestor::Block//LocalVariableDeclaration/VariableDeclarator[
+     (MethodCall | ConstructorCall)
+      [pmd-java:matchesSig("java.util.Calendar#getInstance()")
+       or pmd-java:matchesSig("java.util.GregorianCalendar#getInstance()")
+       or pmd-java:matchesSig("java.util.GregorianCalendar#new()")]
+  ]/VariableId/@Name]
+|
+//ConstructorCall[pmd-java:typeIs("org.joda.time.DateTime") or pmd-java:typeIs("org.joda.time.LocalDateTime")]
+  [ArgumentList[(MethodCall | ConstructorCall)
+       [pmd-java:matchesSig("java.util.Calendar#getInstance()")
+     or pmd-java:matchesSig("java.util.GregorianCalendar#getInstance()")
+     or pmd-java:matchesSig("java.util.GregorianCalendar#new()")]]
+  ]
+
+                ]]></value>
+            </property>
+        </properties>
+        <example>
+            <![CDATA[
+import java.time.LocalDateTime;
+import java.util.Calendar;
+import java.util.Date;
+
+public class DateStuff {
+    private Date bad1() {
+        return Calendar.getInstance().getTime(); // now
+    }
+    private Date good1a() {
+        return new Date(); // now
+    }
+    private LocalDateTime good1b() {
+        return LocalDateTime.now();
+    }
+    private long bad2() {
+        return Calendar.getInstance().getTimeInMillis();
+    }
+    private long good2() {
+        return System.currentTimeMillis();
+    }
+}
+            ]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidFileStream"
+          since="6.0.0"
+          message="Avoid instantiating FileInputStream, FileOutputStream, FileReader, or FileWriter"
+          language="java"
+          minimumLanguageVersion="1.7"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#avoidfilestream">
+        <description>
+The FileInputStream and FileOutputStream classes contains a finalizer method which will cause garbage
+collection pauses.
+See [JDK-8080225](https://bugs.openjdk.org/browse/JDK-8080225) for details.
+
+The FileReader and FileWriter constructors instantiate FileInputStream and FileOutputStream,
+again causing garbage collection issues while finalizer methods are called.
+
+* Use `Files.newInputStream(Paths.get(fileName))` instead of `new FileInputStream(fileName)`.
+* Use `Files.newOutputStream(Paths.get(fileName))` instead of `new FileOutputStream(fileName)`.
+* Use `Files.newBufferedReader(Paths.get(fileName))` instead of `new FileReader(fileName)`.
+* Use `Files.newBufferedWriter(Paths.get(fileName))` instead of `new FileWriter(fileName)`.
+
+Please note, that the `java.nio` API does not throw a `FileNotFoundException` anymore, instead
+it throws a `NoSuchFileException`. If your code dealt explicitly with a `FileNotFoundException`,
+then this needs to be adjusted. Both exceptions are subclasses of `IOException`, so catching
+that one covers both.
+        </description>
+        <priority>1</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ConstructorCall/ClassType[
+       pmd-java:typeIs('java.io.FileInputStream')
+    or pmd-java:typeIs('java.io.FileOutputStream')
+    or pmd-java:typeIs('java.io.FileReader')
+    or pmd-java:typeIs('java.io.FileWriter')
+  ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+    // these instantiations cause garbage collection pauses, even if properly closed
+
+    FileInputStream fis = new FileInputStream(fileName);
+    FileOutputStream fos = new FileOutputStream(fileName);
+    FileReader fr = new FileReader(fileName);
+    FileWriter fw = new FileWriter(fileName);
+
+    // the following instantiations help prevent Garbage Collection pauses, no finalization
+
+    try(InputStream is = Files.newInputStream(Paths.get(fileName))) {
+    }
+    try(OutputStream os = Files.newOutputStream(Paths.get(fileName))) {
+    }
+    try(BufferedReader br = Files.newBufferedReader(Paths.get(fileName), StandardCharsets.UTF_8)) {
+    }
+    try(BufferedWriter wr = Files.newBufferedWriter(Paths.get(fileName), StandardCharsets.UTF_8)) {
+    }
+]]>
+        </example>
+    </rule>
+
+    <rule name="AvoidInstantiatingObjectsInLoops"
+          language="java"
+          since="2.2"
+          message="Avoid instantiating new objects inside loops"
+          class="net.sourceforge.pmd.lang.java.rule.performance.AvoidInstantiatingObjectsInLoopsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#avoidinstantiatingobjectsinloops">
+        <description>
+New objects created within loops should be checked to see if they can created outside them and reused.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Something {
+    public static void main( String as[] ) {
+        for (int i = 0; i < 10; i++) {
+            Foo f = new Foo(); // Avoid this whenever you can it's really expensive
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="BigIntegerInstantiation"
+          language="java"
+          since="3.9"
+          message="Don''t create instances of already existing BigInteger and BigDecimal (ZERO, ONE, TEN)"
+          class="net.sourceforge.pmd.lang.java.rule.performance.BigIntegerInstantiationRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#bigintegerinstantiation">
+        <description>
+Don't create instances of already existing BigInteger (`BigInteger.ZERO`, `BigInteger.ONE`),
+for Java 1.5 onwards, BigInteger.TEN and BigDecimal (`BigDecimal.ZERO`, `BigDecimal.ONE`, `BigDecimal.TEN`) and
+for Java 9 onwards `BigInteger.TWO`.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+BigInteger bi1 = new BigInteger("1");    // reference BigInteger.ONE instead
+BigInteger bi2 = new BigInteger("0");    // reference BigInteger.ZERO instead
+BigInteger bi3;
+bi3 = new BigInteger("0");               // reference BigInteger.ZERO instead
+
+BigDecimal bd1 = new BigDecimal(0);      // reference BigDecimal.ZERO instead
+BigDecimal bd2 = new BigDecimal("0.") ;  // reference BigDecimal.ZERO instead
+BigDecimal bd3 = new BigDecimal(10);     // reference BigDecimal.TEN instead
+]]>
+        </example>
+    </rule>
+
+    <rule name="ConsecutiveAppendsShouldReuse"
+          language="java"
+          since="5.1"
+          message="StringBuffer (or StringBuilder).append is called consecutively without reusing the target variable."
+          class="net.sourceforge.pmd.lang.java.rule.performance.ConsecutiveAppendsShouldReuseRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#consecutiveappendsshouldreuse">
+        <description>
+Consecutive calls to StringBuffer/StringBuilder .append should be chained, reusing the target object. This can improve the performance
+by producing a smaller bytecode, reducing overhead and improving inlining. A complete analysis can be found [here](https://github.com/pmd/pmd/issues/202#issuecomment-274349067)
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+String foo = " ";
+
+StringBuffer buf = new StringBuffer();
+buf.append("Hello"); // poor
+buf.append(foo);
+buf.append("World");
+
+StringBuffer buf = new StringBuffer();
+buf.append("Hello").append(foo).append("World"); // good
+]]>
+        </example>
+    </rule>
+
+    <rule name="ConsecutiveLiteralAppends"
+          language="java"
+          since="3.5"
+          message="StringBuffer (or StringBuilder).append is called {0} consecutive times with literals. Use a single append with a single combined String."
+          class="net.sourceforge.pmd.lang.java.rule.performance.ConsecutiveLiteralAppendsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#consecutiveliteralappends">
+        <description>
+Consecutively calling StringBuffer/StringBuilder.append(...) with literals should be avoided.
+Since the literals are constants, they can already be combined into a single String literal and this String
+can be appended in a single method call.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+StringBuilder buf = new StringBuilder();
+buf.append("Hello").append(" ").append("World");    // poor
+buf.append("Hello World");                          // good
+
+buf.append('h').append('e').append('l').append('l').append('o'); // poor
+buf.append("hello");                                             // good
+
+buf.append(1).append('m');  // poor
+buf.append("1m");           // good
+]]>
+        </example>
+    </rule>
+
+    <rule name="InefficientEmptyStringCheck"
+          language="java"
+          since="3.6"
+	        message="String.trim().length() == 0 / String.trim().isEmpty() is an inefficient way to validate a blank String."
+          class="net.sourceforge.pmd.lang.java.rule.performance.InefficientEmptyStringCheckRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#inefficientemptystringcheck">
+        <description>
+<![CDATA[
+String.trim().length() == 0 (or String.trim().isEmpty() for the same reason) is an inefficient
+way to check if a String is really blank, as it creates a new String object just to check its size.
+Consider creating a static function that loops through a string, checking Character.isWhitespace()
+on each character and returning false if a non-whitespace character is found. A Smarter code to
+check for an empty string would be:
+
+```java
+private boolean checkTrimEmpty(String str) {
+    for(int i = 0; i < str.length(); i++) {
+        if(!Character.isWhitespace(str.charAt(i))) {
+            return false;
+        }
+    }
+    return true;
+}
+```
+
+You can refer to Apache's StringUtils#isBlank (in commons-lang),
+Spring's StringUtils#hasText (in the Spring framework) or Google's
+CharMatcher#whitespace (in Guava) for existing implementations (some might
+include the check for != null).
+]]>
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public void bar(String string) {
+    if (string != null && string.trim().length() > 0) {
+        doSomething();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="InefficientStringBuffering"
+          language="java"
+          since="3.4"
+          message="Avoid concatenating nonliterals in a StringBuffer/StringBuilder constructor or append()."
+          class="net.sourceforge.pmd.lang.java.rule.performance.InefficientStringBufferingRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#inefficientstringbuffering">
+        <description>
+Avoid concatenating non-literals in a StringBuffer constructor or append() since intermediate buffers will
+need to be be created and destroyed by the JVM.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+// Avoid this, two buffers are actually being created here
+StringBuffer sb = new StringBuffer("tmp = "+System.getProperty("java.io.tmpdir"));
+
+// do this instead
+StringBuffer sb = new StringBuffer("tmp = ");
+sb.append(System.getProperty("java.io.tmpdir"));
+]]>
+        </example>
+    </rule>
+
+    <rule name="InsufficientStringBufferDeclaration"
+          language="java"
+          since="3.6"
+          message="{0} has been initialized with size {1}, but has at least {2} characters appended."
+          class="net.sourceforge.pmd.lang.java.rule.performance.InsufficientStringBufferDeclarationRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#insufficientstringbufferdeclaration">
+        <description>
+Failing to pre-size a StringBuffer or StringBuilder properly could cause it to re-size many times
+during runtime. This rule attempts to determine the total number the characters that are actually
+passed into StringBuffer.append(), but represents a best guess "worst case" scenario. An empty
+StringBuffer/StringBuilder constructor initializes the object to 16 characters. This default
+is assumed if the length of the constructor can not be determined.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+StringBuilder bad = new StringBuilder();
+bad.append("This is a long string that will exceed the default 16 characters");
+
+StringBuilder good = new StringBuilder(41);
+good.append("This is a long string, which is pre-sized");
+]]>
+        </example>
+    </rule>
+
+    <rule name="OptimizableToArrayCall"
+          language="java"
+          since="1.8"
+          minimumLanguageVersion="1.6"
+          message="This call to Collection.toArray() may be optimizable"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#optimizabletoarraycall">
+        <description>
+Calls to a collection's `toArray(E[])` method should specify a target array of zero size. This allows the JVM
+to optimize the memory allocation and copying as much as possible.
+
+Previous versions of this rule (pre PMD 6.0.0) suggested the opposite, but current JVM implementations
+perform always better, when they have full control over the target array. And allocation an array via
+reflection is nowadays as fast as the direct allocation.
+
+See also [Arrays of Wisdom of the Ancients](https://shipilev.net/blog/2016/arrays-wisdom-ancients/)
+
+Note: If you don't need an array of the correct type, then the simple `toArray()` method without an array
+is faster, but returns only an array of type `Object[]`.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//MethodCall[pmd-java:matchesSig("java.util.Collection#toArray(_)")]
+    [ArgumentList/ArrayAllocation/ArrayType/ArrayDimensions/ArrayDimExpr[not(NumericLiteral[@Image="0"])]]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+List<Foo> foos = getFoos();
+
+// much better; this one allows the jvm to allocate an array of the correct size and effectively skip
+// the zeroing, since each array element will be overridden anyways
+Foo[] fooArray = foos.toArray(new Foo[0]);
+
+// inefficient, the array needs to be zeroed out by the jvm before it is handed over to the toArray method
+Foo[] fooArray = foos.toArray(new Foo[foos.size()]);
+]]>
+        </example>
+    </rule>
+
+    <rule name="RedundantFieldInitializer"
+          language="java"
+          since="5.0"
+          message="Avoid using redundant field initializer for ''${variableName}''"
+          class="net.sourceforge.pmd.lang.java.rule.performance.RedundantFieldInitializerRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#redundantfieldinitializer">
+        <description>
+Java will initialize fields with known default values so any explicit initialization of those same defaults
+is redundant and results in a larger class file (approximately three additional bytecode instructions per field).
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class C {
+    boolean b   = false;    // examples of redundant initializers
+    byte by     = 0;
+    short s     = 0;
+    char c      = 0;
+    int i       = 0;
+    long l      = 0;
+
+    float f     = .0f;    // all possible float literals
+    doable d    = 0d;     // all possible double literals
+    Object o    = null;
+
+    MyClass mca[] = null;
+    int i1 = 0, ia1[] = null;
+
+    class Nested {
+        boolean b = false;
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="StringInstantiation"
+          language="java"
+          since="1.0"
+          message="Avoid instantiating String objects; this is usually unnecessary."
+          class="net.sourceforge.pmd.lang.java.rule.performance.StringInstantiationRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#stringinstantiation">
+        <description>
+Avoid instantiating String objects; this is usually unnecessary since they are immutable and can be safely shared.
+        </description>
+        <priority>2</priority>
+        <example>
+<![CDATA[
+private String bar = new String("bar"); // just do a String bar = "bar";
+]]>
+        </example>
+    </rule>
+
+    <rule name="StringToString"
+          language="java"
+          since="1.0"
+          message="Avoid calling toString() on String objects; this is unnecessary."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#stringtostring">
+        <description>
+Avoid calling toString() on objects already known to be string instances; this is unnecessary.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    //MethodCall[pmd-java:matchesSig("java.lang.String#toString()")]
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+private String baz() {
+    String bar = "howdy";
+    return bar.toString();
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="TooFewBranchesForASwitchStatement"
+          language="java"
+          since="4.2"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          message="A switch with less than three branches is inefficient, use a 'if statement' instead."
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#toofewbranchesforaswitchstatement">
+        <description>
+Switch statements are intended to be used to support complex branching behaviour. Using a switch for only a few
+cases is ill-advised, since switches are not as easy to understand as if-else statements. In these cases use the
+if-else statement to increase code readability.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="minimumNumberCaseForASwitch" type="Integer" description="Minimum number of branches for a switch" min="1" max="100" value="3"/>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//SwitchStatement[ (count(*) - 1) < $minimumNumberCaseForASwitch ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+// With a minimumNumberCaseForASwitch of 3
+public class Foo {
+    public void bar() {
+        switch (condition) {
+            case ONE:
+                instruction;
+                break;
+            default:
+                break; // not enough for a 'switch' stmt, a simple 'if' stmt would have been more appropriate
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseArrayListInsteadOfVector"
+          language="java"
+          since="3.0"
+          message="Use ArrayList instead of Vector"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#usearraylistinsteadofvector">
+        <description>
+ArrayList is a much better Collection implementation than Vector if thread-safe operation is not required.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ConstructorCall/ClassType[pmd-java:typeIsExactly('java.util.Vector') or pmd-java:typeIsExactly('Vector')]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+import java.util.*;
+public class SimpleTest extends TestCase {
+    public void testX() {
+    Collection c1 = new Vector();
+    Collection c2 = new ArrayList();    // achieves the same with much better performance
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseArraysAsList"
+          language="java"
+          since="3.5"
+          message="Use asList instead of tight loops"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#usearraysaslist">
+        <description>
+<![CDATA[
+The `java.util.Arrays` class has a `asList()` method that should be used when you want to create a new List from
+an array of objects. It is faster than executing a loop to copy all the elements of the array one by one.
+
+Note that the result of `Arrays.asList()` is backed by the specified array,
+changes in the returned list will result in the array to be modified.
+For that reason, it is not possible to add new elements to the returned list of `Arrays.asList()`
+(UnsupportedOperationException).
+You must use `new ArrayList<>(Arrays.asList(...))` if that is inconvenient for you (e.g. because of concurrent access).
+]]>
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+<![CDATA[
+//ForStatement
+  [ForInit
+    [LocalVariableDeclaration
+      [PrimitiveType[@Kind = 'int']]
+      [VariableDeclarator[NumericLiteral[@IntLiteral][@Image = '0']]]
+    ]
+  ]
+  [*[2]//FieldAccess[@Name = 'length']/VariableAccess[pmd-java:typeIs("java.lang.Object[]")]]
+  /*[last()]/ExpressionStatement/
+    MethodCall
+      [pmd-java:matchesSig('java.util.Collection#add(_)')]
+      [ArgumentList/ArrayAccess
+        [VariableAccess[@Name = ancestor::ForStatement/ForInit/LocalVariableDeclaration/VariableDeclarator/VariableId/@Name]]
+      ]
+|
+//ForeachStatement
+  [VariableAccess[pmd-java:typeIs("java.lang.Object[]")]]
+  /*[last()]/ExpressionStatement/MethodCall
+      [pmd-java:matchesSig('java.util.Collection#add(_)')]
+      [ArgumentList
+        [VariableAccess[@Name = ancestor::ForeachStatement/LocalVariableDeclaration/VariableDeclarator/VariableId/@Name]]
+      ]
+]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+public class Test {
+    public void foo(Integer[] ints) {
+        // could just use Arrays.asList(ints)
+        List<Integer> l = new ArrayList<>(100);
+        for (int i = 0; i < ints.length; i++) {
+            l.add(ints[i]);
+        }
+
+        List<Integer> anotherList = new ArrayList<>();
+        for (int i = 0; i < ints.length; i++) {
+            anotherList.add(ints[i].toString()); // won't trigger the rule
+        }
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseIndexOfChar"
+          language="java"
+          since="3.5"
+          message="String.indexOf(char) is faster than String.indexOf(String)."
+          class="net.sourceforge.pmd.lang.java.rule.performance.UseIndexOfCharRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#useindexofchar">
+        <description>
+Use String.indexOf(char) when checking for the index of a single character; it executes faster.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+String s = "hello world";
+// avoid this
+if (s.indexOf("d") {}
+// instead do this
+if (s.indexOf('d') {}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseIOStreamsWithApacheCommonsFileItem"
+          since="6.25.0"
+          language="java"
+          message="Avoid memory intensive FileItem.get() or FileItem.getString()"
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          typeResolution="true"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#useiostreamswithapachecommonsfileitem">
+        <description>
+Problem: Use of [FileItem.get()](https://javadoc.io/static/commons-fileupload/commons-fileupload/1.5/org/apache/commons/fileupload/FileItem.html#get--)
+and [FileItem.getString()](https://javadoc.io/static/commons-fileupload/commons-fileupload/1.5/org/apache/commons/fileupload/FileItem.html#getString--)
+could exhaust memory since they load the entire file into memory.
+
+Solution: Use [FileItem.getInputStream()](https://javadoc.io/static/commons-fileupload/commons-fileupload/1.5/org/apache/commons/fileupload/FileItem.html#getInputStream--)
+and buffering.
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value>
+                    <![CDATA[
+//MethodCall
+    [@MethodName = 'get' or @MethodName = 'getString']
+    [*[pmd-java:typeIs('org.apache.commons.fileupload.FileItem')]]
+                    ]]>
+                </value>
+            </property>
+        </properties>
+        <example>
+            <![CDATA[
+import org.apache.commons.fileupload.FileItem;
+
+public class FileStuff {
+   private String bad(FileItem fileItem) {
+        return fileItem.getString();
+   }
+
+   private InputStream good(FileItem fileItem) {
+        return fileItem.getInputStream();
+   }
+}
+            ]]>
+        </example>
+    </rule>
+
+    <rule name="UselessStringValueOf"
+          language="java"
+          since="3.8"
+          message="No need to call String.valueOf to append to a string."
+          class="net.sourceforge.pmd.lang.java.rule.performance.UselessStringValueOfRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#uselessstringvalueof">
+        <description>
+No need to call String.valueOf to append to a string; just use the valueOf() argument directly.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public String convert(int i) {
+    String s;
+    s = "a" + String.valueOf(i);    // not required
+    s = "a" + i;                    // preferred approach
+    return s;
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseStringBufferForStringAppends"
+          language="java"
+          since="3.1"
+          message="Prefer StringBuilder (non-synchronized) or StringBuffer (synchronized) over += for concatenating strings"
+          class="net.sourceforge.pmd.lang.java.rule.performance.UseStringBufferForStringAppendsRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#usestringbufferforstringappends">
+        <description>
+The use of the '+=' operator for appending strings causes the JVM to create and use an internal StringBuffer.
+If a non-trivial number of these concatenations are being used then the explicit use of a StringBuilder or
+threadsafe StringBuffer is recommended to avoid this.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    String inefficientConcatenation() {
+        String result = "";
+        for (int i = 0; i < 10; i++) {
+            // warning: this concatenation will create one new StringBuilder per iteration
+            result += getStringFromSomeWhere(i);
+        }
+        return result;
+    }
+
+    String efficientConcatenation() {
+        // better would be to use one StringBuilder for the entire loop
+        StringBuilder result = new StringBuilder();
+        for (int i = 0; i < 10; i++) {
+            result.append(getStringFromSomeWhere(i));
+        }
+        return result.toString();
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="UseStringBufferLength"
+          language="java"
+          since="3.4"
+          message="This is an inefficient use of CharSequence.toString; call CharSequence.length instead."
+          class="net.sourceforge.pmd.lang.rule.xpath.XPathRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_performance.html#usestringbufferlength">
+        <description>
+Use StringBuffer.length() to determine StringBuffer length rather than using StringBuffer.toString().equals("")
+or StringBuffer.toString().length() == ...
+        </description>
+        <priority>3</priority>
+        <properties>
+            <property name="xpath">
+                <value><![CDATA[
+//MethodCall[pmd-java:matchesSig('_#length()')
+    and MethodCall[pmd-java:matchesSig('java.lang.CharSequence#toString()')]]
+|
+(: finds sb.toString().equals(someVar) where var is a final variable initialized with literal "" :)
+//MethodCall[pmd-java:matchesSig('_#equals(_)')
+  and MethodCall[pmd-java:matchesSig('java.lang.AbstractStringBuilder#toString()')]
+  and ArgumentList/VariableAccess[@Name = //VariableDeclarator[StringLiteral[@Image='""']]
+                                            /VariableId[pmd-java:modifiers() = 'final']/@Name]]
+]]></value>
+            </property>
+        </properties>
+        <example>
+<![CDATA[
+StringBuffer sb = new StringBuffer();
+
+if (sb.toString().equals("")) {}        // inefficient
+
+if (sb.length() == 0) {}                // preferred
+]]>
+        </example>
+    </rule>
+
+
+    <!--
+    other optimization/performance should be like avoiding
+    "" + int
+    or "" + (int) i
+    and String.valueOf(int)
+
+    and using Integer.toString(int)
+
+    IntegerToStringShouldBeUsed
+    LongToStringShouldBeUsed
+    BooleanToStringShouldBeUsed
+    -->
+
+</ruleset>
diff --git a/pmd/resources/category/java/security.xml b/pmd/resources/category/java/security.xml
new file mode 100644
index 000000000..0bc45a49e
--- /dev/null
+++ b/pmd/resources/category/java/security.xml
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<ruleset name="Security" xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+
+    <description>
+Rules that flag potential security flaws.
+    </description>
+
+    <rule name="HardCodedCryptoKey"
+          language="java"
+          since="6.4.0"
+          message="Do not use hard coded encryption keys"
+          class="net.sourceforge.pmd.lang.java.rule.security.HardCodedCryptoKeyRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_security.html#hardcodedcryptokey">
+        <description>
+Do not use hard coded values for cryptographic operations. Please store keys outside of source code.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    void good() {
+        SecretKeySpec secretKeySpec = new SecretKeySpec(Properties.getKey(), "AES");
+    }
+
+    void bad() {
+        SecretKeySpec secretKeySpec = new SecretKeySpec("my secret here".getBytes(), "AES");
+    }
+}
+]]>
+        </example>
+    </rule>
+
+    <rule name="InsecureCryptoIv"
+          language="java"
+          since="6.3.0"
+          message="Do not use hard coded initialization vector in crypto operations"
+          class="net.sourceforge.pmd.lang.java.rule.security.InsecureCryptoIvRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_security.html#insecurecryptoiv">
+        <description>
+Do not use hard coded initialization vector in cryptographic operations. Please use a randomly generated IV.
+        </description>
+        <priority>3</priority>
+        <example>
+<![CDATA[
+public class Foo {
+    void good() {
+        SecureRandom random = new SecureRandom();
+        byte iv[] = new byte[16];
+        random.nextBytes(bytes);
+    }
+
+    void bad() {
+        byte[] iv = new byte[] { 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, 00, };
+    }
+
+    void alsoBad() {
+        byte[] iv = "secret iv in here".getBytes();
+    }
+}
+]]>
+        </example>
+    </rule>
+</ruleset>
diff --git a/pmd/resources/rulesets/java/internal/diagnostics.xml b/pmd/resources/rulesets/java/internal/diagnostics.xml
new file mode 100644
index 000000000..52a523fe0
--- /dev/null
+++ b/pmd/resources/rulesets/java/internal/diagnostics.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<ruleset name="Diagnostics"
+         xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+    <description>
+        Contains rules for internal use.
+    </description>
+
+    <rule name="TypeResTest"
+          language="java"
+          since="7.0.0"
+          message="Type Resolution Test"
+          class="net.sourceforge.pmd.lang.java.rule.internal.TypeResTestRule"
+          externalInfoUrl="${pmd.website.baseurl}/pmd_rules_java_diagnostics.html#typerestest">
+        <description>
+            This is just a toy rule that counts the proportion of resolved types in a codebase, not meant as a real rule.
+
+            It is used to test the capability of PMD's own type resolution.
+        </description>
+        <priority>3</priority>
+    </rule>
+
+</ruleset>
diff --git a/pmd/resources/rulesets/java/quickstart.xml b/pmd/resources/rulesets/java/quickstart.xml
new file mode 100644
index 000000000..3ac03a493
--- /dev/null
+++ b/pmd/resources/rulesets/java/quickstart.xml
@@ -0,0 +1,322 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ruleset name="quickstart"
+         xmlns="http://pmd.sourceforge.net/ruleset/2.0.0"
+         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://pmd.sourceforge.net/ruleset/2.0.0 https://pmd.sourceforge.io/ruleset_2_0_0.xsd">
+    <description>Quickstart configuration of PMD. Includes the rules that are most likely to apply everywhere.</description>
+
+    <!-- <rule ref="category/java/bestpractices.xml/AbstractClassWithoutAbstractMethod" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/AccessorClassGeneration" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/AccessorMethodGeneration" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/ArrayIsStoredDirectly" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/AvoidPrintStackTrace" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/AvoidReassigningCatchVariables" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/AvoidReassigningLoopVariables" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/AvoidReassigningParameters" /> -->
+    <rule ref="category/java/bestpractices.xml/AvoidMessageDigestField"/>
+    <rule ref="category/java/bestpractices.xml/AvoidStringBufferField"/>
+    <rule ref="category/java/bestpractices.xml/AvoidUsingHardCodedIP"/>
+    <rule ref="category/java/bestpractices.xml/CheckResultSet"/>
+    <rule ref="category/java/bestpractices.xml/ConstantsInInterface"/>
+    <rule ref="category/java/bestpractices.xml/DefaultLabelNotLastInSwitchStmt"/>
+    <rule ref="category/java/bestpractices.xml/DoubleBraceInitialization"/>
+    <rule ref="category/java/bestpractices.xml/ForLoopCanBeForeach"/>
+    <!-- <rule ref="category/java/bestpractices.xml/ForLoopVariableCount" /> -->
+    <rule ref="category/java/bestpractices.xml/GuardLogStatement"/>
+    <!-- <rule ref="category/java/bestpractices.xml/JUnit4SuitesShouldUseSuiteAnnotation" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/JUnit5TestShouldBePackagePrivate" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/JUnitUseExpected" /> -->
+    <rule ref="category/java/bestpractices.xml/LiteralsFirstInComparisons" />
+    <rule ref="category/java/bestpractices.xml/LooseCoupling"/>
+    <!-- <rule ref="category/java/bestpractices.xml/MethodReturnsInternalArray" /> -->
+    <rule ref="category/java/bestpractices.xml/MissingOverride"/>
+    <rule ref="category/java/bestpractices.xml/OneDeclarationPerLine"/>
+    <rule ref="category/java/bestpractices.xml/PrimitiveWrapperInstantiation"/>
+    <rule ref="category/java/bestpractices.xml/PreserveStackTrace"/>
+    <!-- <rule ref="category/java/bestpractices.xml/ReplaceEnumerationWithIterator" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/ReplaceHashtableWithMap" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/ReplaceVectorWithList" /> -->
+    <rule ref="category/java/bestpractices.xml/SimplifiableTestAssertion"/>
+    <rule ref="category/java/bestpractices.xml/SwitchStmtsShouldHaveDefault"/>
+    <!-- <rule ref="category/java/bestpractices.xml/SystemPrintln" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/UnitTestAssertionsShouldIncludeMessage" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/UnitTestContainsTooManyAsserts" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/UnitTestShouldIncludeAssert" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/UnitTestShouldUseAfterAnnotation" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/UnitTestShouldUseBeforeAnnotation" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/UnitTestShouldUseTestAnnotation" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/UnnecessaryVarargsArrayCreation" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/UnusedAssignment"/> -->
+    <rule ref="category/java/bestpractices.xml/UnusedFormalParameter"/>
+    <rule ref="category/java/bestpractices.xml/UnusedLocalVariable"/>
+    <rule ref="category/java/bestpractices.xml/UnusedPrivateField"/>
+    <rule ref="category/java/bestpractices.xml/UnusedPrivateMethod"/>
+    <rule ref="category/java/bestpractices.xml/UseCollectionIsEmpty"/>
+    <!-- <rule ref="category/java/bestpractices.xml/UseEnumCollections"/> -->
+    <rule ref="category/java/bestpractices.xml/UseStandardCharsets" />
+    <!-- <rule ref="category/java/bestpractices.xml/UseTryWithResources" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/UseVarargs" /> -->
+    <!-- <rule ref="category/java/bestpractices.xml/WhileLoopWithLiteralBoolean" /> -->
+
+
+    <!-- NAMING CONVENTIONS -->
+    <rule ref="category/java/codestyle.xml/ClassNamingConventions"/>
+    <!--<rule ref="category/java/codestyle.xml/FieldNamingConventions" />-->
+    <rule ref="category/java/codestyle.xml/FormalParameterNamingConventions"/>
+    <rule ref="category/java/codestyle.xml/GenericsNaming"/>
+    <rule ref="category/java/codestyle.xml/LambdaCanBeMethodReference"/>
+    <!-- <rule ref="category/java/codestyle.xml/LinguisticNaming" /> -->
+    <rule ref="category/java/codestyle.xml/LocalVariableNamingConventions"/>
+    <!-- <rule ref="category/java/codestyle.xml/LongVariable" /> -->
+    <rule ref="category/java/codestyle.xml/MethodNamingConventions"/>
+    <rule ref="category/java/codestyle.xml/PackageCase"/>
+    <!-- <rule ref="category/java/codestyle.xml/ShortClassName" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/ShortMethodName" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/ShortVariable" /> -->
+
+    <!-- <rule ref="category/java/codestyle.xml/LocalHomeNamingConvention" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/LocalInterfaceSessionNamingConvention" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/MDBAndSessionBeanNamingConvention" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/RemoteInterfaceNamingConvention" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/RemoteSessionInterfaceNamingConvention" /> -->
+
+    <!-- OTHER -->
+    <!-- <rule ref="category/java/codestyle.xml/AtLeastOneConstructor" /> -->
+    <rule ref="category/java/codestyle.xml/AvoidDollarSigns"/>
+    <rule ref="category/java/codestyle.xml/AvoidProtectedFieldInFinalClass"/>
+    <rule ref="category/java/codestyle.xml/AvoidProtectedMethodInFinalClassNotExtending"/>
+    <!-- <rule ref="category/java/codestyle.xml/AvoidUsingNativeCode"/>-->
+    <!-- <rule ref="category/java/codestyle.xml/BooleanGetMethodName" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/CallSuperInConstructor" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/CommentDefaultAccessModifier" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/ConfusingTernary" /> -->
+    <rule ref="category/java/codestyle.xml/ControlStatementBraces"/>
+    <!-- <rule ref="category/java/codestyle.xml/EmptyMethodInAbstractClassShouldBeAbstract" /> -->
+    <rule ref="category/java/codestyle.xml/ExtendsObject"/>
+    <!-- <rule ref="category/java/codestyle.xml/FieldDeclarationsShouldBeAtStartOfClass" /> -->
+    <rule ref="category/java/codestyle.xml/FinalParameterInAbstractMethod"/>
+    <rule ref="category/java/codestyle.xml/ForLoopShouldBeWhileLoop"/>
+    <rule ref="category/java/codestyle.xml/IdenticalCatchBranches"/>
+    <!-- <rule ref="category/java/codestyle.xml/LocalVariableCouldBeFinal" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/MethodArgumentCouldBeFinal" /> -->
+    <rule ref="category/java/codestyle.xml/NoPackage"/>
+    <!-- <rule ref="category/java/codestyle.xml/UseExplicitTypes"/> -->
+    <!-- <rule ref="category/java/codestyle.xml/UseUnderscoresInNumericLiterals" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/OnlyOneReturn" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/PrematureDeclaration" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/TooManyStaticImports" /> -->
+    <rule ref="category/java/codestyle.xml/UnnecessaryAnnotationValueElement"/>
+    <!-- <rule ref="category/java/codestyle.xml/UnnecessaryBoxing" /> -->
+    <!-- <rule ref="category/java/codestyle.xml/UnnecessaryCast" /> -->
+    <rule ref="category/java/codestyle.xml/UnnecessaryConstructor"/>
+    <rule ref="category/java/codestyle.xml/UnnecessaryFullyQualifiedName"/>
+    <rule ref="category/java/codestyle.xml/UnnecessaryImport" />
+    <rule ref="category/java/codestyle.xml/UnnecessaryLocalBeforeReturn"/>
+    <rule ref="category/java/codestyle.xml/UnnecessaryModifier"/>
+    <rule ref="category/java/codestyle.xml/UnnecessaryReturn"/>
+    <!-- <rule ref="category/java/codestyle.xml/UseDiamondOperator" /> -->
+    <rule ref="category/java/codestyle.xml/UselessParentheses"/>
+    <rule ref="category/java/codestyle.xml/UselessQualifiedThis"/>
+
+
+    <rule ref="category/java/design.xml/AbstractClassWithoutAnyMethod"/>
+    <!-- <rule ref="category/java/design.xml/AvoidCatchingGenericException" /> -->
+    <!-- <rule ref="category/java/design.xml/AvoidDeeplyNestedIfStmts" /> -->
+    <!-- <rule ref="category/java/design.xml/AvoidRethrowingException" /> -->
+    <!-- <rule ref="category/java/design.xml/AvoidThrowingNewInstanceOfSameException" /> -->
+    <!--<rule ref="category/java/design.xml/AvoidThrowingNullPointerException" />-->
+    <!-- <rule ref="category/java/design.xml/AvoidThrowingRawExceptionTypes" /> -->
+    <!-- <rule ref="category/java/design.xml/AvoidUncheckedExceptionsInSignatures" /> -->
+    <rule ref="category/java/design.xml/ClassWithOnlyPrivateConstructorsShouldBeFinal"/>
+    <!-- <rule ref="category/java/design.xml/CognitiveComplexity" /> -->
+    <!-- <rule ref="category/java/design.xml/CollapsibleIfStatements"/>-->
+    <!-- <rule ref="category/java/design.xml/CouplingBetweenObjects" /> -->
+    <!-- <rule ref="category/java/design.xml/CyclomaticComplexity" /> -->
+    <!-- <rule ref="category/java/design.xml/DataClass" /> -->
+    <rule ref="category/java/design.xml/DoNotExtendJavaLangError" />
+    <!-- <rule ref="category/java/design.xml/ExceptionAsFlowControl" /> -->
+    <!-- <rule ref="category/java/design.xml/ExcessiveImports" /> -->
+    <!-- <rule ref="category/java/design.xml/ExcessiveParameterList" /> -->
+    <!-- <rule ref="category/java/design.xml/ExcessivePublicCount" /> -->
+    <rule ref="category/java/design.xml/FinalFieldCouldBeStatic"/>
+    <!-- <rule ref="category/java/design.xml/GodClass" /> -->
+    <!-- <rule ref="category/java/design.xml/ImmutableField" /> -->
+    <!-- <rule ref="category/java/design.xml/InvalidJavaBean">-->
+    <!--     <properties>-->
+    <!--         <property name="packages" value="org.example.beans" />-->
+    <!--     </properties>-->
+    <!-- </rule>-->
+    <!-- <rule ref="category/java/design.xml/LawOfDemeter" /> -->
+    <rule ref="category/java/design.xml/LogicInversion"/>
+    <!-- <rule ref="category/java/design.xml/LoosePackageCoupling"> -->
+    <!--     <properties> -->
+    <!--         <property name="packages" value="org.sample,org.sample2" /> -->
+    <!--         <property name="classes" value="org.sample.SampleInterface,org.sample2.SampleInterface" /> -->
+    <!--     </properties> -->
+    <!-- </rule> -->
+    <!-- <rule ref="category/java/design.xml/MutableStaticState" /> -->
+    <!-- <rule ref="category/java/design.xml/NcssCount" /> -->
+    <!-- <rule ref="category/java/design.xml/NPathComplexity" /> -->
+    <!-- <rule ref="category/java/design.xml/SignatureDeclareThrowsException" /> -->
+    <rule ref="category/java/design.xml/SimplifiedTernary"/>
+    <!-- <rule ref="category/java/design.xml/SimplifyBooleanExpressions" /> -->
+    <rule ref="category/java/design.xml/SimplifyBooleanReturns"/>
+    <rule ref="category/java/design.xml/SimplifyConditional"/>
+    <rule ref="category/java/design.xml/SingularField"/>
+    <!-- <rule ref="category/java/design.xml/SwitchDensity" /> -->
+    <!-- <rule ref="category/java/design.xml/TooManyFields" /> -->
+    <!-- <rule ref="category/java/design.xml/TooManyMethods" /> -->
+    <rule ref="category/java/design.xml/UselessOverridingMethod"/>
+    <!-- <rule ref="category/java/design.xml/UseObjectForClearerAPI" /> -->
+    <rule ref="category/java/design.xml/UseUtilityClass"/>
+
+
+    <!-- <rule ref="category/java/documentation.xml/CommentContent" /> -->
+    <!-- <rule ref="category/java/documentation.xml/CommentRequired" /> -->
+    <!-- <rule ref="category/java/documentation.xml/CommentSize" /> -->
+    <rule ref="category/java/documentation.xml/UncommentedEmptyConstructor"/>
+    <rule ref="category/java/documentation.xml/UncommentedEmptyMethodBody"/>
+
+
+
+    <rule ref="category/java/errorprone.xml/AssignmentInOperand">
+        <properties>
+            <property name="allowWhile" value="true"/>
+        </properties>
+    </rule>
+    <rule ref="category/java/errorprone.xml/AssignmentToNonFinalStatic"/>
+    <rule ref="category/java/errorprone.xml/AvoidAccessibilityAlteration"/>
+    <!-- <rule ref="category/java/errorprone.xml/AvoidAssertAsIdentifier" /> -->
+    <rule ref="category/java/errorprone.xml/AvoidBranchingStatementAsLastInLoop"/>
+    <!-- <rule ref="category/java/errorprone.xml/AvoidCallingFinalize" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/AvoidCatchingNPE" /> -->
+    <rule ref="category/java/errorprone.xml/AvoidCatchingThrowable"/>
+    <rule ref="category/java/errorprone.xml/AvoidDecimalLiteralsInBigDecimalConstructor"/>
+    <!-- <rule ref="category/java/errorprone.xml/AvoidDuplicateLiterals" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/AvoidEnumAsIdentifier" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/AvoidFieldNameMatchingMethodName" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/AvoidFieldNameMatchingTypeName" /> -->
+    <rule ref="category/java/errorprone.xml/AvoidInstanceofChecksInCatchClause"/>
+    <!-- <rule ref="category/java/errorprone.xml/AvoidLiteralsInIfCondition" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/AvoidLosingExceptionInformation" /> -->
+    <rule ref="category/java/errorprone.xml/AvoidMultipleUnaryOperators"/>
+    <rule ref="category/java/errorprone.xml/AvoidUsingOctalValues"/>
+    <!-- <rule ref="category/java/errorprone.xml/BeanMembersShouldSerialize" /> -->
+    <rule ref="category/java/errorprone.xml/BrokenNullCheck"/>
+    <!-- <rule ref="category/java/errorprone.xml/CallSuperFirst" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/CallSuperLast" /> -->
+    <rule ref="category/java/errorprone.xml/CheckSkipResult"/>
+    <rule ref="category/java/errorprone.xml/ClassCastExceptionWithToArray"/>
+    <rule ref="category/java/errorprone.xml/CloneMethodMustBePublic"/>
+    <rule ref="category/java/errorprone.xml/CloneMethodMustImplementCloneable"/>
+    <rule ref="category/java/errorprone.xml/CloneMethodReturnTypeMustMatchClassName"/>
+    <!-- <rule ref="category/java/errorprone.xml/CloneThrowsCloneNotSupportedException"/> deprecated since 6.35.0 -->
+    <rule ref="category/java/errorprone.xml/CloseResource"/>
+    <!-- <rule ref="category/java/errorprone.xml/ConfusingArgumentToVarargsMethod"/> -->
+    <rule ref="category/java/errorprone.xml/CompareObjectsWithEquals"/>
+    <rule ref="category/java/errorprone.xml/ComparisonWithNaN"/>
+    <!-- <rule ref="category/java/errorprone.xml/ConstructorCallsOverridableMethod" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/DataflowAnomalyAnalysis" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/DetachedTestCase" /> -->
+    <rule ref="category/java/errorprone.xml/DoNotCallGarbageCollectionExplicitly"/>
+    <!-- <rule ref="category/java/errorprone.xml/DoNotCallSystemExit" /> -->
+    <rule ref="category/java/errorprone.xml/DoNotExtendJavaLangThrowable"/>
+    <!-- <rule ref="category/java/errorprone.xml/DoNotHardCodeSDCard" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/DoNotThrowExceptionInFinally" /> -->
+    <!--<rule ref="category/java/errorprone.xml/DontImportSun" />-->
+    <rule ref="category/java/errorprone.xml/DontUseFloatTypeForLoopIndices"/>
+    <rule ref="category/java/errorprone.xml/EqualsNull"/>
+    <!-- <rule ref="category/java/errorprone.xml/FinalizeDoesNotCallSuperFinalize" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/FinalizeOnlyCallsSuperFinalize" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/FinalizeOverloaded" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/FinalizeShouldBeProtected" /> -->
+    <rule ref="category/java/errorprone.xml/IdempotentOperations"/>
+    <rule ref="category/java/errorprone.xml/ImplicitSwitchFallThrough"/>
+    <rule ref="category/java/errorprone.xml/InstantiationToGetClass"/>
+    <!-- <rule ref="category/java/errorprone.xml/InvalidLogMessageFormat" /> -->
+    <rule ref="category/java/errorprone.xml/JumbledIncrementer"/>
+    <!-- <rule ref="category/java/errorprone.xml/JUnitSpelling" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/JUnitStaticSuite" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/LoggerIsNotStaticFinal" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/MethodWithSameNameAsEnclosingClass" /> -->
+    <rule ref="category/java/errorprone.xml/MisplacedNullCheck"/>
+    <!-- <rule ref="category/java/errorprone.xml/MissingSerialVersionUID" /> -->
+    <rule ref="category/java/errorprone.xml/MissingStaticMethodInNonInstantiatableClass"/>
+    <!-- <rule ref="category/java/errorprone.xml/MoreThanOneLogger" /> -->
+    <rule ref="category/java/errorprone.xml/NonCaseLabelInSwitchStatement"/>
+    <rule ref="category/java/errorprone.xml/NonStaticInitializer"/>
+    <!-- <rule ref="category/java/errorprone.xml/NullAssignment" /> -->
+    <rule ref="category/java/errorprone.xml/OverrideBothEqualsAndHashcode"/>
+    <rule ref="category/java/errorprone.xml/ProperCloneImplementation"/>
+    <rule ref="category/java/errorprone.xml/ProperLogger"/>
+    <rule ref="category/java/errorprone.xml/ReturnEmptyCollectionRatherThanNull"/>
+    <rule ref="category/java/errorprone.xml/ReturnFromFinallyBlock"/>
+    <!-- <rule ref="category/java/errorprone.xml/SimpleDateFormatNeedsLocale" /> -->
+    <rule ref="category/java/errorprone.xml/SingleMethodSingleton"/>
+    <rule ref="category/java/errorprone.xml/SingletonClassReturningNewInstance"/>
+    <!-- <rule ref="category/java/errorprone.xml/StaticEJBFieldShouldBeFinal" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/StringBufferInstantiationWithChar" /> -->
+    <rule ref="category/java/errorprone.xml/SuspiciousEqualsMethodName"/>
+    <rule ref="category/java/errorprone.xml/SuspiciousHashcodeMethodName"/>
+    <rule ref="category/java/errorprone.xml/SuspiciousOctalEscape"/>
+    <!-- <rule ref="category/java/errorprone.xml/TestClassWithoutTestCases" /> -->
+    <rule ref="category/java/errorprone.xml/UnconditionalIfStatement"/>
+    <!-- <rule ref="category/java/errorprone.xml/UnnecessaryBooleanAssertion" /> -->
+    <!-- <rule ref="category/java/errorprone.xml/UnnecessaryCaseChange" /> -->
+    <rule ref="category/java/errorprone.xml/UnnecessaryConversionTemporary"/>
+    <rule ref="category/java/errorprone.xml/UnusedNullCheckInEquals"/>
+    <!-- <rule ref="category/java/errorprone.xml/UseCorrectExceptionLogging" /> -->
+    <rule ref="category/java/errorprone.xml/UseEqualsToCompareStrings"/>
+    <rule ref="category/java/errorprone.xml/UselessOperationOnImmutable"/>
+    <rule ref="category/java/errorprone.xml/UseLocaleWithCaseConversions"/>
+    <!-- <rule ref="category/java/errorprone.xml/UseProperClassLoader" /> -->
+
+    <!-- Empty rules -->
+    <rule ref="category/java/codestyle.xml/EmptyControlStatement"/>
+    <rule ref="category/java/codestyle.xml/UnnecessarySemicolon"/>
+    <rule ref="category/java/errorprone.xml/EmptyCatchBlock"/>
+    <rule ref="category/java/errorprone.xml/EmptyFinalizer"/>
+
+
+    <!-- <rule ref="category/java/multithreading.xml/AvoidSynchronizedAtMethodLevel" /> -->
+    <!-- <rule ref="category/java/multithreading.xml/AvoidSynchronizedStatement" /> -->
+    <rule ref="category/java/multithreading.xml/AvoidThreadGroup"/>
+    <rule ref="category/java/multithreading.xml/AvoidUsingVolatile"/>
+    <!-- <rule ref="category/java/multithreading.xml/DoNotUseThreads" /> -->
+    <rule ref="category/java/multithreading.xml/DontCallThreadRun"/>
+    <rule ref="category/java/multithreading.xml/DoubleCheckedLocking"/>
+    <rule ref="category/java/multithreading.xml/NonThreadSafeSingleton"/>
+    <rule ref="category/java/multithreading.xml/UnsynchronizedStaticFormatter"/>
+    <!-- <rule ref="category/java/multithreading.xml/UseConcurrentHashMap" /> -->
+    <rule ref="category/java/multithreading.xml/UseNotifyAllInsteadOfNotify"/>
+
+
+    <!-- <rule ref="category/java/performance.xml/AddEmptyString" /> -->
+    <!-- <rule ref="category/java/performance.xml/AppendCharacterWithChar" /> -->
+    <!-- <rule ref="category/java/performance.xml/AvoidArrayLoops" /> -->
+    <!-- <rule ref="category/java/performance.xml/AvoidCalendarDateCreation" /> -->
+    <!-- <rule ref="category/java/performance.xml/AvoidFileStream" /> -->
+    <!-- <rule ref="category/java/performance.xml/AvoidInstantiatingObjectsInLoops" /> -->
+    <rule ref="category/java/performance.xml/BigIntegerInstantiation"/>
+    <!-- <rule ref="category/java/performance.xml/ConsecutiveAppendsShouldReuse" /> -->
+    <!-- <rule ref="category/java/performance.xml/ConsecutiveLiteralAppends" /> -->
+    <!-- <rule ref="category/java/performance.xml/InefficientEmptyStringCheck" /> -->
+    <!-- <rule ref="category/java/performance.xml/InefficientStringBuffering" /> -->
+    <!-- <rule ref="category/java/performance.xml/InsufficientStringBufferDeclaration" /> -->
+    <rule ref="category/java/performance.xml/OptimizableToArrayCall"/>
+    <!--<rule ref="category/java/performance.xml/RedundantFieldInitializer"/>-->
+    <!-- <rule ref="category/java/performance.xml/StringInstantiation" /> -->
+    <!-- <rule ref="category/java/performance.xml/StringToString" /> -->
+    <!--<rule ref="category/java/performance.xml/TooFewBranchesForASwitchStatement"/>-->
+    <!-- <rule ref="category/java/performance.xml/UseArrayListInsteadOfVector" /> -->
+    <!-- <rule ref="category/java/performance.xml/UseArraysAsList" /> -->
+    <!-- <rule ref="category/java/performance.xml/UseIndexOfChar" /> -->
+    <!-- <rule ref="category/java/performance.xml/UseIOStreamsWithApacheCommonsFileItem" /> -->
+    <!-- <rule ref="category/java/performance.xml/UselessStringValueOf" /> -->
+    <!-- <rule ref="category/java/performance.xml/UseStringBufferForStringAppends" /> -->
+    <!-- <rule ref="category/java/performance.xml/UseStringBufferLength" /> -->
+
+
+    <!-- <rule ref="category/java/security.xml/HardCodedCryptoKey" /> -->
+    <!-- <rule ref="category/java/security.xml/InsecureCryptoIv" /> -->
+</ruleset>