Browse Source

fix compiler warnings and errorprone warnings

Jason Rivard 4 years ago
parent
commit
9ac9d07fa5
43 changed files with 441 additions and 559 deletions
  1. 1 0
      build/checkstyle-import.xml
  2. 1 2
      data-service/src/main/java/password/pwm/receiver/Settings.java
  3. 1 1
      server/src/main/java/password/pwm/PwmEnvironment.java
  4. 1 1
      server/src/main/java/password/pwm/config/profile/PwmPasswordPolicy.java
  5. 1 1
      server/src/main/java/password/pwm/config/stored/StoredConfigItemKey.java
  6. 1 0
      server/src/main/java/password/pwm/config/stored/StoredConfigXmlConstants.java
  7. 1 24
      server/src/main/java/password/pwm/config/stored/StoredConfigXmlSerializer.java
  8. 1 1
      server/src/main/java/password/pwm/config/value/AbstractValue.java
  9. 2 4
      server/src/main/java/password/pwm/config/value/ValueTypeConverter.java
  10. 0 33
      server/src/main/java/password/pwm/config/value/data/FormConfiguration.java
  11. 150 152
      server/src/main/java/password/pwm/error/PwmError.java
  12. 7 5
      server/src/main/java/password/pwm/health/CertificateChecker.java
  13. 3 3
      server/src/main/java/password/pwm/health/LDAPHealthChecker.java
  14. 7 16
      server/src/main/java/password/pwm/http/PwmHttpRequestWrapper.java
  15. 3 3
      server/src/main/java/password/pwm/http/auth/HttpAuthenticationUtilities.java
  16. 4 9
      server/src/main/java/password/pwm/http/servlet/GuestRegistrationServlet.java
  17. 2 3
      server/src/main/java/password/pwm/http/servlet/ShortcutServlet.java
  18. 7 2
      server/src/main/java/password/pwm/http/servlet/configeditor/ConfigEditorServlet.java
  19. 1 1
      server/src/main/java/password/pwm/http/servlet/configguide/GuideStep.java
  20. 0 2
      server/src/main/java/password/pwm/http/servlet/configmanager/ConfigManagerLoginServlet.java
  21. 2 2
      server/src/main/java/password/pwm/http/servlet/forgottenpw/ForgottenPasswordUtil.java
  22. 14 0
      server/src/main/java/password/pwm/http/servlet/helpdesk/HelpdeskServlet.java
  23. 2 2
      server/src/main/java/password/pwm/http/state/LocalSessionBeanImpl.java
  24. 1 1
      server/src/main/java/password/pwm/ldap/LdapBrowser.java
  25. 2 3
      server/src/main/java/password/pwm/ldap/schema/EdirSchemaExtender.java
  26. 1 1
      server/src/main/java/password/pwm/svc/event/LdapXmlUserHistory.java
  27. 1 1
      server/src/main/java/password/pwm/svc/shorturl/UrlShortenerService.java
  28. 1 1
      server/src/main/java/password/pwm/util/JarMain.java
  29. 4 9
      server/src/main/java/password/pwm/util/cli/MainClass.java
  30. 1 1
      server/src/main/java/password/pwm/util/db/JDBCDriverLoader.java
  31. 0 58
      server/src/main/java/password/pwm/util/form/FormState.java
  32. 20 20
      server/src/main/java/password/pwm/util/java/JavaHelper.java
  33. 2 8
      server/src/main/java/password/pwm/util/java/StringUtil.java
  34. 12 29
      server/src/main/java/password/pwm/util/logging/PwmLogLevel.java
  35. 5 0
      server/src/main/java/password/pwm/util/logging/PwmLogger.java
  36. 4 3
      server/src/main/java/password/pwm/util/operations/cr/NMASCrOperator.java
  37. 1 1
      server/src/main/java/password/pwm/util/operations/otp/OTPPamUtil.java
  38. 14 12
      server/src/main/java/password/pwm/util/password/RandomPasswordGenerator.java
  39. 1 1
      server/src/main/java/password/pwm/util/queue/SmsQueueManager.java
  40. 3 3
      server/src/main/java/password/pwm/util/secure/HttpsServerCertificateManager.java
  41. 11 4
      server/src/test/java/password/pwm/http/servlet/ControlledPwmServletTest.java
  42. 28 22
      server/src/test/java/password/pwm/util/localdb/LocalDBLoggerExtendedTest.java
  43. 117 114
      server/src/test/java/password/pwm/util/password/PasswordRuleChecksTest.java

+ 1 - 0
build/checkstyle-import.xml

@@ -58,6 +58,7 @@
 
     <!-- testing -->
     <allow pkg="org.junit"/>
+    <allow pkg="org.hamcrest"/>
     <allow pkg="org.mockito"/>
     <allow pkg="com.github.tomakehurst.wiremock"/>
     <allow pkg="org.reflections"/>

+ 1 - 2
data-service/src/main/java/password/pwm/receiver/Settings.java

@@ -23,7 +23,6 @@ package password.pwm.receiver;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.TimeDuration;
 
-import java.io.File;
 import java.io.FileInputStream;
 import java.io.IOException;
 import java.io.InputStreamReader;
