[java-opensaml] branch main updated: IDP-2069 - Null Handling Task

Scott Cantor cantor.2 at osu.edu
Mon Apr 3 23:21:17 UTC 2023


This is an automated email from the git hooks/post-receive script.

scantor pushed a commit to branch main
in repository java-opensaml.

View the commit online:
http://git.shibboleth.net/view/?p=java-opensaml.git;a=commit;h=f3e512fe8b26e751203605b97542839553d20689

The following commit(s) were added to refs/heads/main by this push:
     new f3e512fe8 IDP-2069 - Null Handling Task
f3e512fe8 is described below

commit f3e512fe8b26e751203605b97542839553d20689
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Apr 3 19:21:14 2023 -0400

    IDP-2069 - Null Handling Task
    
    https://shibboleth.atlassian.net/browse/IDP-2069
    
    Start saml-impl cleanup.
    Notably, eliminating nulls from metadata impl child collections.
---
 .../resolver/filter/MetadataNodeProcessor.java     |  4 +-
 .../artifact/impl/BasicSAMLArtifactMap.java        |  2 +-
 .../impl/StorageServiceSAMLArtifactMap.java        |  2 +-
 .../StorageServiceSAMLArtifactMapEntryFactory.java |  5 +-
 .../impl/AddChannelBindingsHeaderHandler.java      |  9 ++-
 .../binding/impl/CheckMessageVersionHandler.java   | 27 ++++-----
 .../binding/impl/DefaultEndpointResolver.java      |  3 +-
 .../PopulateSignatureSigningParametersHandler.java | 12 ++--
 .../SAMLAddAttributeConsumingServiceHandler.java   | 11 ++--
 .../binding/impl/SAMLMetadataLookupHandler.java    | 56 ++++++++++--------
 .../impl/SAMLOutboundDestinationHandler.java       |  4 +-
 .../binding/impl/SAMLProtocolAndRoleHandler.java   |  2 +-
 .../binding/impl/SAMLSOAPDecoderBodyHandler.java   | 12 ++--
 .../BaseSAMLSimpleSignatureSecurityHandler.java    | 66 +++++++++++++---------
 .../impl/BaseSAMLXMLSignatureSecurityHandler.java  | 53 ++++++++++++-----
 ...ecordServerTLSEntityAuthenticationtHandler.java |  8 +--
 .../impl/EndpointURLSchemeSecurityHandler.java     |  3 +-
 .../security/impl/InResponseToSecurityHandler.java | 41 +++++++-------
 .../impl/MessageLifetimeSecurityHandler.java       |  6 +-
 .../impl/ReceivedEndpointSecurityHandler.java      | 10 +---
 .../impl/SAMLMDClientCertAuthSecurityHandler.java  | 28 +++++----
 .../SAMLOutboundProtocolMessageSigningHandler.java | 18 +++---
 ...ProtocolMessageXMLSignatureSecurityHandler.java | 12 ++--
 .../config/impl/XMLObjectProviderInitializer.java  |  6 +-
 .../idpdisco/impl/DiscoveryResponseBuilder.java    |  5 +-
 .../reqattr/impl/RequestedAttributesBuilder.java   | 12 ++--
 .../ext/reqattr/impl/RequestedAttributesImpl.java  | 26 +++++----
 .../impl/RequestedAttributesUnmarshaller.java      |  6 +-
 ...aluableEntityRoleEntityDescriptorCriterion.java |  6 +-
 .../resolver/filter/impl/AlgorithmFilter.java      | 38 +++++++------
 .../impl/BasicDynamicTrustedNamesStrategy.java     | 48 ++++++++++------
 .../filter/impl/ByReferenceMetadataFilter.java     |  8 +--
 .../impl/EntitiesDescriptorNameProcessor.java      |  5 +-
 .../filter/impl/EntityAttributesFilter.java        |  7 ++-
 .../resolver/filter/impl/EntityRoleFilter.java     | 11 ++--
 .../resolver/filter/impl/NameIDFormatFilter.java   | 39 +++++++------
 .../filter/impl/NodeProcessingMetadataFilter.java  | 26 +++------
 .../resolver/filter/impl/PredicateFilter.java      |  5 +-
 .../filter/impl/RequiredValidUntilFilter.java      |  3 +-
 .../filter/impl/SchemaValidationFilter.java        |  7 +--
 .../filter/impl/ScriptedTrustedNamesFunction.java  |  3 +-
 .../filter/impl/SignatureValidationFilter.java     | 20 ++++---
 .../resolver/index/impl/EndpointMetadataIndex.java | 18 +++---
 .../metadata/impl/AffiliationDescriptorImpl.java   |  9 ++-
 .../impl/AttributeAuthorityDescriptorImpl.java     | 10 +++-
 .../impl/AuthnAuthorityDescriptorImpl.java         | 10 +++-
 .../saml2/metadata/impl/ContactPersonImpl.java     | 24 ++++++--
 .../metadata/impl/EntitiesDescriptorImpl.java      | 11 +++-
 .../saml2/metadata/impl/EntityDescriptorImpl.java  | 22 ++++++--
 .../saml2/metadata/impl/IDPSSODescriptorImpl.java  | 10 +++-
 .../saml2/metadata/impl/KeyDescriptorImpl.java     | 10 +++-
 .../saml/saml2/metadata/impl/OrganizationImpl.java |  9 ++-
 .../saml2/metadata/impl/PDPDescriptorImpl.java     |  4 +-
 .../saml2/metadata/impl/RoleDescriptorImpl.java    |  6 +-
 .../saml2/metadata/impl/SSODescriptorImpl.java     | 11 +++-
 .../impl/SAMLMetadataLookupHandlerTest.java        |  3 +-
 ...ocolMessageXMLSignatureSecurityHandlerTest.java | 12 ++--
 .../logic/tests/EntityGroupNamePredicateTest.java  |  5 +-
 .../impl/EntitiesDescriptorNameProcessorTest.java  |  1 +
 59 files changed, 511 insertions(+), 339 deletions(-)

diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/metadata/resolver/filter/MetadataNodeProcessor.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/metadata/resolver/filter/MetadataNodeProcessor.java
index d80c34ffc..80240e000 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/metadata/resolver/filter/MetadataNodeProcessor.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/metadata/resolver/filter/MetadataNodeProcessor.java
@@ -17,6 +17,8 @@
 
 package org.opensaml.saml.metadata.resolver.filter;
 
+import javax.annotation.Nonnull;
+
 import org.opensaml.core.xml.XMLObject;
 
 /**
@@ -31,6 +33,6 @@ public interface MetadataNodeProcessor {
      * @param metadataNode the metadata node to process
      * @throws FilterException if a fatal error is encountered while processing the node
      */