@@ -75,7 +74,7 @@ public class Settings
     static Settings readFromFile( final String filename ) throws IOException
     {
         final Properties properties = new Properties();
-        try ( Reader reader = new InputStreamReader( new FileInputStream( new File( filename ) ), StandardCharsets.UTF_8 ) )
+        try ( Reader reader = new InputStreamReader( new FileInputStream( filename ), StandardCharsets.UTF_8 ) )
         {
             properties.load( reader );
             final Map<Setting, String> returnMap = new HashMap<>();

+ 1 - 1
server/src/main/java/password/pwm/PwmEnvironment.java

@@ -320,7 +320,7 @@ public class PwmEnvironment
             }
 
             final Properties propValues = new Properties();
-            try ( FileInputStream fileInputStream = new FileInputStream( new File( input ) ) )
+            try ( FileInputStream fileInputStream = new FileInputStream( input ) )
             {
                 propValues.load( fileInputStream );
             }

+ 1 - 1
server/src/main/java/password/pwm/config/profile/PwmPasswordPolicy.java

@@ -129,7 +129,7 @@ public class PwmPasswordPolicy implements Profile, Serializable
             final Locale locale
     )
     {
-        final SettingReader settingReader = new SettingReader( domainConfig.getStoredConfiguration(), domainConfig.getDomainID(), profileID );
+        final SettingReader settingReader = new SettingReader( domainConfig.getStoredConfiguration(), profileID,  domainConfig.getDomainID() );
         final Map<String, String> passwordPolicySettings = new LinkedHashMap<>();
         for ( final PwmPasswordRule rule : PwmPasswordRule.values() )
         {

+ 1 - 1
server/src/main/java/password/pwm/config/stored/StoredConfigItemKey.java

@@ -261,7 +261,7 @@ public class StoredConfigItemKey implements Serializable, Comparable<StoredConfi
     @Override
     public int hashCode()
     {
-        return Objects.hash( recordType, recordID, profileID );
+        return Objects.hash( recordType, domainID, recordID, profileID );
     }
 
     @Override

+ 1 - 0
server/src/main/java/password/pwm/config/stored/StoredConfigXmlConstants.java

@@ -36,6 +36,7 @@ public class StoredConfigXmlConstants
     public static final String XML_ATTRIBUTE_KEY = "key";
     public static final String XML_ATTRIBUTE_SYNTAX = "syntax";
     public static final String XML_ATTRIBUTE_PROFILE = "profile";
+    public static final String XML_ATTRIBUTE_DOMAIN = "domain";
     public static final String XML_ATTRIBUTE_VALUE_APP = "app";
     public static final String XML_ATTRIBUTE_VALUE_CONFIG = "config";
     public static final String XML_ATTRIBUTE_CREATE_TIME = "createTime";

+ 1 - 24
server/src/main/java/password/pwm/config/stored/StoredConfigXmlSerializer.java

@@ -23,10 +23,8 @@ package password.pwm.config.stored;
 import password.pwm.PwmConstants;
 import password.pwm.bean.UserIdentity;
 import password.pwm.config.PwmSetting;
-import password.pwm.config.PwmSettingCategory;
 import password.pwm.config.PwmSettingFlag;
 import password.pwm.config.PwmSettingTemplate;
-import password.pwm.config.PwmSettingTemplateSet;
 import password.pwm.config.value.LocalizedStringValue;
 import password.pwm.config.value.StoredValue;
 import password.pwm.config.value.StoredValueEncoder;
@@ -37,7 +35,6 @@ import password.pwm.config.value.ValueTypeConverter;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.i18n.PwmLocaleBundle;
 import password.pwm.util.java.JavaHelper;
-import password.pwm.util.java.LazySupplier;
 import password.pwm.util.java.PwmExceptionLoggingConsumer;
 import password.pwm.util.java.StringUtil;
 import password.pwm.util.java.TimeDuration;
@@ -55,15 +52,12 @@ import java.time.Instant;
 import java.time.format.DateTimeParseException;
 import java.util.ArrayList;
 import java.util.Collections;
-import java.util.EnumMap;
-import java.util.EnumSet;
 import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Queue;
 import java.util.ResourceBundle;
-import java.util.Set;
 import java.util.concurrent.ConcurrentLinkedQueue;
 import java.util.function.Consumer;
 import java.util.function.Function;
@@ -126,8 +120,6 @@ public class StoredConfigXmlSerializer implements StoredConfigSerializer
 
     static class XmlInputDocumentReader
     {
-        private final EnumMap<PwmSettingCategory, List<String>> cachedProfiles = new EnumMap<>( PwmSettingCategory.class );
-
         private final XmlDocument document;
         private final PwmSecurityKey pwmSecurityKey;
 
@@ -188,7 +180,7 @@ public class StoredConfigXmlSerializer implements StoredConfigSerializer
             final Function<XmlElement, Stream<StoredConfigData.ValueAndMetaCarrier>> readSettingForXmlElement = xmlElement ->
             {
                 final Optional<StoredConfigData.ValueAndMetaCarrier> valueAndMetaCarrier = readSetting( xmlElement );
-                return valueAndMetaCarrier.map( Stream::of ).orElseGet( Stream::empty );
+                return valueAndMetaCarrier.stream();
             };
 
             final List<XmlElement> settingElements = xpathForAllSetting();
@@ -266,15 +258,6 @@ public class StoredConfigXmlSerializer implements StoredConfigSerializer
             return null;
         }
 
-        private final LazySupplier<PwmSettingTemplateSet> templateSetSupplier = new LazySupplier<>( () ->
-        {
-            final Set<PwmSettingTemplate> templates = EnumSet.noneOf( PwmSettingTemplate.class );
-            templates.add( readTemplateValue( PwmSetting.TEMPLATE_LDAP ) );
-            templates.add( readTemplateValue( PwmSetting.TEMPLATE_STORAGE ) );
-            templates.add( readTemplateValue( PwmSetting.DB_VENDOR_TEMPLATE ) );
-            return new PwmSettingTemplateSet( templates );
-        } );
-
         private PwmSettingTemplate readTemplateValue( final PwmSetting pwmSetting )
         {
             final Optional<XmlElement> settingElement = xpathForSetting( pwmSetting, null );
@@ -386,12 +369,6 @@ public class StoredConfigXmlSerializer implements StoredConfigSerializer
             return document.evaluateXpathToElements( xpathString );
         }
 
-        XmlElement xpathForSettings()
-        {
-            return document.getRootElement().getChild( StoredConfigXmlConstants.XML_ELEMENT_SETTINGS )
-                    .orElseThrow( () -> new IllegalStateException( "configuration xml document missing 'settings' element" ) );
-        }
-
         List<XmlElement> xpathForAllSetting()
         {
             final String xpathString = "//" + StoredConfigXmlConstants.XML_ELEMENT_SETTING;

+ 1 - 1
server/src/main/java/password/pwm/config/value/AbstractValue.java

@@ -86,7 +86,7 @@ public abstract class AbstractValue implements StoredValue
             document.getRootElement().addContent( xmlValues );
             final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
             XmlFactory.getFactory().outputDocument( document, byteArrayOutputStream );
-            final String stringToHash = new String( byteArrayOutputStream.toByteArray(), PwmConstants.DEFAULT_CHARSET );
+            final String stringToHash = byteArrayOutputStream.toString( PwmConstants.DEFAULT_CHARSET );
             return SecureEngine.hash( stringToHash, PwmHashAlgorithm.SHA512 );
 
         }

+ 2 - 4
server/src/main/java/password/pwm/config/value/ValueTypeConverter.java

@@ -43,6 +43,7 @@ import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
+import java.util.Objects;
 import java.util.Set;
 import java.util.stream.Collectors;
 
@@ -74,10 +75,7 @@ public final class ValueTypeConverter
 
     public static String valueToString( final StoredValue value )
     {
-        if ( value == null )
-        {
-            return null;
-        }
+        Objects.requireNonNull( value );
         if ( ( !( value instanceof StringValue ) ) && ( !( value instanceof BooleanValue ) ) )
         {
             throw new IllegalArgumentException( "setting value is type '" + value.getClass().getSimpleName() + "' not readable as string" );

+ 0 - 33
server/src/main/java/password/pwm/config/value/data/FormConfiguration.java

@@ -32,7 +32,6 @@ import password.pwm.error.PwmOperationalException;
 import password.pwm.error.PwmUnrecoverableException;
 import password.pwm.i18n.Display;
 import password.pwm.util.i18n.LocaleHelper;
-import password.pwm.util.java.JsonUtil;
 import password.pwm.util.java.StringUtil;
 
 import java.io.Serializable;
@@ -268,38 +267,6 @@ public class FormConfiguration implements Serializable
         return source == null ? Source.ldap : source;
     }
 
-    public boolean equals( final Object o )
-    {
-        if ( this == o )
-        {
-            return true;
-        }
-        if ( !( o instanceof FormConfiguration ) )
-        {
-            return false;
-        }
-
-        final FormConfiguration parameterConfig = ( FormConfiguration ) o;
-
-        return !( name != null ? !name.equals( parameterConfig.name ) : parameterConfig.name != null );
-    }
-
-    public int hashCode( )
-    {
-        return ( name != null ? name.hashCode() : 0 );
-    }
-
-    public String toString( )
-    {
-        final StringBuilder sb = new StringBuilder();
-
-        sb.append( "FormItem: " );
-        sb.append( JsonUtil.serialize( this ) );
-
-        return sb.toString();
-    }
-
-
     public void checkValue( final DomainConfig config, final String value, final Locale locale )
             throws PwmDataValidationException, PwmUnrecoverableException
     {

+ 150 - 152
server/src/main/java/password/pwm/error/PwmError.java

@@ -28,8 +28,6 @@ import password.pwm.util.java.JavaHelper;
 import java.util.Collections;
 import java.util.Locale;
 import java.util.Set;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
 
 /**
  * @author Jason D. Rivard
@@ -37,132 +35,132 @@ import java.util.stream.Stream;
 public enum PwmError
 {
     PASSWORD_MISSING_CONFIRM(
-            4001, "Password_MissingConfirm", null ),
+            4001, "Password_MissingConfirm", Collections.emptySet() ),
     PASSWORD_MISSING(
-            4002, "Password_Missing", null ),
+            4002, "Password_Missing", Collections.emptySet() ),
     PASSWORD_DOESNOTMATCH(
-            4003, "Password_DoesNotMatch", null ),
+            4003, "Password_DoesNotMatch", Collections.emptySet() ),
     PASSWORD_PREVIOUSLYUSED(
-            4004, "Password_PreviouslyUsed", Collections.singleton( ChaiError.PASSWORD_PREVIOUSLYUSED ) ),
+            4004, "Password_PreviouslyUsed", Set.of( ChaiError.PASSWORD_PREVIOUSLYUSED ) ),
     PASSWORD_BADOLDPASSWORD(
-            4005, "Password_BadOldPassword", Collections.singleton( ChaiError.PASSWORD_BADOLDPASSWORD ) ),
+            4005, "Password_BadOldPassword", Set.of( ChaiError.PASSWORD_BADOLDPASSWORD ) ),
     PASSWORD_BADPASSWORD(
-            4006, "Password_BadPassword", Collections.singleton( ChaiError.PASSWORD_BADPASSWORD ) ),
+            4006, "Password_BadPassword", Set.of( ChaiError.PASSWORD_BADPASSWORD ) ),
     PASSWORD_TOO_SHORT(
-            4007, "Password_TooShort", Collections.singleton( ChaiError.PASSWORD_TOO_SHORT ) ),
+            4007, "Password_TooShort", Set.of( ChaiError.PASSWORD_TOO_SHORT ) ),
     PASSWORD_TOO_LONG(
-            4008, "Password_TooLong", Collections.singleton( ChaiError.PASSWORD_TOO_LONG ) ),
+            4008, "Password_TooLong", Set.of( ChaiError.PASSWORD_TOO_LONG ) ),
     PASSWORD_NOT_ENOUGH_NUM(
-            4009, "Password_NotEnoughNum", Collections.singleton( ChaiError.PASSWORD_NOT_ENOUGH_NUM ) ),
+            4009, "Password_NotEnoughNum", Set.of( ChaiError.PASSWORD_NOT_ENOUGH_NUM ) ),
     PASSWORD_NOT_ENOUGH_ALPHA(
-            4010, "Password_NotEnoughAlpha", Collections.singleton( ChaiError.PASSWORD_NOT_ENOUGH_ALPHA ) ),
+            4010, "Password_NotEnoughAlpha", Set.of( ChaiError.PASSWORD_NOT_ENOUGH_ALPHA ) ),
     PASSWORD_NOT_ENOUGH_SPECIAL(
-            4011, "Password_NotEnoughSpecial", Collections.singleton( ChaiError.PASSWORD_NOT_ENOUGH_SPECIAL ) ),
+            4011, "Password_NotEnoughSpecial", Set.of( ChaiError.PASSWORD_NOT_ENOUGH_SPECIAL ) ),
     PASSWORD_NOT_ENOUGH_LOWER(
-            4012, "Password_NotEnoughLower", Collections.singleton( ChaiError.PASSWORD_NOT_ENOUGH_LOWER ) ),
+            4012, "Password_NotEnoughLower", Set.of( ChaiError.PASSWORD_NOT_ENOUGH_LOWER ) ),
     PASSWORD_NOT_ENOUGH_UPPER(
-            4013, "Password_NotEnoughUpper", Collections.singleton( ChaiError.PASSWORD_NOT_ENOUGH_UPPER ) ),
+            4013, "Password_NotEnoughUpper", Set.of( ChaiError.PASSWORD_NOT_ENOUGH_UPPER ) ),
     PASSWORD_NOT_ENOUGH_UNIQUE(
-            4014, "Password_NotEnoughUnique", Collections.singleton( ChaiError.PASSWORD_NOT_ENOUGH_UNIQUE ) ),
+            4014, "Password_NotEnoughUnique", Set.of( ChaiError.PASSWORD_NOT_ENOUGH_UNIQUE ) ),
     PASSWORD_TOO_MANY_REPEAT(
-            4015, "Password_TooManyRepeat", Collections.singleton( ChaiError.PASSWORD_TOO_MANY_REPEAT ) ),
+            4015, "Password_TooManyRepeat", Set.of( ChaiError.PASSWORD_TOO_MANY_REPEAT ) ),
     PASSWORD_TOO_MANY_NUMERIC(
-            4016, "Password_TooManyNumeric", Stream.of( ChaiError.PASSWORD_TOO_MANY_NUMERIC, ChaiError.PASSWORD_NUMERIC_DISALLOWED ).collect( Collectors.toSet() ) ),
+            4016, "Password_TooManyNumeric", Set.of( ChaiError.PASSWORD_TOO_MANY_NUMERIC, ChaiError.PASSWORD_NUMERIC_DISALLOWED ) ),
     PASSWORD_TOO_MANY_ALPHA(
-            4017, "Password_TooManyAlpha", Collections.singleton( ChaiError.PASSWORD_TOO_MANY_ALPHA ) ),
+            4017, "Password_TooManyAlpha", Set.of( ChaiError.PASSWORD_TOO_MANY_ALPHA ) ),
     PASSWORD_TOO_MANY_LOWER(
-            4018, "Password_TooManyLower", Collections.singleton( ChaiError.PASSWORD_TOO_MANY_LOWER ) ),
+            4018, "Password_TooManyLower", Set.of( ChaiError.PASSWORD_TOO_MANY_LOWER ) ),
     PASSWORD_TOO_MANY_UPPER(
-            4019, "Password_TooManyUpper", Collections.singleton( ChaiError.PASSWORD_TOO_MANY_UPPER ) ),
+            4019, "Password_TooManyUpper", Set.of( ChaiError.PASSWORD_TOO_MANY_UPPER ) ),
     PASSWORD_FIRST_IS_NUMERIC(
-            4020, "Password_FirstIsNumeric", Collections.singleton( ChaiError.PASSWORD_FIRST_IS_NUMERIC ) ),
+            4020, "Password_FirstIsNumeric", Set.of( ChaiError.PASSWORD_FIRST_IS_NUMERIC ) ),
     PASSWORD_LAST_IS_NUMERIC(
-            4021, "Password_LastIsNumeric", Collections.singleton( ChaiError.PASSWORD_LAST_IS_NUMERIC ) ),
+            4021, "Password_LastIsNumeric", Set.of( ChaiError.PASSWORD_LAST_IS_NUMERIC ) ),
     PASSWORD_FIRST_IS_SPECIAL(
-            4022, "Password_FirstIsSpecial", Collections.singleton( ChaiError.PASSWORD_FIRST_IS_SPECIAL ) ),
+            4022, "Password_FirstIsSpecial", Set.of( ChaiError.PASSWORD_FIRST_IS_SPECIAL ) ),
     PASSWORD_LAST_IS_SPECIAL(
-            4023, "Password_LastIsSpecial", Collections.singleton( ChaiError.PASSWORD_LAST_IS_SPECIAL ) ),
+            4023, "Password_LastIsSpecial", Set.of( ChaiError.PASSWORD_LAST_IS_SPECIAL ) ),
     PASSWORD_TOO_MANY_SPECIAL(
-            4024, "Password_TooManyNonAlphaSpecial", Stream.of( ChaiError.PASSWORD_TOO_MANY_SPECIAL, ChaiError.PASSWORD_NUMERIC_DISALLOWED ).collect( Collectors.toSet() ) ),
+            4024, "Password_TooManyNonAlphaSpecial", Set.of( ChaiError.PASSWORD_TOO_MANY_SPECIAL, ChaiError.PASSWORD_NUMERIC_DISALLOWED ) ),
     PASSWORD_INVALID_CHAR(
-            4025, "Password_InvalidChar", Collections.singleton( ChaiError.PASSWORD_INVALID_CHAR ) ),
+            4025, "Password_InvalidChar", Set.of( ChaiError.PASSWORD_INVALID_CHAR ) ),
     PASSWORD_REQUIREDMISSING(
-            4026, "Password_RequiredMissing", null ),
+            4026, "Password_RequiredMissing", Collections.emptySet() ),
     PASSWORD_INWORDLIST(
-            4027, "Password_InWordlist", Collections.singleton( ChaiError.PASSWORD_INWORDLIST ) ),
+            4027, "Password_InWordlist", Set.of( ChaiError.PASSWORD_INWORDLIST ) ),
     PASSWORD_SAMEASOLD(
-            4028, "Password_SameAsOld", null ),
+            4028, "Password_SameAsOld", Collections.emptySet() ),
     PASSWORD_SAMEASATTR(
-            4029, "Password_SameAsAttr", Collections.singleton( ChaiError.PASSWORD_SAMEASATTR ) ),
+            4029, "Password_SameAsAttr", Set.of( ChaiError.PASSWORD_SAMEASATTR ) ),
     PASSWORD_MEETS_RULES(
-            4030, "Password_MeetsRules", null ),
+            4030, "Password_MeetsRules", Collections.emptySet() ),
     PASSWORD_TOO_MANY_OLD_CHARS(
-            4031, "Password_TooManyOldChars", null ),
+            4031, "Password_TooManyOldChars", Collections.emptySet() ),
     PASSWORD_HISTORY_FULL(
-            4032, "Password_HistoryFull", Collections.singleton( ChaiError.PASSWORD_HISTORY_FULL ) ),
+            4032, "Password_HistoryFull", Set.of( ChaiError.PASSWORD_HISTORY_FULL ) ),
     PASSWORD_TOO_SOON(
-            4033, "Password_TooSoon", Collections.singleton( ChaiError.PASSWORD_TOO_SOON ) ),
+            4033, "Password_TooSoon", Set.of( ChaiError.PASSWORD_TOO_SOON ) ),
     PASSWORD_USING_DISALLOWED(
-            4034, "Password_UsingDisallowedValue", null ),
+            4034, "Password_UsingDisallowedValue", Collections.emptySet() ),
     PASSWORD_TOO_WEAK(
-            4035, "Password_TooWeak", null ),
+            4035, "Password_TooWeak", Collections.emptySet() ),
     PASSWORD_TOO_MANY_NONALPHA(
-            4036, "Password_TooManyNonAlpha", null ),
+            4036, "Password_TooManyNonAlpha", Collections.emptySet() ),
     PASSWORD_NOT_ENOUGH_NONALPHA(
-            4037, "Password_NotEnoughNonAlpha", null ),
+            4037, "Password_NotEnoughNonAlpha", Collections.emptySet() ),
     PASSWORD_UNKNOWN_VALIDATION(
-            4038, "Password_UnknownValidation", null ),
+            4038, "Password_UnknownValidation", Collections.emptySet() ),
     PASSWORD_NEW_PASSWORD_REQUIRED(
-            4039, "Password_NewPasswordRequired", Collections.singleton( ChaiError.NEW_PASSWORD_REQUIRED ) ),
+            4039, "Password_NewPasswordRequired", Set.of( ChaiError.NEW_PASSWORD_REQUIRED ) ),
     PASSWORD_EXPIRED(
-            4040, "Password_Expired", Collections.singleton( ChaiError.PASSWORD_EXPIRED ) ),
+            4040, "Password_Expired", Set.of( ChaiError.PASSWORD_EXPIRED ) ),
     PASSWORD_CUSTOM_ERROR(
-            4041, "Password_CustomError", null ),
+            4041, "Password_CustomError", Collections.emptySet() ),
     PASSWORD_NOT_ENOUGH_GROUPS(
-            4042, "Password_NotEnoughGroups", null ),
+            4042, "Password_NotEnoughGroups", Collections.emptySet() ),
     PASSWORD_TOO_MANY_CONSECUTIVE(
-            4043, "Password_TooManyConsecutive", null ),
+            4043, "Password_TooManyConsecutive", Collections.emptySet() ),
 
     ERROR_WRONGPASSWORD(
-            5001, "Error_WrongPassword", Collections.singleton( ChaiError.FAILED_AUTHENTICATION ) ),
+            5001, "Error_WrongPassword", Set.of( ChaiError.FAILED_AUTHENTICATION ) ),
     ERROR_INCORRECT_RESPONSE(
-            5002, "Error_WrongResponse", null ),
+            5002, "Error_WrongResponse", Collections.emptySet() ),
     ERROR_USERAUTHENTICATED(
-            5003, "Error_UserAuthenticated", null ),
+            5003, "Error_UserAuthenticated", Collections.emptySet() ),
     ERROR_AUTHENTICATION_REQUIRED(
-            5004, "Error_AuthenticationRequired", null ),
+            5004, "Error_AuthenticationRequired", Collections.emptySet() ),
     ERROR_RESPONSES_NORESPONSES(
-            5006, "Error_Response_NoResponse", null ),
+            5006, "Error_Response_NoResponse", Collections.emptySet() ),
     ERROR_RESPONSE_WORDLIST(
-            5007, "Error_Response_Wordlist", null ),
+            5007, "Error_Response_Wordlist", Collections.emptySet() ),
     ERROR_RESPONSE_TOO_SHORT(
-            5008, "Error_Response_TooShort", null ),
+            5008, "Error_Response_TooShort", Collections.emptySet() ),
     ERROR_RESPONSE_TOO_LONG(
-            5009, "Error_Response_TooLong", null ),
+            5009, "Error_Response_TooLong", Collections.emptySet() ),
     ERROR_RESPONSE_DUPLICATE(
-            5010, "Error_Response_Duplicate", null ),
+            5010, "Error_Response_Duplicate", Collections.emptySet() ),
     ERROR_CHALLENGE_DUPLICATE(
-            5011, "Error_Challenge_Duplicate", null ),
+            5011, "Error_Challenge_Duplicate", Collections.emptySet() ),
     ERROR_MISSING_CHALLENGE_TEXT(
-            5012, "Error_Missing_Challenge_Text", null ),
+            5012, "Error_Missing_Challenge_Text", Collections.emptySet() ),
     ERROR_MISSING_PARAMETER(
-            5013, "Error_MissingParameter", null ),
+            5013, "Error_MissingParameter", Collections.emptySet() ),
     ERROR_INTERNAL(
             5015, "Error_Internal", null, ErrorFlag.ForceLogout ),
     ERROR_CANT_MATCH_USER(
-            5016, "Error_CantMatchUser", null ),
+            5016, "Error_CantMatchUser", Collections.emptySet() ),
     ERROR_DIRECTORY_UNAVAILABLE(
             5017, "Error_DirectoryUnavailable", null, ErrorFlag.ForceLogout ),
     ERROR_ACTIVATION_VALIDATIONFAIL(
-            5018, "Error_ActivationValidationFailed", null ),
+            5018, "Error_ActivationValidationFailed", Collections.emptySet() ),
     ERROR_SERVICE_NOT_AVAILABLE(
-            5019, "Error_ServiceNotAvailable", null ),
+            5019, "Error_ServiceNotAvailable", Collections.emptySet() ),
     ERROR_USER_MISMATCH(
-            5020, "Error_UserMisMatch", null ),
+            5020, "Error_UserMisMatch", Collections.emptySet() ),
     ERROR_ACTIVATE_NO_PERMISSION(
-            5021, "Error_ActivateUserNoQueryMatch", null ),
+            5021, "Error_ActivateUserNoQueryMatch", Collections.emptySet() ),
     ERROR_NO_CHALLENGES(
-            5022, "Error_NoChallenges", null ),
+            5022, "Error_NoChallenges", Collections.emptySet() ),
     ERROR_INTRUDER_USER(
             5023, "Error_UserIntruder", null, ErrorFlag.Permanent ),
     ERROR_INTRUDER_ADDRESS(
@@ -170,186 +168,186 @@ public enum PwmError
     ERROR_INTRUDER_SESSION(
             5025, "Error_SessionIntruder", null, ErrorFlag.Permanent ),
     ERROR_BAD_SESSION_PASSWORD(
-            5026, "Error_BadSessionPassword", null ),
+            5026, "Error_BadSessionPassword", Collections.emptySet() ),
     ERROR_UNAUTHORIZED(
             5027, "Error_Unauthorized", null, ErrorFlag.Permanent ),
     ERROR_BAD_SESSION(
-            5028, "Error_BadSession", null ),
+            5028, "Error_BadSession", Collections.emptySet() ),
     ERROR_MISSING_REQUIRED_RESPONSE(
-            5029, "Error_MissingRequiredResponse", null ),
+            5029, "Error_MissingRequiredResponse", Collections.emptySet() ),
     ERROR_MISSING_RANDOM_RESPONSE(
-            5030, "Error_MissingRandomResponse", null ),
+            5030, "Error_MissingRandomResponse", Collections.emptySet() ),
     ERROR_BAD_CAPTCHA_RESPONSE(
-            5031, "Error_BadCaptchaResponse", null ),
+            5031, "Error_BadCaptchaResponse", Collections.emptySet() ),
     ERROR_CAPTCHA_API_ERROR(
-            5032, "Error_CaptchaAPIError", null ),
+            5032, "Error_CaptchaAPIError", Collections.emptySet() ),
     ERROR_INVALID_CONFIG(
-            5033, "Error_InvalidConfig", null ),
+            5033, "Error_InvalidConfig", Collections.emptySet() ),
     ERROR_INVALID_FORMID(
-            5034, "Error_InvalidFormID", null ),
+            5034, "Error_InvalidFormID", Collections.emptySet() ),
     ERROR_INCORRECT_REQ_SEQUENCE(
-            5035, "Error_IncorrectRequestSequence", null ),
+            5035, "Error_IncorrectRequestSequence", Collections.emptySet() ),
     ERROR_TOKEN_MISSING_CONTACT(
-            5036, "Error_TokenMissingContact", null ),
+            5036, "Error_TokenMissingContact", Collections.emptySet() ),
     ERROR_TOKEN_INCORRECT(
-            5037, "Error_TokenIncorrect", null ),
+            5037, "Error_TokenIncorrect", Collections.emptySet() ),
     ERROR_BAD_CURRENT_PASSWORD(
-            5038, "Error_BadCurrentPassword", null ),
+            5038, "Error_BadCurrentPassword", Collections.emptySet() ),
     ERROR_CLOSING(
-            5039, "Error_Closing", null ),
+            5039, "Error_Closing", Collections.emptySet() ),
     ERROR_MISSING_GUID(
-            5040, "Error_Missing_GUID", null ),
+            5040, "Error_Missing_GUID", Collections.emptySet() ),
     ERROR_TOKEN_EXPIRED(
-            5041, "Error_TokenExpired", null ),
+            5041, "Error_TokenExpired", Collections.emptySet() ),
     ERROR_MULTI_USERNAME(
-            5042, "Error_Multi_Username", null ),
+            5042, "Error_Multi_Username", Collections.emptySet() ),
     ERROR_ORIG_ADMIN_ONLY(
-            5043, "Error_Orig_Admin_Only", null ),
+            5043, "Error_Orig_Admin_Only", Collections.emptySet() ),
     ERROR_SECURE_REQUEST_REQUIRED(
-            5044, "Error_SecureRequestRequired", null ),
+            5044, "Error_SecureRequestRequired", Collections.emptySet() ),
     ERROR_WRITING_RESPONSES(
-            5045, "Error_Writing_Responses", null ),
+            5045, "Error_Writing_Responses", Collections.emptySet() ),
     ERROR_UNLOCK_FAILURE(
-            5046, "Error_Unlock_Failure", null ),
+            5046, "Error_Unlock_Failure", Collections.emptySet() ),
     ERROR_UPDATE_ATTRS_FAILURE(
-            5047, "Error_Update_Attrs_Failure", null ),
+            5047, "Error_Update_Attrs_Failure", Collections.emptySet() ),
     ERROR_ACTIVATION_FAILURE(
-            5048, "Error_Activation_Failure", null ),
+            5048, "Error_Activation_Failure", Collections.emptySet() ),
     ERROR_NEW_USER_FAILURE(
-            5049, "Error_NewUser_Failure", null ),
+            5049, "Error_NewUser_Failure", Collections.emptySet() ),
     ERROR_ACTIVATION(
-            5050, "Error_Activation", null ),
+            5050, "Error_Activation", Collections.emptySet() ),
     ERROR_DB_UNAVAILABLE(
-            5051, "Error_DB_Unavailable", null ),
+            5051, "Error_DB_Unavailable", Collections.emptySet() ),
     ERROR_LOCALDB_UNAVAILABLE(
-            5052, "Error_LocalDB_Unavailable", null ),
+            5052, "Error_LocalDB_Unavailable", Collections.emptySet() ),
     ERROR_APP_UNAVAILABLE(
-            5053, "Error_App_Unavailable", null ),
+            5053, "Error_App_Unavailable", Collections.emptySet() ),
     ERROR_UNREACHABLE_CLOUD_SERVICE(
-            5054, "Error_UnreachableCloudService", null ),
+            5054, "Error_UnreachableCloudService", Collections.emptySet() ),
     ERROR_INVALID_SECURITY_KEY(
-            5055, "Error_InvalidSecurityKey", null ),
+            5055, "Error_InvalidSecurityKey", Collections.emptySet() ),
     ERROR_CLEARING_RESPONSES(
-            5056, "Error_Clearing_Responses", null ),
+            5056, "Error_Clearing_Responses", Collections.emptySet() ),
     ERROR_SERVICE_UNREACHABLE(
-            5057, "Error_ServiceUnreachable", null ),
+            5057, "Error_ServiceUnreachable", Collections.emptySet() ),
     ERROR_CHALLENGE_IN_RESPONSE(
-            5058, "Error_ChallengeInResponse", null ),
+            5058, "Error_ChallengeInResponse", Collections.emptySet() ),
     ERROR_CERTIFICATE_ERROR(
-            5059, "Error_CertificateError", null ),
+            5059, "Error_CertificateError", Collections.emptySet() ),
     ERROR_SYSLOG_WRITE_ERROR(
-            5060, "Error_SyslogWriteError", null ),
+            5060, "Error_SyslogWriteError", Collections.emptySet() ),
     ERROR_TOO_MANY_THREADS(
-            5061, "Error_TooManyThreads", null ),
+            5061, "Error_TooManyThreads", Collections.emptySet() ),
     ERROR_PASSWORD_REQUIRED(
-            5062, "Error_PasswordRequired", null ),
+            5062, "Error_PasswordRequired", Collections.emptySet() ),
     ERROR_SECURITY_VIOLATION(
-            5063, "Error_SecurityViolation", null ),
+            5063, "Error_SecurityViolation", Collections.emptySet() ),
     ERROR_TRIAL_VIOLATION(
-            5064, "Error_TrialViolation", null ),
+            5064, "Error_TrialViolation", Collections.emptySet() ),
     ERROR_ACCOUNT_DISABLED(
-            5065, "Error_AccountDisabled", Collections.singleton( ChaiError.ACCOUNT_DISABLED ) ),
+            5065, "Error_AccountDisabled", Set.of( ChaiError.ACCOUNT_DISABLED ) ),
     ERROR_ACCOUNT_EXPIRED(
-            5066, "Error_AccountExpired", Collections.singleton( ChaiError.ACCOUNT_EXPIRED ) ),
+            5066, "Error_AccountExpired", Set.of( ChaiError.ACCOUNT_EXPIRED ) ),
     ERROR_NO_OTP_CONFIGURATION(
-            5087, "Error_NoOtpConfiguration", null ),
+            5087, "Error_NoOtpConfiguration", Collections.emptySet() ),
     ERROR_INCORRECT_OTP_TOKEN(
-            5088, "Error_WrongOtpToken", null ),
+            5088, "Error_WrongOtpToken", Collections.emptySet() ),
     ERROR_WRITING_OTP_SECRET(
-            5086, "Error_Writing_Otp_Secret", null ),
+            5086, "Error_Writing_Otp_Secret", Collections.emptySet() ),
     ERROR_INTRUDER_ATTR_SEARCH(
-            5067, "Error_AttrIntruder", null, ErrorFlag.Permanent ),
+            5067, "Error_AttrIntruder", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_AUDIT_WRITE(
-            5068, "Error_AuditWrite", null ),
+            5068, "Error_AuditWrite", Collections.emptySet() ),
     ERROR_INTRUDER_LDAP(
-            5069, "Error_LdapIntruder", Collections.singleton( ChaiError.INTRUDER_LOCKOUT ), ErrorFlag.Permanent ),
+            5069, "Error_LdapIntruder", Set.of( ChaiError.INTRUDER_LOCKOUT ), ErrorFlag.Permanent ),
     ERROR_NO_LDAP_CONNECTION(
-            5070, "Error_NoLdapConnection", null, ErrorFlag.Permanent ),
+            5070, "Error_NoLdapConnection", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_OAUTH_ERROR(
-            5071, "Error_OAuthError", null, ErrorFlag.Permanent ),
+            5071, "Error_OAuthError", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_REPORTING_ERROR(
-            5072, "Error_ReportingError", null, ErrorFlag.Permanent ),
+            5072, "Error_ReportingError", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_INTRUDER_TOKEN_DEST(
-            5073, "Error_TokenDestIntruder", null, ErrorFlag.Permanent ),
+            5073, "Error_TokenDestIntruder", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_OTP_RECOVERY_USED(
-            5074, "Error_OtpRecoveryUsed", null, ErrorFlag.Permanent ),
+            5074, "Error_OtpRecoveryUsed", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_REDIRECT_ILLEGAL(
-            5075, "Error_RedirectIllegal", null, ErrorFlag.Permanent ),
+            5075, "Error_RedirectIllegal", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_CRYPT_ERROR(
-            5076, "Error_CryptError", null, ErrorFlag.Permanent ),
+            5076, "Error_CryptError", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_SMS_SEND_ERROR(
-            5078, "Error_SmsSendError", null, ErrorFlag.Permanent ),
+            5078, "Error_SmsSendError", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_LDAP_DATA_ERROR(
-            5079, "Error_LdapDataError", null, ErrorFlag.Permanent ),
+            5079, "Error_LdapDataError", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_MACRO_PARSE_ERROR(
-            5080, "Error_MacroParseError", null, ErrorFlag.Permanent ),
+            5080, "Error_MacroParseError", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_NO_PROFILE_ASSIGNED(
-            5081, "Error_NoProfileAssigned", null, ErrorFlag.Permanent ),
+            5081, "Error_NoProfileAssigned", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_STARTUP_ERROR(
-            5082, "Error_StartupError", null, ErrorFlag.Permanent ),
+            5082, "Error_StartupError", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_ENVIRONMENT_ERROR(
-            5083, "Error_EnvironmentError", null, ErrorFlag.Permanent ),
+            5083, "Error_EnvironmentError", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_APPLICATION_NOT_RUNNING(
-            5084, "Error_ApplicationNotRunning", null, ErrorFlag.Permanent ),
+            5084, "Error_ApplicationNotRunning", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_EMAIL_SEND_FAILURE(
-            5085, "Error_EmailSendFailure", null, ErrorFlag.Permanent ),
+            5085, "Error_EmailSendFailure", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_PASSWORD_ONLY_BAD(
-            5089, "Error_PasswordOnlyBad", null ),
+            5089, "Error_PasswordOnlyBad", Collections.emptySet() ),
     ERROR_RECOVERY_SEQUENCE_INCOMPLETE(
-            5090, "Error_RecoverySequenceIncomplete", null ),
+            5090, "Error_RecoverySequenceIncomplete", Collections.emptySet() ),
     ERROR_FILE_TYPE_INCORRECT(
-            5091, "Error_FileTypeIncorrect", null ),
+            5091, "Error_FileTypeIncorrect", Collections.emptySet() ),
     ERROR_FILE_TOO_LARGE(
-            5092, "Error_FileTooLarge", null ),
+            5092, "Error_FileTooLarge", Collections.emptySet() ),
     ERROR_NODE_SERVICE_ERROR(
-            5093, "Error_NodeServiceError", null ),
+            5093, "Error_NodeServiceError", Collections.emptySet() ),
     ERROR_WORDLIST_IMPORT_ERROR(
-            5094, "Error_WordlistImportError", null ),
+            5094, "Error_WordlistImportError", Collections.emptySet() ),
     ERROR_PWNOTIFY_SERVICE_ERROR(
-            5095, "Error_PwNotifyServiceError", null ),
+            5095, "Error_PwNotifyServiceError", Collections.emptySet() ),
 
     ERROR_REMOTE_ERROR_VALUE(
-            6000, "Error_RemoteErrorValue", null, ErrorFlag.Permanent ),
+            6000, "Error_RemoteErrorValue", Collections.emptySet(), ErrorFlag.Permanent ),
     ERROR_TELEMETRY_SEND_ERROR(
-            6001, "Error_TelemetrySendError", null ),
+            6001, "Error_TelemetrySendError", Collections.emptySet() ),
 
     ERROR_FIELD_REQUIRED(
-            5100, "Error_FieldRequired", null ),
+            5100, "Error_FieldRequired", Collections.emptySet() ),
     ERROR_FIELD_NOT_A_NUMBER(
-            5101, "Error_FieldNotANumber", null ),
+            5101, "Error_FieldNotANumber", Collections.emptySet() ),
     ERROR_FIELD_INVALID_EMAIL(
-            5102, "Error_FieldInvalidEmail", null ),
+            5102, "Error_FieldInvalidEmail", Collections.emptySet() ),
     ERROR_FIELD_TOO_SHORT(
-            5103, "Error_FieldTooShort", null ),
+            5103, "Error_FieldTooShort", Collections.emptySet() ),
     ERROR_FIELD_TOO_LONG(
-            5104, "Error_FieldTooLong", null ),
+            5104, "Error_FieldTooLong", Collections.emptySet() ),
     ERROR_FIELD_DUPLICATE(
-            5105, "Error_FieldDuplicate", null ),
+            5105, "Error_FieldDuplicate", Collections.emptySet() ),
     ERROR_FIELD_BAD_CONFIRM(
-            5106, "Error_FieldBadConfirm", null ),
+            5106, "Error_FieldBadConfirm", Collections.emptySet() ),
     ERROR_FIELD_REGEX_NOMATCH(
-            5107, "Error_FieldRegexNoMatch", null ),
+            5107, "Error_FieldRegexNoMatch", Collections.emptySet() ),
 
     CONFIG_UPLOAD_SUCCESS(
-            5200, "Error_ConfigUploadSuccess", null ),
+            5200, "Error_ConfigUploadSuccess", Collections.emptySet() ),
     CONFIG_UPLOAD_FAILURE(
-            5201, "Error_ConfigUploadFailure", null ),
+            5201, "Error_ConfigUploadFailure", Collections.emptySet() ),
     CONFIG_SAVE_SUCCESS(
-            5202, "Error_ConfigSaveSuccess", null ),
+            5202, "Error_ConfigSaveSuccess", Collections.emptySet() ),
     CONFIG_FORMAT_ERROR(
-            5203, "Error_ConfigFormatError", null ),
+            5203, "Error_ConfigFormatError", Collections.emptySet() ),
     CONFIG_LDAP_FAILURE(
-            5204, "Error_ConfigLdapFailure", null ),
+            5204, "Error_ConfigLdapFailure", Collections.emptySet() ),
     CONFIG_LDAP_SUCCESS(
-            5205, "Error_ConfigLdapSuccess", null ),
+            5205, "Error_ConfigLdapSuccess", Collections.emptySet() ),
 
     ERROR_HTTP_404(
-            5300, "Error_HTTP_404", null ),
+            5300, "Error_HTTP_404", Collections.emptySet() ),
 
     ERROR_REST_INVOCATION_ERROR(
-            7000, "Error_RestInvocationError", null ),
+            7000, "Error_RestInvocationError", Collections.emptySet() ),
     ERROR_REST_PARAMETER_CONFLICT(
-            7001, "Error_RestParameterConflict", null ),
+            7001, "Error_RestParameterConflict", Collections.emptySet() ),
 
     /* End of list*/;
 
@@ -361,7 +359,7 @@ public enum PwmError
 
     private final int errorCode;
     private final String resourceKey;
-    private final ChaiError[] chaiErrorCode;
+    private final Set<ChaiError> chaiErrorCode;
     private final boolean errorIsPermanent;
     private final boolean forceLogout;
 
@@ -376,7 +374,7 @@ public enum PwmError
         this.errorCode = errorCode;
         this.errorIsPermanent = JavaHelper.enumArrayContainsValue( errorFlags, ErrorFlag.Permanent );
         this.forceLogout = JavaHelper.enumArrayContainsValue( errorFlags, ErrorFlag.ForceLogout );
-        this.chaiErrorCode = chaiErrorCode == null ? null : chaiErrorCode.toArray( new ChaiError[0] );
+        this.chaiErrorCode = chaiErrorCode == null ? Collections.emptySet() : Set.copyOf( chaiErrorCode );
 
     }
 

+ 7 - 5
server/src/main/java/password/pwm/health/CertificateChecker.java

@@ -129,7 +129,9 @@ public class CertificateChecker implements HealthChecker
             final List<X509Certificate> certificates
     )
     {
-        final long warnDurationMs = 1000 * Long.parseLong( domainConfig.readAppProperty( AppProperty.HEALTH_CERTIFICATE_WARN_SECONDS ) );
+        final TimeDuration warnDuration = TimeDuration.of(
+                Long.parseLong( domainConfig.readAppProperty( AppProperty.HEALTH_CERTIFICATE_WARN_SECONDS ) ),
+                TimeDuration.Unit.SECONDS );
 
         if ( certificates != null )
         {
@@ -138,7 +140,7 @@ public class CertificateChecker implements HealthChecker
             {
                 try
                 {
-                    checkCertificate( certificate, warnDurationMs );
+                    checkCertificate( certificate, warnDuration );
                     return Collections.emptyList();
                 }
                 catch ( final PwmOperationalException e )
@@ -148,7 +150,7 @@ public class CertificateChecker implements HealthChecker
                             setting.toMenuLocationDebug( profileID, PwmConstants.DEFAULT_LOCALE ),
                             errorDetail
                     );
-                    return Collections.singletonList( record );
+                    returnList.add( record );
                 }
             }
             return Collections.unmodifiableList( returnList );
@@ -156,7 +158,7 @@ public class CertificateChecker implements HealthChecker
         return Collections.emptyList();
     }
 
-    public static void checkCertificate( final X509Certificate certificate, final long warnDurationMs )
+    public static void checkCertificate( final X509Certificate certificate, final TimeDuration warnDuration )
             throws PwmOperationalException
     {
         if ( certificate == null )
@@ -185,7 +187,7 @@ public class CertificateChecker implements HealthChecker
 
         final Instant expireDate = certificate.getNotAfter().toInstant();
         final TimeDuration durationUntilExpire = TimeDuration.fromCurrent( expireDate );
-        if ( durationUntilExpire.isShorterThan( warnDurationMs ) )
+        if ( durationUntilExpire.isShorterThan( warnDuration ) )
         {
             final StringBuilder errorMsg = new StringBuilder();
             errorMsg.append( "certificate for subject " );

+ 3 - 3
server/src/main/java/password/pwm/health/LDAPHealthChecker.java

@@ -1172,11 +1172,11 @@ public class LDAPHealthChecker implements HealthChecker
     {
         final PwmApplication tempApplication = PwmApplication.createPwmApplication( pwmDomain.getPwmEnvironment().makeRuntimeInstance( config.getAppConfig() ) );
         final LDAPHealthChecker ldapHealthChecker = new LDAPHealthChecker();
-        final List<HealthRecord> profileRecords = new ArrayList<>();
 
         final LdapProfile ldapProfile = config.getLdapProfiles().get( profileID );
-        profileRecords.addAll( ldapHealthChecker.checkBasicLdapConnectivity( tempApplication.getDefaultDomain(), config, ldapProfile,
-                testContextless ) );
+        final List<HealthRecord> profileRecords = new ArrayList<>(
+                ldapHealthChecker.checkBasicLdapConnectivity( tempApplication.getDefaultDomain(), config, ldapProfile, testContextless ) );
+
         if ( fullTest )
         {
             profileRecords.addAll( ldapHealthChecker.checkLdapServerUrls( pwmDomain, config, ldapProfile ) );

+ 7 - 16
server/src/main/java/password/pwm/http/PwmHttpRequestWrapper.java

@@ -427,15 +427,10 @@ public class PwmHttpRequestWrapper
     public String debugHttpHeaders( )
     {
         final String lineSeparator = "\n";
-        final StringBuilder sb = new StringBuilder();
-
-
-        sb.append( "http" ).append( getHttpServletRequest().isSecure() ? "s " : " non-" ).append( "secure request headers: " );
-        sb.append( lineSeparator );
 
-        sb.append( debugOutputMapToString( readHeaderValuesMap(), HTTP_HEADER_DEBUG_STRIP_VALUES ) );
-
-        return sb.toString();
+        return "http" + ( getHttpServletRequest().isSecure() ? "s " : " non-" ) + "secure request headers: "
+                + lineSeparator
+                + debugOutputMapToString( readHeaderValuesMap(), HTTP_HEADER_DEBUG_STRIP_VALUES );
     }
 
     private static String debugOutputMapToString(
@@ -452,14 +447,10 @@ public class PwmHttpRequestWrapper
             for ( final String paramValue : entry.getValue() )
             {
                 sb.append( "  " ).append( paramName ).append( "=" );
-                boolean strip = false;
-                for ( final String stripValue : stripValues )
-                {
-                    if ( paramName.toLowerCase().contains( stripValue.toLowerCase() ) )
-                    {
-                        strip = true;
-                    }
-                }
+
+                final boolean strip = stripValues.stream()
+                        .anyMatch( ( stripValue ) -> paramName.toLowerCase().contains( stripValue.toLowerCase() ) );
+
                 if ( strip )
                 {
                     sb.append( PwmConstants.LOG_REMOVED_VALUE_REPLACEMENT );

+ 3 - 3
server/src/main/java/password/pwm/http/auth/HttpAuthenticationUtilities.java

@@ -60,13 +60,13 @@ public abstract class HttpAuthenticationUtilities
                 try
                 {
                     final String className = authenticationMethod.getClassName();
-                    final Class clazz = Class.forName( className );
-                    final Object newInstance = clazz.newInstance();
+                    final Class<?> clazz = Class.forName( className );
+                    final Object newInstance = clazz.getDeclaredConstructor().newInstance();
                     filterAuthenticationProvider = ( PwmHttpFilterAuthenticationProvider ) newInstance;
                 }
                 catch ( final Exception e )
                 {
-                    LOGGER.trace( () -> "could not load authentication class '" + authenticationMethod + "', will ignore" );
+                    LOGGER.trace( () -> "could not load authentication class '" + authenticationMethod + "', will ignore (error: " + e.getMessage() + ")" );
                     IGNORED_AUTH_METHODS.add( authenticationMethod );
                 }
 

+ 4 - 9
server/src/main/java/password/pwm/http/servlet/GuestRegistrationServlet.java

@@ -316,7 +316,7 @@ public class GuestRegistrationServlet extends AbstractPwmServlet
         final DomainConfig config = pwmDomain.getConfig();
 
         final String adminDnAttribute = config.readSettingAsString( PwmSetting.GUEST_ADMIN_ATTRIBUTE );
-        final Boolean origAdminOnly = config.readSettingAsBoolean( PwmSetting.GUEST_EDIT_ORIG_ADMIN_ONLY );
+        final boolean origAdminOnly = config.readSettingAsBoolean( PwmSetting.GUEST_EDIT_ORIG_ADMIN_ONLY );
 
         final String usernameParam = pwmRequest.readParameterAsString( "username" );
         final GuestRegistrationBean guBean = pwmDomain.getSessionStateService().getBean( pwmRequest, GuestRegistrationBean.class );
@@ -665,14 +665,8 @@ public class GuestRegistrationServlet extends AbstractPwmServlet
         final List<FormConfiguration> formItems = domainConfig.readSettingAsForm( PwmSetting.GUEST_FORM );
 
         {
-            boolean namingIsInForm = false;
-            for ( final FormConfiguration formItem : formItems )
-            {
-                if ( namingAttribute.equalsIgnoreCase( formItem.getName() ) )
-                {
-                    namingIsInForm = true;
-                }
-            }
+            final boolean namingIsInForm = formItems.stream()
+                    .anyMatch( ( formItem ) ->  namingAttribute.equalsIgnoreCase( formItem.getName() ) );
 
             if ( !namingIsInForm )
             {
@@ -687,6 +681,7 @@ public class GuestRegistrationServlet extends AbstractPwmServlet
         }
     }
 
+
     private void calculateFutureDateFlags( final PwmRequest pwmRequest, final GuestRegistrationBean guestRegistrationBean )
     {
         final PwmDateFormat dateFormat = PwmDateFormat.newPwmDateFormat( "yyyy-MM-dd" );

+ 2 - 3
server/src/main/java/password/pwm/http/servlet/ShortcutServlet.java

@@ -136,8 +136,7 @@ public class ShortcutServlet extends AbstractPwmServlet
     private void forwardToJsp( final PwmRequest pwmRequest, final ShortcutsBean shortcutsBean )
             throws ServletException, PwmUnrecoverableException, IOException
     {
-        final ArrayList<ShortcutItem> shortcutItems = new ArrayList<>();
-        shortcutItems.addAll( shortcutsBean.getVisibleItems().values() );
+        final ArrayList<ShortcutItem> shortcutItems = new ArrayList<>( shortcutsBean.getVisibleItems().values() );
         pwmRequest.setAttribute( PwmRequestAttribute.ShortcutItems, shortcutItems );
         pwmRequest.forwardToJsp( JspUrl.SHORTCUT );
     }
@@ -148,7 +147,7 @@ public class ShortcutServlet extends AbstractPwmServlet
     private static Map<String, ShortcutItem> figureVisibleShortcuts(
             final PwmRequest pwmRequest
     )
-            throws PwmUnrecoverableException, ChaiUnavailableException
+            throws PwmUnrecoverableException
     {
         final Collection<String> configValues = pwmRequest.getConfig().readSettingAsLocalizedStringArray( PwmSetting.SHORTCUT_ITEMS, pwmRequest.getLocale() );
 

+ 7 - 2
server/src/main/java/password/pwm/http/servlet/configeditor/ConfigEditorServlet.java

@@ -653,7 +653,12 @@ public class ConfigEditorServlet extends ControlledPwmServlet
         LOGGER.debug( pwmRequest, () -> "beginning restEmailHealthCheck" );
 
         final Map<String, String> params = pwmRequest.readBodyAsJsonStringMap();
-        final EmailItemBean testEmailItem = new EmailItemBean( params.get( "to" ), params.get( "from" ), params.get( "subject" ), params.get( "body" ), null );
+        final EmailItemBean testEmailItem = new EmailItemBean(
+                params.get( "to" ),
+                params.get( "from" ),
+                params.get( "subject" ),
+                params.get( "body" ),
+                null );
 
         final StringBuilder output = new StringBuilder();
         output.append( "beginning EMail send process:\n" );
@@ -675,7 +680,7 @@ public class ConfigEditorServlet extends ControlledPwmServlet
                 }
                 catch ( final PwmException e )
                 {
-                    output.append( "error: " + StringUtil.escapeHtml( JavaHelper.readHostileExceptionMessage( e ) ) );
+                    output.append( "error: " ).append( StringUtil.escapeHtml( JavaHelper.readHostileExceptionMessage( e ) ) );
                 }
             }
         }

+ 1 - 1
server/src/main/java/password/pwm/http/servlet/configguide/GuideStep.java

@@ -104,7 +104,7 @@ public enum GuideStep
             final VisibilityCheck visibilityCheckImpl;
             try
             {
-                visibilityCheckImpl = visibilityCheckClass.newInstance();
+                visibilityCheckImpl = visibilityCheckClass.getDeclaredConstructor().newInstance();
                 return visibilityCheckImpl.visible( configGuideBean );
             }
             catch ( final ReflectiveOperationException e )

+ 0 - 2
server/src/main/java/password/pwm/http/servlet/configmanager/ConfigManagerLoginServlet.java

@@ -147,7 +147,6 @@ public class ConfigManagerLoginServlet extends AbstractPwmServlet
                 LOGGER.trace( pwmRequest, () -> "valid configuration password accepted" );
                 updateLoginHistory( pwmRequest, pwmRequest.getUserInfoIfLoggedIn(), true );
                 processLoginSuccess( pwmRequest, true );
-                return;
             }
             else
             {
@@ -158,7 +157,6 @@ public class ConfigManagerLoginServlet extends AbstractPwmServlet
                 updateLoginHistory( pwmRequest, pwmRequest.getUserInfoIfLoggedIn(), false );
                 setLastError( pwmRequest, errorInformation );
                 forwardToJsp( pwmRequest );
-                return;
             }
         }
     }

+ 2 - 2
server/src/main/java/password/pwm/http/servlet/forgottenpw/ForgottenPasswordUtil.java

@@ -545,11 +545,11 @@ public class ForgottenPasswordUtil
         forgottenPasswordBean.setUserIdentity( null );
         forgottenPasswordBean.setPresentableChallengeSet( null );
 
-        final List<Challenge> challengeList = new ArrayList<>( );
+        final List<Challenge> challengeList;
         {
             final String firstProfile = pwmRequestContext.getConfig().getChallengeProfileIDs().iterator().next();
             final ChallengeSet challengeSet = pwmRequestContext.getConfig().getChallengeProfile( firstProfile, PwmConstants.DEFAULT_LOCALE ).getChallengeSet();
-            challengeList.addAll( challengeSet.getRequiredChallenges() );
+            challengeList = new ArrayList<>( challengeSet.getRequiredChallenges() );
             for ( int i = 0; i < challengeSet.getMinRandomRequired(); i++ )
             {
                 challengeList.add( challengeSet.getRandomChallenges().get( i ) );

+ 14 - 0
server/src/main/java/password/pwm/http/servlet/helpdesk/HelpdeskServlet.java

@@ -218,6 +218,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
         return ProcessStatus.Continue;
     }
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "clientData" )
     private ProcessStatus restClientData( final PwmRequest pwmRequest )
             throws IOException, PwmUnrecoverableException
@@ -231,6 +232,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
         return ProcessStatus.Halt;
     }
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "executeAction" )
     private ProcessStatus processExecuteActionRequest(
             final PwmRequest pwmRequest
@@ -312,6 +314,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
         }
     }
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "deleteUser" )
     private ProcessStatus restDeleteUserRequest(
             final PwmRequest pwmRequest
@@ -399,6 +402,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
         return ProcessStatus.Halt;
     }
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "detail" )
     private ProcessStatus processDetailRequest(
             final PwmRequest pwmRequest
@@ -414,6 +418,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
         return ProcessStatus.Halt;
     }
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "card" )
     private ProcessStatus processCardRequest(
             final PwmRequest pwmRequest
@@ -432,6 +437,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
         return ProcessStatus.Halt;
     }
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "search" )
     private ProcessStatus restSearchRequest(
             final PwmRequest pwmRequest
@@ -569,6 +575,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
                 .build();
     }
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "unlockIntruder" )
     private ProcessStatus restUnlockIntruder(
             final PwmRequest pwmRequest
@@ -643,6 +650,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
         return ProcessStatus.Halt;
     }
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "validateOtpCode" )
     private ProcessStatus restValidateOtpCodeRequest(
             final PwmRequest pwmRequest
@@ -728,6 +736,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
         return ProcessStatus.Halt;
     }
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "sendVerificationToken" )
     private ProcessStatus restSendVerificationTokenRequest(
             final PwmRequest pwmRequest
@@ -829,6 +838,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
         return ProcessStatus.Halt;
     }
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "verifyVerificationToken" )
     private ProcessStatus restVerifyVerificationTokenRequest(
             final PwmRequest pwmRequest
@@ -904,6 +914,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
         return outputVerificationResponseBean( pwmRequest, passed, verificationStateBean );
     }
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "clearOtpSecret" )
     private ProcessStatus restClearOtpSecret(
             final PwmRequest pwmRequest
@@ -961,6 +972,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
     }
 
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "checkVerification" )
     private ProcessStatus restCheckVerification( final PwmRequest pwmRequest )
             throws IOException, PwmUnrecoverableException, ServletException
@@ -985,6 +997,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
     }
 
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "showVerifications" )
     private ProcessStatus restShowVerifications( final PwmRequest pwmRequest )
             throws IOException, PwmUnrecoverableException, ServletException, ChaiUnavailableException
@@ -1006,6 +1019,7 @@ public class HelpdeskServlet extends ControlledPwmServlet
         return ProcessStatus.Halt;
     }
 
+    @SuppressWarnings( "UnusedMethod" )
     @ActionHandler( action = "validateAttributes" )
     private ProcessStatus restValidateAttributes( final PwmRequest pwmRequest )
             throws IOException, PwmUnrecoverableException, ServletException

+ 2 - 2
server/src/main/java/password/pwm/http/state/LocalSessionBeanImpl.java

@@ -44,8 +44,8 @@ class LocalSessionBeanImpl implements SessionBeanProvider
         {
             try
             {
-                final Object newBean = SessionStateService.newBean( null, theClass );
-                sessionBeans.put( theClass, ( PwmSessionBean ) newBean );
+                final PwmSessionBean newBean = SessionStateService.newBean( null, theClass );
+                sessionBeans.put( theClass, newBean );
             }
             catch ( final Exception e )
             {

+ 1 - 1
server/src/main/java/password/pwm/ldap/LdapBrowser.java

@@ -213,7 +213,7 @@ public class LdapBrowser
                 if ( attributeResults.containsKey( "subordinateCount" ) )
                 {
                     // only eDir actually returns this operational attribute
-                    final Integer subordinateCount = Integer.parseInt( attributeResults.get( "subordinateCount" ).iterator().next() );
+                    final int subordinateCount = Integer.parseInt( attributeResults.get( "subordinateCount" ).iterator().next() );
                     hasSubs = subordinateCount > 0;
                 }
                 else

+ 2 - 3
server/src/main/java/password/pwm/ldap/schema/EdirSchemaExtender.java

@@ -84,15 +84,14 @@ public class EdirSchemaExtender implements SchemaExtender
 
     private boolean allStatesCorrect( )
     {
-        boolean allStatesCorrect = true;
         for ( final SchemaDefinition.State value : stateMap.values() )
         {
             if ( SchemaDefinition.State.correct != value )
             {
-                allStatesCorrect = false;
+                return false;
             }
         }
-        return allStatesCorrect;
+        return true;
     }
 
     private void execute( final boolean readOnly ) throws PwmUnrecoverableException

+ 1 - 1
server/src/main/java/password/pwm/svc/event/LdapXmlUserHistory.java

@@ -284,7 +284,7 @@ class LdapXmlUserHistory implements UserHistoryStore
             try ( ByteArrayOutputStream outputStream = new ByteArrayOutputStream() )
             {
                 xmlFactory.outputDocument( doc,  outputStream, XmlFactory.OutputFlag.Compact );
-                return new String( outputStream.toByteArray(), PwmConstants.DEFAULT_CHARSET );
+                return outputStream.toString( PwmConstants.DEFAULT_CHARSET );
             }
             catch ( final IOException e )
             {

+ 1 - 1
server/src/main/java/password/pwm/svc/shorturl/UrlShortenerService.java

@@ -137,7 +137,7 @@ public class UrlShortenerService implements PwmService
             final Pattern p = Pattern.compile( urlRegex );
             final Matcher m = p.matcher( text );
             final StringBuilder result = new StringBuilder();
-            Boolean found = m.find();
+            boolean found = m.find();
             if ( found )
             {
                 int start = 0;

+ 1 - 1
server/src/main/java/password/pwm/util/JarMain.java

@@ -44,7 +44,7 @@ public class JarMain
     {
         final StringBuilder sb = new StringBuilder();
 
-        sb.append( PwmConstants.PWM_APP_NAME + " v" + PwmConstants.BUILD_VERSION + "\n" );
+        sb.append( PwmConstants.PWM_APP_NAME ).append( " v" ).append( PwmConstants.BUILD_VERSION ).append( "\n" );
         sb.append( "\n" );
         sb.append( "Build Information: \n" );
 

+ 4 - 9
server/src/main/java/password/pwm/util/cli/MainClass.java

@@ -26,9 +26,9 @@ import org.apache.log4j.Layout;
 import org.apache.log4j.Logger;
 import password.pwm.AppProperty;
 import password.pwm.PwmApplication;
-import password.pwm.PwmDomain;
 import password.pwm.PwmApplicationMode;
 import password.pwm.PwmConstants;
+import password.pwm.PwmDomain;
 import password.pwm.PwmEnvironment;
 import password.pwm.config.AppConfig;
 import password.pwm.config.DomainConfig;
@@ -68,7 +68,6 @@ import password.pwm.util.cli.commands.VersionCommand;
 import password.pwm.util.java.FileSystemUtility;
 import password.pwm.util.java.JavaHelper;
 import password.pwm.util.localdb.LocalDB;
-import password.pwm.util.localdb.LocalDBException;
 import password.pwm.util.localdb.LocalDBFactory;
 import password.pwm.util.logging.PwmLogLevel;
 import password.pwm.util.logging.PwmLogManager;
@@ -82,7 +81,7 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashSet;
+import java.util.EnumSet;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -414,10 +413,6 @@ public class MainClass
                 out( "error closing LocalDB environment: " + e.getMessage() );
             }
         }
-
-        //System.exit(0);
-        return;
-
     }
 
     private static void initLog4j( final PwmLogLevel logLevel )
@@ -476,10 +471,10 @@ public class MainClass
             final File configurationFile,
             final boolean readonly
     )
-            throws LocalDBException, PwmUnrecoverableException
+            throws PwmUnrecoverableException
     {
         final PwmApplicationMode mode = readonly ? PwmApplicationMode.READ_ONLY : PwmApplicationMode.RUNNING;
-        final Collection<PwmEnvironment.ApplicationFlag> applicationFlags = new HashSet<>();
+        final Collection<PwmEnvironment.ApplicationFlag> applicationFlags = EnumSet.noneOf( PwmEnvironment.ApplicationFlag.class  );
         if ( flags == null )
         {
             applicationFlags.addAll( PwmEnvironment.ParseHelper.readApplicationFlagsFromSystem( null ) );

+ 1 - 1
server/src/main/java/password/pwm/util/db/JDBCDriverLoader.java

@@ -138,7 +138,7 @@ public class JDBCDriverLoader
             try
             {
                 LOGGER.debug( () -> "loading JDBC database driver from classpath: " + jdbcClassName );
-                final Driver driver = ( Driver ) Class.forName( jdbcClassName ).newInstance();
+                final Driver driver = ( Driver ) Class.forName( jdbcClassName ).getDeclaredConstructor().newInstance();
 
                 LOGGER.debug( () -> "successfully loaded JDBC database driver from classpath: " + jdbcClassName );
                 return driver;

+ 0 - 58
server/src/main/java/password/pwm/util/form/FormState.java

@@ -1,58 +0,0 @@
-/*
- * Password Management Servlets (PWM)
- * http://www.pwm-project.org
- *
- * Copyright (c) 2006-2009 Novell, Inc.
- * Copyright (c) 2009-2020 The PWM Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package password.pwm.util.form;
-
-import password.pwm.bean.SessionLabel;
-import password.pwm.config.value.data.FormConfiguration;
-import password.pwm.error.PwmUnrecoverableException;
-import password.pwm.ldap.UserInfo;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-public class FormState
-{
-    private final List<FormConfiguration> formConfigurations;
-    private final Map<String, String> values;
-
-    private FormState( final List<FormConfiguration> formConfigurations, final Map<String, String> values )
-    {
-        this.formConfigurations = Collections.unmodifiableList( formConfigurations );
-        this.values = values;
-    }
-
-    public static FormState initialize( final List<FormConfiguration> formConfigurations )
-    {
-        final FormState formState = new FormState(
-                Collections.unmodifiableList( formConfigurations ),
-                new HashMap<>()
-        );
-        return formState;
-    }
-
-    public void readDataFromSources( final SessionLabel sessionLabel, final UserInfo userInfo )
-            throws PwmUnrecoverableException
-    {
-        FormUtility.populateFormMapFromLdap( formConfigurations, sessionLabel, userInfo );
-    }
-}

+ 20 - 20
server/src/main/java/password/pwm/util/java/JavaHelper.java

@@ -125,13 +125,13 @@ public class JavaHelper
             ch = ( byte ) ( ch & 0x0F );
 
             // convert the nibble to a String Character
-            out.append( pseudo[ ( int ) ch ] );
+            out.append( pseudo[( int ) ch] );
 
             // strip off low nibble
             ch = ( byte ) ( b & 0x0F );
 
             // convert the nibble to a String Character
-            out.append( pseudo[ ( int ) ch ] );
+            out.append( pseudo[( int ) ch] );
         }
 
         return out.toString();
@@ -140,11 +140,11 @@ public class JavaHelper
     public static String binaryArrayToHex( final byte[] buf )
     {
         final char[] hexChars = "0123456789ABCDEF".toCharArray();
-        final char[] chars = new char[ 2 * buf.length ];
+        final char[] chars = new char[2 * buf.length];
         for ( int i = 0; i < buf.length; ++i )
         {
-            chars[ 2 * i ] = hexChars[ ( buf[ i ] & 0xF0 ) >>> 4 ];
-            chars[ 2 * i + 1 ] = hexChars[ buf[ i ] & 0x0F ];
+            chars[2 * i] = hexChars[( buf[i] & 0xF0 ) >>> 4];
+            chars[2 * i + 1] = hexChars[buf[i] & 0x0F];
         }
         return new String( chars );
     }
@@ -292,7 +292,7 @@ public class JavaHelper
             throws IOException
     {
         final int bufferSize = 4 * 1024;
-        final byte[] buffer = new byte[ bufferSize ];
+        final byte[] buffer = new byte[bufferSize];
         return IOUtils.copyLarge( input, output, 0, -1, buffer );
     }
 
@@ -301,7 +301,7 @@ public class JavaHelper
     {
         final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
         JavaHelper.copy( input, byteArrayOutputStream );
-        return new String( byteArrayOutputStream.toByteArray(), PwmConstants.DEFAULT_CHARSET );
+        return byteArrayOutputStream.toString( PwmConstants.DEFAULT_CHARSET );
     }
 
     public static ImmutableByteArray copyToBytes( final InputStream inputStream )
@@ -337,7 +337,7 @@ public class JavaHelper
     )
             throws IOException
     {
-        final byte[] buffer = new byte[ bufferSize ];
+        final byte[] buffer = new byte[bufferSize];
         int bytesCopied;
         long totalCopied = 0;
         do
@@ -437,12 +437,11 @@ public class JavaHelper
                 + threadInfo.getThreadState() );
         if ( threadInfo.getLockName() != null )
         {
-            sb.append( " on " + threadInfo.getLockName() );
+            sb.append( " on " ).append( threadInfo.getLockName() );
         }
         if ( threadInfo.getLockOwnerName() != null )
         {
-            sb.append( " owned by \"" + threadInfo.getLockOwnerName()
-                    + "\" Id=" + threadInfo.getLockOwnerId() );
+            sb.append( " owned by \"" ).append( threadInfo.getLockOwnerName() ).append( "\" Id=" ).append( threadInfo.getLockOwnerId() );
         }
         if ( threadInfo.isSuspended() )
         {
@@ -467,15 +466,15 @@ public class JavaHelper
                 switch ( ts )
                 {
                     case BLOCKED:
-                        sb.append( "\t-  blocked on " + threadInfo.getLockInfo() );
+                        sb.append( "\t-  blocked on " ).append( threadInfo.getLockInfo() );
                         sb.append( '\n' );
                         break;
                     case WAITING:
-                        sb.append( "\t-  waiting on " + threadInfo.getLockInfo() );
+                        sb.append( "\t-  waiting on " ).append( threadInfo.getLockInfo() );
                         sb.append( '\n' );
                         break;
                     case TIMED_WAITING:
-                        sb.append( "\t-  waiting on " + threadInfo.getLockInfo() );
+                        sb.append( "\t-  waiting on " ).append( threadInfo.getLockInfo() );
                         sb.append( '\n' );
                         break;
                     default:
@@ -486,7 +485,7 @@ public class JavaHelper
             {
                 if ( mi.getLockedStackDepth() == counter )
                 {
-                    sb.append( "\t-  locked " + mi );
+                    sb.append( "\t-  locked " ).append( mi );
                     sb.append( '\n' );
                 }
             }
@@ -500,11 +499,11 @@ public class JavaHelper
         final LockInfo[] locks = threadInfo.getLockedSynchronizers();
         if ( locks.length > 0 )
         {
-            sb.append( "\n\tNumber of locked synchronizers = " + locks.length );
+            sb.append( "\n\tNumber of locked synchronizers = " ).append( locks.length );
             sb.append( '\n' );
             for ( final LockInfo li : locks )
             {
-                sb.append( "\t- " + li );
+                sb.append( "\t- " ).append( li );
                 sb.append( '\n' );
             }
         }
@@ -534,7 +533,7 @@ public class JavaHelper
 
     public static int rangeCheck( final int min, final int max, final int value )
     {
-        return (int) rangeCheck( (long) min, (long) max, (long) value );
+        return ( int ) rangeCheck( ( long ) min, ( long ) max, ( long ) value );
     }
 
     public static long rangeCheck( final long min, final long max, final long value )
@@ -588,6 +587,7 @@ public class JavaHelper
     /**
      * Very naive implementation to get a rough order estimate of object memory size, used for debug
      * purposes only.
+     *
      * @param object object to be analyzed
      * @return size of object (very rough estimate)
      */
@@ -611,7 +611,7 @@ public class JavaHelper
     {
         Objects.requireNonNull( properties );
         final Map<String, String> returnMap = new LinkedHashMap<>( properties.size() );
-        properties.forEach( ( key, value ) -> returnMap.put( ( String ) key, (String) value ) );
+        properties.forEach( ( key, value ) -> returnMap.put( ( String ) key, ( String ) value ) );
         return returnMap;
     }
 
@@ -707,7 +707,7 @@ public class JavaHelper
     {
         if ( StringUtil.isEmpty( input ) )
         {
-            throw new NullPointerException( );
+            throw new NullPointerException();
         }
         return input;
     }

+ 2 - 8
server/src/main/java/password/pwm/util/java/StringUtil.java

@@ -212,18 +212,12 @@ public abstract class StringUtil
 
         if ( diskSize > count * count * count )
         {
-            final StringBuilder sb = new StringBuilder();
-            sb.append( nf.format( diskSize / count / count / count ) );
-            sb.append( " GB" );
-            return sb.toString();
+            return nf.format( diskSize / count / count / count ) + " GB";
         }
 
         if ( diskSize > count * count )
         {
-            final StringBuilder sb = new StringBuilder();
-            sb.append( nf.format( diskSize / count / count ) );
-            sb.append( " MB" );
-            return sb.toString();
+            return nf.format( diskSize / count / count ) + " MB";
         }
 
         return PwmNumberFormat.forDefaultLocale().format( diskSize ) + " bytes";

+ 12 - 29
server/src/main/java/password/pwm/util/logging/PwmLogLevel.java

@@ -21,6 +21,7 @@
 package password.pwm.util.logging;
 
 import org.apache.log4j.Level;
+import password.pwm.util.java.JavaHelper;
 
 public enum PwmLogLevel
 {
@@ -31,16 +32,16 @@ public enum PwmLogLevel
     ERROR( Level.ERROR ),
     FATAL( Level.FATAL ),;
 
+    private final int log4jLevel;
+
     PwmLogLevel( final Level log4jLevel )
     {
-        this.log4jLevel = log4jLevel;
+        this.log4jLevel = log4jLevel.toInt();
     }
 
-    private final Level log4jLevel;
-
     public Level getLog4jLevel( )
     {
-        return log4jLevel;
+        return Level.toLevel( log4jLevel );
     }
 
     public static PwmLogLevel fromLog4jLevel( final Level level )
@@ -50,30 +51,12 @@ public enum PwmLogLevel
             return null;
         }
 
-        if ( Level.TRACE.equals( level ) )
-        {
-            return TRACE;
-        }
-        else if ( Level.DEBUG.equals( level ) )
-        {
-            return DEBUG;
-        }
-        else if ( Level.INFO.equals( level ) )
-        {
-            return INFO;
-        }
-        else if ( Level.WARN.equals( level ) )
-        {
-            return WARN;
-        }
-        else if ( Level.ERROR.equals( level ) )
-        {
-            return ERROR;
-        }
-        else if ( Level.FATAL.equals( level ) )
-        {
-            return FATAL;
-        }
-        return TRACE;
+        final int log4jIntLevel = level.toInt();
+
+        return JavaHelper.readEnumFromPredicate(
+                PwmLogLevel.class,
+                pwmLogLevel -> pwmLogLevel.log4jLevel == log4jIntLevel
+        )
+                .orElse( TRACE );
     }
 }

+ 5 - 0
server/src/main/java/password/pwm/util/logging/PwmLogger.java

@@ -425,6 +425,11 @@ public class PwmLogger
         doLogEvent( PwmLogLevel.ERROR, sessionLabel, message, null );
     }
 
+    public void error( final SessionLabel sessionLabel, final Supplier<CharSequence> message, final Supplier<TimeDuration> timeDurationSupplier )
+    {
+        doLogEvent( PwmLogLevel.ERROR, sessionLabel, message, null, timeDurationSupplier );
+    }
+
     public void error( final SessionLabel sessionLabel, final ErrorInformation errorInformation )
     {
         doLogEvent( PwmLogLevel.ERROR, sessionLabel, convertErrorInformation( errorInformation ), null );

+ 4 - 3
server/src/main/java/password/pwm/util/operations/cr/NMASCrOperator.java

@@ -60,8 +60,8 @@ import org.w3c.dom.NodeList;
 import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
 import password.pwm.AppProperty;
-import password.pwm.PwmDomain;
 import password.pwm.PwmConstants;
+import password.pwm.PwmDomain;
 import password.pwm.bean.ResponseInfoBean;
 import password.pwm.bean.SessionLabel;
 import password.pwm.bean.UserIdentity;
@@ -1145,12 +1145,13 @@ public class NMASCrOperator implements CrOperator
             return null;
         }
 
-        private SaslClientFactory getRealSaslClientFactory( ) throws IllegalAccessException, InstantiationException, ClassNotFoundException
+        private SaslClientFactory getRealSaslClientFactory( )
+                throws ReflectiveOperationException
         {
             final String className = "com.novell.sasl.client.ClientFactory";
             final ClassLoader threadLocalClassLoader = Thread.currentThread().getContextClassLoader();
             final Class threadLocalClass = threadLocalClassLoader.loadClass( className );
-            return ( SaslClientFactory ) threadLocalClass.newInstance();
+            return ( SaslClientFactory ) threadLocalClass.getDeclaredConstructor().newInstance();
         }
 
         @Override

+ 1 - 1
server/src/main/java/password/pwm/util/operations/otp/OTPPamUtil.java

@@ -151,7 +151,7 @@ public class OTPPamUtil
             {
                 if ( !code.isUsed() )
                 {
-                    pamData.append( code.getHashCode() + "\n" );
+                    pamData.append( code.getHashCode() ).append( "\n" );
                 }
             }
         }