-    public void process(XMLObject metadataNode) throws FilterException;
+    public void process(@Nonnull XMLObject metadataNode) throws FilterException;
     
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/BasicSAMLArtifactMap.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/BasicSAMLArtifactMap.java
index d414e94ae..60d4ae2d4 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/BasicSAMLArtifactMap.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/BasicSAMLArtifactMap.java
@@ -33,13 +33,13 @@ import org.opensaml.saml.common.SAMLObject;
 import org.opensaml.saml.common.binding.artifact.ExpiringSAMLArtifactMapEntry;
 import org.opensaml.saml.common.binding.artifact.SAMLArtifactMap;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.AbstractInitializableComponent;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.TimerSupport;
 
 /** Basic artifact map implementation. */
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMap.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMap.java
index 94f5a4739..fd5fdae7e 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMap.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMap.java
@@ -30,13 +30,13 @@ import org.opensaml.storage.StorageRecord;
 import org.opensaml.storage.StorageSerializer;
 import org.opensaml.storage.StorageService;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.AbstractInitializableComponent;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /** Artifact map implementation backed by {@link StorageService}. */
 public class StorageServiceSAMLArtifactMap extends AbstractInitializableComponent implements SAMLArtifactMap {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMapEntryFactory.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMapEntryFactory.java
index 4b30c5128..78ad6b7df 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMapEntryFactory.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/artifact/impl/StorageServiceSAMLArtifactMapEntryFactory.java
@@ -36,13 +36,13 @@ import org.opensaml.saml.common.binding.artifact.SAMLArtifactMap.SAMLArtifactMap
 import org.opensaml.saml.common.binding.artifact.SAMLArtifactMap.SAMLArtifactMapEntryFactory;
 import org.opensaml.storage.StorageSerializer;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.w3c.dom.Element;
 import org.w3c.dom.Node;
 
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.AbstractInitializableComponent;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.xml.ElementSupport;
 import net.shibboleth.shared.xml.ParserPool;
 import net.shibboleth.shared.xml.QNameSupport;
@@ -66,7 +66,8 @@ public class StorageServiceSAMLArtifactMapEntryFactory extends AbstractInitializ
     
     /** Constructor. */
     public StorageServiceSAMLArtifactMapEntryFactory() {
-        parserPool = XMLObjectProviderRegistrySupport.getParserPool();
+        parserPool = Constraint.isNotNull(XMLObjectProviderRegistrySupport.getParserPool(),
+                "Default ParserPool was null");
     }
 
     /**
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/AddChannelBindingsHeaderHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/AddChannelBindingsHeaderHandler.java
index f909dee10..c0dceac37 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/AddChannelBindingsHeaderHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/AddChannelBindingsHeaderHandler.java
@@ -34,9 +34,9 @@ import org.opensaml.soap.messaging.SOAPMessagingSupport;
 import org.opensaml.soap.soap11.ActorBearing;
 import org.opensaml.soap.util.SOAPSupport;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * MessageHandler to add {@link ChannelBindings} headers to an outgoing SOAP envelope.
@@ -78,12 +78,14 @@ public class AddChannelBindingsHeaderHandler extends AbstractMessageHandler {
             return false;
         }
         
-        channelBindingsContext = channelBindingsContextLookupStrategy.apply(messageContext);
-        if (channelBindingsContext == null || channelBindingsContext.getChannelBindings().isEmpty()) {
+        final ChannelBindingsContext cbCtx = channelBindingsContextLookupStrategy.apply(messageContext);
+        if (cbCtx == null || cbCtx.getChannelBindings().isEmpty()) {
             log.debug("{} No ChannelBindings to add, nothing to do", getLogPrefix());
             return false;
         }
         
+        channelBindingsContext = cbCtx;
+        
         return true;
     }
 
@@ -95,6 +97,7 @@ public class AddChannelBindingsHeaderHandler extends AbstractMessageHandler {
                 XMLObjectProviderRegistrySupport.getBuilderFactory().<ChannelBindings>ensureBuilder(
                         ChannelBindings.DEFAULT_ELEMENT_NAME);
         
+        assert channelBindingsContext != null;
         for (final ChannelBindings cb : channelBindingsContext.getChannelBindings()) {
             final ChannelBindings header = cbBuilder.buildObject();
             header.setType(cb.getType());
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/CheckMessageVersionHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/CheckMessageVersionHandler.java
index 665fad86e..0a2f719e2 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/CheckMessageVersionHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/CheckMessageVersionHandler.java
@@ -26,7 +26,8 @@ import org.opensaml.saml.common.SAMLVersion;
 import org.opensaml.saml.saml1.core.ResponseAbstractType;
 import org.opensaml.saml.saml2.core.StatusResponseType;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /** Handler that checks whether a SAML message has an appropriate version. */
 public class CheckMessageVersionHandler extends AbstractMessageHandler {
@@ -58,24 +59,24 @@ public class CheckMessageVersionHandler extends AbstractMessageHandler {
             if (!ignoreMissingOrUnrecognized) {
                 throw new MessageHandlerException("Message was not found");
             }
-        } else if (message instanceof org.opensaml.saml.saml1.core.RequestAbstractType) {
-            final SAMLVersion version = ((org.opensaml.saml.saml1.core.RequestAbstractType) message).getVersion();
-            if (version.getMajorVersion() != 1) { 
+        } else if (message instanceof org.opensaml.saml.saml1.core.RequestAbstractType req) {
+            final SAMLVersion version = req.getVersion();
+            if (version == null || version.getMajorVersion() != 1) { 
                 throw new MessageHandlerException("Request major version  was invalid");
             }
-        } else if (message instanceof ResponseAbstractType) {
-            final SAMLVersion version = ((ResponseAbstractType) message).getVersion();
-            if (version.getMajorVersion() != 1) { 
+        } else if (message instanceof ResponseAbstractType resp) {
+            final SAMLVersion version = resp.getVersion();
+            if (version == null || version.getMajorVersion() != 1) { 
                 throw new MessageHandlerException("Request major version  was invalid");
             }
-        } else if (message instanceof org.opensaml.saml.saml2.core.RequestAbstractType) {
-            final SAMLVersion version = ((org.opensaml.saml.saml2.core.RequestAbstractType) message).getVersion();
-            if (version.getMajorVersion() != 2) { 
+        } else if (message instanceof org.opensaml.saml.saml2.core.RequestAbstractType req) {
+            final SAMLVersion version = req.getVersion();
+            if (version == null || version.getMajorVersion() != 2) { 
                 throw new MessageHandlerException("Response major version  was invalid");
             }
-        } else if (message instanceof StatusResponseType) {
-            final SAMLVersion version = ((StatusResponseType) message).getVersion();
-            if (version.getMajorVersion() != 2) { 
+        } else if (message instanceof StatusResponseType resp) {
+            final SAMLVersion version = resp.getVersion();
+            if (version == null || version.getMajorVersion() != 2) { 
                 throw new MessageHandlerException("Response major version  was invalid");
             }
         } else {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/DefaultEndpointResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/DefaultEndpointResolver.java
index 599258791..947e46972 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/DefaultEndpointResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/DefaultEndpointResolver.java
@@ -24,12 +24,11 @@ import javax.annotation.Nonnull;
 import org.opensaml.saml.common.binding.AbstractEndpointResolver;
 import org.opensaml.saml.criterion.BindingCriterion;
 import org.opensaml.saml.criterion.EndpointCriterion;
-import org.opensaml.saml.criterion.StartsWithLocationCriterion;
 import org.opensaml.saml.saml2.metadata.Endpoint;
 import org.opensaml.saml.saml2.metadata.IndexedEndpoint;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 /**
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/PopulateSignatureSigningParametersHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/PopulateSignatureSigningParametersHandler.java
index f6fa73601..67e1101aa 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/PopulateSignatureSigningParametersHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/PopulateSignatureSigningParametersHandler.java
@@ -31,6 +31,7 @@ import org.opensaml.messaging.handler.MessageHandlerException;
 import org.opensaml.saml.common.messaging.context.SAMLMetadataContext;
 import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext;
 import org.opensaml.saml.criterion.RoleDescriptorCriterion;
+import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.opensaml.xmlsec.SecurityConfigurationSupport;
 import org.opensaml.xmlsec.SignatureSigningConfiguration;
 import org.opensaml.xmlsec.SignatureSigningParameters;
@@ -38,11 +39,11 @@ import org.opensaml.xmlsec.SignatureSigningParametersResolver;
 import org.opensaml.xmlsec.context.SecurityParametersContext;
 import org.opensaml.xmlsec.criterion.SignatureSigningConfigurationCriterion;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 
@@ -224,9 +225,12 @@ public class PopulateSignatureSigningParametersHandler extends AbstractMessageHa
         
         if (metadataContextLookupStrategy != null) {
             final SAMLMetadataContext metadataCtx = metadataContextLookupStrategy.apply(messageContext);
-            if (metadataCtx != null && metadataCtx.getRoleDescriptor() != null) {
-                log.debug("{} Adding metadata to resolution criteria for signing/digest algorithms", getLogPrefix());
-                criteria.add(new RoleDescriptorCriterion(metadataCtx.getRoleDescriptor()));
+            if (metadataCtx != null) {
+                final RoleDescriptor role = metadataCtx.getRoleDescriptor();
+                if (role != null) {
+                    log.debug("{} Adding metadata to resolution criteria for signing/digest algorithms", getLogPrefix());
+                    criteria.add(new RoleDescriptorCriterion(role));
+                }
             }
         }
         
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLAddAttributeConsumingServiceHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLAddAttributeConsumingServiceHandler.java
index ac8832ac6..362db3ce4 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLAddAttributeConsumingServiceHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLAddAttributeConsumingServiceHandler.java
@@ -43,10 +43,10 @@ import org.opensaml.saml.saml2.metadata.AttributeConsumingService;
 import org.opensaml.saml.saml2.metadata.RequestedAttribute;
 import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * SAML {@link org.opensaml.messaging.handler.MessageHandler} that attaches an {@link AttributeConsumingServiceContext}
@@ -180,11 +180,13 @@ public class SAMLAddAttributeConsumingServiceHandler extends AbstractMessageHand
      * @return a suitable AttributeConsumingService
      * @throws MessageHandlerException when the cloning failed
      */
-    private AttributeConsumingService attributeConsumingServiceFromRequestedAttributes() 
+    @Nonnull private AttributeConsumingService attributeConsumingServiceFromRequestedAttributes()
             throws MessageHandlerException {
         final AttributeConsumingService newAcs = (AttributeConsumingService)
                 XMLObjectSupport.buildXMLObject(AttributeConsumingService.DEFAULT_ELEMENT_NAME);
+        assert requestedAttributes != null;
         for (final RequestedAttribute attribute: requestedAttributes) {
+            assert attribute != null;
             try {
                 newAcs.getRequestedAttributes().add(
                         XMLObjectSupport.cloneXMLObject(attribute, CloneOutputOption.DropDOM));
@@ -221,11 +223,10 @@ public class SAMLAddAttributeConsumingServiceHandler extends AbstractMessageHand
     private class AuthnRequestLookup implements Function<MessageContext,AuthnRequest> {
 
         /** {@inheritDoc} */
-        @Override
-        public AuthnRequest apply(@Nullable final MessageContext input) {
+        @Nullable public AuthnRequest apply(@Nullable final MessageContext input) {
             if (input != null) {
                 final Object message = input.getMessage();
-                if (message != null && message instanceof AuthnRequest) {
+                if (message instanceof AuthnRequest) {
                     return (AuthnRequest) message;
                 }
             }
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLMetadataLookupHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLMetadataLookupHandler.java
index 82b75c543..74959b404 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLMetadataLookupHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLMetadataLookupHandler.java
@@ -43,11 +43,11 @@ import org.opensaml.saml.metadata.resolver.RoleDescriptorResolver;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 
@@ -161,30 +161,32 @@ public class SAMLMetadataLookupHandler extends AbstractMessageHandler {
         checkComponentActive();
 
         final AbstractSAMLEntityContext entityCtx = messageContext.getSubcontext(entityContextClass);
+        final String entityID = entityCtx != null ? entityCtx.getEntityId() : null;
+        final QName role = entityCtx != null ? entityCtx.getRole() : null;
 
-        if (entityCtx == null || entityCtx.getEntityId() == null || entityCtx.getRole() == null) {
+        if (entityCtx == null || entityID == null || role == null) {
             log.info("{} SAML entity context class '{}' missing or did not contain an entityID or role", getLogPrefix(),
                     entityContextClass.getName());
             return;
         }
-
-        final SAMLMetadataContext existingMetadataCtx = resolveExisting(messageContext,
-                entityCtx.getEntityId(), entityCtx.getRole());
+        
+        final SAMLMetadataContext existingMetadataCtx = resolveExisting(messageContext, entityID, role);
         if (existingMetadataCtx != null) {
             log.info("{} Resolved existing metadata context, re-using it", getLogPrefix());
             entityCtx.addSubcontext(existingMetadataCtx);
             return;
         }
 
-        final CriteriaSet criteria = buildLookupCriteria(messageContext);
+        final CriteriaSet criteria = buildLookupCriteria(messageContext, entityID, role);
         
         try {
             final RoleDescriptor roleMetadata = metadataResolver.resolveSingle(criteria);
             if (roleMetadata == null) {
-                if (criteria.contains(ProtocolCriterion.class)) {
+                final ProtocolCriterion protocolCriterion = criteria.get(ProtocolCriterion.class);
+                if (protocolCriterion != null) {
                     log.info("{} No metadata returned for {} in role {} with protocol {}",
                             getLogPrefix(), entityCtx.getEntityId(), entityCtx.getRole(),
-                            criteria.get(ProtocolCriterion.class).getProtocol());
+                            protocolCriterion.getProtocol());
                 } else {
                     log.info("{} No metadata returned for {} in role {}",
                             getLogPrefix(), entityCtx.getEntityId(), entityCtx.getRole());
@@ -209,30 +211,35 @@ public class SAMLMetadataLookupHandler extends AbstractMessageHandler {
      * Build the lookup criteria from the message context data.
      * 
      * @param messageContext the current message context
+     * @param entityID entityID to lookup
+     * @param role role to lookup
      * 
      * @return the new lookup criteria
      */
-    protected CriteriaSet buildLookupCriteria(final MessageContext messageContext) {
-        
-        // This must be present in the message context, but is already checked in the calling method
-        final AbstractSAMLEntityContext entityCtx = messageContext.getSubcontext(entityContextClass);
+    protected CriteriaSet buildLookupCriteria(@Nonnull final MessageContext messageContext,
+            @Nonnull final String entityID, @Nonnull final QName role) {
         
-        final EntityIdCriterion entityIdCriterion = new EntityIdCriterion(entityCtx.getEntityId());
-        final EntityRoleCriterion roleCriterion = new EntityRoleCriterion(entityCtx.getRole());
+        final EntityIdCriterion entityIdCriterion = new EntityIdCriterion(entityID);
+        final EntityRoleCriterion roleCriterion = new EntityRoleCriterion(role);
         
         ProtocolCriterion protocolCriterion = null;
         final SAMLProtocolContext protocolCtx = messageContext.getSubcontext(SAMLProtocolContext.class);
-        if (protocolCtx != null && protocolCtx.getProtocol() != null) {
-            protocolCriterion = new ProtocolCriterion(protocolCtx.getProtocol());
+        if (protocolCtx != null) {
+            final String protocol = protocolCtx.getProtocol();
+            if (protocol != null) {
+                protocolCriterion = new ProtocolCriterion(protocol);
+            }
         }
         
         final SAMLMetadataLookupParametersContext lookupParamsContext =
                 messageContext.getSubcontext(SAMLMetadataLookupParametersContext.class); 
         
         DetectDuplicateEntityIDsCriterion detectDuplicatesCriterion = null;
-        if (lookupParamsContext != null && lookupParamsContext.getDetectDuplicateEntityIDs() != null) {
-            detectDuplicatesCriterion =
-                    new DetectDuplicateEntityIDsCriterion(lookupParamsContext.getDetectDuplicateEntityIDs()); 
+        if (lookupParamsContext != null) {
+            final var detect = lookupParamsContext.getDetectDuplicateEntityIDs();
+            if (detect != null) {
+                detectDuplicatesCriterion = new DetectDuplicateEntityIDsCriterion(detect);
+            }
         }
         
         ProfileRequestContextCriterion prcCriterion = null;
@@ -269,13 +276,16 @@ public class SAMLMetadataLookupHandler extends AbstractMessageHandler {
             return null;
         }
 
+        assert copyContextStrategy != null;
         final SAMLMetadataContext existing = copyContextStrategy.apply(messageContext);
         if (existing != null) {
-            if (existing.getEntityDescriptor() != null && existing.getRoleDescriptor() != null) {
+            final EntityDescriptor existingEntity = existing.getEntityDescriptor();
+            final RoleDescriptor existingRole = existing.getRoleDescriptor();
+            if (existingEntity != null && existingRole != null) {
                 // Validate that existing data has the same entityID and role
-                if (Objects.equals(existing.getEntityDescriptor().getEntityID(), entityID)
-                        && (Objects.equals(existing.getRoleDescriptor().getElementQName(), role)
-                                || Objects.equals(existing.getRoleDescriptor().getSchemaType(), role))
+                if (Objects.equals(existingEntity.getEntityID(), entityID)
+                        && (Objects.equals(existingRole.getElementQName(), role)
+                                || Objects.equals(existingRole.getSchemaType(), role))
                         ) {
                     log.debug("{} Found an existing and suitable SAMLMetadataContext from which to copy ",
                             getLogPrefix());
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLOutboundDestinationHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLOutboundDestinationHandler.java
index ddf48d544..b13898b83 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLOutboundDestinationHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLOutboundDestinationHandler.java
@@ -28,7 +28,8 @@ import org.opensaml.saml.common.SAMLObject;
 import org.opensaml.saml.common.binding.BindingException;
 import org.opensaml.saml.common.binding.SAMLBindingSupport;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * Handler for outbound SAML protocol messages which adds the destination endpoint URL as the 'recipient'
@@ -60,6 +61,7 @@ public class SAMLOutboundDestinationHandler extends AbstractMessageHandler {
             } else if (samlMessage instanceof org.opensaml.saml.saml2.core.RequestAbstractType
                     || samlMessage instanceof org.opensaml.saml.saml2.core.StatusResponseType) {
                 log.debug("Adding destination to outbound SAML 2 protocol message: {}", endpointURL);
+                assert samlMessage != null;
                 SAMLBindingSupport.setSAML2Destination(samlMessage, endpointURL);
             }
         } catch (final BindingException e) {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLProtocolAndRoleHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLProtocolAndRoleHandler.java
index 783eec491..266152cec 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLProtocolAndRoleHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLProtocolAndRoleHandler.java
@@ -115,7 +115,7 @@ public class SAMLProtocolAndRoleHandler extends AbstractMessageHandler {
     
     /** {@inheritDoc} */
     @Override
-    protected void doInvoke(final MessageContext messageContext) throws MessageHandlerException {
+    protected void doInvoke(@Nonnull final MessageContext messageContext) throws MessageHandlerException {
         
         BaseContext copySource = null;
         if (copyContextLookup != null) {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLSOAPDecoderBodyHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLSOAPDecoderBodyHandler.java
index 559ec70e1..0796485dc 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLSOAPDecoderBodyHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/impl/SAMLSOAPDecoderBodyHandler.java
@@ -27,9 +27,11 @@ import org.opensaml.messaging.handler.AbstractMessageHandler;
 import org.opensaml.messaging.handler.MessageHandlerException;
 import org.opensaml.saml.common.SAMLObject;
 import org.opensaml.soap.messaging.context.SOAP11Context;
+import org.opensaml.soap.soap11.Body;
 import org.opensaml.soap.soap11.Envelope;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * Body handler impl for use with SAML SOAP message decoders.
@@ -48,11 +50,13 @@ public class SAMLSOAPDecoderBodyHandler extends AbstractMessageHandler {
             throw new MessageHandlerException("SOAP 1.1 context was not present in message context");
         }
         final Envelope soapMessage = soap11Context.getEnvelope();
-        if (soapMessage == null) {
-            throw new MessageHandlerException("SOAP 1.1 envelope was not present in SOAP context");
+        final Body soapBody = soapMessage != null ? soapMessage.getBody() : null; 
+        
+        if (soapBody == null) {
+            throw new MessageHandlerException("SOAP 1.1 envelope/body was not present in SOAP context");
         }
         
-        final List<XMLObject> soapBodyChildren = soapMessage.getBody().getUnknownXMLObjects();
+        final List<XMLObject> soapBodyChildren = soapBody.getUnknownXMLObjects();
         if (soapBodyChildren.size() < 1 || soapBodyChildren.size() > 1) {
             log.error("Unexpected number of children in the SOAP body, " + soapBodyChildren.size()
                     + ".  Unable to extract SAML message");
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/BaseSAMLSimpleSignatureSecurityHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/BaseSAMLSimpleSignatureSecurityHandler.java
index ef07ea026..b56dd67d6 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/BaseSAMLSimpleSignatureSecurityHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/BaseSAMLSimpleSignatureSecurityHandler.java
@@ -17,11 +17,11 @@
 
 package org.opensaml.saml.common.binding.security.impl;
 
-import java.util.Collections;
 import java.util.List;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
+import javax.xml.namespace.QName;
 
 import org.opensaml.core.criterion.EntityIdCriterion;
 import org.opensaml.messaging.context.MessageContext;
@@ -35,11 +35,11 @@ import org.opensaml.security.SecurityException;
 import org.opensaml.security.credential.Credential;
 import org.opensaml.security.credential.UsageType;
 import org.opensaml.security.criteria.UsageCriterion;
+import org.opensaml.xmlsec.SignatureValidationParameters;
 import org.opensaml.xmlsec.context.SecurityParametersContext;
 import org.opensaml.xmlsec.signature.support.SignatureTrustEngine;
 import org.opensaml.xmlsec.signature.support.SignatureValidationParametersCriterion;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Strings;
 
@@ -49,7 +49,9 @@ import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.codec.Base64Support;
 import net.shibboleth.shared.codec.DecodingException;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.NonnullSupplier;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
@@ -68,8 +70,14 @@ public abstract class BaseSAMLSimpleSignatureSecurityHandler extends AbstractMes
     /** The context representing the SAML peer entity. */
     @Nullable private SAMLPeerEntityContext peerContext;
     
-    /** The SAML protocol context in operation. */
-    @Nullable private SAMLProtocolContext samlProtocolContext;
+    /** The SAML protocol in use. */
+    @Nullable private String samlProtocol;
+    
+    /** The SAML role in use. */
+    @Nullable private QName samlRole;
+
+    /** Parameters for signature validation. */
+    @Nullable private SignatureValidationParameters signatureValidationParameters;
     
     /** Signature trust engine used to validate raw signatures. */
     @Nullable private SignatureTrustEngine trustEngine;
@@ -88,7 +96,7 @@ public abstract class BaseSAMLSimpleSignatureSecurityHandler extends AbstractMes
      * 
      * @return current HTTP request
      */
-    @Nullable public HttpServletRequest getHttpServletRequest() {
+    @NonnullAfterInit public HttpServletRequest getHttpServletRequest() {
         if (httpServletRequestSupplier == null) {
             return null;
         }
@@ -134,21 +142,23 @@ public abstract class BaseSAMLSimpleSignatureSecurityHandler extends AbstractMes
         }
         
         peerContext = messageContext.getSubcontext(SAMLPeerEntityContext.class);
-        if (peerContext == null || peerContext.getRole() == null) {
+        samlRole = peerContext != null ? peerContext.getRole() : null;
+        if (samlRole == null) {
             throw new MessageHandlerException("SAMLPeerEntityContext was missing or unpopulated");
         }
         
-        samlProtocolContext = messageContext.getSubcontext(SAMLProtocolContext.class);
-        if (samlProtocolContext == null || samlProtocolContext.getProtocol() == null) {
+        final SAMLProtocolContext samlProtocolContext = messageContext.getSubcontext(SAMLProtocolContext.class);
+        samlProtocol = samlProtocolContext != null ? samlProtocolContext.getProtocol() : null;
+        if (samlProtocol == null) {
             throw new MessageHandlerException("SAMLProtocolContext was missing or unpopulated");
         }
         
         final SecurityParametersContext secParams = messageContext.getSubcontext(SecurityParametersContext.class);
-        if (secParams == null || secParams.getSignatureValidationParameters() == null 
-                || secParams.getSignatureValidationParameters().getSignatureTrustEngine() == null) {
+        signatureValidationParameters = secParams != null ? secParams.getSignatureValidationParameters() : null;
+        trustEngine = signatureValidationParameters != null ? signatureValidationParameters.getSignatureTrustEngine() : null;
+        if (trustEngine == null) {
             throw new MessageHandlerException("No SignatureTrustEngine was available from the MessageContext");
         }
-        trustEngine = secParams.getSignatureValidationParameters().getSignatureTrustEngine();
         
         return true;
     }
@@ -176,6 +186,7 @@ public abstract class BaseSAMLSimpleSignatureSecurityHandler extends AbstractMes
                     getLogPrefix());
             return;
         }
+        assert sigAlg != null;
 
         final byte[] signedContent = getSignedContent();
         if (signedContent == null || signedContent.length == 0) {
@@ -203,8 +214,9 @@ public abstract class BaseSAMLSimpleSignatureSecurityHandler extends AbstractMes
 
         final List<Credential> candidateCredentials = getRequestCredentials(messageContext);
 
-        final String contextEntityID = peerContext.getEntityId();
-
+        final SAMLPeerEntityContext peerEntityContext = peerContext;
+        assert peerEntityContext != null;
+        final String contextEntityID = peerEntityContext.getEntityId();
         
         //TODO authentication flags - on peer or on message?
         
@@ -214,11 +226,11 @@ public abstract class BaseSAMLSimpleSignatureSecurityHandler extends AbstractMes
             final CriteriaSet criteriaSet = buildCriteriaSet(contextEntityID, messageContext);
             if (validateSignature(signature, signedContent, algorithmURI, criteriaSet, candidateCredentials)) {
                 log.debug("{} Validation of request simple signature succeeded", getLogPrefix());
-                if (!peerContext.isAuthenticated()) {
+                if (!peerEntityContext.isAuthenticated()) {
                     log.debug(
                             "{} Authentication via request simple signature succeeded for context issuer entity ID {}",
                             getLogPrefix(), contextEntityID);
-                    peerContext.setAuthenticated(true);
+                    peerEntityContext.setAuthenticated(true);
                 }
                 return;
             }
@@ -234,11 +246,11 @@ public abstract class BaseSAMLSimpleSignatureSecurityHandler extends AbstractMes
             final CriteriaSet criteriaSet = buildCriteriaSet(derivedEntityID, messageContext);
             if (validateSignature(signature, signedContent, algorithmURI, criteriaSet, candidateCredentials)) {
                 log.debug("{} Validation of request simple signature succeeded", getLogPrefix());
-                if (!peerContext.isAuthenticated()) {
+                if (!peerEntityContext.isAuthenticated()) {
                     log.debug("{} Authentication via request simple signature succeeded for derived issuer {}",
                             getLogPrefix(), derivedEntityID);
-                    peerContext.setEntityId(derivedEntityID);
-                    peerContext.setAuthenticated(true);
+                    peerEntityContext.setEntityId(derivedEntityID);
+                    peerEntityContext.setAuthenticated(true);
                 }
                 return;
             }
@@ -273,6 +285,7 @@ public abstract class BaseSAMLSimpleSignatureSecurityHandler extends AbstractMes
             @Nonnull @NonnullElements final List<Credential> candidateCredentials) throws MessageHandlerException {
 
         final SignatureTrustEngine engine = getTrustEngine();
+        assert engine != null;
 
         // Some bindings allow candidate signing credentials to be supplied (e.g. via ds:KeyInfo), some do not.
         // So have 2 slightly different cases.
@@ -315,7 +328,7 @@ public abstract class BaseSAMLSimpleSignatureSecurityHandler extends AbstractMes
     @Nonnull @NonnullElements protected List<Credential> getRequestCredentials(
             @Nonnull final MessageContext messageContext) throws MessageHandlerException {
         // This will be specific to the binding and message types, so no default.
-        return Collections.emptyList();
+        return CollectionSupport.emptyList();
     }
 
     /**
@@ -332,6 +345,7 @@ public abstract class BaseSAMLSimpleSignatureSecurityHandler extends AbstractMes
         if (Strings.isNullOrEmpty(signature)) {
             return null;
         }
+        assert signature != null;
         try {
             return Base64Support.decode(signature);
         } catch (final DecodingException e) {
@@ -380,18 +394,18 @@ public abstract class BaseSAMLSimpleSignatureSecurityHandler extends AbstractMes
 
         final CriteriaSet criteriaSet = new CriteriaSet();
         if (!Strings.isNullOrEmpty(entityID)) {
+            assert entityID != null;
             criteriaSet.add(new EntityIdCriterion(entityID));
         }
         
-        criteriaSet.add(new EntityRoleCriterion(peerContext.getRole()));
-        criteriaSet.add(new ProtocolCriterion(samlProtocolContext.getProtocol()));
+        assert samlRole != null;
+        criteriaSet.add(new EntityRoleCriterion(samlRole));
+        assert samlProtocol != null;
+        criteriaSet.add(new ProtocolCriterion(samlProtocol));
         criteriaSet.add(new UsageCriterion(UsageType.SIGNING));
         
-        final SecurityParametersContext secParamsContext =
-                messageContext.getSubcontext(SecurityParametersContext.class);
-        if (secParamsContext != null && secParamsContext.getSignatureValidationParameters() != null) {
-            criteriaSet.add(
-                    new SignatureValidationParametersCriterion(secParamsContext.getSignatureValidationParameters()));
+        if (signatureValidationParameters != null) {
+            criteriaSet.add(new SignatureValidationParametersCriterion(signatureValidationParameters));
         }
 
         return criteriaSet;
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/BaseSAMLXMLSignatureSecurityHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/BaseSAMLXMLSignatureSecurityHandler.java
index bf5f1361b..05eef7ebf 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/BaseSAMLXMLSignatureSecurityHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/BaseSAMLXMLSignatureSecurityHandler.java
@@ -19,6 +19,7 @@ package org.opensaml.saml.common.binding.security.impl;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
+import javax.xml.namespace.QName;
 
 import org.opensaml.core.criterion.EntityIdCriterion;
 import org.opensaml.messaging.context.MessageContext;
@@ -31,6 +32,7 @@ import org.opensaml.security.credential.UsageType;
 import org.opensaml.security.criteria.UsageCriterion;
 import org.opensaml.security.messaging.impl.BaseTrustEngineSecurityHandler;
 import org.opensaml.security.trust.TrustEngine;
+import org.opensaml.xmlsec.SignatureValidationParameters;
 import org.opensaml.xmlsec.context.SecurityParametersContext;
 import org.opensaml.xmlsec.signature.Signature;
 import org.opensaml.xmlsec.signature.support.SignatureValidationParametersCriterion;
@@ -49,6 +51,15 @@ public abstract class BaseSAMLXMLSignatureSecurityHandler extends BaseTrustEngin
     
     /** The SAML protocol context in operation. */
     @Nullable private SAMLProtocolContext samlProtocolContext;
+
+    /** The SAML protocol in use. */
+    @Nullable private String samlProtocol;
+    
+    /** The SAML role in use. */
+    @Nullable private QName samlRole;
+
+    /** Parameters for signature validation. */
+    @Nullable private SignatureValidationParameters signatureValidationParameters;
     
     /**
      * Get the {@link SAMLPeerEntityContext} associated with the message.
@@ -71,20 +82,28 @@ public abstract class BaseSAMLXMLSignatureSecurityHandler extends BaseTrustEngin
     /** {@inheritDoc} */
     @Override
     protected boolean doPreInvoke(@Nonnull final MessageContext messageContext) throws MessageHandlerException {
-        
+
         if (!super.doPreInvoke(messageContext)) {
             return false;
         }
         
         peerContext = messageContext.getSubcontext(SAMLPeerEntityContext.class);
-        if (peerContext == null || peerContext.getRole() == null) {
+        samlRole = peerContext != null ? peerContext.getRole() : null;
+        if (samlRole == null) {
             throw new MessageHandlerException("SAMLPeerEntityContext was missing or unpopulated");
         }
         
         samlProtocolContext = messageContext.getSubcontext(SAMLProtocolContext.class);
-        if (samlProtocolContext == null || samlProtocolContext.getProtocol() == null) {
+        samlProtocol = samlProtocolContext != null ? samlProtocolContext.getProtocol() : null;
+        if (samlProtocol == null) {
             throw new MessageHandlerException("SAMLProtocolContext was missing or unpopulated");
         }
+     
+        // Shouldn't happen, as this is populated via superclass invoking trust engine lookup.
+        if (signatureValidationParameters == null) {
+            final SecurityParametersContext secParams = messageContext.getSubcontext(SecurityParametersContext.class);
+            signatureValidationParameters = secParams != null ? secParams.getSignatureValidationParameters() : null;
+        }
         
         return true;
     }
@@ -92,11 +111,17 @@ public abstract class BaseSAMLXMLSignatureSecurityHandler extends BaseTrustEngin
     /** {@inheritDoc} */
     @Override
     @Nullable protected TrustEngine<Signature> resolveTrustEngine(@Nonnull final MessageContext messageContext) {
-        final SecurityParametersContext secParams = messageContext.getSubcontext(SecurityParametersContext.class);
-        if (secParams == null || secParams.getSignatureValidationParameters() == null) {
-            return null;
+
+        if (signatureValidationParameters == null) {
+            final SecurityParametersContext secParams = messageContext.getSubcontext(SecurityParametersContext.class);
+            signatureValidationParameters = secParams != null ? secParams.getSignatureValidationParameters() : null;
         }
-        return secParams.getSignatureValidationParameters().getSignatureTrustEngine();
+
+        if (signatureValidationParameters != null) {
+            return signatureValidationParameters.getSignatureTrustEngine();
+        }
+        
+        return null;
     }
 
     /** {@inheritDoc} */
@@ -106,18 +131,18 @@ public abstract class BaseSAMLXMLSignatureSecurityHandler extends BaseTrustEngin
         
         final CriteriaSet criteriaSet = new CriteriaSet();
         if (!Strings.isNullOrEmpty(entityID)) {
+            assert entityID != null;
             criteriaSet.add(new EntityIdCriterion(entityID) );
         }
 
-        criteriaSet.add(new EntityRoleCriterion(peerContext.getRole()));
-        criteriaSet.add(new ProtocolCriterion(samlProtocolContext.getProtocol()));
+        assert samlRole != null;
+        criteriaSet.add(new EntityRoleCriterion(samlRole));
+        assert samlProtocol != null;
+        criteriaSet.add(new ProtocolCriterion(samlProtocol));
         criteriaSet.add( new UsageCriterion(UsageType.SIGNING) );
         
-        final SecurityParametersContext secParamsContext =
-                messageContext.getSubcontext(SecurityParametersContext.class);
-        if (secParamsContext != null && secParamsContext.getSignatureValidationParameters() != null) {
-            criteriaSet.add(
-                    new SignatureValidationParametersCriterion(secParamsContext.getSignatureValidationParameters()));
+        if (signatureValidationParameters != null) {
+            criteriaSet.add(new SignatureValidationParametersCriterion(signatureValidationParameters));
         }
         
         return criteriaSet;
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/CheckAndRecordServerTLSEntityAuthenticationtHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/CheckAndRecordServerTLSEntityAuthenticationtHandler.java
index d27111cd2..f3ab1551b 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/CheckAndRecordServerTLSEntityAuthenticationtHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/CheckAndRecordServerTLSEntityAuthenticationtHandler.java
@@ -32,9 +32,9 @@ import org.opensaml.saml.common.messaging.context.AbstractAuthenticatableSAMLEnt
 import org.opensaml.saml.common.messaging.context.SAMLPeerEntityContext;
 import org.opensaml.security.httpclient.HttpClientSecurityConstants;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * Handler implementation that checks and records the result of {@link org.apache.hc.client5.http.classic.HttpClient}
@@ -50,20 +50,19 @@ import net.shibboleth.shared.logic.Constraint;
 public class CheckAndRecordServerTLSEntityAuthenticationtHandler extends AbstractMessageHandler {
     
     /** Logger. */
-    private Logger log = LoggerFactory.getLogger(CheckAndRecordServerTLSEntityAuthenticationtHandler.class);
+    @Nonnull private Logger log = LoggerFactory.getLogger(CheckAndRecordServerTLSEntityAuthenticationtHandler.class);
     
     /** The strategy function for resolving the {@link HttpClientContext to evaluate}. */
     @Nonnull private ContextDataLookupFunction<MessageContext, HttpClientContext> httpClientContextLookup;
     
     /** The strategy function for resolving the authenticated entityID. */
-    @Nonnull private ContextDataLookupFunction<MessageContext, String> entityIDLookup;
+    @Nullable private ContextDataLookupFunction<MessageContext, String> entityIDLookup;
     
     /** The actual context class holding the authenticatable SAML entity. */
     @Nonnull private Class<? extends AbstractAuthenticatableSAMLEntityContext> entityContextClass;
     
     /** Constructor. */
     public CheckAndRecordServerTLSEntityAuthenticationtHandler() {
-        super();
         entityContextClass = SAMLPeerEntityContext.class;
         httpClientContextLookup = new DefaultHttpClientContextLookup();
         entityIDLookup = new OperationContextEntityIDLookup(entityContextClass);
@@ -127,6 +126,7 @@ public class CheckAndRecordServerTLSEntityAuthenticationtHandler extends Abstrac
                 entityContext.setAuthenticated(true);
                 if (entityContext.getEntityId() == null && entityIDLookup != null) {
                     log.debug("Context entityID was null, attempting to resolve");
+                    assert entityIDLookup != null;
                     final String entityID = entityIDLookup.apply(messageContext);
                     if (entityID != null) {
                         log.debug("Resolved authenticated entityID, populating on entity context: {}", entityID);
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/EndpointURLSchemeSecurityHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/EndpointURLSchemeSecurityHandler.java
index 93d5920e4..8180e1f79 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/EndpointURLSchemeSecurityHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/EndpointURLSchemeSecurityHandler.java
@@ -28,7 +28,8 @@ import org.opensaml.saml.common.binding.BindingException;
 import org.opensaml.saml.common.binding.SAMLBindingSupport;
 import org.opensaml.saml.common.messaging.SAMLMessageSecuritySupport;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * Class which verifies that the {@link org.opensaml.saml.saml2.metadata.Endpoint}
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/InResponseToSecurityHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/InResponseToSecurityHandler.java
index 47e142c47..84c842cf7 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/InResponseToSecurityHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/InResponseToSecurityHandler.java
@@ -20,6 +20,7 @@ package org.opensaml.saml.common.binding.security.impl;
 import java.util.Objects;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.opensaml.messaging.context.InOutOperationContext;
 import org.opensaml.messaging.context.MessageContext;
@@ -27,8 +28,8 @@ import org.opensaml.messaging.handler.AbstractMessageHandler;
 import org.opensaml.messaging.handler.MessageHandlerException;
 import org.opensaml.saml.common.SAMLObject;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 
 /**
@@ -38,7 +39,7 @@ import net.shibboleth.shared.primitive.StringSupport;
 public class InResponseToSecurityHandler extends AbstractMessageHandler {
     
     /** Logger. */
-    private Logger log = LoggerFactory.getLogger(InResponseToSecurityHandler.class);
+    @Nonnull private Logger log = LoggerFactory.getLogger(InResponseToSecurityHandler.class);
 
     /** {@inheritDoc} */
     protected void doInvoke(@Nonnull final MessageContext messageContext) throws MessageHandlerException {
@@ -61,16 +62,14 @@ public class InResponseToSecurityHandler extends AbstractMessageHandler {
      * @param messageContext the message context
      * @return the outbound request ID, or null
      */
-    private String resolveOutboundRequestID(@Nonnull final MessageContext messageContext) {
-        if (messageContext.getParent() instanceof InOutOperationContext) {
-            final MessageContext outboundContext = 
-                    ((InOutOperationContext)messageContext.getParent()).getOutboundMessageContext();
-            if (outboundContext != null && outboundContext.getMessage() instanceof SAMLObject) {
-                final SAMLObject outboundMessage = (SAMLObject) outboundContext.getMessage();
-                if (outboundMessage instanceof org.opensaml.saml.saml2.core.RequestAbstractType) {
-                    return ((org.opensaml.saml.saml2.core.RequestAbstractType)outboundMessage).getID();
-                } else if (outboundMessage instanceof org.opensaml.saml.saml1.core.RequestAbstractType) {
-                    return ((org.opensaml.saml.saml1.core.RequestAbstractType)outboundMessage).getID();
+    @Nullable private String resolveOutboundRequestID(@Nonnull final MessageContext messageContext) {
+        if (messageContext.getParent() instanceof InOutOperationContext inout) {
+            final MessageContext outboundContext = inout.getOutboundMessageContext();
+            if (outboundContext != null && outboundContext.getMessage() instanceof SAMLObject outboundMessage) {
+                if (outboundMessage instanceof org.opensaml.saml.saml2.core.RequestAbstractType req) {
+                    return req.getID();
+                } else if (outboundMessage instanceof org.opensaml.saml.saml1.core.RequestAbstractType req) {
+                    return req.getID();
                 }
             }
         }
@@ -83,16 +82,14 @@ public class InResponseToSecurityHandler extends AbstractMessageHandler {
      * @param messageContext the message context
      * @return the inbound inResponseTo, or null
      */
-    private String resolveInboundInResponseTo(@Nonnull final MessageContext messageContext) {
-        if (messageContext.getParent() instanceof InOutOperationContext) {
-            final MessageContext inboundContext = 
-                    ((InOutOperationContext)messageContext.getParent()).getInboundMessageContext();
-            if (inboundContext != null && inboundContext.getMessage() instanceof SAMLObject) {
-                final SAMLObject inboundMessage = (SAMLObject) inboundContext.getMessage();
-                if (inboundMessage instanceof org.opensaml.saml.saml2.core.StatusResponseType) {
-                    return ((org.opensaml.saml.saml2.core.StatusResponseType)inboundMessage).getInResponseTo();
-                } else if (inboundMessage instanceof org.opensaml.saml.saml1.core.ResponseAbstractType) {
-                    return ((org.opensaml.saml.saml1.core.ResponseAbstractType)inboundMessage).getInResponseTo();
+    @Nullable private String resolveInboundInResponseTo(@Nonnull final MessageContext messageContext) {
+        if (messageContext.getParent() instanceof InOutOperationContext inout) {
+            final MessageContext inboundContext = inout.getInboundMessageContext();
+            if (inboundContext != null && inboundContext.getMessage() instanceof SAMLObject inboundMessage) {
+                if (inboundMessage instanceof org.opensaml.saml.saml2.core.StatusResponseType resp) {
+                    return resp.getInResponseTo();
+                } else if (inboundMessage instanceof org.opensaml.saml.saml1.core.ResponseAbstractType resp) {
+                    return resp.getInResponseTo();
                 }
             }
         }
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageLifetimeSecurityHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageLifetimeSecurityHandler.java
index 90b244cb6..2ebeaf264 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageLifetimeSecurityHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/MessageLifetimeSecurityHandler.java
@@ -27,9 +27,9 @@ import org.opensaml.messaging.handler.AbstractMessageHandler;
 import org.opensaml.messaging.handler.MessageHandlerException;
 import org.opensaml.saml.common.messaging.context.SAMLMessageInfoContext;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * Security message handler implementation that checks for validity of SAML message issue instant date and time.
@@ -124,7 +124,8 @@ public class MessageLifetimeSecurityHandler extends AbstractMessageHandler {
     public void doInvoke(@Nonnull final MessageContext messageContext) throws MessageHandlerException {
         final SAMLMessageInfoContext msgInfoContext = messageContext.ensureSubcontext(SAMLMessageInfoContext.class);
         
-        if (msgInfoContext.getMessageIssueInstant() == null) {
+        final Instant issueInstant = msgInfoContext.getMessageIssueInstant();
+        if (issueInstant == null) {
             if (requiredRule) {
                 log.warn("{} Inbound SAML message issue instant not present in message context", getLogPrefix());
                 throw new MessageHandlerException("Inbound SAML message issue instant not present in message context");
@@ -132,7 +133,6 @@ public class MessageLifetimeSecurityHandler extends AbstractMessageHandler {
             return;
         }
 
-        final Instant issueInstant = msgInfoContext.getMessageIssueInstant();
         final Instant now = Instant.now();
         final Instant latestValid = now.plus(getClockSkew().abs());
         final Instant expiration = issueInstant.plus(getClockSkew().abs()).plus(getMessageLifetime());
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/ReceivedEndpointSecurityHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/ReceivedEndpointSecurityHandler.java
index 34ceb27cc..c4f74492f 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/ReceivedEndpointSecurityHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/ReceivedEndpointSecurityHandler.java
@@ -26,7 +26,6 @@ import org.opensaml.messaging.handler.AbstractMessageHandler;
 import org.opensaml.messaging.handler.MessageHandlerException;
 import org.opensaml.saml.common.binding.SAMLBindingSupport;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import jakarta.servlet.http.HttpServletRequest;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
@@ -36,6 +35,7 @@ import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.net.URIComparator;
 import net.shibboleth.shared.net.URIException;
 import net.shibboleth.shared.net.impl.BasicURLComparator;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.NonnullSupplier;
 import net.shibboleth.shared.primitive.StringSupport;
 
@@ -56,7 +56,6 @@ public class ReceivedEndpointSecurityHandler extends AbstractMessageHandler {
 
     /** Constructor. */
     public ReceivedEndpointSecurityHandler() {
-        super();
         uriComparator = new BasicURLComparator();
     }
 
@@ -116,9 +115,7 @@ public class ReceivedEndpointSecurityHandler extends AbstractMessageHandler {
     protected void doInitialize() throws ComponentInitializationException {
         super.doInitialize();
         
-        if (uriComparator == null) {
-            throw new ComponentInitializationException("URIComparator cannot be null");
-        } else if (getHttpServletRequest() == null) {
+        if (getHttpServletRequest() == null) {
             throw new ComponentInitializationException("HttpServletRequest cannot be null");
         }
     }
@@ -143,10 +140,9 @@ public class ReceivedEndpointSecurityHandler extends AbstractMessageHandler {
      * @throws URIException if one of the URI's to evaluate is invalid 
      */
     protected boolean compareEndpointURIs(@Nonnull @NotEmpty final String messageDestination, 
-            @Nonnull @NotEmpty final String receiverEndpoint, 
+            @Nullable final String receiverEndpoint, 
             @Nonnull final URIComparator comparator) throws URIException {
         Constraint.isNotNull(messageDestination, "Message destination URI was null");
-        Constraint.isNotNull(receiverEndpoint, "Receiver endpoint URI was null");
         Constraint.isNotNull(comparator, "URIComparator was null");
         return comparator.compare(messageDestination, receiverEndpoint);
     }
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/SAMLMDClientCertAuthSecurityHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/SAMLMDClientCertAuthSecurityHandler.java
index da488c9a2..12489f060 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/SAMLMDClientCertAuthSecurityHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/SAMLMDClientCertAuthSecurityHandler.java
@@ -29,10 +29,10 @@ import org.opensaml.saml.criterion.EntityRoleCriterion;
 import org.opensaml.saml.criterion.ProtocolCriterion;
 import org.opensaml.security.messaging.impl.BaseClientCertAuthSecurityHandler;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 /**
@@ -47,17 +47,16 @@ import net.shibboleth.shared.resolver.CriteriaSet;
 public class SAMLMDClientCertAuthSecurityHandler extends BaseClientCertAuthSecurityHandler {
     
     /** Logger. */
-    private Logger log = LoggerFactory.getLogger(SAMLMDClientCertAuthSecurityHandler.class);
+    @Nonnull private Logger log = LoggerFactory.getLogger(SAMLMDClientCertAuthSecurityHandler.class);
     
     /** The actual context class holding the authenticatable SAML entity. */
-    private Class<? extends AbstractAuthenticatableSAMLEntityContext> entityContextClass;
+    @Nonnull private Class<? extends AbstractAuthenticatableSAMLEntityContext> entityContextClass;
 
     /**
      * Constructor.
      *
      */
     public SAMLMDClientCertAuthSecurityHandler() {
-        super();
         entityContextClass = SAMLPeerEntityContext.class;
     }
     
@@ -89,22 +88,21 @@ public class SAMLMDClientCertAuthSecurityHandler extends BaseClientCertAuthSecur
     @Nonnull protected CriteriaSet buildCriteriaSet(@Nullable final String entityID,
             @Nonnull final MessageContext messageContext) throws MessageHandlerException {
         
-        final CriteriaSet criteriaSet = super.buildCriteriaSet(entityID, messageContext);
+        CriteriaSet criteriaSet = super.buildCriteriaSet(entityID, messageContext);
+        if (criteriaSet == null) {
+            // Not expected...
+            criteriaSet = new CriteriaSet();
+        }
         
         try {
             log.trace("Attempting to build criteria based on contents of entity contxt class of type: {}", 
                     entityContextClass.getName());
             final AbstractAuthenticatableSAMLEntityContext entityContext = 
-                    messageContext.getSubcontext(entityContextClass);
-            Constraint.isNotNull(entityContext, "Required authenticatable SAML entity context was not present "
-                    + "in message context: " +  entityContextClass.getName());
-            Constraint.isNotNull(entityContext.getRole(), "SAML entity role was null");
-            criteriaSet.add(new EntityRoleCriterion(entityContext.getRole()));
+                    messageContext.ensureSubcontext(entityContextClass);
+            criteriaSet.add(new EntityRoleCriterion(Constraint.isNotNull(entityContext.getRole(), "SAML entity role was null")));
             
-            final SAMLProtocolContext protocolContext = messageContext.getSubcontext(SAMLProtocolContext.class);
-            Constraint.isNotNull(protocolContext, "SAMLProtocolContext was null");
-            Constraint.isNotNull(protocolContext.getProtocol(), "SAML protocol was null");
-            criteriaSet.add(new ProtocolCriterion(protocolContext.getProtocol()));
+            final SAMLProtocolContext protocolContext = messageContext.ensureSubcontext(SAMLProtocolContext.class);
+            criteriaSet.add(new ProtocolCriterion(Constraint.isNotNull(protocolContext.getProtocol(), "SAML protocol was null")));
         } catch (final ConstraintViolationException e) {
             throw new MessageHandlerException(e);
         }
@@ -121,7 +119,7 @@ public class SAMLMDClientCertAuthSecurityHandler extends BaseClientCertAuthSecur
                     entityContext.getEntityId(), entityContext.getClass().getName());
             return entityContext.getEntityId();
         }
-        log.trace("Authenticatable entityID context was not present: {}", entityContext.getClass().getName());
+        log.trace("Authenticatable entityID context was not present: {}", entityContextClass.getName());
         return null;
     }
 
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/SAMLOutboundProtocolMessageSigningHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/SAMLOutboundProtocolMessageSigningHandler.java
index 915f71502..3b0702db0 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/SAMLOutboundProtocolMessageSigningHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/SAMLOutboundProtocolMessageSigningHandler.java
@@ -31,7 +31,8 @@ import org.opensaml.security.SecurityException;
 import org.opensaml.xmlsec.SignatureSigningParameters;
 import org.opensaml.xmlsec.signature.support.SignatureException;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * A message handler implementation that signs an outbound SAML protocol message if the message context
@@ -93,16 +94,17 @@ public class SAMLOutboundProtocolMessageSigningHandler extends AbstractMessageHa
      */
     private boolean isErrorResponse(@Nullable final Object message) {
         if (message != null) {
-            if (message instanceof Response) {
-                if (((Response) message).getStatus() != null) {
-                    final org.opensaml.saml.saml1.core.StatusCode s1 = ((Response) message).getStatus().getStatusCode();
+            if (message instanceof Response resp) {
+                final org.opensaml.saml.saml1.core.Status status = resp.getStatus();
+                if (status != null) {
+                    final org.opensaml.saml.saml1.core.StatusCode s1 = status.getStatusCode();
                     return s1 != null && s1.getValue() != null
                             && !org.opensaml.saml.saml1.core.StatusCode.SUCCESS.equals(s1.getValue());
                 }
-            } else if (message instanceof StatusResponseType) {
-                if (((StatusResponseType) message).getStatus() != null) {
-                    final org.opensaml.saml.saml2.core.StatusCode s2 =
-                            ((StatusResponseType) message).getStatus().getStatusCode();
+            } else if (message instanceof StatusResponseType resp) {
+                final org.opensaml.saml.saml2.core.Status status = resp.getStatus();
+                if (status != null) {
+                    final org.opensaml.saml.saml2.core.StatusCode s2 = status.getStatusCode();
                     return s2 != null && s2.getValue() != null
                             && !org.opensaml.saml.saml2.core.StatusCode.SUCCESS.equals(s2.getValue());
                 }
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/SAMLProtocolMessageXMLSignatureSecurityHandler.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/SAMLProtocolMessageXMLSignatureSecurityHandler.java
index bd96d094c..cee2a8472 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/SAMLProtocolMessageXMLSignatureSecurityHandler.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/common/binding/security/impl/SAMLProtocolMessageXMLSignatureSecurityHandler.java
@@ -29,7 +29,8 @@ import org.opensaml.xmlsec.signature.Signature;
 import org.opensaml.xmlsec.signature.support.SignatureException;
 import org.opensaml.xmlsec.signature.support.SignaturePrevalidator;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * SAML security message handler which validates the signature (if present) on the
@@ -102,6 +103,8 @@ public class SAMLProtocolMessageXMLSignatureSecurityHandler extends BaseSAMLXMLS
             return;
         }
         final Signature signature = signableObject.getSignature();
+        
+        assert signature != null;
 
         performPrevalidation(signature);
 
@@ -124,7 +127,7 @@ public class SAMLProtocolMessageXMLSignatureSecurityHandler extends BaseSAMLXMLS
         //TODO authentication flags - on peer or on message?
         
         final SAMLPeerEntityContext peerContext = getSAMLPeerEntityContext();
-        if (peerContext.getEntityId() != null) {
+        if (peerContext != null && peerContext.getEntityId() != null) {
             final String contextEntityID = peerContext.getEntityId();
             final String msgType = signableObject.getElementQName().toString();
             log.debug("{} Attempting to verify signature on signed SAML protocol message type: {}",
@@ -158,9 +161,10 @@ public class SAMLProtocolMessageXMLSignatureSecurityHandler extends BaseSAMLXMLS
      * @throws MessageHandlerException thrown if the signature element fails pre-validation
      */
     protected void performPrevalidation(@Nonnull final Signature signature) throws MessageHandlerException {
-        if (getSignaturePrevalidator() != null) {
+        final var prevalidator = getSignaturePrevalidator();
+        if (prevalidator != null) {
             try {
-                getSignaturePrevalidator().validate(signature);
+                prevalidator.validate(signature);
             } catch (final SignatureException e) {
                 log.debug("{} Protocol message signature failed signature pre-validation: {}", getLogPrefix(),
                         e.getMessage());
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/config/impl/XMLObjectProviderInitializer.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/config/impl/XMLObjectProviderInitializer.java
index 9b036e18c..5dd9a4635 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/config/impl/XMLObjectProviderInitializer.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/config/impl/XMLObjectProviderInitializer.java
@@ -17,6 +17,8 @@
 
 package org.opensaml.saml.config.impl;
 
+import javax.annotation.Nonnull;
+
 import org.opensaml.core.xml.config.AbstractXMLObjectProviderInitializer;
 
 /**
@@ -25,7 +27,7 @@ import org.opensaml.core.xml.config.AbstractXMLObjectProviderInitializer;
 public class XMLObjectProviderInitializer extends AbstractXMLObjectProviderInitializer {
     
     /** Config resources. */
-    private static String[] configs = {
+    @Nonnull private static String[] configs = {
         "/saml1-assertion-config.xml", 
         "/saml1-metadata-config.xml", 
         "/saml1-protocol-config.xml",
@@ -50,7 +52,7 @@ public class XMLObjectProviderInitializer extends AbstractXMLObjectProviderIniti
 
     /** {@inheritDoc} */
     @Override
-    protected String[] getConfigResources() {
+    @Nonnull protected String[] getConfigResources() {
         return configs;
     }
 
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/idpdisco/impl/DiscoveryResponseBuilder.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/idpdisco/impl/DiscoveryResponseBuilder.java
index 02f631b44..440341c1a 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/idpdisco/impl/DiscoveryResponseBuilder.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/idpdisco/impl/DiscoveryResponseBuilder.java
@@ -18,6 +18,7 @@
 package org.opensaml.saml.ext.idpdisco.impl;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.opensaml.saml.common.AbstractSAMLObjectBuilder;
 import org.opensaml.saml.common.xml.SAMLConstants;
@@ -34,8 +35,8 @@ public class DiscoveryResponseBuilder extends AbstractSAMLObjectBuilder<Discover
     }
 
     /** {@inheritDoc} */
-    @Nonnull public DiscoveryResponse buildObject(final String namespaceURI, final String localName,
-            final String namespacePrefix) {
+    @Nonnull public DiscoveryResponse buildObject(@Nullable final String namespaceURI, @Nonnull final String localName,
+            @Nullable final String namespacePrefix) {
         return new DiscoveryResponseImpl(namespaceURI, localName, namespacePrefix);
     }
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/reqattr/impl/RequestedAttributesBuilder.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/reqattr/impl/RequestedAttributesBuilder.java
index 68beeed3a..be2679438 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/reqattr/impl/RequestedAttributesBuilder.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/reqattr/impl/RequestedAttributesBuilder.java
@@ -17,6 +17,9 @@
 
 package org.opensaml.saml.ext.reqattr.impl;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
 import org.opensaml.saml.common.AbstractSAMLObjectBuilder;
 import org.opensaml.saml.common.xml.SAMLConstants;
 import org.opensaml.saml.ext.reqattr.RequestedAttributes;
@@ -29,15 +32,16 @@ public class RequestedAttributesBuilder extends AbstractSAMLObjectBuilder<Reques
 
     /** {@inheritDoc} */
     @Override
-    public RequestedAttributes buildObject() {
+    @Nonnull public RequestedAttributes buildObject() {
         return buildObject(SAMLConstants.SAML20PREQ_ATTR_NS, RequestedAttributes.DEFAULT_ELEMENT_LOCAL_NAME,
                 SAMLConstants.SAML20PREQ_ATTRR_PREFIX);
     }
 
     /** {@inheritDoc} */
     @Override
-    public RequestedAttributes buildObject(final String namespaceURI, final String localName,
-            final String namespacePrefix) {
+    @Nonnull public RequestedAttributes buildObject(@Nullable final String namespaceURI,
+            @Nonnull final String localName, @Nullable final String namespacePrefix) {
         return new RequestedAttributesImpl(namespaceURI, localName, namespacePrefix);
     }
-}
+
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/reqattr/impl/RequestedAttributesImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/reqattr/impl/RequestedAttributesImpl.java
index 265ee0397..28e47b9af 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/reqattr/impl/RequestedAttributesImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/reqattr/impl/RequestedAttributesImpl.java
@@ -17,9 +17,11 @@
 
 package org.opensaml.saml.ext.reqattr.impl;
 
-import java.util.ArrayList;
 import java.util.List;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
 import org.opensaml.core.xml.AbstractXMLObject;
 import org.opensaml.core.xml.XMLObject;
 import org.opensaml.core.xml.util.IndexedXMLObjectChildrenList;
@@ -27,6 +29,11 @@ import org.opensaml.core.xml.util.XMLObjectChildrenList;
 import org.opensaml.saml.ext.reqattr.RequestedAttributes;
 import org.opensaml.saml.saml2.metadata.RequestedAttribute;
 
+import net.shibboleth.shared.annotation.constraint.Live;
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
+
 
 /**
  * A concrete {@link RequestedAttributes}.
@@ -34,7 +41,7 @@ import org.opensaml.saml.saml2.metadata.RequestedAttribute;
 public class RequestedAttributesImpl extends AbstractXMLObject implements RequestedAttributes {
 
     /** The policies. */
-    private XMLObjectChildrenList<RequestedAttribute> requestedAttributes;
+    @Nonnull private XMLObjectChildrenList<RequestedAttribute> requestedAttributes;
 
     /**
      * Constructor.
@@ -43,24 +50,21 @@ public class RequestedAttributesImpl extends AbstractXMLObject implements Reques
      * @param elementLocalName the local name of the XML element this Object represents
      * @param namespacePrefix the prefix for the given namespace
      */
-    protected RequestedAttributesImpl(final String namespaceURI, final String elementLocalName,
-            final String namespacePrefix) {
+    protected RequestedAttributesImpl(@Nullable final String namespaceURI, @Nonnull final String elementLocalName,
+            @Nullable final String namespacePrefix) {
         super(namespaceURI, elementLocalName, namespacePrefix);
         requestedAttributes = new IndexedXMLObjectChildrenList<>(this);
     }
 
     /** {@inheritDoc} */
-    @Override
-    public List<RequestedAttribute> getRequestedAttributes() {
+    @Nonnull @Live public List<RequestedAttribute> getRequestedAttributes() {
         return requestedAttributes;
     }
 
     /** {@inheritDoc} */
-    @Override
-    public List<XMLObject> getOrderedChildren() {
-        final ArrayList<XMLObject> children = new ArrayList<>();
-        children.addAll(requestedAttributes);
-        return children;
+    @Nullable @NotLive @Unmodifiable public List<XMLObject> getOrderedChildren() {
+        
+        return CollectionSupport.copyToList(requestedAttributes);
     }
 
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/reqattr/impl/RequestedAttributesUnmarshaller.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/reqattr/impl/RequestedAttributesUnmarshaller.java
index bad695977..0a4068241 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/reqattr/impl/RequestedAttributesUnmarshaller.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/ext/reqattr/impl/RequestedAttributesUnmarshaller.java
@@ -17,6 +17,8 @@
 
 package org.opensaml.saml.ext.reqattr.impl;
 
+import javax.annotation.Nonnull;
+
 import org.opensaml.core.xml.XMLObject;
 import org.opensaml.core.xml.io.UnmarshallingException;
 import org.opensaml.saml.common.AbstractSAMLObjectUnmarshaller;
@@ -31,7 +33,7 @@ public class RequestedAttributesUnmarshaller extends AbstractSAMLObjectUnmarshal
 
     /** {@inheritDoc} */
     @Override
-    protected void processChildElement(final XMLObject parentObject, final XMLObject childObject)
+    protected void processChildElement(@Nonnull final XMLObject parentObject, @Nonnull final XMLObject childObject)
             throws UnmarshallingException {
         final RequestedAttributes pPath = (RequestedAttributes) parentObject;
 
@@ -42,4 +44,4 @@ public class RequestedAttributesUnmarshaller extends AbstractSAMLObjectUnmarshal
         }
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/criteria/entity/impl/EvaluableEntityRoleEntityDescriptorCriterion.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/criteria/entity/impl/EvaluableEntityRoleEntityDescriptorCriterion.java
index dbc8c36d0..596207419 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/criteria/entity/impl/EvaluableEntityRoleEntityDescriptorCriterion.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/criteria/entity/impl/EvaluableEntityRoleEntityDescriptorCriterion.java
@@ -19,6 +19,7 @@ package org.opensaml.saml.metadata.criteria.entity.impl;
 
 import java.util.Objects;
 
+import javax.annotation.Nonnull;
 import javax.xml.namespace.QName;
 
 import org.opensaml.saml.criterion.EntityRoleCriterion;
@@ -36,8 +37,7 @@ import net.shibboleth.shared.logic.Constraint;
 public class EvaluableEntityRoleEntityDescriptorCriterion implements EvaluableEntityDescriptorCriterion {
     
     /** Entity role. */
-    private QName role;
-
+    @Nonnull private QName role;
     
     /**
      * Constructor.
@@ -92,4 +92,4 @@ public class EvaluableEntityRoleEntityDescriptorCriterion implements EvaluableEn
                 .toString();
     }
     
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilter.java
index ed02ea113..b395545dc 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilter.java
@@ -51,7 +51,6 @@ import org.opensaml.xmlsec.algorithm.AlgorithmDescriptor.AlgorithmType;
 import org.opensaml.xmlsec.algorithm.AlgorithmRegistry;
 import org.opensaml.xmlsec.algorithm.AlgorithmSupport;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
@@ -60,6 +59,7 @@ import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.component.AbstractInitializableComponent;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * A filter that adds algorithm extension content to entities in order to drive software
@@ -74,7 +74,7 @@ public class AlgorithmFilter extends AbstractInitializableComponent implements M
     @Nonnull private final Logger log = LoggerFactory.getLogger(AlgorithmFilter.class);
 
     /** Registry for sanity checking algorithms. */
-    @Nonnull private AlgorithmRegistry registry = AlgorithmSupport.getGlobalAlgorithmRegistry();
+    @Nullable private AlgorithmRegistry registry = AlgorithmSupport.getGlobalAlgorithmRegistry();
     
     /** Rules for adding algorithms. */
     @Nonnull @NonnullElements private Multimap<Predicate<EntityDescriptor>,XMLObject> applyMap;
@@ -97,7 +97,7 @@ public class AlgorithmFilter extends AbstractInitializableComponent implements M
      * 
      * @param rules rules to apply
      */
-    public void setRules(@Nonnull @NonnullElements final Map<Predicate<EntityDescriptor>,Collection<XMLObject>> rules) {
+    public void setRules(@Nonnull final Map<Predicate<EntityDescriptor>,Collection<XMLObject>> rules) {
         checkSetterPreconditions();
         Constraint.isNotNull(rules, "Rules map cannot be null");
 
@@ -135,7 +135,6 @@ public class AlgorithmFilter extends AbstractInitializableComponent implements M
 // Checkstyle: CyclomaticComplexity ON
 
     /** {@inheritDoc} */
-    @Override
     @Nullable public XMLObject filter(@Nullable final XMLObject metadata, @Nonnull final MetadataFilterContext context)
             throws FilterException {
         if (metadata == null) {
@@ -227,11 +226,13 @@ public class AlgorithmFilter extends AbstractInitializableComponent implements M
         
         // First we check any contained EntitiesDescriptors.
         for (final EntitiesDescriptor group : descriptor.getEntitiesDescriptors()) {
+            assert group != null;
             filterEntitiesDescriptor(group);
         }
         
         // Next, check contained EntityDescriptors.
         for (final EntityDescriptor entity : descriptor.getEntityDescriptors()) {
+            assert entity != null;
             filterEntityDescriptor(entity);
         }
     }
@@ -296,10 +297,11 @@ public class AlgorithmFilter extends AbstractInitializableComponent implements M
      * @param uri input method
      */
     private void checkDigestMethod(@Nonnull @NotEmpty final String uri) {
-        if (registry != null) {
-            if (!registry.getRegisteredURIsByType(AlgorithmType.MessageDigest).contains(uri)) {
+        final AlgorithmRegistry local = registry;
+        if (local != null) {
+            if (!local.getRegisteredURIsByType(AlgorithmType.MessageDigest).contains(uri)) {
                 log.warn("DigestMethod {} unrecognized by algorithm registry", uri);
-            } else if (!registry.isRuntimeSupported(uri)) {
+            } else if (!local.isRuntimeSupported(uri)) {
                 log.warn("DigestMethod {} unsupported by runtime", uri);
             }
         }
@@ -311,11 +313,12 @@ public class AlgorithmFilter extends AbstractInitializableComponent implements M
      * @param uri input method
      */
     private void checkSigningMethod(@Nonnull @NotEmpty final String uri) {
-        if (registry != null) {
-            if (!registry.getRegisteredURIsByType(AlgorithmType.Signature).contains(uri) &&
-                    !registry.getRegisteredURIsByType(AlgorithmType.Mac).contains(uri)) {
+        final AlgorithmRegistry local = registry;
+        if (local != null) {
+            if (!local.getRegisteredURIsByType(AlgorithmType.Signature).contains(uri) &&
+                    !local.getRegisteredURIsByType(AlgorithmType.Mac).contains(uri)) {
                 log.warn("SigningMethod {} unrecognized by algorithm registry", uri);
-            } else if (!registry.isRuntimeSupported(uri)) {
+            } else if (!local.isRuntimeSupported(uri)) {
                 log.warn("SigningMethod {} unsupported by runtime", uri);
             }
         }
@@ -327,13 +330,14 @@ public class AlgorithmFilter extends AbstractInitializableComponent implements M
      * @param uri input method
      */
     private void checkEncryptionMethod(@Nonnull @NotEmpty final String uri) {
-        if (registry != null) {
-            if (!registry.getRegisteredURIsByType(AlgorithmType.BlockEncryption).contains(uri) &&
-                    !registry.getRegisteredURIsByType(AlgorithmType.KeyTransport).contains(uri) &&
-                    !registry.getRegisteredURIsByType(AlgorithmType.KeyAgreement).contains(uri) &&
-                    !registry.getRegisteredURIsByType(AlgorithmType.SymmetricKeyWrap).contains(uri)) {
+        final AlgorithmRegistry local = registry;
+        if (local != null) {
+            if (!local.getRegisteredURIsByType(AlgorithmType.BlockEncryption).contains(uri) &&
+                    !local.getRegisteredURIsByType(AlgorithmType.KeyTransport).contains(uri) &&
+                    !local.getRegisteredURIsByType(AlgorithmType.KeyAgreement).contains(uri) &&
+                    !local.getRegisteredURIsByType(AlgorithmType.SymmetricKeyWrap).contains(uri)) {
                 log.warn("EncryptionMethod {} unrecognized by algorithm registry", uri);
-            } else if (!registry.isRuntimeSupported(uri)) {
+            } else if (!local.isRuntimeSupported(uri)) {
                 log.warn("EncryptionMethod {} unsupported by runtime", uri);
             }
         }
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/BasicDynamicTrustedNamesStrategy.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/BasicDynamicTrustedNamesStrategy.java
index 88a938997..50127e76f 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/BasicDynamicTrustedNamesStrategy.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/BasicDynamicTrustedNamesStrategy.java
@@ -17,7 +17,6 @@
 
 package org.opensaml.saml.metadata.resolver.filter.impl;
 
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.function.Function;
@@ -25,7 +24,7 @@ import java.util.function.Function;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
-import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.primitive.StringSupport;
 
 import org.opensaml.core.xml.XMLObject;
@@ -51,39 +50,56 @@ import org.opensaml.saml.saml2.metadata.RoleDescriptor;
  */
 public class BasicDynamicTrustedNamesStrategy implements Function<XMLObject, Set<String>> {
 
+// Checkstyle: CyclomaticComplexity OFF
     /** {@inheritDoc} */
-    @Nonnull @NonnullElements public Set<String> apply(@Nullable final XMLObject input) {
+    @Nonnull public Set<String> apply(@Nullable final XMLObject input) {
         if (input == null) {
-            return Collections.emptySet();
+            return CollectionSupport.emptySet();
         }
         
         Set<String> rawResult = null;
         
-        if (input instanceof EntityDescriptor) {
-            rawResult = Collections.singleton(((EntityDescriptor)input).getEntityID());
-        } else if (input instanceof EntitiesDescriptor) {
-            rawResult = Collections.singleton(((EntitiesDescriptor)input).getName());
+        if (input instanceof EntityDescriptor entity) {
+            final String entityID = entity.getEntityID();
+            if (entityID != null) {
+                rawResult = CollectionSupport.singleton(entityID);
+            }
+        } else if (input instanceof EntitiesDescriptor entities) {
+            final String name = entities.getName();
+            if (name != null) {
+                rawResult = CollectionSupport.singleton(name);
+            }
         } else if (input instanceof RoleDescriptor) {
             final XMLObject parent = input.getParent();
-            if (parent instanceof EntityDescriptor) {
-                rawResult = Collections.singleton(((EntityDescriptor)parent).getEntityID());
+            if (parent instanceof EntityDescriptor entity) {
+                final String entityID = entity.getEntityID();
+                if (entityID != null) {
+                    rawResult = CollectionSupport.singleton(entityID);
+                }
             }
-        } else if (input instanceof AffiliationDescriptor) {
+        } else if (input instanceof AffiliationDescriptor affil) {
             rawResult = new HashSet<>();
             
-            rawResult.add(((AffiliationDescriptor)input).getOwnerID());
+            final String owner = affil.getOwnerID();
+            if (owner != null) {
+                rawResult.add(owner);
+            }
             
             final XMLObject parent = input.getParent();
-            if (parent instanceof EntityDescriptor) {
-                rawResult.add(((EntityDescriptor)parent).getEntityID());
+            if (parent instanceof EntityDescriptor entity) {
+                final String entityID = entity.getEntityID();
+                if (entityID != null) {
+                    rawResult.add(entityID);
+                }
             }
         }
         
         if (rawResult != null) {
-            return new HashSet<>(StringSupport.normalizeStringCollection(rawResult));
+            return CollectionSupport.copyToSet(StringSupport.normalizeStringCollection(rawResult));
         }
         
-        return Collections.emptySet();
+        return CollectionSupport.emptySet();
     }
+// Checkstyle: CyclomaticComplexity ON
 
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/ByReferenceMetadataFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/ByReferenceMetadataFilter.java
index 09f448170..85addf720 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/ByReferenceMetadataFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/ByReferenceMetadataFilter.java
@@ -18,7 +18,6 @@
 package org.opensaml.saml.metadata.resolver.filter.impl;
 
 import java.util.Collection;
-import java.util.Collections;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -31,10 +30,11 @@ import org.opensaml.saml.metadata.resolver.filter.MetadataFilter;
 import org.opensaml.saml.metadata.resolver.filter.MetadataFilterContext;
 import org.opensaml.saml.metadata.resolver.filter.data.impl.MetadataSource;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 
 /**
@@ -56,7 +56,7 @@ public class ByReferenceMetadataFilter implements MetadataFilter {
     
     /** Constructor. */
     public ByReferenceMetadataFilter() {
-        filterMap = Collections.emptyMap();
+        filterMap = CollectionSupport.emptyMap();
     }
     
     /**
@@ -88,7 +88,7 @@ public class ByReferenceMetadataFilter implements MetadataFilter {
     }
     
     /** {@inheritDoc} */
-    public XMLObject filter(@Nullable final XMLObject metadata, @Nonnull final MetadataFilterContext context)
+    @Nullable public XMLObject filter(@Nullable final XMLObject metadata, @Nonnull final MetadataFilterContext context)
             throws FilterException {
         
         final MetadataSource source = context.get(MetadataSource.class);
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptorNameProcessor.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptorNameProcessor.java
index 60b8a61ec..395aaf753 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptorNameProcessor.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptorNameProcessor.java
@@ -26,8 +26,8 @@ import org.opensaml.saml.metadata.resolver.filter.MetadataNodeProcessor;
 import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 
 /**
@@ -41,8 +41,7 @@ public class EntitiesDescriptorNameProcessor implements MetadataNodeProcessor {
     @Nonnull private Logger log = LoggerFactory.getLogger(EntitiesDescriptorNameProcessor.class);
 
     /** {@inheritDoc} */
-    @Override
-    public void process(final XMLObject metadataNode) throws FilterException {
+    public void process(@Nonnull final XMLObject metadataNode) throws FilterException {
         if (metadataNode instanceof EntityDescriptor) {
             XMLObject currentParent = metadataNode.getParent();
             while (currentParent != null) {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityAttributesFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityAttributesFilter.java
index 2670e7df7..156b7827f 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityAttributesFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityAttributesFilter.java
@@ -44,7 +44,6 @@ import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.opensaml.saml.saml2.metadata.Extensions;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
@@ -52,6 +51,7 @@ import com.google.common.collect.Multimap;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.component.AbstractInitializableComponent;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * A filter that adds {@link EntityAttributes} extension content to entities in order to drive software
@@ -124,7 +124,6 @@ public class EntityAttributesFilter extends AbstractInitializableComponent imple
     }
 
     /** {@inheritDoc} */
-    @Override
     @Nullable public XMLObject filter(@Nullable final XMLObject metadata, @Nonnull final MetadataFilterContext context)
             throws FilterException {
         if (metadata == null) {
@@ -181,11 +180,13 @@ public class EntityAttributesFilter extends AbstractInitializableComponent imple
         
         // First we check any contained EntitiesDescriptors.
         for (final EntitiesDescriptor group : descriptor.getEntitiesDescriptors()) {
+            assert group != null;
             filterEntitiesDescriptor(group);
         }
         
         // Next, check contained EntityDescriptors.
         for (final EntityDescriptor entity : descriptor.getEntityDescriptors()) {
+            assert entity != null;
             filterEntityDescriptor(entity);
         }
     }
@@ -223,6 +224,7 @@ public class EntityAttributesFilter extends AbstractInitializableComponent imple
         
         if (toMutate != null) {
             for (final XMLObject newValue : input.getAttributeValues()) {
+                assert newValue != null;
                 try {
                     log.info("Adding value to existing EntityAttribute ({}) on EntityDescriptor ({})", input.getName(),
                             descriptor.getEntityID());
@@ -260,6 +262,7 @@ public class EntityAttributesFilter extends AbstractInitializableComponent imple
                 while (iter.hasNext()) {
                     final SAMLObject attribute = iter.next();
                     if (attribute instanceof Attribute) {
+                        assert attributeFilter != null;
                         if (!attributeFilter.test((Attribute) attribute)) {
                             log.warn("Filtering pre-existing attribute '{}' from entity '{}'",
                                     ((Attribute) attribute).getName(), descriptor.getEntityID());
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityRoleFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityRoleFilter.java
index c1c6cea07..5b7aaedd1 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityRoleFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityRoleFilter.java
@@ -18,7 +18,6 @@
 package org.opensaml.saml.metadata.resolver.filter.impl;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 
@@ -35,12 +34,13 @@ import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.ParameterName;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotLive;
 import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * A filter that removes roles from an entity descriptor. For those roles specified within the SAML metadata
@@ -77,11 +77,11 @@ public class EntityRoleFilter implements MetadataFilter {
      * 
      * @param keptRoles list of roles NOT removed by this filter
      */
-    public EntityRoleFilter(@Nullable @NonnullElements @ParameterName(name="keptRoles") final List<QName> keptRoles) {
+    public EntityRoleFilter(@Nullable @ParameterName(name="keptRoles") final List<QName> keptRoles) {
         if (keptRoles != null) {
-            retainedRoles = List.copyOf(keptRoles);
+            retainedRoles = CollectionSupport.copyToList(keptRoles);
         } else {
-            retainedRoles = Collections.emptyList();
+            retainedRoles = CollectionSupport.emptyList();
         }
 
         removeRolelessEntityDescriptors = true;
@@ -151,7 +151,6 @@ public class EntityRoleFilter implements MetadataFilter {
     }
 
     /** {@inheritDoc} */
-    @Override
     @Nullable public XMLObject filter(@Nullable final XMLObject metadata, @Nonnull final MetadataFilterContext context)
             throws FilterException {
         if (metadata == null) {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilter.java
index c4b99e2f0..152443237 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilter.java
@@ -41,7 +41,6 @@ import org.opensaml.saml.saml2.metadata.PDPDescriptor;
 import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.ArrayListMultimap;
 import com.google.common.collect.Multimap;
@@ -49,6 +48,7 @@ import com.google.common.collect.Multimap;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.component.AbstractInitializableComponent;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 
 /**
@@ -67,13 +67,14 @@ public class NameIDFormatFilter extends AbstractInitializableComponent implement
     private boolean removeExistingFormats;
     
     /** Rules for adding formats. */
-    @Nonnull @NonnullElements private Multimap<Predicate<EntityDescriptor>,String> applyMap;
+    @Nonnull private Multimap<Predicate<EntityDescriptor>,String> applyMap;
 
     /** Builder for {@link NameIDFormat}. */
     @Nonnull private final SAMLObjectBuilder<NameIDFormat> formatBuilder;
 
     /** Constructor. */
     public NameIDFormatFilter() {
+        applyMap = ArrayListMultimap.create();
         formatBuilder = (SAMLObjectBuilder<NameIDFormat>)
                 XMLObjectProviderRegistrySupport.getBuilderFactory().<NameIDFormat>ensureBuilder(
                         NameIDFormat.DEFAULT_ELEMENT_NAME);
@@ -97,7 +98,7 @@ public class NameIDFormatFilter extends AbstractInitializableComponent implement
      * 
      * @param rules rules to apply
      */
-    public void setRules(@Nonnull @NonnullElements final Map<Predicate<EntityDescriptor>,Collection<String>> rules) {
+    public void setRules(@Nonnull final Map<Predicate<EntityDescriptor>,Collection<String>> rules) {
         checkSetterPreconditions();
         Constraint.isNotNull(rules, "Rules map cannot be null");
         
@@ -110,7 +111,6 @@ public class NameIDFormatFilter extends AbstractInitializableComponent implement
     }
 
     /** {@inheritDoc} */
-    @Override
     @Nullable public XMLObject filter(@Nullable final XMLObject metadata, @Nonnull final MetadataFilterContext context)
             throws FilterException {
         checkComponentActive();
@@ -154,19 +154,26 @@ public class NameIDFormatFilter extends AbstractInitializableComponent implement
         
         final Collection<NameIDFormat> roleFormats;
         
-        if (role instanceof SPSSODescriptor) {
-            roleFormats = ((SPSSODescriptor) role).getNameIDFormats();
-        } else if (role instanceof AttributeAuthorityDescriptor) {
-            roleFormats = ((AttributeAuthorityDescriptor) role).getNameIDFormats();
-        } else if (role instanceof PDPDescriptor) {
-            roleFormats = ((PDPDescriptor) role).getNameIDFormats();
+        if (role instanceof SPSSODescriptor sp) {
+            roleFormats = sp.getNameIDFormats();
+        } else if (role instanceof AttributeAuthorityDescriptor aa) {
+            roleFormats = aa.getNameIDFormats();
+        } else if (role instanceof PDPDescriptor pdp) {
+            roleFormats = pdp.getNameIDFormats();
         } else {
             return;
         }
         
+        final String entityID;
+        if (role.getParent() instanceof EntityDescriptor entity) {
+            entityID = entity.getEntityID();
+        } else {
+            entityID = null;
+        }
+        
         if (removeExistingFormats && !roleFormats.isEmpty()) {
-            log.debug("Removing existing NameIDFormats from {} role in EntityDescriptor '{}'",
-                    role.getElementQName(), ((EntityDescriptor) role.getParent()).getEntityID());
+            log.debug("Removing existing NameIDFormats from {} role in EntityDescriptor '{}'", role.getElementQName(),
+                    entityID);
             roleFormats.clear();
         }
         
@@ -175,13 +182,11 @@ public class NameIDFormatFilter extends AbstractInitializableComponent implement
         
         for (final String format : formats) {
             if (existingFormats.contains(format)) {
-                log.debug("Ignoring add of existing NameIDFormat '{}' on EntityDescriptor '{}'", format,
-                        ((EntityDescriptor) role.getParent()).getEntityID());
+                log.debug("Ignoring add of existing NameIDFormat '{}' on EntityDescriptor '{}'", format, entityID);
             } else {
                 final NameIDFormat nif = formatBuilder.buildObject();
                 nif.setURI(format);
-                log.info("Adding NameIDFormat '{}' to EntityDescriptor '{}'", format,
-                        ((EntityDescriptor) role.getParent()).getEntityID());
+                log.info("Adding NameIDFormat '{}' to EntityDescriptor '{}'", format, entityID);
                 roleFormats.add(nif);
             }
         }
@@ -197,11 +202,13 @@ public class NameIDFormatFilter extends AbstractInitializableComponent implement
         
         // First we check any contained EntitiesDescriptors.
         for (final EntitiesDescriptor group : descriptor.getEntitiesDescriptors()) {
+            assert group != null;
             filterEntitiesDescriptor(group);
         }
         
         // Next, check contained EntityDescriptors.
         for (final EntityDescriptor entity : descriptor.getEntityDescriptors()) {
+            assert entity != null;
             filterEntityDescriptor(entity);
         }
     }
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/NodeProcessingMetadataFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/NodeProcessingMetadataFilter.java
index 0a05837bb..52d9afa0c 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/NodeProcessingMetadataFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/NodeProcessingMetadataFilter.java
@@ -30,7 +30,7 @@ import org.opensaml.saml.metadata.resolver.filter.MetadataFilterContext;
 import org.opensaml.saml.metadata.resolver.filter.MetadataNodeProcessor;
 
 import net.shibboleth.shared.annotation.constraint.Live;
-import net.shibboleth.shared.annotation.constraint.NonnullElements;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.AbstractInitializableComponent;
 import net.shibboleth.shared.logic.Constraint;
 
@@ -42,7 +42,7 @@ import net.shibboleth.shared.logic.Constraint;
 public class NodeProcessingMetadataFilter extends AbstractInitializableComponent implements MetadataFilter {
 
     /** The ordered list of metadata node processors. */
-    @Nonnull @NonnullElements private List<MetadataNodeProcessor> processors;
+    @Nonnull private List<MetadataNodeProcessor> processors;
     
     /** Constructor. */
     public NodeProcessingMetadataFilter() {
@@ -54,7 +54,7 @@ public class NodeProcessingMetadataFilter extends AbstractInitializableComponent
      * 
      * @return the list of metadata node processors
      */
-    @Nonnull @NonnullElements @Live public List<MetadataNodeProcessor> getNodeProcessors() {
+    @Nonnull @Live public List<MetadataNodeProcessor> getNodeProcessors() {
         return processors;
     }
 
@@ -63,15 +63,14 @@ public class NodeProcessingMetadataFilter extends AbstractInitializableComponent
      * 
      * @param newProcessors the new list of processors to set.
      */
-    public void setNodeProcessors(@Nonnull @NonnullElements final List<MetadataNodeProcessor> newProcessors) {
+    public void setNodeProcessors(@Nonnull final List<MetadataNodeProcessor> newProcessors) {
         checkSetterPreconditions();
         Constraint.isNotNull(newProcessors, "MetadataNodeProcessor list cannot be null");
 
-        processors = new ArrayList<>(List.copyOf(newProcessors));
+        processors = new ArrayList<>(CollectionSupport.copyToList(newProcessors));
     }
 
     /** {@inheritDoc} */
-    @Override
     @Nullable public XMLObject filter(@Nullable final XMLObject metadata, @Nonnull final MetadataFilterContext context)
             throws FilterException {
         checkComponentActive();
@@ -85,12 +84,6 @@ public class NodeProcessingMetadataFilter extends AbstractInitializableComponent
         return metadata;
     }
 
-    /** {@inheritDoc} */
-    @Override protected void doDestroy() {
-        processors = null;
-        super.doDestroy();
-    }
-
     /**
      * Process an individual metadata node.
      * 
@@ -98,7 +91,7 @@ public class NodeProcessingMetadataFilter extends AbstractInitializableComponent
      * 
      * @throws FilterException if a fatal error is encountered while processing a node
      */
-    protected void processNode(final XMLObject node) throws FilterException {
+    protected void processNode(@Nonnull final XMLObject node) throws FilterException {
         
         for (final MetadataNodeProcessor processor : getNodeProcessors()) {
             processor.process(node);
@@ -106,10 +99,9 @@ public class NodeProcessingMetadataFilter extends AbstractInitializableComponent
 
         final List<XMLObject> children = node.getOrderedChildren();
         if (children != null) {
-            for (final XMLObject child : node.getOrderedChildren()) {
-                if (child != null) {
-                    processNode(child);
-                }
+            for (final XMLObject child : children) {
+                assert child != null;
+                processNode(child);
             }
         }
     }
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/PredicateFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/PredicateFilter.java
index ebb1f6277..69e71a23c 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/PredicateFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/PredicateFilter.java
@@ -32,9 +32,9 @@ import org.opensaml.saml.metadata.resolver.filter.MetadataFilterContext;
 import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * A filter that removes any {@link EntityDescriptor} that does or does not match a {@link Predicate}, thus
@@ -122,8 +122,7 @@ public class PredicateFilter implements MetadataFilter {
     }
 
     /** {@inheritDoc} */
-    @Override
-    public XMLObject filter(@Nullable final XMLObject metadata, @Nonnull final MetadataFilterContext context)
+    @Nullable public XMLObject filter(@Nullable final XMLObject metadata, @Nonnull final MetadataFilterContext context)
             throws FilterException {
         
         if (metadata == null) {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilFilter.java
index 532551ca8..3ecb1aada 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilFilter.java
@@ -30,7 +30,8 @@ import org.opensaml.saml.metadata.resolver.filter.MetadataFilterContext;
 import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * A metadata filter that requires the presence of a <code>validUntil</code> attribute on the root element of the
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/SchemaValidationFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/SchemaValidationFilter.java
index b5700616b..82fb6ee84 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/SchemaValidationFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/SchemaValidationFilter.java
@@ -28,12 +28,11 @@ import org.opensaml.saml.metadata.resolver.filter.FilterException;
 import org.opensaml.saml.metadata.resolver.filter.MetadataFilter;
 import org.opensaml.saml.metadata.resolver.filter.MetadataFilterContext;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.xml.sax.SAXException;
 
 import net.shibboleth.shared.annotation.ParameterName;
 import net.shibboleth.shared.logic.Constraint;
-import net.shibboleth.shared.xml.SchemaBuilder;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * A metadata filter that schema validates an incoming metadata file.
@@ -43,9 +42,6 @@ public class SchemaValidationFilter implements MetadataFilter {
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(SchemaValidationFilter.class);
 
-    /** Self-managed SchemaBuilder to support old extension schema parameter. */
-    @Nullable private SchemaBuilder schemaBuilder;
-
     /** SAML schema source. */
     @Nonnull private SAMLSchemaBuilder samlSchemaBuilder;
         
@@ -59,7 +55,6 @@ public class SchemaValidationFilter implements MetadataFilter {
     }
 
     /** {@inheritDoc} */
-    @Override
     @Nullable public XMLObject filter(@Nullable final XMLObject metadata, @Nonnull final MetadataFilterContext context)
             throws FilterException {
         if (metadata == null) {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/ScriptedTrustedNamesFunction.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/ScriptedTrustedNamesFunction.java
index bc3007ab9..f88b4c040 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/ScriptedTrustedNamesFunction.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/ScriptedTrustedNamesFunction.java
@@ -72,13 +72,14 @@ public class ScriptedTrustedNamesFunction extends AbstractScriptEvaluator implem
     }
 
     /** {@inheritDoc} */
+    @SuppressWarnings("unchecked")
     @Nullable public Set<String> apply(@Nullable final XMLObject context) {
         return (Set<String>) evaluate(context);
     }
     
     /** {@inheritDoc} */
     protected void prepareContext(@Nonnull final ScriptContext scriptContext, @Nullable final Object... input) {
-        scriptContext.setAttribute("profileContext", input[0], ScriptContext.ENGINE_SCOPE);
+        scriptContext.setAttribute("profileContext", input != null ? input[0] : null, ScriptContext.ENGINE_SCOPE);
     }
 
     /**
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/SignatureValidationFilter.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/SignatureValidationFilter.java
index a9ba1e5b6..3c347f92f 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/SignatureValidationFilter.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/filter/impl/SignatureValidationFilter.java
@@ -45,11 +45,11 @@ import org.opensaml.xmlsec.signature.support.SignatureException;
 import org.opensaml.xmlsec.signature.support.SignaturePrevalidator;
 import org.opensaml.xmlsec.signature.support.SignatureTrustEngine;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.ParameterName;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 /**
@@ -213,7 +213,6 @@ public class SignatureValidationFilter implements MetadataFilter {
     }
 
     /** {@inheritDoc} */
-    @Override
     @Nullable public XMLObject filter(@Nullable final XMLObject metadata, @Nonnull final MetadataFilterContext context)
             throws FilterException {
         if (metadata == null) {
@@ -292,8 +291,8 @@ public class SignatureValidationFilter implements MetadataFilter {
             }
         }
         
-        if (entityDescriptor.getAffiliationDescriptor() != null) {
-            final AffiliationDescriptor affiliationDescriptor = entityDescriptor.getAffiliationDescriptor();
+        final AffiliationDescriptor affiliationDescriptor = entityDescriptor.getAffiliationDescriptor();
+        if (affiliationDescriptor != null) {
             if (!affiliationDescriptor.isSigned()) {
                 log.trace("AffiliationDescriptor member was not signed, skipping signature processing...");
             } else {
@@ -448,9 +447,10 @@ public class SignatureValidationFilter implements MetadataFilter {
      */
     protected void performPreValidation(@Nonnull final Signature signature,
             @Nonnull @NotEmpty final String metadataEntryName) throws FilterException {
-        if (getSignaturePrevalidator() != null) {
+        final var prevalidator = getSignaturePrevalidator();
+        if (prevalidator != null) {
             try {
-                getSignaturePrevalidator().validate(signature);
+                prevalidator.validate(signature);
             } catch (final SignatureException e) {
                 log.error("Signature on metadata entry '{}' failed signature pre-validation: {}", metadataEntryName,
                         e.getMessage());
@@ -486,8 +486,9 @@ public class SignatureValidationFilter implements MetadataFilter {
         }
         
         // If configured, add dynamic trusted names computed from metadata via strategy function.
-        if (getDynamicTrustedNamesStrategy() != null) {
-            final Set<String> dynamicTrustedNames = getDynamicTrustedNamesStrategy().apply(signedMetadata);
+        final var namesStrategy = getDynamicTrustedNamesStrategy(); 
+        if (namesStrategy != null) {
+            final Set<String> dynamicTrustedNames = namesStrategy.apply(signedMetadata);
             if (dynamicTrustedNames != null && !dynamicTrustedNames.isEmpty()) {
                 newCriteriaSet.add(new TrustedNamesCriterion(dynamicTrustedNames));
             }
@@ -504,7 +505,8 @@ public class SignatureValidationFilter implements MetadataFilter {
      * 
      * @return the constructed role ID token.
      */
-    protected String getRoleIDToken(@Nonnull @NotEmpty final String entityID, @Nonnull final RoleDescriptor role) {
+    @Nonnull protected String getRoleIDToken(@Nonnull @NotEmpty final String entityID,
+            @Nonnull final RoleDescriptor role) {
         final String roleName = role.getElementQName().getLocalPart();
         return "[Role: " + entityID + "::" + roleName + "]";
     }
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/EndpointMetadataIndex.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/EndpointMetadataIndex.java
index 0da0b5e3b..bbea0391c 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/EndpointMetadataIndex.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/EndpointMetadataIndex.java
@@ -18,7 +18,6 @@
 package org.opensaml.saml.metadata.resolver.index.impl;
 
 import java.net.MalformedURLException;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Map;
 import java.util.Objects;
@@ -38,18 +37,19 @@ import org.opensaml.saml.saml2.metadata.Endpoint;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.base.MoreObjects;
-import com.google.common.base.Predicates;
 
 import net.shibboleth.shared.annotation.ParameterName;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.annotation.constraint.NotLive;
 import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.PredicateSupport;
 import net.shibboleth.shared.net.URLBuilder;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
@@ -65,7 +65,7 @@ import net.shibboleth.shared.resolver.CriteriaSet;
 public class EndpointMetadataIndex implements MetadataIndex {
     
     /** Logger. */
-    private Logger log = LoggerFactory.getLogger(EndpointMetadataIndex.class);
+    @Nonnull private Logger log = LoggerFactory.getLogger(EndpointMetadataIndex.class);
     
     /** The predicate which selects which endpoints to index. */
     @Nonnull private Predicate<Endpoint> endpointSelectionPredicate;
@@ -78,7 +78,7 @@ public class EndpointMetadataIndex implements MetadataIndex {
      * </p>
      */
     public EndpointMetadataIndex() {
-        endpointSelectionPredicate = Predicates.alwaysTrue();
+        endpointSelectionPredicate = PredicateSupport.alwaysTrue();
     }
     
     /**
@@ -163,12 +163,14 @@ public class EndpointMetadataIndex implements MetadataIndex {
         final String location = StringSupport.trimOrNull(endpoint.getLocation());
         if (location != null) {
             for (final String variant : processLocation(criteriaSet, location)) {
+                assert variant != null;
                 result.add(new EndpointMetadataIndexKey(roleType, endpointType, variant, false));
             }
         }
         final String responseLocation = StringSupport.trimOrNull(endpoint.getResponseLocation());
         if (responseLocation != null) {
             for (final String variant : processLocation(criteriaSet, responseLocation)) {
+                assert variant != null;
                 result.add(new EndpointMetadataIndexKey(roleType, endpointType, variant, true));
             }
         }
@@ -216,7 +218,7 @@ public class EndpointMetadataIndex implements MetadataIndex {
             return result;
         }
         
-        return Collections.singleton(location);
+        return CollectionSupport.singleton(location);
     }
 
 
@@ -234,7 +236,7 @@ public class EndpointMetadataIndex implements MetadataIndex {
          * Constructor.
          */
         public DefaultEndpointSelectionPredicate() {
-            endpointTypes = Collections.emptyMap();
+            endpointTypes = CollectionSupport.emptyMap();
         }
         
         /**
@@ -284,7 +286,7 @@ public class EndpointMetadataIndex implements MetadataIndex {
     protected static class EndpointMetadataIndexKey implements MetadataIndexKey {
         
         /** Logger. */
-        private final Logger log = LoggerFactory.getLogger(EndpointMetadataIndexKey.class);
+        @Nonnull private final Logger log = LoggerFactory.getLogger(EndpointMetadataIndexKey.class);
         
         /** The role type. */
         @Nonnull private final QName role;
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/AffiliationDescriptorImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/AffiliationDescriptorImpl.java
index d2ec716da..d21941163 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/AffiliationDescriptorImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/AffiliationDescriptorImpl.java
@@ -24,7 +24,6 @@ package org.opensaml.saml.saml2.metadata.impl;
 import java.time.Duration;
 import java.time.Instant;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 import org.opensaml.core.xml.XMLObject;
@@ -36,6 +35,8 @@ import org.opensaml.saml.saml2.metadata.AffiliateMember;
 import org.opensaml.saml.saml2.metadata.AffiliationDescriptor;
 import org.opensaml.saml.saml2.metadata.KeyDescriptor;
 
+import net.shibboleth.shared.collection.CollectionSupport;
+
 /**
  * Concrete implementation of {@link org.opensaml.saml.saml2.metadata.AffiliationDescriptor}.
  */
@@ -174,13 +175,15 @@ public class AffiliationDescriptorImpl extends AbstractSignableSAMLObject implem
             children.add(getSignature());
         }
         
-        children.add(getExtensions());
+        if (getExtensions() != null) {
+            children.add(getExtensions());
+        }
 
         children.addAll(getMembers());
 
         children.addAll(getKeyDescriptors());
 
-        return Collections.unmodifiableList(children);
+        return CollectionSupport.copyToList(children);
     }
 
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/AttributeAuthorityDescriptorImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/AttributeAuthorityDescriptorImpl.java
index d7db30fea..e1d787545 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/AttributeAuthorityDescriptorImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/AttributeAuthorityDescriptorImpl.java
@@ -33,6 +33,8 @@ import org.opensaml.saml.saml2.metadata.AttributeService;
 import org.opensaml.saml.saml2.metadata.Endpoint;
 import org.opensaml.saml.saml2.metadata.NameIDFormat;
 
+import net.shibboleth.shared.collection.CollectionSupport;
+
 /**
  * A concrete implementation of {@link org.opensaml.saml.saml2.metadata.AttributeAuthorityDescriptor}.
  */
@@ -118,13 +120,17 @@ public class AttributeAuthorityDescriptorImpl extends RoleDescriptorImpl impleme
     public List<XMLObject> getOrderedChildren() {
         final ArrayList<XMLObject> children = new ArrayList<>();
 
-        children.addAll(super.getOrderedChildren());
+        final List<XMLObject> parentChildren = super.getOrderedChildren();
+        if (parentChildren != null) {
+            children.addAll(parentChildren);
+        }
+        
         children.addAll(attributeServices);
         children.addAll(assertionIDRequestServices);
         children.addAll(nameFormats);
         children.addAll(attributeProfiles);
         children.addAll(attributes);
 
-        return Collections.unmodifiableList(children);
+        return CollectionSupport.copyToList(children);
     }
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/AuthnAuthorityDescriptorImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/AuthnAuthorityDescriptorImpl.java
index c71edb198..0061a8521 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/AuthnAuthorityDescriptorImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/AuthnAuthorityDescriptorImpl.java
@@ -31,6 +31,8 @@ import org.opensaml.saml.saml2.metadata.AuthnQueryService;
 import org.opensaml.saml.saml2.metadata.Endpoint;
 import org.opensaml.saml.saml2.metadata.NameIDFormat;
 
+import net.shibboleth.shared.collection.CollectionSupport;
+
 /**
  * Concrete implementation of {@link org.opensaml.saml.saml2.metadata.AuthnAuthorityDescriptor}.
  */
@@ -98,11 +100,15 @@ public class AuthnAuthorityDescriptorImpl extends RoleDescriptorImpl implements
     public List<XMLObject> getOrderedChildren() {
         final ArrayList<XMLObject> children = new ArrayList<>();
 
-        children.addAll(super.getOrderedChildren());
+        final List<XMLObject> parentChildren = super.getOrderedChildren();
+        if (parentChildren != null) {
+            children.addAll(parentChildren);
+        }
+        
         children.addAll(authnQueryServices);
         children.addAll(assertionIDRequestServices);
         children.addAll(nameIDFormats);
 
-        return Collections.unmodifiableList(children);
+        return CollectionSupport.copyToList(children);
     }
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/ContactPersonImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/ContactPersonImpl.java
index 40a970895..6087c12d7 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/ContactPersonImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/ContactPersonImpl.java
@@ -37,6 +37,8 @@ import org.opensaml.saml.saml2.metadata.GivenName;
 import org.opensaml.saml.saml2.metadata.SurName;
 import org.opensaml.saml.saml2.metadata.TelephoneNumber;
 
+import net.shibboleth.shared.collection.CollectionSupport;
+
 /**
  * Concrete implementation of {@link org.opensaml.saml.saml2.metadata.ContactPerson}.
  */
@@ -164,13 +166,25 @@ public class ContactPersonImpl extends AbstractXMLObject implements ContactPerso
     public List<XMLObject> getOrderedChildren() {
         final ArrayList<XMLObject> children = new ArrayList<>();
 
-        children.add(extensions);
-        children.add(company);
-        children.add(givenName);
-        children.add(surName);
+        if (extensions != null) {
+            children.add(extensions);
+        }
+        
+        if (company != null) {
+            children.add(company);
+        }
+        
+        if (givenName != null) {
+            children.add(givenName);
+        }
+        
+        if (surName != null) {
+            children.add(surName);
+        }
+        
         children.addAll(emailAddresses);
         children.addAll(telephoneNumbers);
 
-        return children;
+        return CollectionSupport.copyToList(children);
     }
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/EntitiesDescriptorImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/EntitiesDescriptorImpl.java
index 8c3478257..4e26695cc 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/EntitiesDescriptorImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/EntitiesDescriptorImpl.java
@@ -20,7 +20,6 @@ package org.opensaml.saml.saml2.metadata.impl;
 import java.time.Duration;
 import java.time.Instant;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 import org.opensaml.core.xml.XMLObject;
@@ -28,6 +27,9 @@ import org.opensaml.core.xml.util.IndexedXMLObjectChildrenList;
 import org.opensaml.saml.common.AbstractSignableSAMLObject;
 import org.opensaml.saml.common.SAMLObject;
 import org.opensaml.saml.saml2.metadata.Extensions;
+
+import net.shibboleth.shared.collection.CollectionSupport;
+
 import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 
@@ -151,9 +153,12 @@ public class EntitiesDescriptorImpl extends AbstractSignableSAMLObject implement
             children.add(getSignature());
         }
         
-        children.add(getExtensions());
+        if (getExtensions() != null) {
+            children.add(getExtensions());
+        }
+        
         children.addAll(orderedDescriptors);
 
-        return Collections.unmodifiableList(children);
+        return CollectionSupport.copyToList(children);
     }
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/EntityDescriptorImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/EntityDescriptorImpl.java
index faa1a51f0..c655c8221 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/EntityDescriptorImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/EntityDescriptorImpl.java
@@ -20,7 +20,6 @@ package org.opensaml.saml.saml2.metadata.impl;
 import java.time.Duration;
 import java.time.Instant;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 import javax.xml.namespace.QName;
@@ -43,6 +42,8 @@ import org.opensaml.saml.saml2.metadata.PDPDescriptor;
 import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
 
+import net.shibboleth.shared.collection.CollectionSupport;
+
 /**
  * Concretate implementation of {@link org.opensaml.saml.saml2.metadata.EntitiesDescriptor}.
  */
@@ -287,13 +288,24 @@ public class EntityDescriptorImpl extends AbstractSignableSAMLObject implements
         if (getSignature() != null) {
             children.add(getSignature());
         }
-        children.add(getExtensions());
+        
+        if (getExtensions() != null) {
+            children.add(getExtensions());
+        }
+        
         children.addAll(roleDescriptors);
-        children.add(getAffiliationDescriptor());
-        children.add(getOrganization());
+        
+        if (getAffiliationDescriptor() != null) {
+            children.add(getAffiliationDescriptor());
+        }
+        
+        if (getOrganization() != null) {
+            children.add(getOrganization());
+        }
+        
         children.addAll(contactPersons);
         children.addAll(additionalMetadata);
 
-        return Collections.unmodifiableList(children);
+        return CollectionSupport.copyToList(children);
     }
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/IDPSSODescriptorImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/IDPSSODescriptorImpl.java
index f1a68457a..6edd6dda9 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/IDPSSODescriptorImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/IDPSSODescriptorImpl.java
@@ -38,6 +38,8 @@ import org.opensaml.saml.saml2.metadata.IDPSSODescriptor;
 import org.opensaml.saml.saml2.metadata.NameIDMappingService;
 import org.opensaml.saml.saml2.metadata.SingleSignOnService;
 
+import net.shibboleth.shared.collection.CollectionSupport;
+
 /**
  * Concrete implementation of {@link org.opensaml.saml.saml2.metadata.IDPSSODescriptor}.
  */
@@ -159,13 +161,17 @@ public class IDPSSODescriptorImpl extends SSODescriptorImpl implements IDPSSODes
     public List<XMLObject> getOrderedChildren() {
         final ArrayList<XMLObject> children = new ArrayList<>();
 
-        children.addAll(super.getOrderedChildren());
+        final List<XMLObject> parentChildren = super.getOrderedChildren();
+        if (parentChildren != null) {
+            children.addAll(parentChildren);
+        }
+        
         children.addAll(singleSignOnServices);
         children.addAll(nameIDMappingServices);
         children.addAll(assertionIDRequestServices);
         children.addAll(attributeProfiles);
         children.addAll(attributes);
 
-        return Collections.unmodifiableList(children);
+        return CollectionSupport.copyToList(children);
     }
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/KeyDescriptorImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/KeyDescriptorImpl.java
index 59141846c..aee0de7d6 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/KeyDescriptorImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/KeyDescriptorImpl.java
@@ -18,7 +18,6 @@
 package org.opensaml.saml.saml2.metadata.impl;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 
 import org.opensaml.core.xml.AbstractXMLObject;
@@ -29,6 +28,8 @@ import org.opensaml.saml.saml2.metadata.KeyDescriptor;
 import org.opensaml.security.credential.UsageType;
 import org.opensaml.xmlsec.signature.KeyInfo;
 
+import net.shibboleth.shared.collection.CollectionSupport;
+
 /**
  * Concrete implementation of {@link org.opensaml.saml.saml2.metadata.KeyDescriptor}.
  */
@@ -90,9 +91,12 @@ public class KeyDescriptorImpl extends AbstractXMLObject implements KeyDescripto
     public List<XMLObject> getOrderedChildren() {
         final ArrayList<XMLObject> children = new ArrayList<>();
 
-        children.add(keyInfo);
+        if (keyInfo != null) {
+            children.add(keyInfo);
+        }
+        
         children.addAll(encryptionMethods);
 
-        return Collections.unmodifiableList(children);
+        return CollectionSupport.copyToList(children);
     }
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/OrganizationImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/OrganizationImpl.java
index f2da62120..2a364096d 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/OrganizationImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/OrganizationImpl.java
@@ -34,6 +34,8 @@ import org.opensaml.saml.saml2.metadata.OrganizationDisplayName;
 import org.opensaml.saml.saml2.metadata.OrganizationName;
 import org.opensaml.saml.saml2.metadata.OrganizationURL;
 
+import net.shibboleth.shared.collection.CollectionSupport;
+
 /**
  * Concrete implementation of {@link org.opensaml.saml.saml2.metadata.Organization}.
  */
@@ -110,11 +112,14 @@ public class OrganizationImpl extends AbstractXMLObject implements Organization
     public List<XMLObject> getOrderedChildren() {
         final ArrayList<XMLObject> children = new ArrayList<>();
 
-        children.add(extensions);
+        if (extensions != null) {
+            children.add(extensions);
+        }
+        
         children.addAll(names);
         children.addAll(displayNames);
         children.addAll(urls);
 
-        return children;
+        return CollectionSupport.copyToList(children);
     }
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/PDPDescriptorImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/PDPDescriptorImpl.java
index 06deb3712..ccb434304 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/PDPDescriptorImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/PDPDescriptorImpl.java
@@ -35,6 +35,8 @@ import org.opensaml.saml.saml2.metadata.Endpoint;
 import org.opensaml.saml.saml2.metadata.NameIDFormat;
 import org.opensaml.saml.saml2.metadata.PDPDescriptor;
 
+import net.shibboleth.shared.collection.CollectionSupport;
+
 /**
  * Concrete implementation of {@link org.opensaml.saml.saml2.metadata.PDPDescriptor}.
  */
@@ -107,6 +109,6 @@ public class PDPDescriptorImpl extends RoleDescriptorImpl implements PDPDescript
         children.addAll(assertionIDRequestServices);
         children.addAll(nameIDFormats);
 
-        return children;
+        return CollectionSupport.copyToList(children);
     }
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/RoleDescriptorImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/RoleDescriptorImpl.java
index 7c84f8e84..3285a331c 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/RoleDescriptorImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/RoleDescriptorImpl.java
@@ -24,6 +24,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.collection.LazyList;
 import net.shibboleth.shared.primitive.StringSupport;
 
@@ -230,12 +231,15 @@ public abstract class RoleDescriptorImpl extends AbstractSignableSAMLObject impl
         if (extensions != null) {
             children.add(getExtensions());
         }
+        
         children.addAll(getKeyDescriptors());
+        
         if (organization != null) {
             children.add(getOrganization());
         }
+        
         children.addAll(getContactPersons());
 
-        return Collections.unmodifiableList(children);
+        return CollectionSupport.copyToList(children);
     }
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/SSODescriptorImpl.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/SSODescriptorImpl.java
index 76170ab9a..dd5959989 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/SSODescriptorImpl.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/saml2/metadata/impl/SSODescriptorImpl.java
@@ -37,6 +37,8 @@ import org.opensaml.saml.saml2.metadata.NameIDFormat;
 import org.opensaml.saml.saml2.metadata.SSODescriptor;
 import org.opensaml.saml.saml2.metadata.SingleLogoutService;
 
+import net.shibboleth.shared.collection.CollectionSupport;
+
 /**
  * Concrete implementation of {@link org.opensaml.saml.saml2.metadata.SSODescriptor}.
  */
@@ -114,19 +116,22 @@ public abstract class SSODescriptorImpl extends RoleDescriptorImpl implements SS
             return Collections.unmodifiableList(new ArrayList<Endpoint>(manageNameIDServices));
         }
         
-        return Collections.EMPTY_LIST;
+        return CollectionSupport.emptyList();
     }
     
     /** {@inheritDoc} */
     public List<XMLObject> getOrderedChildren() {
         final ArrayList<XMLObject> children = new ArrayList<>();
         
-        children.addAll(super.getOrderedChildren());
+        final List<XMLObject> parentChildren = super.getOrderedChildren();
+        if (parentChildren != null) {
+            children.addAll(parentChildren);
+        }
         children.addAll(artifactResolutionServices);
         children.addAll(singleLogoutServices);
         children.addAll(manageNameIDServices);
         children.addAll(nameIDFormats);
         
-        return Collections.unmodifiableList(children);
+        return CollectionSupport.copyToList(children);
     }
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/impl/SAMLMetadataLookupHandlerTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/impl/SAMLMetadataLookupHandlerTest.java
index a0626422d..43ac411ae 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/impl/SAMLMetadataLookupHandlerTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/impl/SAMLMetadataLookupHandlerTest.java
@@ -57,6 +57,7 @@ import net.shibboleth.shared.resolver.ResolverException;
 /**
  * Test for {@link SAMLMetadataLookupHandler}.
  */
+ at SuppressWarnings("javadoc")
 public class SAMLMetadataLookupHandlerTest extends XMLObjectBaseTestCase {
 
     private PredicateRoleDescriptorResolver roleResolver;
@@ -373,7 +374,7 @@ public class SAMLMetadataLookupHandlerTest extends XMLObjectBaseTestCase {
         messageContext.setMessage(request);
 
         // The context data/criterion won't influence the actual results, so just test that criterion has been added as expected.
-        CriteriaSet criteria = handler.buildLookupCriteria(messageContext);
+        CriteriaSet criteria = handler.buildLookupCriteria(messageContext, "urn:mace:incommon:osu.edu", IDPSSODescriptor.DEFAULT_ELEMENT_NAME);
         Assert.assertNotNull(criteria);
         Assert.assertTrue(criteria.contains(DetectDuplicateEntityIDsCriterion.class));
         Assert.assertEquals(criteria.get(DetectDuplicateEntityIDsCriterion.class).getValue(), DetectDuplicateEntityIDs.Batch);
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/SAMLProtocolMessageXMLSignatureSecurityHandlerTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/SAMLProtocolMessageXMLSignatureSecurityHandlerTest.java
index a25420425..95b3bc346 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/SAMLProtocolMessageXMLSignatureSecurityHandlerTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/binding/security/impl/SAMLProtocolMessageXMLSignatureSecurityHandlerTest.java
@@ -148,10 +148,10 @@ public class SAMLProtocolMessageXMLSignatureSecurityHandlerTest extends XMLObjec
         
         messageContext = new MessageContext();
         messageContext.setMessage(buildInboundSAMLMessage());
-        messageContext.getSubcontext(SAMLPeerEntityContext.class, true).setEntityId(issuer);
-        messageContext.getSubcontext(SAMLPeerEntityContext.class, true).setRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
-        messageContext.getSubcontext(SAMLProtocolContext.class, true).setProtocol(SAMLConstants.SAML20P_NS);
-        messageContext.getSubcontext(SecurityParametersContext.class, true).setSignatureValidationParameters(sigValParams);
+        messageContext.ensureSubcontext(SAMLPeerEntityContext.class).setEntityId(issuer);
+        messageContext.ensureSubcontext(SAMLPeerEntityContext.class).setRole(SPSSODescriptor.DEFAULT_ELEMENT_NAME);
+        messageContext.ensureSubcontext(SAMLProtocolContext.class).setProtocol(SAMLConstants.SAML20P_NS);
+        messageContext.ensureSubcontext(SecurityParametersContext.class).setSignatureValidationParameters(sigValParams);
     }
     
     /**
@@ -165,10 +165,10 @@ public class SAMLProtocolMessageXMLSignatureSecurityHandlerTest extends XMLObjec
         
         handler.invoke(messageContext);
         
-        Assert.assertEquals(messageContext.getSubcontext(SAMLPeerEntityContext.class, true).getEntityId(), issuer, 
+        Assert.assertEquals(messageContext.ensureSubcontext(SAMLPeerEntityContext.class).getEntityId(), issuer, 
                 "Unexpected value for Issuer found");
         //TODO before this was evaling isInboundSAMLMessageAuthenticated
-        Assert.assertTrue(messageContext.getSubcontext(SAMLPeerEntityContext.class, true).isAuthenticated(), 
+        Assert.assertTrue(messageContext.ensureSubcontext(SAMLPeerEntityContext.class).isAuthenticated(), 
                 "Unexpected value for context authentication state");
     }
     
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/logic/tests/EntityGroupNamePredicateTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/logic/tests/EntityGroupNamePredicateTest.java
index bf61ca817..fb1106dd7 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/logic/tests/EntityGroupNamePredicateTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/profile/logic/tests/EntityGroupNamePredicateTest.java
@@ -20,13 +20,13 @@ package org.opensaml.saml.common.profile.logic.tests;
 import java.util.Arrays;
 import java.util.Collections;
 
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.spring.resource.ResourceHelper;
 
 import org.opensaml.core.criterion.EntityIdCriterion;
 import org.opensaml.core.testing.XMLObjectBaseTestCase;
 import org.opensaml.saml.common.profile.logic.EntityGroupNamePredicate;
-import org.opensaml.saml.metadata.resolver.filter.MetadataNodeProcessor;
 import org.opensaml.saml.metadata.resolver.filter.impl.EntitiesDescriptorNameProcessor;
 import org.opensaml.saml.metadata.resolver.filter.impl.NodeProcessingMetadataFilter;
 import org.opensaml.saml.metadata.resolver.impl.ResourceBackedMetadataResolver;
@@ -41,6 +41,7 @@ import org.testng.annotations.Test;
 /**
  * Unit tests for {@link EntityGroupNamePredicate}.
  */
+ at SuppressWarnings("javadoc")
 public class EntityGroupNamePredicateTest extends XMLObjectBaseTestCase {
 
     private NodeProcessingMetadataFilter filter;
@@ -54,7 +55,7 @@ public class EntityGroupNamePredicateTest extends XMLObjectBaseTestCase {
                 new ClassPathResource("/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptor-Name-metadata.xml");
         
         filter = new NodeProcessingMetadataFilter();
-        filter.setNodeProcessors(Collections.<MetadataNodeProcessor>singletonList(new EntitiesDescriptorNameProcessor()));
+        filter.setNodeProcessors(CollectionSupport.singletonList(new EntitiesDescriptorNameProcessor()));
         filter.initialize();
         
         metadataProvider = new ResourceBackedMetadataResolver(null, ResourceHelper.of(resource));
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptorNameProcessorTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptorNameProcessorTest.java
index aea9b816f..d53c474a6 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptorNameProcessorTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/EntitiesDescriptorNameProcessorTest.java
@@ -36,6 +36,7 @@ import org.testng.annotations.Test;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 
+ at SuppressWarnings("javadoc")
 public class EntitiesDescriptorNameProcessorTest extends XMLObjectBaseTestCase {
     
     private FilesystemMetadataResolver metadataProvider;

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.


More information about the commits mailing list