+ 14 - 12
server/src/main/java/password/pwm/util/password/RandomPasswordGenerator.java

@@ -39,6 +39,7 @@ import password.pwm.svc.stats.StatisticsManager;
 import password.pwm.svc.wordlist.SeedlistService;
 import password.pwm.util.PasswordData;
 import password.pwm.util.java.TimeDuration;
+import password.pwm.util.logging.PwmLogLevel;
 import password.pwm.util.logging.PwmLogger;
 import password.pwm.util.secure.PwmRandom;
 
@@ -161,10 +162,9 @@ public class RandomPasswordGenerator
         // determine the password policy to use for random generation
         final PwmPasswordPolicy randomGenPolicy;
         {
-            final Map<String, String> newPolicyMap = new HashMap<>();
-            newPolicyMap.putAll( effectiveConfig.getPasswordPolicy().getPolicyMap() );
+            final Map<String, String> newPolicyMap = new HashMap<>( effectiveConfig.getPasswordPolicy().getPolicyMap() );
 
-            final String max = newPolicyMap.put( PwmPasswordRule.MaximumLength.getKey(), String.valueOf( effectiveConfig.getMaximumLength() ) );
+            newPolicyMap.put( PwmPasswordRule.MaximumLength.getKey(), String.valueOf( effectiveConfig.getMaximumLength() ) );
 
             if ( effectiveConfig.getMinimumLength() > effectiveConfig.getPasswordPolicy().getRuleHelper().readIntValue( PwmPasswordRule.MinimumLength ) )
             {
@@ -220,22 +220,24 @@ public class RandomPasswordGenerator
 
         // report outcome
         {
-            final TimeDuration td = TimeDuration.fromCurrent( startTime );
             final PwmPasswordRuleValidator pwmPasswordRuleValidator = new PwmPasswordRuleValidator( pwmDomain, randomGenPolicy );
             if ( validPassword )
             {
                 final int finalTryCount = tryCount;
-                LOGGER.trace( sessionLabel, () -> "finished random password generation in "
-                        + td.asCompactString() + " after " + finalTryCount + " tries." );
+                LOGGER.trace( sessionLabel, () -> "finished random password generation after " + finalTryCount
+                        + " tries.", () -> TimeDuration.fromCurrent( startTime ) );
             }
             else
             {
-                final List<ErrorInformation> errors = pwmPasswordRuleValidator.internalPwmPolicyValidator( password.toString(), null, null );
-                final int judgeLevel = PasswordUtility.judgePasswordStrength( pwmDomain.getConfig(), password.toString() );
-                final StringBuilder sb = new StringBuilder();
-                sb.append( "failed random password generation after " ).append( td.asCompactString() ).append( " after " ).append( tryCount ).append( " tries. " );
-                sb.append( "(errors=" ).append( errors.size() ).append( ", judgeLevel=" ).append( judgeLevel );
-                LOGGER.error( sessionLabel, () -> sb.toString() );
+                if ( LOGGER.isEnabled( PwmLogLevel.ERROR ) )
+                {
+                    final int errors = pwmPasswordRuleValidator.internalPwmPolicyValidator( password.toString(), null, null ).size();
+                    final int judgeLevel = PasswordUtility.judgePasswordStrength( pwmDomain.getConfig(), password.toString() );
+                    final int finalTryCount = tryCount;
+                    LOGGER.error( sessionLabel, () -> "failed random password generation after "
+                            + finalTryCount + " tries. " + "(errors=" + errors + ", judgeLevel=" + judgeLevel,
+                            () -> TimeDuration.fromCurrent( startTime ) );
+                }
             }
         }
 

+ 1 - 1
server/src/main/java/password/pwm/util/queue/SmsQueueManager.java

@@ -208,7 +208,7 @@ public class SmsQueueManager implements PwmService
     )
             throws PwmUnrecoverableException
     {
-        final Boolean shorten = pwmDomain.getConfig().readSettingAsBoolean( PwmSetting.SMS_USE_URL_SHORTENER );
+        final boolean shorten = pwmDomain.getConfig().readSettingAsBoolean( PwmSetting.SMS_USE_URL_SHORTENER );
         if ( shorten )
         {
             final String message = smsItem.getMessage();

+ 3 - 3
server/src/main/java/password/pwm/util/secure/HttpsServerCertificateManager.java

@@ -41,7 +41,7 @@ import java.security.PrivateKey;
 import java.security.cert.X509Certificate;
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Enumeration;
+import java.util.Iterator;
 import java.util.List;
 
 public class HttpsServerCertificateManager
@@ -142,9 +142,9 @@ public class HttpsServerCertificateManager
             final String effectiveAlias;
             {
                 final List<String> allAliases = new ArrayList<>();
-                for ( final Enumeration<String> aliasEnum = keyStore.aliases(); aliasEnum.hasMoreElements(); )
+                for ( final Iterator<String> aliasEnum = keyStore.aliases().asIterator(); aliasEnum.hasNext(); )
                 {
-                    final String value = aliasEnum.nextElement();
+                    final String value = aliasEnum.next();
                     allAliases.add( value );
                 }
                 effectiveAlias = allAliases.size() == 1 ? allAliases.iterator().next() : alias;

+ 11 - 4
server/src/test/java/password/pwm/http/servlet/ControlledPwmServletTest.java

@@ -47,13 +47,17 @@ import java.util.Set;
 public class ControlledPwmServletTest
 {
     @Test
-    public void testProcess() throws IllegalAccessException, InstantiationException
+    public void testProcess() throws Exception
     {
         final Map<Class<? extends ControlledPwmServlet>, Map<String, Method>> dataMap = getClassAndMethods();
 
         for ( final Class<? extends ControlledPwmServlet> controlledPwmServlet : dataMap.keySet() )
         {
-            final Class<? extends AbstractPwmServlet.ProcessAction> processActionsClass = controlledPwmServlet.newInstance().getProcessActionsClass();
+            final Class<? extends AbstractPwmServlet.ProcessAction> processActionsClass = controlledPwmServlet
+                    .getDeclaredConstructor()
+                    .newInstance()
+                    .getProcessActionsClass();
+
             if ( !processActionsClass.isEnum() )
             {
                 Assert.fail( controlledPwmServlet.getName() + " process action class must be an enum" );
@@ -131,7 +135,8 @@ public class ControlledPwmServletTest
 
 
     @Test
-    public void testActionHandlersExistence() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException
+    public void testActionHandlersExistence()
+            throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException
     {
         final Map<Class<? extends ControlledPwmServlet>, Map<String, Method>> dataMap = getClassAndMethods();
 
@@ -139,7 +144,9 @@ public class ControlledPwmServletTest
         {
             final String servletName = controlledPwmServlet.getName();
 
-            final Class<? extends AbstractPwmServlet.ProcessAction> processActionsClass = controlledPwmServlet.newInstance().getProcessActionsClass();
+            final Class<? extends AbstractPwmServlet.ProcessAction> processActionsClass = controlledPwmServlet
+                    .getDeclaredConstructor(  )
+                    .newInstance().getProcessActionsClass();
             final List<String> names = new ArrayList<>();
             for ( final Object enumObject : processActionsClass.getEnumConstants() )
             {

+ 28 - 22
server/src/test/java/password/pwm/util/localdb/LocalDBLoggerExtendedTest.java

@@ -20,6 +20,8 @@
 
 package password.pwm.util.localdb;
 
+import lombok.Builder;
+import lombok.Value;
 import org.junit.Before;
 import org.junit.Rule;
 import org.junit.Test;
@@ -48,6 +50,7 @@ import java.time.Instant;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
+import java.util.Map;
 import java.util.Random;
 import java.util.Timer;
 import java.util.TimerTask;
@@ -104,11 +107,12 @@ public class LocalDBLoggerExtendedTest
             localDBLogger = new LocalDBLogger( null, localDB, settings );
         }
 
-        settings = new Settings();
-        settings.threads = 10;
-        settings.testDuration = TimeDuration.of( 1, TimeDuration.Unit.MINUTES );
-        settings.valueLength = 5000;
-        settings.batchSize = 100;
+        settings = Settings.builder()
+                .threads( 10 )
+                .testDuration( TimeDuration.of( 1, TimeDuration.Unit.MINUTES ) )
+                .valueLength( 5000 )
+                .batchSize( 100 )
+                .build();
     }
 
     private void out( final String output )
@@ -190,16 +194,14 @@ public class LocalDBLoggerExtendedTest
 
     private void outputDebugInfo()
     {
-        final StringBuilder sb = new StringBuilder();
-        sb.append( "added " ).append( numberFormat.format( eventsAdded.get() ) );
-        sb.append( ", size: " ).append( StringUtil.formatDiskSize( FileSystemUtility.getFileDirectorySize( localDB.getFileLocation() ) ) );
-        sb.append( ", eventsInDb: " ).append( figureEventsInDbStat() );
-        sb.append( ", free: " ).append( StringUtil.formatDiskSize(
-                FileSystemUtility.diskSpaceRemaining( localDB.getFileLocation() ) ) );
-        sb.append( ", eps: " ).append( eventRateMeter.readEventRate().setScale( 0, RoundingMode.UP ) );
-        sb.append( ", remain: " ).append( settings.testDuration.subtract( TimeDuration.fromCurrent( startTime ) ).asCompactString() );
-        sb.append( ", tail: " ).append( TimeDuration.fromCurrent( localDBLogger.getTailDate() ).asCompactString() );
-        out( sb.toString() );
+        final Map<String, String> debugParams = Map.of(
+                "size", StringUtil.formatDiskSize( FileSystemUtility.getFileDirectorySize( localDB.getFileLocation() ) ),
+                "eventsInDb", figureEventsInDbStat(),
+                "free", StringUtil.formatDiskSize( FileSystemUtility.diskSpaceRemaining( localDB.getFileLocation() ) ),
+                "eps", eventRateMeter.readEventRate().setScale( 0, RoundingMode.UP ).toString(),
+                "remain", settings.testDuration.subtract( TimeDuration.fromCurrent( startTime ) ).asCompactString(),
+                "tail", TimeDuration.fromCurrent( localDBLogger.getTailDate() ).asCompactString() );
+        out( "added " + StringUtil.mapToString( debugParams ) );
     }
 
     private String figureEventsInDbStat()
@@ -213,13 +215,13 @@ public class LocalDBLoggerExtendedTest
 
     private Results makeResults()
     {
-        final Results results = new Results();
-        results.dbClass = config.readAppProperty( AppProperty.LOCALDB_IMPLEMENTATION );
-        results.duration = TimeDuration.fromCurrent( startTime ).asCompactString();
-        results.recordsAdded = eventsAdded.get();
-        results.dbSize = StringUtil.formatDiskSize( FileSystemUtility.getFileDirectorySize( localDB.getFileLocation() ) );
-        results.eventsInDb = figureEventsInDbStat();
-        return results;
+        return Results.builder()
+                .dbClass( config.readAppProperty( AppProperty.LOCALDB_IMPLEMENTATION ) )
+                .duration( TimeDuration.fromCurrent( startTime ).asCompactString() )
+                .recordsAdded( eventsAdded.get() )
+                .dbSize( StringUtil.formatDiskSize( FileSystemUtility.getFileDirectorySize( localDB.getFileLocation() ) ) )
+                .eventsInDb( figureEventsInDbStat() )
+                .build();
     }
 
     private class DebugOutputTimerTask extends TimerTask
@@ -231,6 +233,8 @@ public class LocalDBLoggerExtendedTest
         }
     }
 
+    @Value
+    @Builder
     private static class Settings implements Serializable
     {
         private TimeDuration testDuration;
@@ -239,6 +243,8 @@ public class LocalDBLoggerExtendedTest
         private int batchSize;
     }
 
+    @Value
+    @Builder
     private static class Results implements Serializable
     {
         private String dbClass;

+ 117 - 114
server/src/test/java/password/pwm/util/password/PasswordRuleChecksTest.java

@@ -20,7 +20,10 @@
 
 package password.pwm.util.password;
 
-import org.junit.Assert;
+import org.hamcrest.CoreMatchers;
+import org.hamcrest.Matcher;
+import org.hamcrest.MatcherAssert;
+import org.hamcrest.core.IsCollectionContaining;
 import org.junit.Test;
 import password.pwm.config.profile.PwmPasswordPolicy;
 import password.pwm.config.profile.PwmPasswordRule;
@@ -44,14 +47,14 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MinimumLength.getKey(), "7" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "123" ), hasItems( PwmError.PASSWORD_TOO_SHORT ) );
-        Assert.assertThat( doCheck( policyMap, "1234" ), hasItems( PwmError.PASSWORD_TOO_SHORT ) );
-        Assert.assertThat( doCheck( policyMap, "12345" ), hasItems( PwmError.PASSWORD_TOO_SHORT ) );
-        Assert.assertThat( doCheck( policyMap, "123456" ),  hasItems( PwmError.PASSWORD_TOO_SHORT ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "123" ), hasItems( PwmError.PASSWORD_TOO_SHORT ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "1234" ), hasItems( PwmError.PASSWORD_TOO_SHORT ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "12345" ), hasItems( PwmError.PASSWORD_TOO_SHORT ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "123456" ),  hasItems( PwmError.PASSWORD_TOO_SHORT ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "1234567" ), not( hasItems( PwmError.PASSWORD_TOO_SHORT ) ) );
-        Assert.assertThat( doCheck( policyMap, "12345678" ), not( hasItems( PwmError.PASSWORD_TOO_SHORT ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "1234567" ), not( hasItems( PwmError.PASSWORD_TOO_SHORT ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "12345678" ), not( hasItems( PwmError.PASSWORD_TOO_SHORT ) ) );
     }
 
     @Test
@@ -62,15 +65,15 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MaximumLength.getKey(), "7" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "12345678" ), hasItems( PwmError.PASSWORD_TOO_LONG ) );
-        Assert.assertThat( doCheck( policyMap, "123456789" ), hasItems( PwmError.PASSWORD_TOO_LONG ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "12345678" ), hasItems( PwmError.PASSWORD_TOO_LONG ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "123456789" ), hasItems( PwmError.PASSWORD_TOO_LONG ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "123" ), not( hasItems( PwmError.PASSWORD_TOO_LONG ) ) );
-        Assert.assertThat( doCheck( policyMap, "1234" ), not( hasItems( PwmError.PASSWORD_TOO_LONG ) ) );
-        Assert.assertThat( doCheck( policyMap, "12345" ), not( hasItems( PwmError.PASSWORD_TOO_LONG ) ) );
-        Assert.assertThat( doCheck( policyMap, "123456" ),  not( hasItems( PwmError.PASSWORD_TOO_LONG ) ) );
-        Assert.assertThat( doCheck( policyMap, "1234567" ),  not( hasItems( PwmError.PASSWORD_TOO_LONG ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "123" ), not( hasItems( PwmError.PASSWORD_TOO_LONG ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "1234" ), not( hasItems( PwmError.PASSWORD_TOO_LONG ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "12345" ), not( hasItems( PwmError.PASSWORD_TOO_LONG ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "123456" ),  not( hasItems( PwmError.PASSWORD_TOO_LONG ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "1234567" ),  not( hasItems( PwmError.PASSWORD_TOO_LONG ) ) );
     }
 
     @Test
@@ -81,15 +84,15 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MinimumUpperCase.getKey(), "3" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "A" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) );
-        Assert.assertThat( doCheck( policyMap, "AB" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) );
-        Assert.assertThat( doCheck( policyMap, "ABc" ),  hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "A" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "AB" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "ABc" ),  hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "ABC" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) ) );
-        Assert.assertThat( doCheck( policyMap, "ABCD" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) ) );
-        Assert.assertThat( doCheck( policyMap, "ABCDe" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) ) );
-        Assert.assertThat( doCheck( policyMap, "123456ABC" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "ABC" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "ABCD" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "ABCDe" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "123456ABC" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_UPPER ) ) );
     }
 
     @Test
@@ -100,14 +103,14 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MaximumUpperCase.getKey(), "3" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "ABCD" ), hasItems( PwmError.PASSWORD_TOO_MANY_UPPER ) );
-        Assert.assertThat( doCheck( policyMap, "ABCDE" ), hasItems( PwmError.PASSWORD_TOO_MANY_UPPER ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "ABCD" ), hasItems( PwmError.PASSWORD_TOO_MANY_UPPER ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "ABCDE" ), hasItems( PwmError.PASSWORD_TOO_MANY_UPPER ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "A" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_UPPER ) ) );
-        Assert.assertThat( doCheck( policyMap, "AB" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_UPPER ) ) );
-        Assert.assertThat( doCheck( policyMap, "ABC" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_UPPER ) ) );
-        Assert.assertThat( doCheck( policyMap, "ABCd" ),  not( hasItems( PwmError.PASSWORD_TOO_MANY_UPPER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "A" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_UPPER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "AB" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_UPPER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "ABC" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_UPPER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "ABCd" ),  not( hasItems( PwmError.PASSWORD_TOO_MANY_UPPER ) ) );
     }
 
     @Test
@@ -118,15 +121,15 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MinimumLowerCase.getKey(), "3" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "a" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) );
-        Assert.assertThat( doCheck( policyMap, "ab" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) );
-        Assert.assertThat( doCheck( policyMap, "abC" ),  hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "a" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "ab" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abC" ),  hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "abc" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) ) );
-        Assert.assertThat( doCheck( policyMap, "abcd" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) ) );
-        Assert.assertThat( doCheck( policyMap, "abcdE" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) ) );
-        Assert.assertThat( doCheck( policyMap, "123456abc" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abc" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abcd" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abcdE" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "123456abc" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_LOWER ) ) );
     }
 
     @Test
@@ -137,14 +140,14 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MaximumLowerCase.getKey(), "3" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "abcd" ), hasItems( PwmError.PASSWORD_TOO_MANY_LOWER ) );
-        Assert.assertThat( doCheck( policyMap, "abcde" ), hasItems( PwmError.PASSWORD_TOO_MANY_LOWER ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abcd" ), hasItems( PwmError.PASSWORD_TOO_MANY_LOWER ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abcde" ), hasItems( PwmError.PASSWORD_TOO_MANY_LOWER ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "a" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_LOWER ) ) );
-        Assert.assertThat( doCheck( policyMap, "ab" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_LOWER ) ) );
-        Assert.assertThat( doCheck( policyMap, "abc" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_LOWER ) ) );
-        Assert.assertThat( doCheck( policyMap, "abcD" ),  not( hasItems( PwmError.PASSWORD_TOO_MANY_LOWER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "a" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_LOWER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "ab" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_LOWER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abc" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_LOWER ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abcD" ),  not( hasItems( PwmError.PASSWORD_TOO_MANY_LOWER ) ) );
     }
 
     @Test
@@ -156,13 +159,13 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MinimumSpecial.getKey(), "3" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "!" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_SPECIAL ) );
-        Assert.assertThat( doCheck( policyMap, "!!" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_SPECIAL ) );
-        Assert.assertThat( doCheck( policyMap, "!!A" ),  hasItems( PwmError.PASSWORD_NOT_ENOUGH_SPECIAL ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "!" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_SPECIAL ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "!!" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_SPECIAL ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "!!A" ),  hasItems( PwmError.PASSWORD_NOT_ENOUGH_SPECIAL ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "!!!" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_SPECIAL ) ) );
-        Assert.assertThat( doCheck( policyMap, "!!!A" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_SPECIAL ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "!!!" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_SPECIAL ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "!!!A" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_SPECIAL ) ) );
     }
 
     @Test
@@ -174,12 +177,12 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MaximumSpecial.getKey(), "3" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "!!!!" ), hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) );
-        Assert.assertThat( doCheck( policyMap, "!!!!!" ), hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "!!!!" ), hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "!!!!!" ), hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "!!!" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
-        Assert.assertThat( doCheck( policyMap, "!!!A" ),  not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "!!!" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "!!!A" ),  not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
     }
 
     @Test
@@ -190,13 +193,13 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MinimumAlpha.getKey(), "3" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "a" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_ALPHA ) );
-        Assert.assertThat( doCheck( policyMap, "ab" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_ALPHA ) );
-        Assert.assertThat( doCheck( policyMap, "ab1" ),  hasItems( PwmError.PASSWORD_NOT_ENOUGH_ALPHA ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "a" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_ALPHA ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "ab" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_ALPHA ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "ab1" ),  hasItems( PwmError.PASSWORD_NOT_ENOUGH_ALPHA ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "abc" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_ALPHA ) ) );
-        Assert.assertThat( doCheck( policyMap, "abcd" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_ALPHA ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abc" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_ALPHA ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abcd" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_ALPHA ) ) );
     }
 
     @Test
@@ -207,12 +210,12 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MaximumAlpha.getKey(), "3" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "abcd" ), hasItems( PwmError.PASSWORD_TOO_MANY_ALPHA ) );
-        Assert.assertThat( doCheck( policyMap, "abcd1" ), hasItems( PwmError.PASSWORD_TOO_MANY_ALPHA ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abcd" ), hasItems( PwmError.PASSWORD_TOO_MANY_ALPHA ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abcd1" ), hasItems( PwmError.PASSWORD_TOO_MANY_ALPHA ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "abc" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_ALPHA ) ) );
-        Assert.assertThat( doCheck( policyMap, "abc1" ),  not( hasItems( PwmError.PASSWORD_TOO_MANY_ALPHA ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abc" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_ALPHA ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "abc1" ),  not( hasItems( PwmError.PASSWORD_TOO_MANY_ALPHA ) ) );
     }
 
     @Test
@@ -223,13 +226,13 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MinimumNonAlpha.getKey(), "3" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "!!" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_NONALPHA ) );
-        Assert.assertThat( doCheck( policyMap, "44" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_NONALPHA ) );
-        Assert.assertThat( doCheck( policyMap, "5" ),  hasItems( PwmError.PASSWORD_NOT_ENOUGH_NONALPHA ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "!!" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_NONALPHA ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "44" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_NONALPHA ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "5" ),  hasItems( PwmError.PASSWORD_NOT_ENOUGH_NONALPHA ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "!!!" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_NONALPHA ) ) );
-        Assert.assertThat( doCheck( policyMap, ",,," ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_NONALPHA ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "!!!" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_NONALPHA ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, ",,," ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_NONALPHA ) ) );
     }
 
     @Test
@@ -240,12 +243,12 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MaximumNonAlpha.getKey(), "3" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "1234" ), hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) );
-        Assert.assertThat( doCheck( policyMap, "----" ), hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "1234" ), hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "----" ), hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "123" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
-        Assert.assertThat( doCheck( policyMap, "---" ),  not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "123" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "---" ),  not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
     }
 
     @Test
@@ -257,13 +260,13 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MinimumNumeric.getKey(), "3" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "1" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_NUM ) );
-        Assert.assertThat( doCheck( policyMap, "12" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_NUM ) );
-        Assert.assertThat( doCheck( policyMap, "12a" ),  hasItems( PwmError.PASSWORD_NOT_ENOUGH_NUM ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "1" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_NUM ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "12" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_NUM ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "12a" ),  hasItems( PwmError.PASSWORD_NOT_ENOUGH_NUM ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "123" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_NUM ) ) );
-        Assert.assertThat( doCheck( policyMap, "1234" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_NUM ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "123" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_NUM ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "1234" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_NUM ) ) );
     }
 
     @Test
@@ -275,12 +278,12 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MaximumNumeric.getKey(), "3" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "1234" ), hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) );
-        Assert.assertThat( doCheck( policyMap, "12345" ), hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "1234" ), hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "12345" ), hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "12" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) ) );
-        Assert.assertThat( doCheck( policyMap, "123" ),  not( hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "12" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "123" ),  not( hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) ) );
     }
 
     @Test
@@ -291,13 +294,13 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MinimumUnique.getKey(), "4" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "aaa" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_UNIQUE ) );
-        Assert.assertThat( doCheck( policyMap, "aaa2" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_UNIQUE ) );
-        Assert.assertThat( doCheck( policyMap, "aaa23" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_UNIQUE ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aaa" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_UNIQUE ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aaa2" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_UNIQUE ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aaa23" ), hasItems( PwmError.PASSWORD_NOT_ENOUGH_UNIQUE ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "aaa234" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_UNIQUE ) ) );
-        Assert.assertThat( doCheck( policyMap, "aaa2345" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_UNIQUE ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aaa234" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_UNIQUE ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aaa2345" ), not( hasItems( PwmError.PASSWORD_NOT_ENOUGH_UNIQUE ) ) );
     }
 
     @Test
@@ -308,13 +311,13 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MaximumSequentialRepeat.getKey(), "4" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "aaaaa" ), hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) );
-        Assert.assertThat( doCheck( policyMap, "aaaaaa" ), hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aaaaa" ), hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aaaaaa" ), hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) ) );
-        Assert.assertThat( doCheck( policyMap, "aaaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) ) );
-        Assert.assertThat( doCheck( policyMap, "aaa23" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aaaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aaa23" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) ) );
     }
 
     @Test
@@ -325,13 +328,13 @@ public class PasswordRuleChecksTest
         policyMap.put( PwmPasswordRule.MaximumRepeat.getKey(), "4" );
 
         // violations
-        Assert.assertThat( doCheck( policyMap, "aa2aaa" ), hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) );
-        Assert.assertThat( doCheck( policyMap, "aa2aaaa" ), hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aa2aaa" ), hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aa2aaaa" ), hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) );
 
         // not violations
-        Assert.assertThat( doCheck( policyMap, "aa2a" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) ) );
-        Assert.assertThat( doCheck( policyMap, "aa2aa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) ) );
-        Assert.assertThat( doCheck( policyMap, "aa2a23" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aa2a" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aa2aa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) ) );
+        MatcherAssert.assertThat( doCheck( policyMap, "aa2a23" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_REPEAT ) ) );
     }
 
     @Test
@@ -343,18 +346,18 @@ public class PasswordRuleChecksTest
             policyMap.put( PwmPasswordRule.AllowNumeric.getKey(), "true" );
 
             // not violations
-            Assert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) ) );
-            Assert.assertThat( doCheck( policyMap, "aaa2" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "aaa2" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) ) );
         }
         {
             final Map<String, String> policyMap = new HashMap<>();
             policyMap.put( PwmPasswordRule.AllowNumeric.getKey(), "false" );
 
             // violations
-            Assert.assertThat( doCheck( policyMap, "aaa2" ), hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "aaa2" ), hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) );
 
             // not violations
-            Assert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NUMERIC ) ) );
         }
     }
 
@@ -367,21 +370,21 @@ public class PasswordRuleChecksTest
             policyMap.put( PwmPasswordRule.AllowSpecial.getKey(), "true" );
 
             // not violations
-            Assert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
-            Assert.assertThat( doCheck( policyMap, "aaa^" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
-            Assert.assertThat( doCheck( policyMap, "123" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "aaa^" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "123" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
         }
         {
             final Map<String, String> policyMap = new HashMap<>();
             policyMap.put( PwmPasswordRule.AllowSpecial.getKey(), "false" );
 
             // violations
-            Assert.assertThat( doCheck( policyMap, "aaa^" ), hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) );
-            Assert.assertThat( doCheck( policyMap, "^" ), hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "aaa^" ), hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "^" ), hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) );
 
             // not violations
-            Assert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
-            Assert.assertThat( doCheck( policyMap, "123" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "123" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_SPECIAL ) ) );
         }
     }
 
@@ -394,24 +397,24 @@ public class PasswordRuleChecksTest
             policyMap.put( PwmPasswordRule.AllowNonAlpha.getKey(), "true" );
 
             // violations
-            Assert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
 
             // not violations
-            Assert.assertThat( doCheck( policyMap, "^" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
-            Assert.assertThat( doCheck( policyMap, "aaa^" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
-            Assert.assertThat( doCheck( policyMap, "123" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "^" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "aaa^" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "123" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
         }
         {
             final Map<String, String> policyMap = new HashMap<>();
             policyMap.put( PwmPasswordRule.AllowNonAlpha.getKey(), "false" );
 
             // violations
-            Assert.assertThat( doCheck( policyMap, "^" ), hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) );
-            Assert.assertThat( doCheck( policyMap, "aaa^" ), hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) );
-            Assert.assertThat( doCheck( policyMap, "123" ), hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "^" ), hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "aaa^" ), hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "123" ), hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) );
 
             // not violations
-            Assert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
+            MatcherAssert.assertThat( doCheck( policyMap, "aaa" ), not( hasItems( PwmError.PASSWORD_TOO_MANY_NONALPHA ) ) );
         }
     }
 
@@ -428,13 +431,13 @@ public class PasswordRuleChecksTest
         return errorResults.stream().map( ErrorInformation::getError ).collect( Collectors.toSet() );
     }
 
-    private static <T> org.hamcrest.Matcher<T> not( final org.hamcrest.Matcher<T> matcher )
+    private static <T> Matcher<T> not( final org.hamcrest.Matcher<T> matcher )
     {
-        return org.hamcrest.CoreMatchers.not( matcher );
+        return CoreMatchers.not( matcher );
     }
 
-    private static <T> org.hamcrest.Matcher<java.lang.Iterable<T>> hasItems( final T... items )
+    private static <T> Matcher<Iterable<T>> hasItems( final T... items )
     {
-        return org.hamcrest.core.IsCollectionContaining.hasItems( items );
+        return IsCollectionContaining.hasItems( items );
     }
 }