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

Scott Cantor cantor.2 at osu.edu
Mon Apr 10 22:33:47 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=b137c4f81477e42d1241265ac0f0122e89d6fb9a

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

commit b137c4f81477e42d1241265ac0f0122e89d6fb9a
Author: Scott Cantor <cantor.2 at osu.edu>
AuthorDate: Mon Apr 10 18:33:44 2023 -0400

    IDP-2069 - Null Handling Task
    
    https://shibboleth.atlassian.net/browse/IDP-2069
    
    Clean metadata and some outstanding security classes.
    Clean more tests.
---
 .../metadata/resolver/index/MetadataIndex.java     |   4 +-
 .../impl/AbstractBatchMetadataResolver.java        |  40 +-
 .../impl/AbstractDynamicHTTPMetadataResolver.java  |  38 +-
 .../impl/AbstractDynamicMetadataResolver.java      | 207 ++++++----
 .../resolver/impl/AbstractMetadataResolver.java    |  90 ++--
 .../impl/AbstractReloadingMetadataResolver.java    | 106 ++---
 .../resolver/impl/CompositeMetadataResolver.java   |  97 ++---
 .../resolver/impl/DOMMetadataResolver.java         |  24 +-
 .../DefaultLocalDynamicSourceKeyGenerator.java     |  13 +-
 .../resolver/impl/EntityIDDigestGenerator.java     |  18 +-
 .../impl/FileBackedHTTPMetadataResolver.java       |  44 +-
 .../resolver/impl/FilesystemMetadataResolver.java  |  30 +-
 .../FunctionDrivenDynamicHTTPMetadataResolver.java |  10 +-
 .../impl/HTTPEntityIDRequestURLBuilder.java        |  16 +-
 .../resolver/impl/HTTPMetadataResolver.java        |  51 +--
 .../impl/LocalDynamicMetadataResolver.java         |  15 +-
 .../MetadataQueryProtocolRequestURLBuilder.java    |  28 +-
 .../impl/PredicateRoleDescriptorResolver.java      |  47 +--
 .../resolver/impl/RegexRequestURLBuilder.java      |  15 +-
 .../resolver/impl/SAMLArtifactURLBuilder.java      |  16 +-
 .../resolver/impl/TemplateRequestURLBuilder.java   |  26 +-
 .../resolver/index/impl/EndpointMetadataIndex.java |  17 +-
 .../index/impl/FunctionDrivenMetadataIndex.java    |   4 +-
 .../resolver/index/impl/MetadataIndexManager.java  |   2 +-
 .../resolver/index/impl/RoleMetadataIndex.java     |   5 +-
 .../index/impl/SAMLArtifactMetadataIndex.java      |  14 +-
 .../InlineSelfEncryptionParametersStrategy.java    |  39 +-
 .../security/impl/MetadataCredentialResolver.java  |  53 ++-
 .../security/impl/SAMLMDCredentialContext.java     |  20 +-
 .../SAMLMetadataEncryptionParametersResolver.java  | 187 +++++----
 ...MetadataSignatureSigningParametersResolver.java |  38 +-
 .../context/tests/SAMLMessageInfoContextTest.java  |  13 +-
 .../saml/common/testing/SAMLTestSupport.java       |   6 +-
 .../ext/idpdisco/impl/DiscoveryResponseTest.java   |  14 +-
 .../resolver/filter/impl/AlgorithmFilterTest.java  |  13 +-
 .../impl/BasicDynamicTrustedNamesStrategyTest.java |   1 +
 .../filter/impl/ByReferenceMetadataFilterTest.java |  27 +-
 .../impl/EntitiesDescriptorNameProcessorTest.java  |   6 +-
 .../filter/impl/EntityAttributesFilterTest.java    |  18 +-
 .../resolver/filter/impl/EntityRoleFilterTest.java |   1 +
 .../filter/impl/NameIDFormatFilterTest.java        |  32 +-
 .../impl/NodeProcessingMetadataFilterTest.java     |   1 +
 .../resolver/filter/impl/PredicateFilterTest.java  |  25 +-
 .../filter/impl/RequiredValidUntilTest.java        |   1 +
 .../filter/impl/SchemaValidationFilterTest.java    |   1 +
 .../resolver/filter/impl/ScriptedFunctionTest.java |  10 +-
 .../SignatureValidationFilterExplicitKeyTest.java  |  15 +-
 .../impl/SignatureValidationFilterPKIXTest.java    |   4 +-
 .../AbstractDynamicHTTPMetadataResolverTest.java   |  17 +-
 .../impl/AbstractDynamicMetadataResolverTest.java  |  13 +-
 .../impl/ChainingMetadataResolverTest.java         |   5 +-
 .../resolver/impl/DOMMetadataResolverTest.java     |   5 +-
 .../DefaultLocalDynamicSourceKeyGeneratorTest.java |   4 +-
 .../resolver/impl/EntityIDDigestGeneratorTest.java |   4 +-
 .../impl/FileBackedHTTPMetadataResolverTest.java   |   1 +
 .../impl/FilesystemMetadataResolverTest.java       |   1 +
 ...ctionDrivenDynamicHTTPMetadataResolverTest.java |   1 +
 .../impl/HTTPEntityIDRequestURLBuilderTest.java    |   6 +-
 .../impl/LocalDynamicMetadataResolverTest.java     |   9 +-
 ...MetadataQueryProtocolRequestURLBuilderTest.java |  13 +-
 .../resolver/impl/PredicateFilteringTest.java      |   1 +
 .../impl/PredicateRoleDescriptorResolverTest.java  |  26 +-
 .../resolver/impl/RegexRequestURLBuilderTest.java  |   1 +
 .../impl/ResourceBackedMetadataResolverTest.java   |   2 +-
 .../resolver/impl/SAMLArtifactURLBuilderTest.java  |   4 +-
 .../impl/TemplateRequestURLBuilderTest.java        |   6 +-
 .../impl/ConstantEntityDescriptorFunction.java     |   1 +
 .../index/impl/EndpointMetadataIndexTest.java      |  30 +-
 .../impl/FunctionDrivenMetadataIndexTest.java      |  19 +-
 .../index/impl/MetadataIndexManagerTest.java       |  10 +-
 .../index/impl/MetadataIndexStoreTest.java         |   4 +-
 .../index/impl/MetadataIndexSupportTest.java       |  10 +-
 .../resolver/index/impl/MetadataIndexingTest.java  |   5 +-
 .../resolver/index/impl/RoleMetadataIndexTest.java |  27 +-
 .../index/impl/SAMLArtifactMetadataIndexTest.java  |  29 +-
 .../index/impl/SimpleStringCriteriaFunction.java   |   1 +
 .../resolver/index/impl/SimpleStringCriterion.java |   1 +
 .../impl/UppercaseEntityIdDescriptorFunction.java  |  14 +-
 ...InlineSelfEncryptionParametersStrategyTest.java |  63 +--
 .../impl/MetadataCredentialResolverTest.java       |  92 +++--
 ...MLMetadataEncryptionParametersResolverTest.java | 451 +++++++++++++--------
 ...dataSignatureSigningParametersResolverTest.java |  46 ++-
 .../impl/SAMLSignatureProfileValidatorTest.java    |  23 +-
 ...bstractCriteriaFilteringCredentialResolver.java |   2 +-
 .../impl/BasicEncryptionParametersResolver.java    |   2 +-
 85 files changed, 1382 insertions(+), 1069 deletions(-)

diff --git a/opensaml-saml-api/src/main/java/org/opensaml/saml/metadata/resolver/index/MetadataIndex.java b/opensaml-saml-api/src/main/java/org/opensaml/saml/metadata/resolver/index/MetadataIndex.java
index 22a1a92a6..03f3d6329 100644
--- a/opensaml-saml-api/src/main/java/org/opensaml/saml/metadata/resolver/index/MetadataIndex.java
+++ b/opensaml-saml-api/src/main/java/org/opensaml/saml/metadata/resolver/index/MetadataIndex.java
@@ -65,6 +65,6 @@ public interface MetadataIndex {
      *         but will not contain null elements.
      */
     @Nullable @Unmodifiable @NotLive 
-    public Set<MetadataIndexKey> generateKeys(@Nonnull final CriteriaSet criteriaSet);
+    public Set<MetadataIndexKey> generateKeys(@Nullable final CriteriaSet criteriaSet);
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractBatchMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractBatchMetadataResolver.java
index e530f6ff6..3d95599dd 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractBatchMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractBatchMetadataResolver.java
@@ -18,7 +18,6 @@
 package org.opensaml.saml.metadata.resolver.impl;
 
 import java.time.Instant;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.Optional;
 import java.util.Set;
@@ -37,14 +36,15 @@ import org.opensaml.saml.saml2.common.TimeBoundSAMLObject;
 import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Iterables;
 
 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.component.ComponentInitializationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 
@@ -56,13 +56,13 @@ public abstract class AbstractBatchMetadataResolver extends AbstractMetadataReso
         implements BatchMetadataResolver, IterableMetadataSource {
     
     /** Class logger. */
-    private final Logger log = LoggerFactory.getLogger(AbstractBatchMetadataResolver.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractBatchMetadataResolver.class);
     
     /** Flag indicating whether to cache the original source metadata document. */
     private boolean cacheSourceMetadata;
     
     /** The set of indexes configured. */
-    private Set<MetadataIndex> indexes;
+    @Nonnull private Set<MetadataIndex> indexes;
     
     /** Flag indicating whether resolution may be performed solely by applying predicates to the
      * entire metadata collection. Defaults to false. */
@@ -70,7 +70,7 @@ public abstract class AbstractBatchMetadataResolver extends AbstractMetadataReso
     
     /** Constructor. */
     public AbstractBatchMetadataResolver() {
-        indexes = Collections.emptySet();
+        indexes = CollectionSupport.emptySet();
         
         setCacheSourceMetadata(true);
     }
@@ -78,7 +78,7 @@ public abstract class AbstractBatchMetadataResolver extends AbstractMetadataReso
     /** {@inheritDoc} */
     @Override public Iterator<EntityDescriptor> iterator() {
         checkComponentActive();
-        return Collections.unmodifiableList(getBackingStore().getOrderedDescriptors()).iterator();
+        return CollectionSupport.copyToList(ensureBackingStore().getOrderedDescriptors()).iterator();
     }
 
     /**
@@ -117,9 +117,9 @@ public abstract class AbstractBatchMetadataResolver extends AbstractMetadataReso
     public void setIndexes(@Nullable final Set<MetadataIndex> newIndexes) {
         checkSetterPreconditions();
         if (newIndexes == null) {
-            indexes = Collections.emptySet();
+            indexes = CollectionSupport.emptySet();
         } else {
-            indexes = Set.copyOf(newIndexes);
+            indexes = CollectionSupport.copyToSet(newIndexes);
         }
     }
 
@@ -146,7 +146,7 @@ public abstract class AbstractBatchMetadataResolver extends AbstractMetadataReso
 
     /** {@inheritDoc} */
     @Nullable public Instant getRootValidUntil() {
-        final XMLObject cached = getBackingStore().getCachedOriginalMetadata();
+        final XMLObject cached = ensureBackingStore().getCachedOriginalMetadata();
         if (cached != null && cached instanceof TimeBoundSAMLObject) {
             return ((TimeBoundSAMLObject)cached).getValidUntil();
         }
@@ -155,7 +155,7 @@ public abstract class AbstractBatchMetadataResolver extends AbstractMetadataReso
 
     /** {@inheritDoc} */
     @Nullable public Boolean isRootValid() {
-        final XMLObject cached = getBackingStore().getCachedOriginalMetadata();
+        final XMLObject cached = ensureBackingStore().getCachedOriginalMetadata();
         if (cached == null) {
             return null;
         }
@@ -163,10 +163,12 @@ public abstract class AbstractBatchMetadataResolver extends AbstractMetadataReso
     }
 
     /** {@inheritDoc} */
-    @Override @Nonnull protected Iterable<EntityDescriptor> doResolve(final CriteriaSet criteria) throws ResolverException {
+    @Override
+    @Nonnull protected Iterable<EntityDescriptor> doResolve(@Nullable final CriteriaSet criteria)
+            throws ResolverException {
         checkComponentActive();
         
-        final EntityIdCriterion entityIdCriterion = criteria.get(EntityIdCriterion.class);
+        final EntityIdCriterion entityIdCriterion = criteria != null ? criteria.get(EntityIdCriterion.class) : null;
         if (entityIdCriterion != null) {
             final Iterable<EntityDescriptor> entityIdcandidates = lookupEntityID(entityIdCriterion.getEntityId());
             if (log.isDebugEnabled()) {
@@ -195,7 +197,7 @@ public abstract class AbstractBatchMetadataResolver extends AbstractMetadataReso
             return predicateFilterCandidates(this, criteria, true);
         } else {
             log.debug("{} Resolved no secondary indexed candidates, returning empty result", getLogPrefix());
-            return Collections.emptySet();
+            return CollectionSupport.emptySet();
         }
         
     }
@@ -212,8 +214,8 @@ public abstract class AbstractBatchMetadataResolver extends AbstractMetadataReso
      *          and the wrapped set contains the indexed data, which may be empty.
      */
     @Nonnull @NonnullElements 
-    protected Optional<Set<EntityDescriptor>> lookupByIndexes(@Nonnull final CriteriaSet criteria) {
-        return getBackingStore().getSecondaryIndexManager().lookupIndexedItems(criteria);
+    protected Optional<Set<EntityDescriptor>> lookupByIndexes(@Nullable final CriteriaSet criteria) {
+        return ensureBackingStore().getSecondaryIndexManager().lookupIndexedItems(criteria);
     }
     
     /** {@inheritDoc} */
@@ -230,8 +232,8 @@ public abstract class AbstractBatchMetadataResolver extends AbstractMetadataReso
     }
     
     /** {@inheritDoc} */
-    @Override @Nonnull protected BatchEntityBackingStore getBackingStore() {
-        return (BatchEntityBackingStore) super.getBackingStore();
+    @Override @Nonnull protected BatchEntityBackingStore ensureBackingStore() {
+        return (BatchEntityBackingStore) super.ensureBackingStore();
     }
     
     /** {@inheritDoc} */
@@ -254,7 +256,7 @@ public abstract class AbstractBatchMetadataResolver extends AbstractMetadataReso
      * @return the current effective cached metadata document
      */
     @Nullable protected XMLObject getCachedOriginalMetadata() {
-       return getBackingStore().getCachedOriginalMetadata(); 
+       return ensureBackingStore().getCachedOriginalMetadata(); 
     }
     
     /**
@@ -268,7 +270,7 @@ public abstract class AbstractBatchMetadataResolver extends AbstractMetadataReso
      * @return the current effective cached metadata document
      */
     @Nullable protected XMLObject getCachedFilteredMetadata() {
-       return getBackingStore().getCachedFilteredMetadata(); 
+       return ensureBackingStore().getCachedFilteredMetadata(); 
     }
 
     /**
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicHTTPMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicHTTPMetadataResolver.java
index 6b2b56db4..8870cb9d6 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicHTTPMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicHTTPMetadataResolver.java
@@ -21,7 +21,6 @@ import java.io.ByteArrayInputStream;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.Arrays;
-import java.util.Collections;
 import java.util.List;
 import java.util.Set;
 import java.util.Timer;
@@ -43,7 +42,6 @@ import org.opensaml.core.xml.util.XMLObjectSource;
 import org.opensaml.security.httpclient.HttpClientSecurityParameters;
 import org.opensaml.security.httpclient.HttpClientSecuritySupport;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.slf4j.MDC;
 
 import com.google.common.base.Strings;
@@ -54,10 +52,12 @@ import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 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.collection.LazySet;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.net.MediaTypeSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
@@ -207,7 +207,7 @@ public abstract class AbstractDynamicHTTPMetadataResolver extends AbstractDynami
     public void setSupportedContentTypes(@Nullable final List<String> types) {
         checkSetterPreconditions();
         if (types == null) {
-            supportedContentTypes = Collections.emptyList();
+            supportedContentTypes = CollectionSupport.emptyList();
         } else {
             supportedContentTypes = StringSupport.normalizeStringCollection(types)
                     .stream()
@@ -233,28 +233,15 @@ public abstract class AbstractDynamicHTTPMetadataResolver extends AbstractDynami
                 supportedMediaTypes.add(MediaType.parse(contentType));
             }
         } else {
-            supportedMediaTypes = Collections.emptySet();
+            supportedMediaTypes = CollectionSupport.emptySet();
         }
         
         log.debug("{} Supported content types are: {}", getLogPrefix(), getSupportedContentTypes());
     }
     
-   /** {@inheritDoc} */
-    @Override
-    protected void doDestroy() {
-        httpClient = null;
-        httpClientSecurityParameters = null;
-        
-        supportedContentTypes = null;
-        supportedContentTypesValue = null;
-        supportedMediaTypes = null;
-        
-        super.doDestroy();
-    }
-    
     /** {@inheritDoc} */
     @Override
-    @Nullable protected XMLObject fetchFromOriginSource(@Nonnull final CriteriaSet criteria) 
+    @Nullable protected XMLObject fetchFromOriginSource(@Nullable final CriteriaSet criteria) 
             throws IOException {
             
         final ClassicHttpRequest request = buildHttpRequest(criteria);
@@ -281,7 +268,7 @@ public abstract class AbstractDynamicHTTPMetadataResolver extends AbstractDynami
      * @param criteria the input criteria set
      * @return the newly constructed request, or null if it can not be built from the supplied criteria
      */
-    @Nullable protected ClassicHttpRequest buildHttpRequest(@Nonnull final CriteriaSet criteria) {
+    @Nullable protected ClassicHttpRequest buildHttpRequest(@Nullable final CriteriaSet criteria) {
         final String url = buildRequestURL(criteria);
         log.debug("{} Built request URL of: {}", getLogPrefix(), url);
         
@@ -307,7 +294,7 @@ public abstract class AbstractDynamicHTTPMetadataResolver extends AbstractDynami
      * @param criteria the input criteria set
      * @return the request URL, or null if it can not be built based on the supplied criteria
      */
-    @Nullable protected abstract String buildRequestURL(@Nonnull final CriteriaSet criteria);
+    @Nullable protected abstract String buildRequestURL(@Nullable final CriteriaSet criteria);
         
     /**
      * Build the {@link HttpClientContext} instance which will be used to invoke the {@link HttpClient} request.
@@ -316,8 +303,9 @@ public abstract class AbstractDynamicHTTPMetadataResolver extends AbstractDynami
      * 
      * @return a new instance of {@link HttpClientContext}
      */
-    protected HttpClientContext buildHttpClientContext(@Nonnull final ClassicHttpRequest request) {
+    @Nonnull protected HttpClientContext buildHttpClientContext(@Nonnull final ClassicHttpRequest request) {
         final HttpClientContext context = HttpClientContext.create();
+        assert context != null;
         
         HttpClientSecuritySupport.marshalSecurityParameters(context, httpClientSecurityParameters, true);
         HttpClientSecuritySupport.addDefaultTLSTrustEngineCriteria(context, request);
@@ -332,7 +320,7 @@ public abstract class AbstractDynamicHTTPMetadataResolver extends AbstractDynami
 
         /** {@inheritDoc} */
         @Override
-        public XMLObject handleResponse(@Nonnull final ClassicHttpResponse response) throws IOException {
+        public XMLObject handleResponse(final ClassicHttpResponse response) throws IOException {
             
             final int httpStatusCode = response.getCode();
             
@@ -362,7 +350,7 @@ public abstract class AbstractDynamicHTTPMetadataResolver extends AbstractDynami
             try {
                 final InputStream ins = response.getEntity().getContent();
                 final byte[] source = ByteStreams.toByteArray(ins);
-                try (ByteArrayInputStream bais = new ByteArrayInputStream(source)) {
+                try (final ByteArrayInputStream bais = new ByteArrayInputStream(source)) {
                     final XMLObject xmlObject = unmarshallMetadata(bais);
                     xmlObject.getObjectMetadata().put(new XMLObjectSource(source));
                     return xmlObject;
@@ -380,7 +368,7 @@ public abstract class AbstractDynamicHTTPMetadataResolver extends AbstractDynami
          * @param response the received response
          * @throws ResolverException if the response was not valid, or if there is a fatal error validating the response
          */
-        protected void validateHttpResponse(@Nonnull final ClassicHttpResponse response) throws ResolverException {
+        protected void validateHttpResponse(final ClassicHttpResponse response) throws ResolverException {
             if (!getSupportedMediaTypes().isEmpty()) {
                 final String contentType = StringSupport.trimOrNull(response.getEntity().getContentType());
                 log.debug("{} Saw raw Content-Type from response header '{}'", getLogPrefix(), contentType);
@@ -394,4 +382,4 @@ public abstract class AbstractDynamicHTTPMetadataResolver extends AbstractDynami
             
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicMetadataResolver.java
index 99b1db6ca..f0b21e838 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicMetadataResolver.java
@@ -22,7 +22,6 @@ import java.security.NoSuchAlgorithmException;
 import java.time.Duration;
 import java.time.Instant;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
@@ -59,14 +58,12 @@ import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.opensaml.security.crypto.JCAConstants;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.codahale.metrics.Gauge;
 import com.codahale.metrics.MetricRegistry;
 import com.codahale.metrics.RatioGauge;
 import com.codahale.metrics.Timer.Context;
 import com.google.common.base.MoreObjects;
-import com.google.common.base.Predicates;
 
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
@@ -76,9 +73,13 @@ import net.shibboleth.shared.annotation.constraint.Positive;
 import net.shibboleth.shared.annotation.constraint.Unmodifiable;
 import net.shibboleth.shared.codec.StringDigester;
 import net.shibboleth.shared.codec.StringDigester.OutputFormat;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.collection.Pair;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.logic.PredicateSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 import net.shibboleth.shared.primitive.TimerSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
@@ -103,10 +104,11 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
     @Nonnull @NotEmpty public static final String METRIC_GAUGE_NUM_LIVE_ENTITYIDS = "gauge.numLiveEntityIDs";
     
     /** Metric name for the gauge of the persistent cache initialization metrics. */
-    @Nonnull @NotEmpty public static final String METRIC_GAUGE_PERSISTENT_CACHE_INIT = "gauge.persistentCacheInitialization";
+    @Nonnull @NotEmpty
+    public static final String METRIC_GAUGE_PERSISTENT_CACHE_INIT = "gauge.persistentCacheInitialization";
     
     /** Class logger. */
-    private final Logger log = LoggerFactory.getLogger(AbstractDynamicMetadataResolver.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractDynamicMetadataResolver.class);
     
     /** Base name for Metrics instrumentation names. */
     @NonnullAfterInit private String metricsBaseName;
@@ -127,7 +129,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
     @Nullable private Gauge<PersistentCacheInitializationMetrics> gaugePersistentCacheInit;
     
     /** Timer used to schedule background metadata update tasks. */
-    @Nullable private Timer taskTimer;
+    @NonnullAfterInit private Timer taskTimer;
     
     /** Whether we created our own task timer during object construction. */
     private boolean createdOwnTaskTimer;
@@ -142,7 +144,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
     @Nonnull private Duration negativeLookupCacheDuration;
     
     /** Factor used to compute when the next refresh interval will occur. Default value: 0.75 */
-    @Positive private Float refreshDelayFactor;
+    @Positive @Nonnull private Float refreshDelayFactor;
     
     /** The maximum idle time for which the resolver will keep data for a given entityID, 
      * before it is removed. */
@@ -162,10 +164,10 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
     private BackingStoreCleanupSweeper cleanupTask;
     
     /** The manager for the persistent cache store for resolved metadata. */
-    private XMLObjectLoadSaveManager<EntityDescriptor> persistentCacheManager;
+    @Nullable private XMLObjectLoadSaveManager<EntityDescriptor> persistentCacheManager;
     
     /** Function for generating the String key used with the cache manager. */
-    private Function<EntityDescriptor,String> persistentCacheKeyGenerator;
+    @Nullable private Function<EntityDescriptor,String> persistentCacheKeyGenerator;
     
     /** Flag indicating whether should initialize from the persistent cache in the background. */
     private boolean initializeFromPersistentCacheInBackground;
@@ -175,13 +177,13 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
     
     /** Predicate which determines whether a given entity should be loaded from the persistent cache
      * at resolver initialization time. */
-    private Predicate<EntityDescriptor> initializationFromCachePredicate;
+    @Nullable private Predicate<EntityDescriptor> initializationFromCachePredicate;
     
     /** Object tracking metrics related to the persistent cache initialization. */
     @NonnullAfterInit private PersistentCacheInitializationMetrics persistentCacheInitMetrics;
     
     /** The set of indexes configured. */
-    private Set<MetadataIndex> indexes;
+    @Nonnull private Set<MetadataIndex> indexes;
     
     /** Flag used to track state of whether currently initializing or not. */
     private boolean initializing;
@@ -192,7 +194,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
      * @param backgroundTaskTimer the {@link Timer} instance used to run resolver background management tasks
      */
     public AbstractDynamicMetadataResolver(@Nullable final Timer backgroundTaskTimer) {
-        indexes = Collections.emptySet();
+        indexes = CollectionSupport.emptySet();
         
         if (backgroundTaskTimer == null) {
             taskTimer = new Timer(TimerSupport.getTimerName(this), true);
@@ -288,6 +290,18 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
         return persistentCacheManager;
     }
 
+    /**
+     * Get the manager for the persistent cache store for resolved metadata, raising a
+     * {@link ConstraintViolationException} if null.
+     * 
+     * @return the cache manager if configured
+     * 
+     * @since 5.0.0
+     */
+    @Nonnull public XMLObjectLoadSaveManager<EntityDescriptor> ensurePersistentCacheManager() {
+        return Constraint.isNotNull(persistentCacheManager, "Persistent cache manager was null");
+    }
+
     /**
      * Set the manager for the persistent cache store for resolved metadata.
      * 
@@ -523,11 +537,11 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
         
         if (threshold == null) {
             expirationWarningThreshold = Duration.ZERO;
-        }
-        if (threshold.isNegative()) {
+        } else if (threshold.isNegative()) {
             throw new IllegalArgumentException("Expiration warning threshold must be greater than or equal to 0");
+        } else {
+            expirationWarningThreshold = threshold;
         }
-        expirationWarningThreshold = threshold;
     }
 
     /**
@@ -594,9 +608,9 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
         checkSetterPreconditions();
 
         if (newIndexes == null) {
-            indexes = Collections.emptySet();
+            indexes = CollectionSupport.emptySet();
         } else {
-            indexes = Set.copyOf(newIndexes);
+            indexes = CollectionSupport.copyToSet(newIndexes);
         }
     }
     
@@ -606,24 +620,25 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
      * @return true if active, false if not.
      */
     protected boolean indexesEnabled() {
-        return ! getBackingStore().getSecondaryIndexManager().getIndexes().isEmpty();
+        return !ensureBackingStore().getSecondaryIndexManager().getIndexes().isEmpty();
     }
     
     /** {@inheritDoc} */
     public void clear() throws ResolverException {
-        final DynamicEntityBackingStore backingStore = getBackingStore();
+        final DynamicEntityBackingStore backingStore = ensureBackingStore();
         final Set<String> entityIDs = new HashSet<>();
         entityIDs.addAll(backingStore.getIndexedDescriptors().keySet());
         entityIDs.addAll(backingStore.getManagementDataEntityIDs());
         
         for (final String entityID : entityIDs) {
+            assert entityID != null;
             clear(entityID);
         }
     }
 
     /** {@inheritDoc} */
     public void clear(@Nonnull final String entityID) throws ResolverException {
-        final DynamicEntityBackingStore backingStore = getBackingStore();
+        final DynamicEntityBackingStore backingStore = ensureBackingStore();
         final EntityManagementData mgmtData = backingStore.getManagementData(entityID);
         final Lock writeLock = mgmtData.getReadWriteLock().writeLock();
         try {
@@ -639,7 +654,8 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
 
     /** {@inheritDoc} */
     @Override
-    @Nonnull protected Iterable<EntityDescriptor> doResolve(@Nonnull final CriteriaSet criteria) throws ResolverException {
+    @Nonnull protected Iterable<EntityDescriptor> doResolve(@Nullable final CriteriaSet criteria)
+            throws ResolverException {
         checkComponentActive();
         
         final Context contextResolve = MetricsSupport.startTimer(timerResolve);
@@ -650,7 +666,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
             if (entityID != null) {
                 log.debug("{} Resolved criteria to entityID: {}", getLogPrefix(), entityID);
 
-                final EntityManagementData mgmtData = getBackingStore().getManagementData(entityID);
+                final EntityManagementData mgmtData = ensureBackingStore().getManagementData(entityID);
                 final Lock readLock = mgmtData.getReadWriteLock().readLock();
                 try {
                     readLock.lock();
@@ -661,7 +677,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
                             log.debug("{} Did not find requested metadata in backing store, " 
                                     + "and negative lookup cache is active, returning empty result", 
                                     getLogPrefix());
-                            return Collections.emptyList();
+                            return CollectionSupport.emptyList();
                         }
                         log.debug("{} Did not find requested metadata in backing store, " 
                                 + "attempting to resolve dynamically", 
@@ -704,7 +720,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
     * @param criteria the criteria set on which to operate
     * @return the resolve entityID, or null if a single entityID could not be resolved
     */
-    @Nullable protected String resolveEntityID(@Nonnull final CriteriaSet criteria) {
+    @Nullable protected String resolveEntityID(@Nullable final CriteriaSet criteria) {
         final Set<String> entityIDs = resolveEntityIDs(criteria);
         if (entityIDs.size() == 1) {
             return entityIDs.iterator().next();
@@ -724,25 +740,25 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
     * @param criteria the criteria set on which to operate
     * @return the resolved entityIDs, may be empty
     */
-    @Nonnull protected Set<String> resolveEntityIDs(@Nonnull final CriteriaSet criteria) {
-        final EntityIdCriterion entityIdCriterion = criteria.get(EntityIdCriterion.class);
+    @Nonnull protected Set<String> resolveEntityIDs(@Nullable final CriteriaSet criteria) {
+        final EntityIdCriterion entityIdCriterion = criteria != null ? criteria.get(EntityIdCriterion.class) : null;
         if (entityIdCriterion != null) {
             log.debug("{} Found entityID in criteria: {}", getLogPrefix(), entityIdCriterion.getEntityId());
-            return Collections.singleton(entityIdCriterion.getEntityId());
+            return CollectionSupport.singleton(entityIdCriterion.getEntityId());
         }
         log.debug("{} EntityID was not supplied in criteria, processing criteria with secondary indexes",
                 getLogPrefix());
         
         if (!indexesEnabled()) {
             log.trace("Indexes not enabled, skipping secondary index processing");
-            return Collections.emptySet();
+            return CollectionSupport.emptySet();
         }
 
         Optional<Set<String>> indexedResult = Optional.empty();
-        final Lock readLock = getBackingStore().getSecondaryIndexManager().getReadWriteLock().readLock();
+        final Lock readLock = ensureBackingStore().getSecondaryIndexManager().getReadWriteLock().readLock();
         try {
             readLock.lock();
-            indexedResult = getBackingStore().getSecondaryIndexManager().lookupIndexedItems(criteria);
+            indexedResult = ensureBackingStore().getSecondaryIndexManager().lookupIndexedItems(criteria);
         } finally {
             readLock.unlock();
         }
@@ -752,19 +768,20 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
             if (entityIDs.isEmpty()) {
                 log.debug("{} No entityIDs resolved from secondary indexes (Optional 'present' with empty set)",
                         getLogPrefix());
-                return Collections.emptySet();
+                return CollectionSupport.emptySet();
             } else if (entityIDs.size() > 1) {
                 log.debug("{} Multiple entityIDs resolved from secondary indexes: {}", 
                         getLogPrefix(), entityIDs);
                 return new HashSet<>(entityIDs);
             } else {
                 final String entityID = entityIDs.iterator().next();
+                assert entityID != null;
                 log.debug("{} Resolved 1 entityID from secondary indexes: {}", getLogPrefix(), entityID);
-                return Collections.singleton(entityID);
+                return CollectionSupport.singleton(entityID);
             }
         }
         log.debug("{} No entityIDs resolved from secondary indexes (Optional 'absent').", getLogPrefix());
-        return null;
+        return CollectionSupport.emptySet();
     }
     
     /**
@@ -777,7 +794,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
      * @throws ResolverException  if there is a fatal error attempting to resolve the metadata
      */
     @Nonnull @NonnullElements protected Iterable<EntityDescriptor> resolveFromOriginSource(
-            @Nonnull final CriteriaSet criteria, @Nullable final String entityID) throws ResolverException {
+            @Nullable final CriteriaSet criteria, @Nullable final String entityID) throws ResolverException {
         
         if (entityID != null) {
             log.debug("{} Resolving from origin source based on entityID: {}", getLogPrefix(), entityID);
@@ -799,9 +816,9 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
      */
     @Nonnull @NonnullElements
     protected Iterable<EntityDescriptor> resolveFromOriginSourceWithEntityID(
-            @Nonnull final CriteriaSet criteria, @Nonnull final String entityID) throws ResolverException {
+            @Nullable final CriteriaSet criteria, @Nonnull final String entityID) throws ResolverException {
         
-        final EntityManagementData mgmtData = getBackingStore().getManagementData(entityID);
+        final EntityManagementData mgmtData = ensureBackingStore().getManagementData(entityID);
         final Lock writeLock = mgmtData.getReadWriteLock().writeLock(); 
         
         try {
@@ -865,7 +882,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
      * @throws ResolverException if there is a fatal error attempting to resolve the metadata
      */
     @Nonnull @NonnullElements 
-    protected Iterable<EntityDescriptor> resolveFromOriginSourceWithoutEntityID(@Nonnull final CriteriaSet criteria) 
+    protected Iterable<EntityDescriptor> resolveFromOriginSourceWithoutEntityID(@Nullable final CriteriaSet criteria) 
             throws ResolverException {
         
         XMLObject root = null;
@@ -882,12 +899,12 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
         if (root == null) {
             log.debug("{} No metadata was fetched from the origin source", getLogPrefix());
             return lookupCriteria(criteria);
-        } else if (root instanceof EntityDescriptor){
+        } else if (root instanceof EntityDescriptor entity){
             log.debug("{} Fetched EntityDescriptor from the origin source", getLogPrefix());
-            return processNonEntityIDFetchedEntityDescriptor((EntityDescriptor) root);
-        } else if (root instanceof EntitiesDescriptor) {
+            return processNonEntityIDFetchedEntityDescriptor(entity);
+        } else if (root instanceof EntitiesDescriptor entities) {
             log.debug("{} Fetched EntitiesDescriptor from the origin source", getLogPrefix());
-            return processNonEntityIDFetchedEntittiesDescriptor((EntitiesDescriptor) root);
+            return processNonEntityIDFetchedEntittiesDescriptor(entities);
         } else {
             log.warn("{} Fetched metadata was of an unsupported type: {}", getLogPrefix(), root.getClass().getName());
             return lookupCriteria(criteria);
@@ -903,11 +920,12 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
      * @throws ResolverException if there is a fatal error attempting to resolve the metadata
      */
     @Nonnull @NonnullElements 
-    protected Iterable<EntityDescriptor> lookupCriteria(@Nonnull final CriteriaSet criteria) throws ResolverException {
+    protected Iterable<EntityDescriptor> lookupCriteria(@Nullable final CriteriaSet criteria) throws ResolverException {
         final List<EntityDescriptor> entities = new ArrayList<>();
         final Set<String> entityIDs = resolveEntityIDs(criteria);
         for (final String entityID : entityIDs) {
-            final EntityManagementData mgmtData = getBackingStore().getManagementData(entityID);
+            assert entityID != null;
+            final EntityManagementData mgmtData = ensureBackingStore().getManagementData(entityID);
             final Lock readLock = mgmtData.getReadWriteLock().readLock();
             try {
                 readLock.lock();
@@ -927,16 +945,18 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
      * @return the resolved descriptor(s)
      * @throws ResolverException if there is a fatal error attempting to resolve the metadata
      */
-    @Nullable protected List<EntityDescriptor> processNonEntityIDFetchedEntittiesDescriptor(
+    @Nonnull protected List<EntityDescriptor> processNonEntityIDFetchedEntittiesDescriptor(
             @Nonnull final EntitiesDescriptor entities) throws ResolverException {
         
         final List<EntityDescriptor> returnedEntities = new ArrayList<>();
         
         for (final EntitiesDescriptor childEntities : entities.getEntitiesDescriptors()) {
+            assert childEntities != null;
             returnedEntities.addAll(processNonEntityIDFetchedEntittiesDescriptor(childEntities));
         }
         
         for (final EntityDescriptor entity : entities.getEntityDescriptors()) {
+            assert entity != null;
             returnedEntities.addAll(processNonEntityIDFetchedEntityDescriptor(entity));
         }
         
@@ -950,11 +970,14 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
      * @return the resolved descriptor(s)
      * @throws ResolverException if there is a fatal error attempting to resolve the metadata
      */
-    @Nullable protected List<EntityDescriptor> processNonEntityIDFetchedEntityDescriptor(
+    @Nonnull protected List<EntityDescriptor> processNonEntityIDFetchedEntityDescriptor(
             @Nonnull final EntityDescriptor entity) throws ResolverException {
         
         final String entityID = entity.getEntityID();
-        final EntityManagementData mgmtData = getBackingStore().getManagementData(entityID);
+        if (entityID == null) {
+            throw new ResolverException("EntityDescriptor contained null entityID");
+        }
+        final EntityManagementData mgmtData = ensureBackingStore().getManagementData(entityID);
         final Lock writeLock = mgmtData.getReadWriteLock().writeLock(); 
         try {
             writeLock.lock();            
@@ -977,14 +1000,14 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
      * @return the resolved metadata root XMLObject, or null if metadata could not be fetched
      * @throws IOException if there is a fatal error fetching metadata from the origin source
      */
-    @Nullable protected abstract XMLObject fetchFromOriginSource(@Nonnull final CriteriaSet criteria) 
+    @Nullable protected abstract XMLObject fetchFromOriginSource(@Nullable final CriteriaSet criteria) 
             throws IOException;
 
     /** {@inheritDoc} */
     @Override
     @Nonnull @NonnullElements protected List<EntityDescriptor> lookupEntityID(@Nonnull final String entityID) 
             throws ResolverException {
-        getBackingStore().getManagementData(entityID).recordEntityAccess();
+        ensureBackingStore().getManagementData(entityID).recordEntityAccess();
         return super.lookupEntityID(entityID);
     }
 
@@ -1055,15 +1078,15 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
                 return;
             }
             
-            preProcessEntityDescriptor(entityDescriptor, getBackingStore());
+            preProcessEntityDescriptor(entityDescriptor, ensureBackingStore());
             
             log.info("{} Successfully loaded new EntityDescriptor with entityID '{}' from {}",
                     getLogPrefix(), entityDescriptor.getEntityID(), 
                     fromPersistentCache ? "persistent cache" : "origin source");
             
             // Note: we store in the cache the original input XMLObject, not the filtered one
-            if (isPersistentCachingEnabled() && !fromPersistentCache && (root instanceof EntityDescriptor)) {
-                final EntityDescriptor origDescriptor = (EntityDescriptor) root;
+            if (isPersistentCachingEnabled() && !fromPersistentCache
+                    && root instanceof EntityDescriptor origDescriptor) {
                 final String key = getPersistentCacheKeyGenerator().apply(origDescriptor);
                 log.trace("{} Storing resolved EntityDescriptor '{}' in persistent cache with key '{}'", 
                         getLogPrefix(), origDescriptor.getEntityID(), key);
@@ -1072,7 +1095,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
                             getLogPrefix(), origDescriptor.getEntityID());
                 } else {
                     try {
-                        getPersistentCacheManager().save(key, origDescriptor, true);
+                        ensurePersistentCacheManager().save(key, origDescriptor, true);
                     } catch (final IOException e) {
                         log.warn("{} Error saving EntityDescriptor '{}' to cache store with key {}'", 
                                 getLogPrefix(), origDescriptor.getEntityID(), key);
@@ -1119,6 +1142,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
             @Nonnull final EntityBackingStore backingStore) {
         
         final String entityID = StringSupport.trimOrNull(entityDescriptor.getEntityID());
+        assert entityID != null;
         
         removeByEntityID(entityID, backingStore);
         
@@ -1154,16 +1178,19 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
             log.warn("{} Metadata with ID '{}' currently live is expired or otherwise invalid",
                     getLogPrefix(), descriptor.getEntityID());
         } else {
-            if (isRequireValidMetadata() && descriptor.getValidUntil() != null) {
-                if (!getExpirationWarningThreshold().isZero() 
-                        && descriptor.getValidUntil().isBefore(now.plus(getExpirationWarningThreshold()))) {
-                    log.warn("{} Metadata with ID '{}' currently live will expire "
-                            + "within the configured threshhold at '{}'",
-                            getLogPrefix(), descriptor.getEntityID(), descriptor.getValidUntil());
-                } else if (descriptor.getValidUntil().isBefore(nextRefresh)) {
-                    log.warn("{} Metadata with ID '{}' currently live will expire "
-                            + "at '{}' before the next refresh scheduled for {}'",
-                            getLogPrefix(), descriptor.getEntityID(), descriptor.getValidUntil(), nextRefresh);
+            if (isRequireValidMetadata()) {
+                final Instant validUntil = descriptor.getValidUntil();
+                if (validUntil != null) {
+                    if (!getExpirationWarningThreshold().isZero() 
+                            && validUntil.isBefore(now.plus(getExpirationWarningThreshold()))) {
+                        log.warn("{} Metadata with ID '{}' currently live will expire "
+                                + "within the configured threshhold at '{}'",
+                                getLogPrefix(), descriptor.getEntityID(), descriptor.getValidUntil());
+                    } else if (validUntil.isBefore(nextRefresh)) {
+                        log.warn("{} Metadata with ID '{}' currently live will expire "
+                                + "at '{}' before the next refresh scheduled for {}'",
+                                getLogPrefix(), descriptor.getEntityID(), descriptor.getValidUntil(), nextRefresh);
+                    }
                 }
             }
         }
@@ -1182,10 +1209,11 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
         final Instant lowerBound = now.plus(getMinCacheDuration());
         
         Instant expiration = SAML2Support.getEarliestExpiration(entityDescriptor, now.plus(getMaxCacheDuration()), now);
-        if (expiration.isBefore(lowerBound)) {
+        if (expiration == null || expiration.isBefore(lowerBound)) {
             expiration = lowerBound;
         }
         
+        assert expiration != null;
         return expiration;
     }
     
@@ -1236,10 +1264,16 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
     
     /** {@inheritDoc} */
     @Override
-    @NonnullAfterInit protected DynamicEntityBackingStore getBackingStore() {
+    @Nullable protected DynamicEntityBackingStore getBackingStore() {
         return (DynamicEntityBackingStore) super.getBackingStore();
     }
-    
+
+    /** {@inheritDoc} */
+    @Override
+    @Nonnull protected DynamicEntityBackingStore ensureBackingStore() {
+        return (DynamicEntityBackingStore) super.ensureBackingStore();
+    }
+
     /** {@inheritDoc} */
     @Override
     protected void initMetadataResolver() throws ComponentInitializationException {
@@ -1257,7 +1291,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
             }
             
             if (getInitializationFromCachePredicate() == null) {
-                setInitializationFromCachePredicate(Predicates.alwaysTrue());
+                setInitializationFromCachePredicate(PredicateSupport.alwaysTrue());
             }
             
             persistentCacheInitMetrics = new PersistentCacheInitializationMetrics();
@@ -1302,14 +1336,20 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
             timerFetchFromOriginSource = metricRegistry.timer(
                     MetricRegistry.name(getMetricsBaseName(), METRIC_TIMER_FETCH_FROM_ORIGIN_SOURCE));
 
+            // Cache for null guarding.
+            final com.codahale.metrics.Timer timerResolve2 = timerResolve;
+            assert timerResolve2 != null;
+            final com.codahale.metrics.Timer timerFetchFromOriginSource2 = timerFetchFromOriginSource;
+            assert timerFetchFromOriginSource2 != null;
+
             // Note that these gauges must use the support method to register in a synchronized fashion,
             // and also must store off the instances for later use in destroy.
             ratioGaugeFetchToResolve = MetricsSupport.register(
                     MetricRegistry.name(getMetricsBaseName(), METRIC_RATIOGAUGE_FETCH_TO_RESOLVE), 
                     new RatioGauge() {
                         protected Ratio getRatio() {
-                            return Ratio.of(timerFetchFromOriginSource.getCount(), 
-                                    timerResolve.getCount());
+                                return Ratio.of(timerFetchFromOriginSource2.getCount(), 
+                                        timerResolve2.getCount());
                         }},
                     true);
             
@@ -1317,7 +1357,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
                     MetricRegistry.name(getMetricsBaseName(), METRIC_GAUGE_NUM_LIVE_ENTITYIDS),
                     new Gauge<Integer>() {
                         public Integer getValue() {
-                            return getBackingStore().getIndexedDescriptors().keySet().size();
+                            return ensureBackingStore().getIndexedDescriptors().keySet().size();
                         }},
                     true);
             
@@ -1344,15 +1384,19 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
         
         final long start = System.nanoTime();
         try {
-            for (final Pair<String, EntityDescriptor> cacheEntry: getPersistentCacheManager().listAll()) {
+            for (final Pair<String, EntityDescriptor> cacheEntry: ensurePersistentCacheManager().listAll()) {
                 persistentCacheInitMetrics.entriesTotal++;
                 final EntityDescriptor descriptor = cacheEntry.getSecond();
+                assert descriptor != null;
                 final String currentKey = cacheEntry.getFirst();
+                assert currentKey != null;
+                final String entityID = StringSupport.trimOrNull(descriptor.getEntityID());
+                // This has to be non-null at this point...
+                assert entityID != null;
                 log.trace("{} Loaded EntityDescriptor from cache store with entityID '{}' and storage key '{}'", 
-                        getLogPrefix(), descriptor.getEntityID(), currentKey);
+                        getLogPrefix(), entityID, currentKey);
                 
-                final String entityID = StringSupport.trimOrNull(descriptor.getEntityID());
-                final EntityManagementData mgmtData = getBackingStore().getManagementData(entityID);
+                final EntityManagementData mgmtData = ensureBackingStore().getManagementData(entityID);
                 final Lock writeLock = mgmtData.getReadWriteLock().writeLock(); 
                 
                 try {
@@ -1393,7 +1437,9 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
         if (isValid(descriptor)) {
             if (getInitializationFromCachePredicate().test(descriptor)) {
                 try {
-                    processNewMetadata(descriptor, descriptor.getEntityID(), true);
+                    final String entityID = descriptor.getEntityID();
+                    assert entityID != null;
+                    processNewMetadata(descriptor, entityID, true);
                     log.trace("{} Successfully processed EntityDescriptor with entityID '{}' from cache", 
                             getLogPrefix(), descriptor.getEntityID());
                     persistentCacheInitMetrics.entriesLoaded++;
@@ -1415,7 +1461,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
                 if (!Objects.equals(currentKey, expectedKey)) {
                     log.trace("{} Current cache storage key '{}' differs from expected key '{}', updating",
                             getLogPrefix(), currentKey, expectedKey);
-                    getPersistentCacheManager().updateKey(currentKey, expectedKey);
+                    ensurePersistentCacheManager().updateKey(currentKey, expectedKey);
                     log.trace("{} Successfully updated cache storage key '{}' to '{}'", 
                             getLogPrefix(), currentKey, expectedKey);
                 }
@@ -1423,13 +1469,13 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
                 log.warn("{} Error updating cache storage key '{}' to '{}'", 
                         getLogPrefix(), currentKey, expectedKey, e);
             }
-                
         } else {
+                
             log.trace("{} EntityDescriptor with entityID '{}' and storaage key '{}' in cache was " 
                     + "not valid, skipping and removing", getLogPrefix(), descriptor.getEntityID(), currentKey);
             persistentCacheInitMetrics.entriesSkippedInvalid++;
             try {
-                getPersistentCacheManager().remove(currentKey);
+                ensurePersistentCacheManager().remove(currentKey);
             } catch (final IOException e) {
                 log.warn("{} Error removing invalid EntityDescriptor '{}' from persistent cache with key '{}'",
                         getLogPrefix(), descriptor.getEntityID(), currentKey);
@@ -1439,7 +1485,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
 
     /** {@inheritDoc} */
     @Override
-    protected void removeByEntityID(final String entityID, final EntityBackingStore backingStore) {
+    protected void removeByEntityID(@Nonnull final String entityID, @Nonnull final EntityBackingStore backingStore) {
         final List<EntityDescriptor> descriptors = backingStore.getIndexedDescriptors().get(entityID);
         if (descriptors != null) {
             for (final EntityDescriptor descriptor : descriptors) {
@@ -1459,7 +1505,7 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
                 if (isPersistentCachingEnabled()) {
                     final String key = getPersistentCacheKeyGenerator().apply(descriptor);
                     try {
-                        getPersistentCacheManager().remove(key);
+                        ensurePersistentCacheManager().remove(key);
                     } catch (final IOException e) {
                         log.warn("{} Error removing EntityDescriptor '{}' from cache store with key '{}'", 
                                 getLogPrefix(), descriptor.getEntityID(), key);
@@ -1796,12 +1842,13 @@ public abstract class AbstractDynamicMetadataResolver extends AbstractMetadataRe
             final Instant now = Instant.now();
             final Instant earliestValidLastAccessed = now.minus(getMaxIdleEntityData());
             
-            final DynamicEntityBackingStore backingStore = getBackingStore();
+            final DynamicEntityBackingStore backingStore = ensureBackingStore();
             final Set<String> entityIDs = new HashSet<>();
             entityIDs.addAll(backingStore.getIndexedDescriptors().keySet());
             entityIDs.addAll(backingStore.getManagementDataEntityIDs());
             
             for (final String entityID : entityIDs) {
+                assert entityID != null;
                 final EntityManagementData mgmtData = backingStore.getManagementData(entityID);
                 final Lock writeLock = mgmtData.getReadWriteLock().writeLock();
                 try {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractMetadataResolver.java
index b2736a6e2..92a6ac8ca 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractMetadataResolver.java
@@ -20,7 +20,6 @@ package org.opensaml.saml.metadata.resolver.impl;
 import java.io.IOException;
 import java.io.InputStream;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
@@ -50,7 +49,6 @@ import org.opensaml.saml.saml2.common.SAML2Support;
 import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
 
 import com.google.common.base.Strings;
@@ -59,9 +57,12 @@ import com.google.common.collect.Iterables;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.AbstractIdentifiableInitializableComponent;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.ConstraintViolationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.CriterionPredicateRegistry;
@@ -71,8 +72,8 @@ import net.shibboleth.shared.xml.ParserPool;
 import net.shibboleth.shared.xml.QNameSupport;
 
 /** An abstract, base, implementation of a metadata provider. */
-public abstract class AbstractMetadataResolver extends AbstractIdentifiableInitializableComponent implements
-        MetadataResolver {
+public abstract class AbstractMetadataResolver extends AbstractIdentifiableInitializableComponent
+        implements MetadataResolver {
 
     /** Class logger. */
     @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractMetadataResolver.class);
@@ -287,13 +288,15 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
     }
     
     /** {@inheritDoc} */
-    @Nullable public Iterable<EntityDescriptor> resolve(@Nullable final CriteriaSet criteria) throws ResolverException {
+    @Nonnull public Iterable<EntityDescriptor> resolve(@Nullable final CriteriaSet criteria) throws ResolverException {
         checkComponentActive();
         if (activationCondition != null) {
-            final ProfileRequestContextCriterion prc = criteria.get(ProfileRequestContextCriterion.class);
+            final ProfileRequestContextCriterion prc =
+                    criteria != null ? criteria.get(ProfileRequestContextCriterion.class) : null;
+            assert activationCondition != null;
             if (!activationCondition.test(prc != null ? prc.getProfileRequestContext() : null)) {
                 log.info("{} Metadata resolver bypassed due to failed activation condition", getLogPrefix());
-                return null; 
+                return CollectionSupport.emptyList();
             }
         }
         
@@ -309,7 +312,7 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
      * 
      * @throws ResolverException if an error occurs
      */
-    @Nullable protected abstract Iterable<EntityDescriptor> doResolve(@Nullable final CriteriaSet criteria)
+    @Nonnull protected abstract Iterable<EntityDescriptor> doResolve(@Nullable final CriteriaSet criteria)
             throws ResolverException;
     
     /**
@@ -324,7 +327,7 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
     /** {@inheritDoc} */
     @Override protected final void doInitialize() throws ComponentInitializationException {
         super.doInitialize();
-
+        
         try {
             initMetadataResolver();
         } catch (final ComponentInitializationException e) {
@@ -338,18 +341,6 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
         }
     }
 
-    /** {@inheritDoc} */
-    @Override protected void doDestroy() {
-        unmarshallerFactory = null;
-        mdFilter = null;
-        entityBackingStore = null;
-        parser = null;
-        criterionPredicateRegistry = null;
-        activationCondition = null;
-
-        super.doDestroy();
-    }
-
     /**
      * Subclasses should override this method to perform any initialization logic necessary. Default implementation is a
      * no-op.
@@ -414,9 +405,10 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
      * @throws FilterException thrown if there is an error filtering the metadata
      */
     @Nullable protected XMLObject filterMetadata(@Nullable final XMLObject metadata) throws FilterException {
-        if (getMetadataFilter() != null) {
+        final MetadataFilter filter = getMetadataFilter();
+        if (filter != null) {
             log.debug("{} Applying metadata filter", getLogPrefix());
-            return getMetadataFilter().filter(metadata, newFilterContext());
+            return filter.filter(metadata, newFilterContext());
         }
         return metadata;
     }
@@ -488,7 +480,7 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
 
         if (Strings.isNullOrEmpty(entityID)) {
             log.debug("{} EntityDescriptor entityID was null or empty, skipping search for it", getLogPrefix());
-            return Collections.emptyList();
+            return CollectionSupport.emptyList();
         }
 
         final List<EntityDescriptor> descriptors = lookupIndexedEntityID(entityID);
@@ -521,11 +513,11 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
      */
     @Nonnull @NonnullElements protected List<EntityDescriptor> lookupIndexedEntityID(
             @Nonnull @NotEmpty final String entityID) {
-        final List<EntityDescriptor> descriptors = getBackingStore().getIndexedDescriptors().get(entityID);
+        final List<EntityDescriptor> descriptors = ensureBackingStore().getIndexedDescriptors().get(entityID);
         if (descriptors != null) {
             return new ArrayList<>(descriptors);
         }
-        return Collections.emptyList();
+        return CollectionSupport.emptyList();
     }
 
     /**
@@ -545,17 +537,29 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
      * 
      * @return the current effective entity backing store
      */
-    @Nonnull protected EntityBackingStore getBackingStore() {
+    @Nullable protected EntityBackingStore getBackingStore() {
         return entityBackingStore;
     }
 
+    /**
+     * Get the EntityDescriptor backing store currently in use by the metadata resolver, raising
+     * a {@link ConstraintViolationException} if null.
+     * 
+     * @return the current effective entity backing store
+     * 
+     * @since 5.0.0
+     */
+    @Nonnull protected EntityBackingStore ensureBackingStore() {
+        return Constraint.isNotNull(entityBackingStore, "EntityBackingStore was null at time of call");
+    }
+
     /**
      * Set the EntityDescriptor backing store currently in use by the metadata resolver.
      * 
      * @param newBackingStore the new entity backing store
      */
     protected void setBackingStore(@Nonnull final EntityBackingStore newBackingStore) {
-        entityBackingStore = Constraint.isNotNull(newBackingStore, "EntityBackingStore may not be null");
+        entityBackingStore = Constraint.isNotNull(newBackingStore, "EntityBackingStore cannot be null");
     }
 
     /**
@@ -617,11 +621,15 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
     protected void preProcessEntitiesDescriptor(@Nonnull final EntitiesDescriptor entitiesDescriptor,
             final EntityBackingStore backingStore) {
 
-        for (final XMLObject child : entitiesDescriptor.getOrderedChildren()) {
-            if (child instanceof EntityDescriptor) {
-                preProcessEntityDescriptor((EntityDescriptor) child, backingStore);
-            } else if (child instanceof EntitiesDescriptor) {
-                preProcessEntitiesDescriptor((EntitiesDescriptor) child, backingStore);
+        // TODO: If order doesn't matter here, we should change to use the non-null getters of the specific child types.
+        final List<XMLObject> children = entitiesDescriptor.getOrderedChildren();
+        if (children != null) {
+            for (final XMLObject child : children) {
+                if (child instanceof EntityDescriptor) {
+                    preProcessEntityDescriptor((EntityDescriptor) child, backingStore);
+                } else if (child instanceof EntitiesDescriptor) {
+                    preProcessEntitiesDescriptor((EntitiesDescriptor) child, backingStore);
+                }
             }
         }
     }
@@ -639,13 +647,13 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
      * 
      * @throws ResolverException if there is a fatal error during resolution
      */
-    protected Iterable<EntityDescriptor> predicateFilterCandidates(@Nonnull final Iterable<EntityDescriptor> candidates,
-            @Nonnull final CriteriaSet criteria, final boolean onEmptyPredicatesReturnEmpty)
-                    throws ResolverException {
+    @Nonnull protected Iterable<EntityDescriptor> predicateFilterCandidates(
+            @Nonnull final Iterable<EntityDescriptor> candidates, @Nullable final CriteriaSet criteria,
+            final boolean onEmptyPredicatesReturnEmpty) throws ResolverException {
         
         if (!candidates.iterator().hasNext()) {
             log.debug("{} Candidates iteration was empty, nothing to filter via predicates", getLogPrefix());
-            return Collections.emptySet();
+            return CollectionSupport.emptySet();
         }
         
         log.debug("{} Attempting to filter candidate EntityDescriptors via resolved Predicates", getLogPrefix());
@@ -656,7 +664,8 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
         log.trace("{} Resolved {} Predicates: {}", getLogPrefix(), predicates.size(), predicates);
         
         final boolean satisfyAny;
-        final SatisfyAnyCriterion satisfyAnyCriterion = criteria.get(SatisfyAnyCriterion.class);
+        final SatisfyAnyCriterion satisfyAnyCriterion =
+                criteria != null ? criteria.get(SatisfyAnyCriterion.class) : null;
         if (satisfyAnyCriterion  != null) {
             log.trace("{} CriteriaSet contained SatisfyAnyCriterion", getLogPrefix());
             satisfyAny = satisfyAnyCriterion.isSatisfyAny();
@@ -685,6 +694,7 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
         if (logPrefix == null) {
             logPrefix = String.format("%s %s:", getClass().getSimpleName(), getId());
         }
+        assert logPrefix != null;
         return logPrefix;
     }
 
@@ -694,10 +704,10 @@ public abstract class AbstractMetadataResolver extends AbstractIdentifiableIniti
     protected class EntityBackingStore {
 
         /** Index of entity IDs to their descriptors. */
-        private Map<String, List<EntityDescriptor>> indexedDescriptors;
+        @Nonnull private final Map<String, List<EntityDescriptor>> indexedDescriptors;
 
         /** Ordered list of entity descriptors. */
-        private List<EntityDescriptor> orderedDescriptors;
+        @Nonnull private final List<EntityDescriptor> orderedDescriptors;
 
         /** Constructor. */
         protected EntityBackingStore() {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractReloadingMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractReloadingMetadataResolver.java
index d92cff843..b58567aea 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractReloadingMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/AbstractReloadingMetadataResolver.java
@@ -37,11 +37,12 @@ import org.opensaml.saml.metadata.resolver.filter.FilterException;
 import org.opensaml.saml.saml2.common.SAML2Support;
 import org.opensaml.saml.saml2.common.TimeBoundSAMLObject;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.w3c.dom.Document;
+import org.w3c.dom.Element;
 
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.TimerSupport;
 import net.shibboleth.shared.resolver.ResolverException;
 
@@ -66,13 +67,13 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
     @Nonnull private final Logger log = LoggerFactory.getLogger(AbstractReloadingMetadataResolver.class);
 
     /** Timer used to schedule background metadata update tasks. */
-    private Timer taskTimer;
+    @Nonnull private Timer taskTimer;
     
     /** Whether we created our own task timer during object construction. */
     private boolean createdOwnTaskTimer;
         
     /** Current task to refresh metadata. */
-    private RefreshMetadataTask refreshMetadataTask;
+    @Nullable private RefreshMetadataTask refreshMetadataTask;
     
     /** Factor used to compute when the next refresh interval will occur. Default value: 0.75 */
     private float refreshDelayFactor = 0.75f;
@@ -158,7 +159,7 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
      * 
      * @return time when the currently cached metadata expires, or null if no metadata is cached
      */
-    public Instant getExpirationTime() {
+    @Nullable public Instant getExpirationTime() {
         return expirationTime;
     }
 
@@ -193,7 +194,7 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
      * 
      * @return time when the next refresh cycle will occur
      */
-    public Instant getNextRefresh() {
+    @Nullable public Instant getNextRefresh() {
         return nextRefresh;
     }
 
@@ -293,20 +294,14 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
     /** {@inheritDoc} */
     @Override
     protected void doDestroy() {
-        refreshMetadataTask.cancel();
+        if (refreshMetadataTask != null) {
+            refreshMetadataTask.cancel();
+        }
         
         if (createdOwnTaskTimer) {
             taskTimer.cancel();
         }
         
-        expirationTime = null;
-        lastRefresh = null;
-        lastUpdate = null;
-        nextRefresh = null;
-        wasLastRefreshSuccess = null;
-        lastSuccessfulRefresh = null;
-        lastFailureCause = null;
-        
         super.doDestroy();
     }
 
@@ -374,7 +369,9 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
             throw new ResolverException(String.format("Saw an error of type '%s' with message '%s'", 
                     t.getClass().getName(), t.getMessage()));
         } finally {
-            logCachedMetadataExpiration(now);
+            if (now != null) {
+                logCachedMetadataExpiration(now);
+            }
             
             if (trackRefreshSuccess) {
                 wasLastRefreshSuccess = true;
@@ -385,11 +382,13 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
             }
             
             refreshMetadataTask = new RefreshMetadataTask();
-            final long nextRefreshDelay = nextRefresh.toEpochMilli() - System.currentTimeMillis();
+            final Instant nextRefreshCopy = nextRefresh;
+            // TODO: why is this actually non-null here? Needs review.
+            assert nextRefreshCopy != null;
+            final long nextRefreshDelay = nextRefreshCopy.toEpochMilli() - System.currentTimeMillis();
             taskTimer.schedule(refreshMetadataTask, nextRefreshDelay);
             log.info("{} Next refresh cycle for metadata provider '{}' will occur on '{}' ('{}' local time)",
-                    new Object[] {getLogPrefix(), mdId, nextRefresh, 
-                            nextRefresh.atZone(ZoneId.systemDefault()),});
+                    new Object[] {getLogPrefix(), mdId, nextRefresh, nextRefreshCopy.atZone(ZoneId.systemDefault()),});
             lastRefresh = now;
         }
     }
@@ -401,22 +400,24 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
      */
     private void logCachedMetadataExpiration(@Nonnull final Instant now) {
         final String mdId = getMetadataIdentifier();
-        final XMLObject cached = getBackingStore().getCachedOriginalMetadata();
+        final XMLObject cached = ensureBackingStore().getCachedOriginalMetadata();
         if (cached != null && !isValid(cached)) {
             log.warn("{} Metadata root from '{}' currently live (post-refresh) is expired or otherwise invalid",
                     getLogPrefix(), mdId);
-        } else if (cached instanceof TimeBoundSAMLObject) {
-            final TimeBoundSAMLObject timebound = (TimeBoundSAMLObject) cached;
-            if (isRequireValidMetadata() && timebound.getValidUntil() != null) {
-                if (!getExpirationWarningThreshold().isZero() 
-                        && timebound.getValidUntil().isBefore(now.plus(getExpirationWarningThreshold()))) {
-                    log.warn("{} Metadata root from '{}' currently live (post-refresh) will expire "
-                            + "within the configured threshhold at '{}'",
-                            getLogPrefix(), mdId, timebound.getValidUntil());
-                } else if (timebound.getValidUntil().isBefore(nextRefresh)) {
-                    log.warn("{} Metadata root from '{}' currently live (post-refresh) will expire "
-                            + "at '{}' before the next refresh scheduled for {}'",
-                            getLogPrefix(), mdId, timebound.getValidUntil(), nextRefresh);
+        } else if (cached instanceof TimeBoundSAMLObject timebound) {
+            if (isRequireValidMetadata()) {
+                final Instant validUntil = timebound.getValidUntil();
+                if (validUntil != null) {
+                    if (!getExpirationWarningThreshold().isZero() 
+                            && validUntil.isBefore(now.plus(getExpirationWarningThreshold()))) {
+                        log.warn("{} Metadata root from '{}' currently live (post-refresh) will expire "
+                                + "within the configured threshhold at '{}'",
+                                getLogPrefix(), mdId, timebound.getValidUntil());
+                    } else if (validUntil.isBefore(nextRefresh)) {
+                        log.warn("{} Metadata root from '{}' currently live (post-refresh) will expire "
+                                + "at '{}' before the next refresh scheduled for {}'",
+                                getLogPrefix(), mdId, timebound.getValidUntil(), nextRefresh);
+                    }
                 }
             }
         }
@@ -447,7 +448,7 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
      * 
      * @throws ResolverException thrown if the metadata can not be unmarshalled
      */
-    protected XMLObject unmarshallMetadata(final byte[] metadataBytes) throws ResolverException {
+    @Nonnull protected XMLObject unmarshallMetadata(@Nonnull final byte[] metadataBytes) throws ResolverException {
         try {
             return unmarshallMetadata(new ByteArrayInputStream(metadataBytes));
         } catch (final UnmarshallingException e) {
@@ -465,11 +466,11 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
      * 
      * @throws ResolverException throw is there is a problem process the cached metadata
      */
-    protected void processCachedMetadata(final String metadataIdentifier, final Instant refreshStart)
+    protected void processCachedMetadata(@Nonnull final String metadataIdentifier, @Nonnull final Instant refreshStart)
             throws ResolverException {
         log.debug("{} Computing new expiration time for cached metadata from '{}'", getLogPrefix(), metadataIdentifier);
         final Instant metadataExpirationTime = 
-                SAML2Support.getEarliestExpiration(getBackingStore().getCachedOriginalMetadata(),
+                SAML2Support.getEarliestExpiration(ensureBackingStore().getCachedOriginalMetadata(),
                 refreshStart.plus(getMaxRefreshDelay()), refreshStart);
 
         trackRefreshSuccess = true;
@@ -487,8 +488,8 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
      * 
      * @throws ResolverException thrown if there is a problem unmarshalling or filtering the new metadata
      */
-    protected void processNewMetadata(final String metadataIdentifier, final Instant refreshStart,
-            final byte[] metadataBytes) throws ResolverException {
+    protected void processNewMetadata(@Nonnull final String metadataIdentifier, @Nonnull final Instant refreshStart,
+            @Nonnull final byte[] metadataBytes) throws ResolverException {
         log.debug("{} Unmarshalling metadata from '{}'", getLogPrefix(), metadataIdentifier);
         final XMLObject metadata = unmarshallMetadata(metadataBytes);
 
@@ -509,8 +510,9 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
      * @param metadataBytes raw bytes of the new metadata document
      * @param metadata new metadata document unmarshalled
      */
-    protected void processPreExpiredMetadata(final String metadataIdentifier, final Instant refreshStart,
-            final byte[] metadataBytes, final XMLObject metadata) {
+    protected void processPreExpiredMetadata(@Nonnull final String metadataIdentifier,
+            @Nonnull final Instant refreshStart, @Nonnull final byte[] metadataBytes,
+            @Nonnull final XMLObject metadata) {
         log.warn("{} Entire metadata document from '{}' was expired at time of loading, " 
                 + "previous metadata retained, if any", getLogPrefix(), metadataIdentifier);
 
@@ -532,9 +534,12 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
      * 
      * @throws ResolverException thrown if there s a problem processing the metadata
      */
-    protected void processNonExpiredMetadata(final String metadataIdentifier, final Instant refreshStart,
-            final byte[] metadataBytes, final XMLObject metadata) throws ResolverException {
-        final Document metadataDom = metadata.getDOM().getOwnerDocument();
+    protected void processNonExpiredMetadata(@Nonnull final String metadataIdentifier,
+            @Nonnull final Instant refreshStart, @Nonnull final byte[] metadataBytes,
+            @Nonnull final XMLObject metadata) throws ResolverException {
+        final Element domElement = metadata.getDOM();
+        assert domElement != null;
+        final Document metadataDom = domElement.getOwnerDocument();
 
         log.debug("{} Preprocessing metadata from '{}'", getLogPrefix(), metadataIdentifier);
         BatchEntityBackingStore newBackingStore = null;
@@ -558,10 +563,10 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
         // Note: As noted in its Javadocs, technically this method can sometimes return null, but won't in this case
         // since the candidate time (2nd arg) is not null.
         final Instant metadataExpirationTime = SAML2Support.getEarliestExpiration(
-                newBackingStore.getCachedOriginalMetadata(), refreshStart.plus(getMaxRefreshDelay()),
-                refreshStart);
+                newBackingStore.getCachedOriginalMetadata(), refreshStart.plus(getMaxRefreshDelay()), refreshStart);
+        assert metadataExpirationTime != null;
         log.debug("{} Expiration of metadata from '{}' will occur at {}", getLogPrefix(), metadataIdentifier, 
-                metadataExpirationTime.toString());
+                metadataExpirationTime);
 
         // This is where the new processed data becomes effective. Exceptions thrown prior to this point
         // therefore result in the old data being kept effective.
@@ -599,9 +604,9 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
      * 
      * @throws ResolverException thrown if there is a problem with the provided data
      */
-    protected void postProcessMetadata(final byte[] metadataBytes, final Document metadataDom,
-            final XMLObject originalMetadata, final XMLObject filteredMetadata) throws ResolverException {
-
+    protected void postProcessMetadata(@Nonnull final byte[] metadataBytes, @Nonnull final Document metadataDom,
+            @Nonnull final XMLObject originalMetadata, @Nullable final XMLObject filteredMetadata)
+                    throws ResolverException {
     }
 
     /**
@@ -612,7 +617,7 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
      * 
      * @return delay until the next refresh time
      */
-    @Nonnull protected Duration computeNextRefreshDelay(final Instant expectedExpiration) {
+    @Nonnull protected Duration computeNextRefreshDelay(@Nullable final Instant expectedExpiration) {
         final long now = System.currentTimeMillis();
 
         long expireInstant = 0;
@@ -639,7 +644,7 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
      * 
      * @throws ResolverException thrown if there is a problem reading the resultant byte array
      */
-    protected byte[] inputstreamToByteArray(final InputStream ins) throws ResolverException {
+    @Nonnull protected byte[] inputstreamToByteArray(@Nonnull final InputStream ins) throws ResolverException {
         try {
             // 1 MB read buffer
             final byte[] buffer = new byte[1024 * 1024];
@@ -684,4 +689,5 @@ public abstract class AbstractReloadingMetadataResolver extends AbstractBatchMet
         }
         //CheckStyle: ReturnCount ON
     }
-}
+
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/CompositeMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/CompositeMetadataResolver.java
index c07653077..d4f0ebd2f 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/CompositeMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/CompositeMetadataResolver.java
@@ -18,9 +18,9 @@
 package org.opensaml.saml.metadata.resolver.impl;
 
 import java.time.Instant;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.NoSuchElementException;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
@@ -31,13 +31,13 @@ import org.opensaml.saml.metadata.resolver.RefreshableMetadataResolver;
 import org.opensaml.saml.metadata.resolver.filter.MetadataFilter;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 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.component.AbstractIdentifiedInitializableComponent;
-import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 
@@ -45,6 +45,9 @@ import net.shibboleth.shared.resolver.ResolverException;
 /**
  * A {@link MetadataResolver} implementation that answers requests by composing the answers of child
  * {@link MetadataResolver}s.
+ * 
+ * <p>Note: This appears to be unused, and contained a number of bugs that may or may not have been
+ * fully corrected.</p>
  */
 public class CompositeMetadataResolver extends AbstractIdentifiedInitializableComponent implements MetadataResolver,
         RefreshableMetadataResolver, ClearableMetadataResolver {
@@ -57,7 +60,7 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
 
     /** Constructor. */
     public CompositeMetadataResolver() {
-        resolvers = Collections.emptyList();
+        resolvers = CollectionSupport.emptyList();
     }
 
     /**
@@ -76,47 +79,48 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
      * 
      * @throws ResolverException thrown if there is a problem adding the metadata provider
      */
-    public void setResolvers(@Nonnull @NonnullElements final List<MetadataResolver> newResolvers) 
+    public void setResolvers(@Nullable @NonnullElements final List<MetadataResolver> newResolvers) 
             throws ResolverException {
         checkSetterPreconditions();
 
         if (newResolvers == null || newResolvers.isEmpty()) {
-            resolvers = Collections.emptyList();
+            resolvers = CollectionSupport.emptyList();
         } else {
-            resolvers = List.copyOf(newResolvers);
+            resolvers = CollectionSupport.copyToList(newResolvers);
         }
     }
 
     /** {@inheritDoc} */
-    @Override public boolean isRequireValidMetadata() {
+    public boolean isRequireValidMetadata() {
         log.warn("Attempt to access unsupported requireValidMetadata property on ChainingMetadataResolver");
         return false;
     }
 
     /** {@inheritDoc} */
-    @Override public void setRequireValidMetadata(final boolean requireValidMetadata) {
+    public void setRequireValidMetadata(final boolean requireValidMetadata) {
         throw new UnsupportedOperationException("Setting require valid metadata is not supported on chaining resolver");
     }
 
     /** {@inheritDoc} */
-    @Override @Nullable public MetadataFilter getMetadataFilter() {
+    @Nullable public MetadataFilter getMetadataFilter() {
         log.warn("Attempt to access unsupported MetadataFilter property on ChainingMetadataResolver");
         return null;
     }
 
     /** {@inheritDoc} */
-    @Override public void setMetadataFilter(@Nullable final MetadataFilter newFilter) {
+    public void setMetadataFilter(@Nullable final MetadataFilter newFilter) {
         throw new UnsupportedOperationException("Metadata filters are not supported on ChainingMetadataProviders");
     }
 
     /** {@inheritDoc} */
-    @Override public Iterable<EntityDescriptor> resolve(@Nullable final CriteriaSet criteria) throws ResolverException {
+    @Override
+    @Nonnull public Iterable<EntityDescriptor> resolve(@Nullable final CriteriaSet criteria) throws ResolverException {
         checkComponentActive();
         return new CompositeMetadataResolverIterable(resolvers, criteria);
     }
 
     /** {@inheritDoc} */
-    @Override public EntityDescriptor resolveSingle(@Nullable final CriteriaSet criteria) throws ResolverException {
+    public EntityDescriptor resolveSingle(@Nullable final CriteriaSet criteria) throws ResolverException {
         checkComponentActive();
         EntityDescriptor metadata = null;
         for (final MetadataResolver resolver : resolvers) {
@@ -128,22 +132,6 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
 
         return null;
     }
-
-    /** {@inheritDoc} */
-    @Override protected void doInitialize() throws ComponentInitializationException {
-        super.doInitialize();
-        if (resolvers == null) {
-            log.warn("CompositeMetadataResolver was not configured with any member MetadataResolvers");
-            resolvers = Collections.emptyList();
-        }
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void doDestroy() {
-        super.doDestroy();
-
-        resolvers = Collections.emptyList();
-    }
     
     /** {@inheritDoc} */
     public void clear() throws ResolverException {
@@ -155,7 +143,7 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
     }
 
     /** {@inheritDoc} */
-    public void clear(final String entityID) throws ResolverException {
+    public void clear(@Nonnull final String entityID) throws ResolverException {
         for (final MetadataResolver resolver : resolvers) {
             if (resolver instanceof ClearableMetadataResolver) {
                 ((ClearableMetadataResolver) resolver).clear(entityID);
@@ -164,7 +152,7 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override public void refresh() throws ResolverException {
+    public void refresh() throws ResolverException {
         for (final MetadataResolver resolver : resolvers) {
             if (resolver instanceof RefreshableMetadataResolver) {
                 ((RefreshableMetadataResolver) resolver).refresh();
@@ -173,7 +161,6 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
     @Nullable public Instant getLastUpdate() {
         Instant ret = null;
         for (final MetadataResolver resolver : resolvers) {
@@ -189,7 +176,6 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
     }
 
     /** {@inheritDoc} */
-    @Override
     @Nullable public Instant getLastRefresh() {
         Instant ret = null;
         for (final MetadataResolver resolver : resolvers) {
@@ -205,7 +191,7 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
     }
     
     /** {@inheritDoc} */
-    public Instant getLastSuccessfulRefresh() {
+    @Nullable public Instant getLastSuccessfulRefresh() {
         Instant ret = null;
         for (final MetadataResolver resolver : resolvers) {
             if (resolver instanceof RefreshableMetadataResolver) {
@@ -220,11 +206,12 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
     }
 
     /** {@inheritDoc} */
-    public Boolean wasLastRefreshSuccess() {
+    @Nullable public Boolean wasLastRefreshSuccess() {
         for (final MetadataResolver resolver : resolvers) {
             if (resolver instanceof RefreshableMetadataResolver) {
                 final RefreshableMetadataResolver refreshable = (RefreshableMetadataResolver) resolver;
-                if (refreshable.wasLastRefreshSuccess() != null && !refreshable.wasLastRefreshSuccess()) {
+                final Boolean flag = refreshable.wasLastRefreshSuccess();
+                if (flag != null && !flag) {
                     return false;
                 }
             }
@@ -234,7 +221,7 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
     }
 
     /** {@inheritDoc} */
-    public Throwable getLastFailureCause() {
+    @Nullable public Throwable getLastFailureCause() {
         for (final MetadataResolver resolver : resolvers) {
             if (resolver instanceof RefreshableMetadataResolver) {
                 final RefreshableMetadataResolver refreshable = (RefreshableMetadataResolver) resolver;
@@ -254,13 +241,13 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
     private static class CompositeMetadataResolverIterable implements Iterable<EntityDescriptor> {
 
         /** Class logger. */
-        private final Logger log = LoggerFactory.getLogger(CompositeMetadataResolverIterable.class);
+        @Nonnull private final Logger log = LoggerFactory.getLogger(CompositeMetadataResolverIterable.class);
 
         /** Resolvers over which to iterate. */
-        private final List<MetadataResolver> resolvers;
+        @Nonnull private final List<MetadataResolver> resolvers;
 
         /** Criteria being search for. */
-        private final CriteriaSet criteria;
+        @Nullable private final CriteriaSet criteria;
 
         /**
          * Constructor.
@@ -268,15 +255,15 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
          * @param composedResolvers resolvers from which results will be pulled
          * @param metadataCritiera criteria for the resolver query
          */
-        public CompositeMetadataResolverIterable(final List<MetadataResolver> composedResolvers,
-                final CriteriaSet metadataCritiera) {
-            resolvers = List.copyOf(composedResolvers);
+        public CompositeMetadataResolverIterable(@Nonnull final List<MetadataResolver> composedResolvers,
+                @Nullable final CriteriaSet metadataCritiera) {
+            resolvers = CollectionSupport.copyToList(composedResolvers);
 
             criteria = metadataCritiera;
         }
 
         /** {@inheritDoc} */
-        @Override public Iterator<EntityDescriptor> iterator() {
+        public Iterator<EntityDescriptor> iterator() {
             return new CompositeMetadataResolverIterator();
         }
 
@@ -284,7 +271,7 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
         private class CompositeMetadataResolverIterator implements Iterator<EntityDescriptor> {
 
             /** Iterator over the composed resolvers. */
-            private Iterator<MetadataResolver> resolverIterator;
+            @Nonnull private Iterator<MetadataResolver> resolverIterator;
 
             /** Current resolver from which we are getting results. */
             private MetadataResolver currentResolver;
@@ -298,25 +285,29 @@ public class CompositeMetadataResolver extends AbstractIdentifiedInitializableCo
             }
 
             /** {@inheritDoc} */
-            @Override public boolean hasNext() {
-                if (!currentResolverMetadataIterator.hasNext()) {
+            public boolean hasNext() {
+                if (currentResolverMetadataIterator == null || !currentResolverMetadataIterator.hasNext()) {
                     proceedToNextResolverIterator();
                 }
 
-                return currentResolverMetadataIterator.hasNext();
+                return currentResolverMetadataIterator != null && currentResolverMetadataIterator.hasNext();
             }
 
             /** {@inheritDoc} */
-            @Override public EntityDescriptor next() {
-                if (!currentResolverMetadataIterator.hasNext()) {
+            public EntityDescriptor next() {
+                if (currentResolverMetadataIterator == null || !currentResolverMetadataIterator.hasNext()) {
                     proceedToNextResolverIterator();
                 }
-
-                return currentResolverMetadataIterator.next();
+                
+                if (currentResolverMetadataIterator != null) {
+                    return currentResolverMetadataIterator.next();
+                }
+                
+                throw new NoSuchElementException("No further elements");
             }
 
             /** {@inheritDoc} */
-            @Override public void remove() {
+            public void remove() {
                 throw new UnsupportedOperationException();
             }
 
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/DOMMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/DOMMetadataResolver.java
index 8d2442081..9a5447990 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/DOMMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/DOMMetadataResolver.java
@@ -17,15 +17,18 @@
 
 package org.opensaml.saml.metadata.resolver.impl;
 
+import javax.annotation.Nonnull;
+
 import org.opensaml.core.xml.XMLObject;
 import org.opensaml.core.xml.io.Unmarshaller;
 import org.opensaml.core.xml.io.UnmarshallingException;
 import org.opensaml.saml.metadata.resolver.filter.FilterException;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 import org.w3c.dom.Element;
 
 import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 
 /**
  * A <code>MetadataProvider</code> implementation that retrieves metadata from a DOM <code>Element</code> as
@@ -37,26 +40,18 @@ import net.shibboleth.shared.component.ComponentInitializationException;
 public class DOMMetadataResolver extends AbstractBatchMetadataResolver {
 
     /** Class logger. */
-    private final Logger log = LoggerFactory.getLogger(DOMMetadataResolver.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(DOMMetadataResolver.class);
 
     /** Root metadata element exposed by this provider. */
-    private Element metadataElement;
+    @Nonnull private Element metadataElement;
 
     /**
      * Constructor.
      * 
      * @param mdElement the metadata element
      */
-    public DOMMetadataResolver(final Element mdElement) {
-        super();
-        metadataElement = mdElement;
-    }
-
-    /** {@inheritDoc} */
-    @Override protected void doDestroy() {
-        metadataElement = null;
-   
-        super.doDestroy();
+    public DOMMetadataResolver(@Nonnull final Element mdElement) {
+        metadataElement = Constraint.isNotNull(mdElement, "DOM Element cannot be null");
     }
     
     /** {@inheritDoc} */
@@ -64,7 +59,7 @@ public class DOMMetadataResolver extends AbstractBatchMetadataResolver {
         super.initMetadataResolver();
         
         try {
-            final Unmarshaller unmarshaller = getUnmarshallerFactory().getUnmarshaller(metadataElement);
+            final Unmarshaller unmarshaller = getUnmarshallerFactory().ensureUnmarshaller(metadataElement);
             final XMLObject metadataTemp = unmarshaller.unmarshall(metadataElement);
             final BatchEntityBackingStore newBackingStore = preProcessNewMetadata(metadataTemp);
             releaseMetadataDOM(metadataTemp);
@@ -79,4 +74,5 @@ public class DOMMetadataResolver extends AbstractBatchMetadataResolver {
             throw new ComponentInitializationException(errorMsg, e);
         }
     }
+
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/DefaultLocalDynamicSourceKeyGenerator.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/DefaultLocalDynamicSourceKeyGenerator.java
index 09d32a7b5..d701096d5 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/DefaultLocalDynamicSourceKeyGenerator.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/DefaultLocalDynamicSourceKeyGenerator.java
@@ -20,7 +20,6 @@ package org.opensaml.saml.metadata.resolver.impl;
 import javax.annotation.Nullable;
 
 import org.opensaml.core.criterion.EntityIdCriterion;
-import org.opensaml.saml.common.binding.artifact.SAMLArtifact;
 import org.opensaml.saml.common.binding.artifact.SAMLSourceIDArtifact;
 import org.opensaml.saml.criterion.ArtifactCriterion;
 
@@ -51,7 +50,7 @@ public class DefaultLocalDynamicSourceKeyGenerator extends EntityIDDigestGenerat
      *
      */
     public DefaultLocalDynamicSourceKeyGenerator() {
-        super();
+        
     }
 
     /**
@@ -76,14 +75,14 @@ public class DefaultLocalDynamicSourceKeyGenerator extends EntityIDDigestGenerat
             return super.apply(criteria);
         }
         
-        if (criteria.contains(ArtifactCriterion.class)) {
-            final SAMLArtifact artifact = criteria.get(ArtifactCriterion.class).getArtifact();
-            if (artifact instanceof SAMLSourceIDArtifact) {
-                return buildKey(HEX.encode(((SAMLSourceIDArtifact)artifact).getSourceID()));
+        final ArtifactCriterion artifactCriterion = criteria.get(ArtifactCriterion.class);
+        if (artifactCriterion != null) {
+            if (artifactCriterion.getArtifact() instanceof SAMLSourceIDArtifact art) {
+                return buildKey(HEX.encode(art.getSourceID()));
             }
         }
         
         return null;
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/EntityIDDigestGenerator.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/EntityIDDigestGenerator.java
index 30b77b706..887d79f7f 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/EntityIDDigestGenerator.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/EntityIDDigestGenerator.java
@@ -74,25 +74,33 @@ public class EntityIDDigestGenerator implements Function<CriteriaSet, String> {
         suffix = StringSupport.trimOrNull(keySuffix);
         separator = StringSupport.trimOrNull(valueSeparator);
         
-        digester = valueDigester;
-        if (digester == null) {
+        if (valueDigester != null) {
+            digester = valueDigester;
+        } else {
             try {
                 digester = new StringDigester(JCAConstants.DIGEST_SHA1, OutputFormat.HEX_LOWER);
             } catch (final NoSuchAlgorithmException e) {
                 // this can't really happen b/c SHA-1 is required to be supported on all JREs.
+                throw new RuntimeException("No SHA-1 support in runtime");
             }
         }
     }
 
     /** {@inheritDoc} */
     @Nullable public String apply(@Nullable final CriteriaSet criteria) {
-        if (criteria == null || !criteria.contains(EntityIdCriterion.class)) {
+        
+        final EntityIdCriterion criterion = criteria != null ? criteria.get(EntityIdCriterion.class) : null;
+        if (criterion == null) {
             return null;
         }
         
-        final String digested = digester.apply(criteria.get(EntityIdCriterion.class).getEntityId());
+        final String digested = digester.apply(criterion.getEntityId());
+        
+        if (digested != null) {
+            return buildKey(digested);
+        }
         
-        return buildKey(digested);
+        return null;
     }
     
     /**
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolver.java
index 2f7006cfc..45285b845 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolver.java
@@ -33,13 +33,13 @@ import org.opensaml.core.xml.XMLObject;
 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 org.w3c.dom.Document;
 
 import com.google.common.io.Files;
 
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.ResolverException;
 
 /**
@@ -66,7 +66,7 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
     @Nonnull private final Logger log = LoggerFactory.getLogger(FileBackedHTTPMetadataResolver.class);
 
     /** File containing the backup of the metadata. */
-    @Nullable private File metadataBackupFile;
+    @Nonnull private File metadataBackupFile;
     
     /** Flag used to track state of whether currently initializing or not. */
     private boolean initializing;
@@ -90,9 +90,8 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
      * @throws ResolverException thrown if the URL is not a valid URL, the metadata can not be retrieved from
      *             the URL
      */
-    public FileBackedHTTPMetadataResolver(final HttpClient client, 
-                                          final String metadataURL, final String backupFilePath) 
-            throws ResolverException {
+    public FileBackedHTTPMetadataResolver(@Nonnull final HttpClient client, @Nonnull final String metadataURL,
+            @Nonnull final String backupFilePath) throws ResolverException {
         this(null, client, metadataURL, backupFilePath);
     }
 
@@ -107,14 +106,13 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
      * @throws ResolverException thrown if the URL is not a valid URL, the metadata can not be retrieved from
      *             the URL
      */
-    public FileBackedHTTPMetadataResolver(final Timer backgroundTaskTimer, 
-                                          final HttpClient client, final String metadataURL,
-            final String backupFilePath) throws ResolverException {
+    public FileBackedHTTPMetadataResolver(@Nullable final Timer backgroundTaskTimer, @Nonnull final HttpClient client,
+            @Nonnull final String metadataURL, @Nonnull final String backupFilePath) throws ResolverException {
         super(backgroundTaskTimer, client, metadataURL);
         
         backupFileInitNextRefreshDelay = Duration.ofSeconds(5);
         
-        setBackupFile(backupFilePath);
+        metadataBackupFile = new File(backupFilePath);
     }
     
     /**
@@ -180,14 +178,6 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
         backupFileInitNextRefreshDelay = delay;
     }
 
-    /** {@inheritDoc} */
-    @Override
-    protected void doDestroy() {
-        metadataBackupFile = null;
-
-        super.doDestroy();
-    }
-
     /** {@inheritDoc} */
     @Override
     protected void initMetadataResolver() throws ComponentInitializationException {
@@ -218,11 +208,10 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
      * 
      * @throws ResolverException thrown if the backup file is not read/writable or creatable
      */
-    protected void setBackupFile(final String backupFilePath) throws ResolverException {
+    protected void setBackupFile(@Nonnull final String backupFilePath) throws ResolverException {
         checkSetterPreconditions();
 
-        final File backingFile = new File(backupFilePath);
-        metadataBackupFile = backingFile;
+        metadataBackupFile = new File(backupFilePath);
     }
 
     /**
@@ -232,7 +221,7 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
      * @param backupFile the file to evaluate
      * @throws ResolverException if file does not pass basic properties required of a metadata backup file
      */
-    protected void validateBackupFile(final File backupFile) throws ResolverException {
+    protected void validateBackupFile(@Nonnull final File backupFile) throws ResolverException {
         if (!backupFile.exists()) {
             try {
                 log.debug("{} Testing creation of backup file", getLogPrefix());
@@ -270,9 +259,10 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
         }
     }
 
+// Checkstyle: CyclomaticComplexity OFF
     /** {@inheritDoc} */
     @Override
-    protected byte[] fetchMetadata() throws ResolverException {
+    @Nullable protected byte[] fetchMetadata() throws ResolverException {
         if (initializing && initializeFromBackupFile && metadataBackupFile.exists()) {
             log.debug("{} On initialization, detected existing backup file, attempting load from that: {}",
                         getLogPrefix(), metadataBackupFile.getAbsolutePath());
@@ -318,9 +308,10 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
             throw new ResolverException("Unable to read metadata from remote server and backup does not exist");
         }
     }
+// Checkstyle: CyclomaticComplexity ON
 
     /** {@inheritDoc} */
-    protected MetadataFilterContext newFilterContext() {
+    @Nonnull protected MetadataFilterContext newFilterContext() {
         final MetadataFilterContext context = super.newFilterContext();
         if (initializing && initializedFromBackupFile) {
             MetadataSource metadataSource = context.get(MetadataSource.class);
@@ -346,9 +337,9 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
 
     /** {@inheritDoc} */
     @Override
-    protected void postProcessMetadata(final byte[] metadataBytes, 
-                                       final Document metadataDom, final XMLObject originalMetadata, 
-            final XMLObject filteredMetadata) throws ResolverException {
+    protected void postProcessMetadata(@Nonnull final byte[] metadataBytes, @Nonnull final Document metadataDom,
+            @Nonnull final XMLObject originalMetadata, @Nullable final XMLObject filteredMetadata)
+                    throws ResolverException {
 
         final File staging = new File(metadataBackupFile.getAbsolutePath() + ".staging");
         try {
@@ -376,4 +367,5 @@ public class FileBackedHTTPMetadataResolver extends HTTPMetadataResolver {
             super.postProcessMetadata(metadataBytes, metadataDom, originalMetadata, filteredMetadata);
         }
     }
+    
 }
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FilesystemMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FilesystemMetadataResolver.java
index 8c07445c7..3ddb9cb60 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FilesystemMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FilesystemMetadataResolver.java
@@ -27,9 +27,9 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.ResolverException;
 
 /**
@@ -50,7 +50,7 @@ import net.shibboleth.shared.resolver.ResolverException;
 public class FilesystemMetadataResolver extends AbstractReloadingMetadataResolver {
 
     /** Class logger. */
-    private final Logger log = LoggerFactory.getLogger(FilesystemMetadataResolver.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(FilesystemMetadataResolver.class);
 
     /** The metadata file. */
     @Nonnull private File metadataFile;
@@ -58,27 +58,26 @@ public class FilesystemMetadataResolver extends AbstractReloadingMetadataResolve
     /**
      * Constructor.
      * 
-     * @param metadata the metadata file
+     * @param file the metadata file
      * 
      * @throws ResolverException  this exception is no longer thrown
      */
-    public FilesystemMetadataResolver(@Nonnull final File metadata) throws ResolverException {
-        super();
-        setMetadataFile(metadata);
+    public FilesystemMetadataResolver(@Nonnull final File file) throws ResolverException {
+        metadataFile = Constraint.isNotNull(file, "Metadata file cannot be null");
     }
 
     /**
      * Constructor.
      * 
-     * @param metadata the metadata file
+     * @param file the metadata file
      * @param backgroundTaskTimer timer used to refresh metadata in the background
      * 
      * @throws ResolverException  this exception is no longer thrown
      */
-    public FilesystemMetadataResolver(@Nullable final Timer backgroundTaskTimer, @Nonnull final File metadata)
+    public FilesystemMetadataResolver(@Nullable final Timer backgroundTaskTimer, @Nonnull final File file)
             throws ResolverException {
         super(backgroundTaskTimer);
-        setMetadataFile(metadata);
+        metadataFile = Constraint.isNotNull(file, "Metadata file cannot be null");
     }
 
     /**
@@ -93,28 +92,21 @@ public class FilesystemMetadataResolver extends AbstractReloadingMetadataResolve
 
         metadataFile = Constraint.isNotNull(file, "Metadata file cannot be null");
     }
-
-    /** {@inheritDoc} */
-    @Override
-    protected void doDestroy() {
-        metadataFile = null;
-          
-        super.doDestroy();
-    }
     
     /** {@inheritDoc} */
     @Override
-    protected String getMetadataIdentifier() {
+    @Nonnull protected String getMetadataIdentifier() {
         return metadataFile.getAbsolutePath();
     }
 
     /** {@inheritDoc} */
     @Override
-    protected byte[] fetchMetadata() throws ResolverException {
+    @Nullable protected byte[] fetchMetadata() throws ResolverException {
         try {
             validateMetadataFile(metadataFile);
             final Instant metadataUpdateTime = Instant.ofEpochMilli(metadataFile.lastModified());
             if (getLastRefresh() == null || getLastUpdate() == null || metadataUpdateTime.isAfter(getLastUpdate())) {
+                // This closes the stream....
                 return inputstreamToByteArray(new FileInputStream(metadataFile));
             }
 
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FunctionDrivenDynamicHTTPMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FunctionDrivenDynamicHTTPMetadataResolver.java
index 2e2f549ff..88f0d0f40 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FunctionDrivenDynamicHTTPMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/FunctionDrivenDynamicHTTPMetadataResolver.java
@@ -25,9 +25,9 @@ import javax.annotation.Nullable;
 
 import org.apache.hc.client5.http.classic.HttpClient;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 /**
@@ -66,7 +66,7 @@ public class FunctionDrivenDynamicHTTPMetadataResolver extends AbstractDynamicHT
     public FunctionDrivenDynamicHTTPMetadataResolver(@Nullable final Timer backgroundTaskTimer,
                                                      @Nonnull final HttpClient client) {
         super(backgroundTaskTimer, client);
-        setRequestURLBuilder(new HTTPEntityIDRequestURLBuilder());
+        requestURLBuilder = new HTTPEntityIDRequestURLBuilder();
     }
 
     /**
@@ -90,12 +90,12 @@ public class FunctionDrivenDynamicHTTPMetadataResolver extends AbstractDynamicHT
      */
     public void setRequestURLBuilder(@Nonnull final Function<CriteriaSet, String> builder) {
         checkSetterPreconditions();
-        requestURLBuilder = Constraint.isNotNull(builder, "Request URL builder function was null");
+        requestURLBuilder = Constraint.isNotNull(builder, "Request URL builder function cannot be null");
     }
 
     /** {@inheritDoc} */
     @Override
-    @Nullable protected String buildRequestURL(@Nonnull final CriteriaSet criteria) {
+    @Nullable protected String buildRequestURL(@Nullable final CriteriaSet criteria) {
         final String url = getRequestURLBuilder().apply(criteria);
         
         log.debug("{} URL generated by request builder was: {}", getLogPrefix(), url);
@@ -103,4 +103,4 @@ public class FunctionDrivenDynamicHTTPMetadataResolver extends AbstractDynamicHT
         return url;
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/HTTPEntityIDRequestURLBuilder.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/HTTPEntityIDRequestURLBuilder.java
index 33ffc4c6d..b185b3a45 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/HTTPEntityIDRequestURLBuilder.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/HTTPEntityIDRequestURLBuilder.java
@@ -22,12 +22,11 @@ import java.util.function.Function;
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
-import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 import org.opensaml.core.criterion.EntityIdCriterion;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Function which examines an entity ID from supplied criteria and returns it as a metadata request URL 
@@ -40,15 +39,13 @@ public class HTTPEntityIDRequestURLBuilder implements Function<CriteriaSet, Stri
 
     /** {@inheritDoc} */
     @Nullable public String apply(@Nullable final CriteriaSet criteria) {
-        Constraint.isNotNull(criteria, "Criteria was null");
-        if (!criteria.contains(EntityIdCriterion.class)) {
+        
+        final EntityIdCriterion criterion = criteria != null ? criteria.get(EntityIdCriterion.class) : null;
+        if (criterion == null) {
             log.trace("Criteria did not contain entity ID, unable to build request URL");
             return null;
         }
-        final String entityID = criteria.get(EntityIdCriterion.class).getEntityId();
-        
-        Constraint.isNotNull(entityID, "Entity ID was null");
-        
+        final String entityID = criterion.getEntityId();
         if (entityID.toLowerCase().startsWith("http:") || entityID.toLowerCase().startsWith("https:")) {
             log.debug("Saw entityID with HTTP/HTTPS URL syntax, returning the entityID itself as request URL");
             return entityID;
@@ -57,5 +54,4 @@ public class HTTPEntityIDRequestURLBuilder implements Function<CriteriaSet, Stri
         return null;
     }
 
-
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/HTTPMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/HTTPMetadataResolver.java
index 94de0a5f6..f3e39108f 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/HTTPMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/HTTPMetadataResolver.java
@@ -38,8 +38,9 @@ import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.opensaml.security.httpclient.HttpClientSecurityParameters;
 import org.opensaml.security.httpclient.HttpClientSecuritySupport;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
+import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.ResolverException;
 
 /**
@@ -62,16 +63,16 @@ public class HTTPMetadataResolver extends AbstractReloadingMetadataResolver {
     @Nonnull private final Logger log = LoggerFactory.getLogger(HTTPMetadataResolver.class);
 
     /** HTTP Client used to pull the metadata. */
-    private HttpClient httpClient;
+    @Nonnull private HttpClient httpClient;
 
     /** URL to the Metadata. */
-    private URI metadataURI;
+    @Nonnull private URI metadataURI;
 
     /** The ETag provided when the currently cached metadata was fetched. */
-    private String cachedMetadataETag;
+    @Nullable private String cachedMetadataETag;
 
     /** The Last-Modified information provided when the currently cached metadata was fetched. */
-    private String cachedMetadataLastModified;
+    @Nullable private String cachedMetadataLastModified;
 
     /** Optional HttpClient security parameters.*/
     @Nullable private HttpClientSecurityParameters httpClientSecurityParameters;
@@ -84,7 +85,7 @@ public class HTTPMetadataResolver extends AbstractReloadingMetadataResolver {
      * 
      * @throws ResolverException thrown if the HTTP client is null or the metadata URL provided is invalid
      */
-    public HTTPMetadataResolver(final HttpClient client, final String metadataURL) throws ResolverException {
+    public HTTPMetadataResolver(@Nonnull final HttpClient client, final String metadataURL) throws ResolverException {
         this(null, client, metadataURL);
     }
 
@@ -97,14 +98,11 @@ public class HTTPMetadataResolver extends AbstractReloadingMetadataResolver {
      * 
      * @throws ResolverException thrown if the HTTP client is null or the metadata URL provided is invalid
      */
-    public HTTPMetadataResolver(final Timer backgroundTaskTimer, final HttpClient client, final String metadataURL)
-            throws ResolverException {
+    public HTTPMetadataResolver(final Timer backgroundTaskTimer, @Nonnull final HttpClient client,
+            final String metadataURL) throws ResolverException {
         super(backgroundTaskTimer);
 
-        if (client == null) {
-            throw new ResolverException("HTTP client may not be null");
-        }
-        httpClient = client;
+        httpClient = Constraint.isNotNull(client, "HttpClient cannot be null");
 
         try {
             metadataURI = new URI(metadataURL);
@@ -118,7 +116,7 @@ public class HTTPMetadataResolver extends AbstractReloadingMetadataResolver {
      * 
      * @return the URL to fetch the metadata
      */
-    public String getMetadataURI() {
+    @Nonnull public String getMetadataURI() {
         return metadataURI.toASCIIString();
     }
         
@@ -175,19 +173,7 @@ public class HTTPMetadataResolver extends AbstractReloadingMetadataResolver {
 
     /** {@inheritDoc} */
     @Override
-    protected void doDestroy() {
-        httpClient = null;
-        httpClientSecurityParameters = null;
-        metadataURI = null;
-        cachedMetadataETag = null;
-        cachedMetadataLastModified = null;
-
-        super.doDestroy();
-    }
-
-    /** {@inheritDoc} */
-    @Override
-    protected String getMetadataIdentifier() {
+    @Nonnull protected String getMetadataIdentifier() {
         return metadataURI.toString();
     }
 
@@ -200,7 +186,7 @@ public class HTTPMetadataResolver extends AbstractReloadingMetadataResolver {
      * @throws ResolverException thrown if there is a problem retrieving the metadata from the remote server
      */
     @Override
-    protected byte[] fetchMetadata() throws ResolverException {
+    @Nullable protected byte[] fetchMetadata() throws ResolverException {
         final HttpGet httpGet = buildHttpGet();
         final HttpClientContext context = buildHttpClientContext(httpGet);
         ClassicHttpResponse response = null;
@@ -253,7 +239,7 @@ public class HTTPMetadataResolver extends AbstractReloadingMetadataResolver {
      * 
      * @return the constructed HttpGet instance
      */
-    protected HttpGet buildHttpGet() {
+    @Nonnull protected HttpGet buildHttpGet() {
         final HttpGet getMethod = new HttpGet(getMetadataURI());
 
         if (cachedMetadataETag != null) {
@@ -273,9 +259,9 @@ public class HTTPMetadataResolver extends AbstractReloadingMetadataResolver {
      * 
      * @return a new instance of {@link HttpClientContext}
      */
-    protected HttpClientContext buildHttpClientContext(@Nonnull final ClassicHttpRequest request) {
-        // TODO Really request should be @Nonnull, change when we remove deprecated buildHttpClientContext()
+    @Nonnull protected HttpClientContext buildHttpClientContext(@Nonnull final ClassicHttpRequest request) {
         final HttpClientContext context = HttpClientContext.create();
+        assert context != null;
         
         HttpClientSecuritySupport.marshalSecurityParameters(context, httpClientSecurityParameters, true);
         HttpClientSecuritySupport.addDefaultTLSTrustEngineCriteria(context, request);
@@ -288,7 +274,7 @@ public class HTTPMetadataResolver extends AbstractReloadingMetadataResolver {
      * 
      * @param response GetMethod containing a valid HTTP response
      */
-    protected void processConditionalRetrievalHeaders(final ClassicHttpResponse response) {
+    protected void processConditionalRetrievalHeaders(@Nonnull final ClassicHttpResponse response) {
         Header httpHeader = response.getFirstHeader("ETag");
         if (httpHeader != null) {
             cachedMetadataETag = httpHeader.getValue();
@@ -309,7 +295,8 @@ public class HTTPMetadataResolver extends AbstractReloadingMetadataResolver {
      * 
      * @throws ResolverException thrown if there is a problem getting the raw metadata bytes from the response
      */
-    protected byte[] getMetadataBytesFromResponse(final ClassicHttpResponse response) throws ResolverException {
+    @Nonnull protected byte[] getMetadataBytesFromResponse(@Nonnull final ClassicHttpResponse response)
+            throws ResolverException {
         log.debug("{} Attempting to extract metadata from response to request for metadata from '{}'", 
                 getLogPrefix(), getMetadataURI());
         try {
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/LocalDynamicMetadataResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/LocalDynamicMetadataResolver.java
index 6d7f7bc57..c94afc803 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/LocalDynamicMetadataResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/LocalDynamicMetadataResolver.java
@@ -29,9 +29,9 @@ import org.opensaml.core.xml.XMLObject;
 import org.opensaml.core.xml.persist.ConditionalLoadXMLObjectLoadSaveManager;
 import org.opensaml.core.xml.persist.XMLObjectLoadSaveManager;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 /**
@@ -41,7 +41,7 @@ import net.shibboleth.shared.resolver.CriteriaSet;
 public class LocalDynamicMetadataResolver extends AbstractDynamicMetadataResolver {
     
     /** Logger. */
-    @Nullable private Logger log = LoggerFactory.getLogger(LocalDynamicMetadataResolver.class);
+    @Nonnull private Logger log = LoggerFactory.getLogger(LocalDynamicMetadataResolver.class);
     
     /** The manager for the local store of metadata. */
     @Nonnull private XMLObjectLoadSaveManager<XMLObject> sourceManager;
@@ -94,14 +94,15 @@ public class LocalDynamicMetadataResolver extends AbstractDynamicMetadataResolve
         
         sourceManager = Constraint.isNotNull(manager, "Local source manager was null");
         
-        sourceKeyGenerator = keyGenerator;
-        if (sourceKeyGenerator == null) {
+        if (keyGenerator == null) {
             sourceKeyGenerator = new DefaultLocalDynamicSourceKeyGenerator();
+        } else {
+            sourceKeyGenerator = keyGenerator;
         }
     }
     
     /** {@inheritDoc} */
-    protected void removeByEntityID(final String entityID, final EntityBackingStore backingStore) {
+    protected void removeByEntityID(@Nonnull final String entityID, @Nonnull final EntityBackingStore backingStore) {
         if (sourceManager instanceof ConditionalLoadXMLObjectLoadSaveManager) {
             final String key = sourceKeyGenerator.apply(new CriteriaSet(new EntityIdCriterion(entityID)));
             if (key != null) {
@@ -114,7 +115,7 @@ public class LocalDynamicMetadataResolver extends AbstractDynamicMetadataResolve
 
     /** {@inheritDoc} */
     @Override
-    protected XMLObject fetchFromOriginSource(final CriteriaSet criteria) throws IOException {
+    protected XMLObject fetchFromOriginSource(@Nullable final CriteriaSet criteria) throws IOException {
         final String key = sourceKeyGenerator.apply(criteria);
         if (key != null) {
             log.trace("{} Attempting to load from local source manager with generated key '{}'", getLogPrefix(), key);
@@ -131,4 +132,4 @@ public class LocalDynamicMetadataResolver extends AbstractDynamicMetadataResolve
         return null;
     }
     
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/MetadataQueryProtocolRequestURLBuilder.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/MetadataQueryProtocolRequestURLBuilder.java
index c69e9fcf0..082b8b80f 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/MetadataQueryProtocolRequestURLBuilder.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/MetadataQueryProtocolRequestURLBuilder.java
@@ -25,7 +25,6 @@ import javax.annotation.Nullable;
 
 import org.opensaml.core.criterion.EntityIdCriterion;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.escape.Escaper;
 import com.google.common.net.UrlEscapers;
@@ -33,7 +32,9 @@ import com.google.common.net.UrlEscapers;
 import net.shibboleth.shared.annotation.ParameterName;
 import net.shibboleth.shared.annotation.constraint.NonnullElements;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
@@ -55,19 +56,19 @@ import net.shibboleth.shared.resolver.CriteriaSet;
 public class MetadataQueryProtocolRequestURLBuilder implements Function<CriteriaSet, String> {
     
     /** Logger. */
-    private final Logger log = LoggerFactory.getLogger(MetadataQueryProtocolRequestURLBuilder.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(MetadataQueryProtocolRequestURLBuilder.class);
     
     /** The request base URL per the specification. */
-    private String base;
+    @Nonnull @NotEmpty private String base;
     
     /** Function which transforms the entityID prior to substitution into the URL. */
-    private Function<String, String> transformer;
+    @Nullable private Function<String, String> transformer;
     
     /** Path escaper for escaping the input value inserted into the URL path. */
-    private Escaper pathEscaper = UrlEscapers.urlPathSegmentEscaper();
+    @Nonnull private final Escaper pathEscaper = UrlEscapers.urlPathSegmentEscaper();
     
     /** List of secondary URL builders. */
-    private List<MetadataQueryProtocolURLBuilder> urlBuilders;
+    @Nullable private List<MetadataQueryProtocolURLBuilder> urlBuilders;
     
     /**
      * Constructor.
@@ -127,16 +128,17 @@ public class MetadataQueryProtocolRequestURLBuilder implements Function<Criteria
         transformer = transform;
         
         if (secondaryURLBuilders != null) {
-            urlBuilders = List.copyOf(secondaryURLBuilders);
+            urlBuilders = CollectionSupport.copyToList(secondaryURLBuilders);
         }
     }
 
     /** {@inheritDoc} */
     @Nullable public String apply(@Nullable final CriteriaSet criteria) {
-        Constraint.isNotNull(criteria, "Criteria was null");
-        if (criteria.contains(EntityIdCriterion.class)) {
+        final EntityIdCriterion criterion = criteria != null ? criteria.get(EntityIdCriterion.class) : null;
+
+        if (criterion != null) {
             log.debug("Criteria contained entity ID, building on that basis");
-            return buildFromEntityID(criteria.get(EntityIdCriterion.class).getEntityId());
+            return buildFromEntityID(criterion.getEntityId());
         } else if (urlBuilders != null) {
             log.debug("Criteria did not contain entity ID, attempting to build using secondary URL builders");
             return buildFromSecondaryLookups(criteria);
@@ -175,7 +177,7 @@ public class MetadataQueryProtocolRequestURLBuilder implements Function<Criteria
      * @param criteria the criteria
      * @return the request URL, or null
      */
-    private String buildFromSecondaryLookups(@Nonnull final CriteriaSet criteria) {
+    private String buildFromSecondaryLookups(@Nullable final CriteriaSet criteria) {
         if (urlBuilders != null) {
             for (final MetadataQueryProtocolURLBuilder builder : urlBuilders) {
                 final String url = builder.buildURL(base, criteria);
@@ -203,8 +205,8 @@ public class MetadataQueryProtocolRequestURLBuilder implements Function<Criteria
          * @return a URL based on the supplied inputs, or null if the implementation did not support
          *     or understand any of the supplied criteria 
          */
-        @Nullable public String buildURL(@Nonnull final String baseURL, @Nonnull final CriteriaSet criteria);
+        @Nullable public String buildURL(@Nonnull final String baseURL, @Nullable final CriteriaSet criteria);
         
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/PredicateRoleDescriptorResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/PredicateRoleDescriptorResolver.java
index dbf815009..ed80f6201 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/PredicateRoleDescriptorResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/PredicateRoleDescriptorResolver.java
@@ -18,7 +18,6 @@
 package org.opensaml.saml.metadata.resolver.impl;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.Set;
 import java.util.UUID;
@@ -39,16 +38,17 @@ import org.opensaml.saml.saml2.common.IsTimeboundSAMLObjectValidPredicate;
 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.Predicates;
 import com.google.common.collect.Iterables;
 
 import net.shibboleth.shared.annotation.ParameterName;
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.AbstractIdentifiedInitializableComponent;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.logic.PredicateSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.CriterionPredicateRegistry;
 import net.shibboleth.shared.resolver.ResolverException;
@@ -73,23 +73,23 @@ public class PredicateRoleDescriptorResolver extends AbstractIdentifiedInitializ
         implements RoleDescriptorResolver {
     
     /** Predicate for evaluating whether a TimeboundSAMLObject is valid. */
-    private static final Predicate<XMLObject> IS_VALID_PREDICATE = new IsTimeboundSAMLObjectValidPredicate();
+    @Nonnull private static final Predicate<XMLObject> IS_VALID_PREDICATE = new IsTimeboundSAMLObjectValidPredicate();
     
     /** Logger. */
-    private Logger log = LoggerFactory.getLogger(PredicateRoleDescriptorResolver.class);
+    @Nonnull private Logger log = LoggerFactory.getLogger(PredicateRoleDescriptorResolver.class);
     
     /** Whether metadata is required to be valid. */
     private boolean requireValidMetadata;
  
     /** Resolver of EntityDescriptors. */
-    private MetadataResolver entityDescriptorResolver;
+    @Nonnull private MetadataResolver entityDescriptorResolver;
     
     /** Flag which determines whether predicates used in filtering are connected by 
      * a logical 'OR' (true) or by logical 'AND' (false). Defaults to false. */
     private boolean satisfyAnyPredicates;
     
     /** Registry used in resolving predicates from criteria. */
-    private CriterionPredicateRegistry<RoleDescriptor> criterionPredicateRegistry;
+    @Nullable private CriterionPredicateRegistry<RoleDescriptor> criterionPredicateRegistry;
     
     /** Flag which determines whether the default predicate registry will be used if no one is supplied explicitly.
      * Defaults to true. */
@@ -232,8 +232,7 @@ public class PredicateRoleDescriptorResolver extends AbstractIdentifiedInitializ
     }
     
     /** {@inheritDoc} */
-    @Override
-    @Nullable public RoleDescriptor resolveSingle(final CriteriaSet criteria) throws ResolverException {
+    @Nullable public RoleDescriptor resolveSingle(@Nullable final CriteriaSet criteria) throws ResolverException {
         checkComponentActive();
         final Iterable<RoleDescriptor> iterable = resolve(criteria);
         if (iterable != null) {
@@ -246,14 +245,13 @@ public class PredicateRoleDescriptorResolver extends AbstractIdentifiedInitializ
     }
 
     /** {@inheritDoc} */
-    @Override
-    @Nonnull public Iterable<RoleDescriptor> resolve(final CriteriaSet criteria) throws ResolverException {
+    @Nonnull public Iterable<RoleDescriptor> resolve(@Nullable final CriteriaSet criteria) throws ResolverException {
         checkComponentActive();
         
         final Iterable<EntityDescriptor> entityDescriptorsSource = entityDescriptorResolver.resolve(criteria);
         if (!entityDescriptorsSource.iterator().hasNext()) {
             log.debug("Resolved no EntityDescriptors via underlying MetadataResolver, returning empty collection");
-            return Collections.emptySet();
+            return CollectionSupport.emptySet();
         }
         
         if (log.isDebugEnabled()) {
@@ -261,7 +259,7 @@ public class PredicateRoleDescriptorResolver extends AbstractIdentifiedInitializ
         }
         
         final Predicate<? super RoleDescriptor> predicate = isRequireValidMetadata() ? IS_VALID_PREDICATE 
-                : Predicates.<XMLObject>alwaysTrue();
+                : PredicateSupport.alwaysTrue();
             
         if (haveRoleCriteria(criteria)) {
             final Iterable<RoleDescriptor> candidates =
@@ -280,7 +278,7 @@ public class PredicateRoleDescriptorResolver extends AbstractIdentifiedInitializ
             return predicateFilterCandidates(Iterables.filter(candidates, predicate::test), criteria, true);
         } else {
             log.debug("Found no role criteria and predicate-only resolution is disabled, returning empty collection");
-            return Collections.emptySet();
+            return CollectionSupport.emptySet();
         }
         
     }
@@ -292,8 +290,8 @@ public class PredicateRoleDescriptorResolver extends AbstractIdentifiedInitializ
      * 
      * @return true if have role criteria, false otherwise
      */
-    protected boolean haveRoleCriteria(@Nonnull final CriteriaSet criteria) {
-        return criteria.contains(EntityRoleCriterion.class);
+    protected boolean haveRoleCriteria(@Nullable final CriteriaSet criteria) {
+        return criteria != null && criteria.contains(EntityRoleCriterion.class);
     }
 
     /**
@@ -310,11 +308,13 @@ public class PredicateRoleDescriptorResolver extends AbstractIdentifiedInitializ
      * @return the role descriptors corresponding to the input entity role and protocol
      */
     protected Iterable<RoleDescriptor> getCandidatesByRoleAndProtocol(
-            @Nonnull final Iterable<EntityDescriptor> entityDescriptors, @Nonnull final CriteriaSet criteria) {
+            @Nonnull final Iterable<EntityDescriptor> entityDescriptors, @Nullable final CriteriaSet criteria) {
         
-        final EntityRoleCriterion roleCriterion = Constraint.isNotNull(criteria.get(EntityRoleCriterion.class), 
-                "EntityRoleCriterion was not supplied");
+        final EntityRoleCriterion roleCriterion =
+                Constraint.isNotNull(criteria != null ? criteria.get(EntityRoleCriterion.class) : null,
+                        "EntityRoleCriterion was not supplied");
         
+        assert criteria != null;
         final ProtocolCriterion protocolCriterion = criteria.get(ProtocolCriterion.class);
         
         final ArrayList<Iterable<RoleDescriptor>> aggregate = new ArrayList<>();
@@ -360,12 +360,12 @@ public class PredicateRoleDescriptorResolver extends AbstractIdentifiedInitializ
      * @throws ResolverException if there is a fatal error during resolution
      */
     protected Iterable<RoleDescriptor> predicateFilterCandidates(@Nonnull final Iterable<RoleDescriptor> candidates,
-            @Nonnull final CriteriaSet criteria, final boolean onEmptyPredicatesReturnEmpty)
+            @Nullable final CriteriaSet criteria, final boolean onEmptyPredicatesReturnEmpty)
                     throws ResolverException {
         
         if (!candidates.iterator().hasNext()) {
             log.debug("Candidates iteration was empty, nothing to filter via predicates");
-            return Collections.emptySet();
+            return CollectionSupport.emptySet();
         }
         
         log.debug("Attempting to filter candidate RoleDescriptors via resolved Predicates");
@@ -376,7 +376,8 @@ public class PredicateRoleDescriptorResolver extends AbstractIdentifiedInitializ
         log.trace("Resolved {} Predicates: {}", predicates.size(), predicates);
         
         final boolean satisfyAny;
-        final SatisfyAnyCriterion satisfyAnyCriterion = criteria.get(SatisfyAnyCriterion.class);
+        final SatisfyAnyCriterion satisfyAnyCriterion =
+                criteria != null ? criteria.get(SatisfyAnyCriterion.class) : null;
         if (satisfyAnyCriterion  != null) {
             log.trace("CriteriaSet contained SatisfyAnyCriterion");
             satisfyAny = satisfyAnyCriterion.isSatisfyAny();
@@ -395,4 +396,4 @@ public class PredicateRoleDescriptorResolver extends AbstractIdentifiedInitializ
         return result;
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/RegexRequestURLBuilder.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/RegexRequestURLBuilder.java
index f132713aa..473ac6aae 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/RegexRequestURLBuilder.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/RegexRequestURLBuilder.java
@@ -26,12 +26,12 @@ import javax.annotation.Nullable;
 
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 import org.opensaml.core.criterion.EntityIdCriterion;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Function which produces a URL by evaluating a supplied regular expression against the criteria entity ID, 
@@ -74,13 +74,13 @@ import org.slf4j.LoggerFactory;
 public class RegexRequestURLBuilder implements Function<CriteriaSet, String> {
     
     /** Logger. */
-    @Nullable private final Logger log = LoggerFactory.getLogger(RegexRequestURLBuilder.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(RegexRequestURLBuilder.class);
     
     /** The compiled pattern. */
-    private Pattern pattern;
+    @Nonnull private final Pattern pattern;
     
     /** The replacement template. */
-    private String template;
+    @Nonnull private final String template;
    
     /**
      * Constructor.
@@ -107,12 +107,13 @@ public class RegexRequestURLBuilder implements Function<CriteriaSet, String> {
 
     /** {@inheritDoc} */
     @Nullable public String apply(@Nullable final CriteriaSet criteria) {
-        Constraint.isNotNull(criteria, "Criteria was null");
-        if (!criteria.contains(EntityIdCriterion.class)) {
+        
+        final EntityIdCriterion criterion = criteria != null ? criteria.get(EntityIdCriterion.class) : null;
+        if (criterion == null) {
             log.trace("Criteria did not contain entity ID, unable to build request URL");
             return null;
         }
-        final String entityID = criteria.get(EntityIdCriterion.class).getEntityId();
+        final String entityID = criterion.getEntityId();
         
         try {
             final Matcher matcher = pattern.matcher(entityID);
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/SAMLArtifactURLBuilder.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/SAMLArtifactURLBuilder.java
index 3f39caa56..205a21ab5 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/SAMLArtifactURLBuilder.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/SAMLArtifactURLBuilder.java
@@ -18,6 +18,7 @@
 package org.opensaml.saml.metadata.resolver.impl;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 
 import org.opensaml.saml.common.binding.artifact.SAMLSourceIDArtifact;
 import org.opensaml.saml.criterion.ArtifactCriterion;
@@ -33,17 +34,18 @@ import net.shibboleth.shared.resolver.CriteriaSet;
 public class SAMLArtifactURLBuilder implements MetadataQueryProtocolURLBuilder {
     
     /** Hex encoder. */
-    private static final BaseEncoding HEX = BaseEncoding.base16().lowerCase();
+    @Nonnull private static final BaseEncoding HEX = BaseEncoding.base16().lowerCase();
 
     /** {@inheritDoc} */
-    public String buildURL(@Nonnull final String baseURL, @Nonnull final CriteriaSet criteria) {
-        if (!criteria.contains(ArtifactCriterion.class)) {
+    public String buildURL(@Nonnull final String baseURL, @Nullable final CriteriaSet criteria) {
+        
+        final ArtifactCriterion artifactCriterion = criteria != null ? criteria.get(ArtifactCriterion.class) : null;
+        if (artifactCriterion == null) {
             return null;
         }
-        final ArtifactCriterion artifactCriterion = criteria.get(ArtifactCriterion.class);
         
-        if (artifactCriterion.getArtifact() instanceof SAMLSourceIDArtifact) {
-            return buildFromSourceID(baseURL, (SAMLSourceIDArtifact)artifactCriterion.getArtifact());
+        if (artifactCriterion.getArtifact() instanceof SAMLSourceIDArtifact art) {
+            return buildFromSourceID(baseURL, art);
         }
         
         return null;
@@ -64,4 +66,4 @@ public class SAMLArtifactURLBuilder implements MetadataQueryProtocolURLBuilder {
         return baseURL + "entities/" + "%7Bsha1%7D" + HEX.encode(sourceIDArtifact.getSourceID());
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/TemplateRequestURLBuilder.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/TemplateRequestURLBuilder.java
index 5136b26e3..1b088ba87 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/TemplateRequestURLBuilder.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/impl/TemplateRequestURLBuilder.java
@@ -28,12 +28,12 @@ import org.apache.velocity.VelocityContext;
 import org.apache.velocity.app.VelocityEngine;
 import org.opensaml.core.criterion.EntityIdCriterion;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.net.UrlEscapers;
 
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.velocity.Template;
@@ -72,16 +72,16 @@ public class TemplateRequestURLBuilder implements Function<CriteriaSet, String>
     @Nonnull @NotEmpty public static final String CONTEXT_KEY_ENTITY_ID = "entityID";
     
     /** Logger. */
-    private final Logger log = LoggerFactory.getLogger(TemplateRequestURLBuilder.class);
+    @Nonnull private final Logger log = LoggerFactory.getLogger(TemplateRequestURLBuilder.class);
     
     /** Velocity template instance used to render the request URL. */
-    private Template template;
+    @Nonnull private Template template;
     
     /** The template text, for logging purposes. */
-    private String templateText;
+    @Nonnull private String templateText;
     
     /** Function which transforms the entityID prior to substitution into the template. */
-    private Function<String, String> transformer;
+    @Nullable private Function<String, String> transformer;
     
     /** Enum value indicating whether and how to encode the entity ID value before substitution. */
     private EncodingStyle entityIDEncodingStyle;
@@ -139,9 +139,9 @@ public class TemplateRequestURLBuilder implements Function<CriteriaSet, String>
         transformer = transform;
         
         if (charSet != null) {
-            template = Template.fromTemplate(engine, trimmedTemplate, charSet);
+            template = Template.fromTemplate(engine, templateText, charSet);
         } else {
-            template = Template.fromTemplate(engine, trimmedTemplate);
+            template = Template.fromTemplate(engine, templateText);
         }
         
         entityIDEncodingStyle = encodingStyle != null ? encodingStyle : EncodingStyle.none;
@@ -149,12 +149,14 @@ public class TemplateRequestURLBuilder implements Function<CriteriaSet, String>
 
     /** {@inheritDoc} */
     @Nullable public String apply(@Nullable final CriteriaSet criteria) {
-        Constraint.isNotNull(criteria, "Criteria was null");
-        if (!criteria.contains(EntityIdCriterion.class)) {
-            log.trace("Criteria did not contain entity ID, unable to build request URL");
+        
+        final EntityIdCriterion criterion = criteria != null ? criteria.get(EntityIdCriterion.class) : null;
+        if (criterion == null) {
+            log.trace("CriteriaSet did not contain EntityIdCriterion, unable to build request URL");
             return null;
         }
-        String entityID = criteria.get(EntityIdCriterion.class).getEntityId();
+        
+        String entityID = criterion.getEntityId();
         
         log.debug("Saw input entityID '{}'", entityID);
         
@@ -197,4 +199,4 @@ public class TemplateRequestURLBuilder implements Function<CriteriaSet, String>
         }
     }
 
-}
+}
\ No newline at end of file
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 13baf4162..b8db798ff 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
@@ -130,11 +130,11 @@ public class EndpointMetadataIndex implements MetadataIndex {
 
     /** {@inheritDoc} */
     @Nullable @NonnullElements @Unmodifiable @NotLive
-    public Set<MetadataIndexKey> generateKeys(@Nonnull final CriteriaSet criteriaSet) {
-        Constraint.isNotNull(criteriaSet, "CriteriaSet was null");
-        final EntityRoleCriterion roleCrit = criteriaSet.get(EntityRoleCriterion.class);
-        @SuppressWarnings("unchecked")
-        final EndpointCriterion<Endpoint> endpointCrit = criteriaSet.get(EndpointCriterion.class);
+    public Set<MetadataIndexKey> generateKeys(@Nullable final CriteriaSet criteriaSet) {
+        final EntityRoleCriterion roleCrit = criteriaSet != null ? criteriaSet.get(EntityRoleCriterion.class) : null;
+        final EndpointCriterion<Endpoint> endpointCrit =
+            criteriaSet != null ? criteriaSet.get(EndpointCriterion.class) : null;
+        
         if (roleCrit != null && endpointCrit != null) {
             final HashSet<MetadataIndexKey> result = new HashSet<>();
             result.addAll(processCriteria(criteriaSet, roleCrit.getRole(), endpointCrit.getEndpoint()));
@@ -151,7 +151,7 @@ public class EndpointMetadataIndex implements MetadataIndex {
      * @param endpoint the endpoint to process
      * @return the set of metadata index keys for the endpoint
      */
-    @Nonnull private Set<MetadataIndexKey> processCriteria(@Nonnull final CriteriaSet criteriaSet, 
+    @Nonnull private Set<MetadataIndexKey> processCriteria(@Nullable final CriteriaSet criteriaSet, 
             @Nonnull final QName roleType, @Nonnull final Endpoint endpoint) {
         
         final HashSet<MetadataIndexKey> result = new HashSet<>();
@@ -186,10 +186,11 @@ public class EndpointMetadataIndex implements MetadataIndex {
      * @param location the location to process
      * @return the variants of the location to be indexed 
      */
-    @Nonnull private Set<String> processLocation(@Nonnull final CriteriaSet criteriaSet,
+    @Nonnull private Set<String> processLocation(@Nullable final CriteriaSet criteriaSet,
             @Nonnull final String location) {
         boolean generateStartsWithVariants = false;
-        final StartsWithLocationCriterion startsWithCrit = criteriaSet.get(StartsWithLocationCriterion.class);
+        final StartsWithLocationCriterion startsWithCrit =
+                criteriaSet != null ? criteriaSet.get(StartsWithLocationCriterion.class) : null;
         if (startsWithCrit != null) {
             generateStartsWithVariants = startsWithCrit.isMatchStartsWith();
         }
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/FunctionDrivenMetadataIndex.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/FunctionDrivenMetadataIndex.java
index 0f6e5ff12..d9ad5b7ab 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/FunctionDrivenMetadataIndex.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/FunctionDrivenMetadataIndex.java
@@ -58,7 +58,7 @@ public class FunctionDrivenMetadataIndex implements MetadataIndex {
 
     /** {@inheritDoc} */
     @Nullable @NonnullElements @Unmodifiable @NotLive 
-    public Set<MetadataIndexKey> generateKeys(@Nonnull final CriteriaSet criteriaSet) {
+    public Set<MetadataIndexKey> generateKeys(@Nullable final CriteriaSet criteriaSet) {
         Constraint.isNotNull(criteriaSet, "CriteriaSet was null");
         return criteriaStrategy.apply(criteriaSet);
     }
@@ -70,4 +70,4 @@ public class FunctionDrivenMetadataIndex implements MetadataIndex {
         return descriptorStrategy.apply(descriptor);
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexManager.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexManager.java
index 26b8151e1..96dff09a5 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexManager.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexManager.java
@@ -116,7 +116,7 @@ public class MetadataIndexManager<T> {
      *          and the wrapped set contains the indexed data, which may be empty.
      */
     @Nonnull @NonnullElements
-    public Optional<Set<T>> lookupIndexedItems(@Nonnull final CriteriaSet criteria) {
+    public Optional<Set<T>> lookupIndexedItems(@Nullable final CriteriaSet criteria) {
         final Set<T> items = new HashSet<>();
         for (final MetadataIndex index : indexes.keySet()) {
             final Set<MetadataIndexKey> keys = index.generateKeys(criteria);
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/RoleMetadataIndex.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/RoleMetadataIndex.java
index ea906e39a..253fffafe 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/RoleMetadataIndex.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/RoleMetadataIndex.java
@@ -45,9 +45,8 @@ public class RoleMetadataIndex implements MetadataIndex {
 
     /** {@inheritDoc} */
     @Nullable @NonnullElements @Unmodifiable @NotLive 
-    public Set<MetadataIndexKey> generateKeys(@Nonnull final CriteriaSet criteriaSet) {
-        Constraint.isNotNull(criteriaSet, "CriteriaSet was null");
-        final EntityRoleCriterion roleCrit = criteriaSet.get(EntityRoleCriterion.class);
+    public Set<MetadataIndexKey> generateKeys(@Nullable final CriteriaSet criteriaSet) {
+        final EntityRoleCriterion roleCrit = criteriaSet != null ? criteriaSet.get(EntityRoleCriterion.class) : null;
         if (roleCrit != null) {
             final HashSet<MetadataIndexKey> result = new HashSet<>();
             result.add(new RoleMetadataIndexKey(roleCrit.getRole()));
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/SAMLArtifactMetadataIndex.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/SAMLArtifactMetadataIndex.java
index 54e7d9ee7..ff8d3aa71 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/SAMLArtifactMetadataIndex.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/metadata/resolver/index/impl/SAMLArtifactMetadataIndex.java
@@ -116,21 +116,19 @@ public class SAMLArtifactMetadataIndex implements MetadataIndex {
     }
 
     /** {@inheritDoc} */
-    @Nullable public Set<MetadataIndexKey> generateKeys(@Nonnull final CriteriaSet criteriaSet) {
-        Constraint.isNotNull(criteriaSet, "CriteriaSet was null");
-        final ArtifactCriterion artifactCrit = criteriaSet.get(ArtifactCriterion.class);
+    @Nullable public Set<MetadataIndexKey> generateKeys(@Nullable final CriteriaSet criteriaSet) {
+        final ArtifactCriterion artifactCrit = criteriaSet != null ? criteriaSet.get(ArtifactCriterion.class) : null;
         if (artifactCrit != null) {
             final LazySet<MetadataIndexKey> results = new LazySet<>();
             
             final SAMLArtifact artifact = artifactCrit.getArtifact();
             
-            if (artifact instanceof SAMLSourceIDArtifact) {
-                results.add(new ArtifactSourceIDMetadataIndexKey(((SAMLSourceIDArtifact)artifact).getSourceID()));
+            if (artifact instanceof SAMLSourceIDArtifact art) {
+                results.add(new ArtifactSourceIDMetadataIndexKey(art.getSourceID()));
             }
             
-            if (artifact instanceof SAMLSourceLocationArtifact) {
-                results.add(new ArtifactSourceLocationMetadataIndexKey(
-                        ((SAMLSourceLocationArtifact)artifact).getSourceLocation()));
+            if (artifact instanceof SAMLSourceLocationArtifact art) {
+                results.add(new ArtifactSourceLocationMetadataIndexKey(art.getSourceLocation()));
             }
             
             return results;
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/InlineSelfEncryptionParametersStrategy.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/InlineSelfEncryptionParametersStrategy.java
index c51e426ca..1dbdb9f82 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/InlineSelfEncryptionParametersStrategy.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/InlineSelfEncryptionParametersStrategy.java
@@ -18,15 +18,16 @@
 package org.opensaml.saml.security.impl;
 
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.function.Function;
 
 import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.collection.Pair;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 
@@ -42,7 +43,6 @@ import org.opensaml.xmlsec.SecurityConfigurationSupport;
 import org.opensaml.xmlsec.criterion.EncryptionConfigurationCriterion;
 import org.opensaml.xmlsec.impl.BasicEncryptionConfiguration;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import com.google.common.collect.Iterables;
 
@@ -93,29 +93,37 @@ public class InlineSelfEncryptionParametersStrategy
     /** {@inheritDoc} */
     @Nullable
     public List<EncryptionParameters> apply(@Nullable final Pair<ProfileRequestContext, EncryptionParameters> input) {
-        if (input == null || input.getFirst() == null) {
+        
+        final ProfileRequestContext profileRequestContext = input != null ? input.getFirst() : null;
+        if (profileRequestContext == null) {
             log.debug("Input Pair or ProfileRequestContext was null, skipping");
-            return Collections.emptyList();
+            return CollectionSupport.emptyList();
         }
         
-        final List<Credential> credentials = resolveCredentials(input.getFirst());
+        final List<Credential> credentials = resolveCredentials(profileRequestContext);
         if (credentials.isEmpty()) {
             log.debug("No self-encryption credentials were resolved, skipping further processing");
-            return Collections.emptyList();
+            return CollectionSupport.emptyList();
         }
         log.debug("Resolved {} self-encryption credentials", credentials.size());
         
-        final List<EncryptionConfiguration> baseConfigs = resolveBaseConfigurations(input.getFirst());
+        final List<EncryptionConfiguration> baseConfigs = resolveBaseConfigurations(profileRequestContext);
         log.debug("Resolved {} base EncryptionConfigurations", baseConfigs.size());
         
         final ArrayList<EncryptionParameters> encParams = new ArrayList<>();
-        
+
+        final EncryptionParameters requestParams = input != null ? input.getSecond() : null;
+
         for (final Credential cred : credentials) {
+            assert cred != null;
+            
             final BasicEncryptionConfiguration selfConfig = new BasicEncryptionConfiguration();
-            selfConfig.setKeyTransportEncryptionCredentials(Collections.singletonList(cred));
-            if (input.getSecond() != null && input.getSecond().getDataEncryptionAlgorithm() != null) {
-                selfConfig.setDataEncryptionAlgorithms(Collections.singletonList(
-                        input.getSecond().getDataEncryptionAlgorithm()));
+            selfConfig.setKeyTransportEncryptionCredentials(CollectionSupport.singletonList(cred));
+            if (requestParams != null) {
+                final String dataEncAlg = requestParams.getDataEncryptionAlgorithm();
+                if (dataEncAlg != null) {
+                    selfConfig.setDataEncryptionAlgorithms(CollectionSupport.singletonList(dataEncAlg));
+                }
             }
             
             final ArrayList<EncryptionConfiguration> configs = new ArrayList<>();
@@ -152,7 +160,7 @@ public class InlineSelfEncryptionParametersStrategy
             return credentials;
         } catch (final ResolverException e) {
             log.error("Error resolving IdP encryption credentials", e);
-            return Collections.emptyList();
+            return CollectionSupport.emptyList();
         }
     }
 
@@ -168,6 +176,7 @@ public class InlineSelfEncryptionParametersStrategy
         List<EncryptionConfiguration> baseConfigs = null;
         if (configurationLookupStrategy != null) {
             log.debug("Self-encryption EncryptionConfiguration lookup strategy was non-null");
+            assert configurationLookupStrategy != null;
             baseConfigs = configurationLookupStrategy.apply(profileRequestContext);
         } else {
             log.debug("Self-encryption EncryptionConfiguration lookup strategy was null");
@@ -176,7 +185,7 @@ public class InlineSelfEncryptionParametersStrategy
             return baseConfigs;
         }
         log.debug("No self-encryption EncryptionConfigurations were resolved, returning global configuration");
-        return Collections.singletonList(SecurityConfigurationSupport.getGlobalEncryptionConfiguration());
+        return CollectionSupport.singletonList(SecurityConfigurationSupport.getGlobalEncryptionConfiguration());
     }
     
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/MetadataCredentialResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/MetadataCredentialResolver.java
index d79a360b2..236d831a4 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/MetadataCredentialResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/MetadataCredentialResolver.java
@@ -36,6 +36,7 @@ import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.opensaml.saml.saml2.metadata.KeyDescriptor;
 import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.opensaml.security.credential.Credential;
+import org.opensaml.security.credential.CredentialContextSet;
 import org.opensaml.security.credential.MutableCredential;
 import org.opensaml.security.credential.UsageType;
 import org.opensaml.security.credential.impl.AbstractCriteriaFilteringCredentialResolver;
@@ -43,7 +44,6 @@ import org.opensaml.security.criteria.UsageCriterion;
 import org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver;
 import org.opensaml.xmlsec.keyinfo.KeyInfoCriterion;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 import net.shibboleth.shared.annotation.constraint.NonnullAfterInit;
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
@@ -53,6 +53,7 @@ import net.shibboleth.shared.component.InitializableComponent;
 import net.shibboleth.shared.component.UninitializedComponentException;
 import net.shibboleth.shared.component.UnmodifiableComponentException;
 import net.shibboleth.shared.logic.Constraint;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 
@@ -206,7 +207,7 @@ public class MetadataCredentialResolver extends AbstractCriteriaFilteringCredent
 
     /** {@inheritDoc} */
     @Override
-    @Nonnull protected Iterable<Credential> resolveFromSource(@Nonnull final CriteriaSet criteriaSet) 
+    @Nonnull protected Iterable<Credential> resolveFromSource(@Nullable final CriteriaSet criteriaSet) 
             throws ResolverException {
         
         ifNotInitializedThrowUninitializedComponentException();
@@ -214,20 +215,28 @@ public class MetadataCredentialResolver extends AbstractCriteriaFilteringCredent
 
         final UsageType usage = getEffectiveUsageInput(criteriaSet);
         
-        if (criteriaSet.contains(RoleDescriptorCriterion.class)) {
-            final RoleDescriptor roleDescriptor = criteriaSet.get(RoleDescriptorCriterion.class).getRole();
-            return resolveFromRoleDescriptor(criteriaSet, roleDescriptor, usage);
-        } else if (criteriaSet.contains(EntityIdCriterion.class) && criteriaSet.contains(EntityRoleCriterion.class)) {
+        final RoleDescriptorCriterion roleCrit =
+                criteriaSet != null ? criteriaSet.get(RoleDescriptorCriterion.class) : null;
+        if (roleCrit != null) {
+            return resolveFromRoleDescriptor(criteriaSet, roleCrit.getRole(), usage);
+        }
+        
+        final EntityIdCriterion entityIDCrit = criteriaSet != null ? criteriaSet.get(EntityIdCriterion.class) : null;
+        final EntityRoleCriterion entityRoleCrit =
+                criteriaSet != null ? criteriaSet.get(EntityRoleCriterion.class) : null;
+        
+        if (entityIDCrit != null && entityRoleCrit != null) {
             if (getRoleDescriptorResolver() == null) {
                 throw new ResolverException("EntityID and role input were supplied " 
                         + "but no RoleDescriptorResolver is configured");
             }
             
-            final String entityID = criteriaSet.get(EntityIdCriterion.class).getEntityId();
-            final QName role = criteriaSet.get(EntityRoleCriterion.class).getRole();
+            final String entityID = entityIDCrit.getEntityId();
+            final QName role = entityRoleCrit.getRole();
             
             String protocol = null;
-            final ProtocolCriterion protocolCriteria = criteriaSet.get(ProtocolCriterion.class);
+            final ProtocolCriterion protocolCriteria =
+                    criteriaSet != null ? criteriaSet.get(ProtocolCriterion.class) : null;
             if (protocolCriteria != null) {
                 protocol = protocolCriteria.getProtocol();
             }
@@ -247,8 +256,8 @@ public class MetadataCredentialResolver extends AbstractCriteriaFilteringCredent
      * @param criteriaSet the criteria set being processed
      * @return the effective usage value
      */
-    @Nonnull protected UsageType getEffectiveUsageInput(@Nonnull final CriteriaSet criteriaSet) {
-        final UsageCriterion usageCriteria = criteriaSet.get(UsageCriterion.class);
+    @Nonnull protected UsageType getEffectiveUsageInput(@Nullable final CriteriaSet criteriaSet) {
+        final UsageCriterion usageCriteria = criteriaSet != null ? criteriaSet.get(UsageCriterion.class) : null;
         if (usageCriteria != null) {
             return usageCriteria.getUsage();
         }
@@ -267,13 +276,13 @@ public class MetadataCredentialResolver extends AbstractCriteriaFilteringCredent
      * @throws ResolverException thrown if the key, certificate, or CRL information is represented in an unsupported
      *             format
      */
-    @Nonnull protected Collection<Credential> resolveFromRoleDescriptor(@Nonnull final CriteriaSet criteriaSet, 
+    @Nonnull protected Collection<Credential> resolveFromRoleDescriptor(@Nullable final CriteriaSet criteriaSet, 
             @Nonnull final RoleDescriptor roleDescriptor, @Nonnull final UsageType usage) throws ResolverException {
         
         // EntityID here is optional. Not used in resolution, just info stored on the resolved credential(s).
         String entityID = null;
-        if (roleDescriptor.getParent() instanceof EntityDescriptor) {
-            entityID = ((EntityDescriptor)roleDescriptor.getParent()).getEntityID();
+        if (roleDescriptor.getParent() instanceof EntityDescriptor entity) {
+            entityID = entity.getEntityID();
         }
         
         log.debug("Resolving credentials from supplied RoleDescriptor using usage: {}.  Effective entityID was: {}", 
@@ -299,7 +308,7 @@ public class MetadataCredentialResolver extends AbstractCriteriaFilteringCredent
      * @throws ResolverException thrown if the key, certificate, or CRL information is represented in an unsupported
      *             format
      */
-    @Nonnull protected Collection<Credential> resolveFromMetadata(@Nonnull final CriteriaSet criteriaSet, 
+    @Nonnull protected Collection<Credential> resolveFromMetadata(@Nullable final CriteriaSet criteriaSet, 
             @Nonnull @NotEmpty final String entityID, @Nonnull final QName role, 
             @Nullable final String protocol, @Nonnull final UsageType usage) throws ResolverException {
 
@@ -310,6 +319,7 @@ public class MetadataCredentialResolver extends AbstractCriteriaFilteringCredent
         final Iterable<RoleDescriptor> roleDescriptors = getRoleDescriptors(criteriaSet, entityID, role, protocol);
             
         for (final RoleDescriptor roleDescriptor : roleDescriptors) {
+            assert roleDescriptor != null;
             processRoleDescriptor(credentials, roleDescriptor, entityID, usage);
         }
 
@@ -403,7 +413,11 @@ public class MetadataCredentialResolver extends AbstractCriteriaFilteringCredent
                     mutableCred.setEntityId(entityID);
                     mutableCred.setUsageType(mdUsage);
                 }
-                cred.getCredentialContextSet().add(new SAMLMDCredentialContext(keyDescriptor));
+                
+                final CredentialContextSet contextSet = cred.getCredentialContextSet();
+                if (contextSet != null) {
+                    contextSet.add(new SAMLMDCredentialContext(keyDescriptor));
+                }
                 newCreds.add(cred);
             }
             
@@ -442,11 +456,12 @@ public class MetadataCredentialResolver extends AbstractCriteriaFilteringCredent
      * @throws ResolverException thrown if there is an error retrieving role descriptors 
      *          from the entityDescriptorResolver provider
      */
-    @Nonnull protected Iterable<RoleDescriptor> getRoleDescriptors(@Nonnull final CriteriaSet criteriaSet, 
+    @Nonnull protected Iterable<RoleDescriptor> getRoleDescriptors(@Nullable final CriteriaSet criteriaSet, 
             @Nonnull final String entityID, @Nonnull final QName role, 
             @Nullable final String protocol) throws ResolverException {
         
-        if (getRoleDescriptorResolver() == null) {
+        final RoleDescriptorResolver roleResolver = getRoleDescriptorResolver();
+        if (roleResolver == null) {
             throw new ResolverException("No RoleDescriptorResolver is configured");
         }
         
@@ -463,7 +478,7 @@ public class MetadataCredentialResolver extends AbstractCriteriaFilteringCredent
                 criteria.add(new ProtocolCriterion(protocol));
             }
             
-            return getRoleDescriptorResolver().resolve(criteria);
+            return roleResolver.resolve(criteria);
 
         } catch (final ResolverException e) {
             log.error("Unable to resolve information from metadata: {}", e.getMessage());
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/SAMLMDCredentialContext.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/SAMLMDCredentialContext.java
index fc4c1192f..87afa03cc 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/SAMLMDCredentialContext.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/SAMLMDCredentialContext.java
@@ -19,11 +19,17 @@ package org.opensaml.saml.security.impl;
 
 import java.util.List;
 
+import javax.annotation.Nullable;
+
 import org.opensaml.saml.saml2.metadata.EncryptionMethod;
 import org.opensaml.saml.saml2.metadata.KeyDescriptor;
 import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.opensaml.security.credential.CredentialContext;
 
+import net.shibboleth.shared.annotation.constraint.NotLive;
+import net.shibboleth.shared.annotation.constraint.Unmodifiable;
+import net.shibboleth.shared.collection.CollectionSupport;
+
 /**
  * A credential context for credentials resolved from a {@link org.opensaml.xmlsec.signature.KeyInfo} that was found in
  * SAML 2 metadata.
@@ -31,13 +37,13 @@ import org.opensaml.security.credential.CredentialContext;
 public class SAMLMDCredentialContext implements CredentialContext {
 
     /** Key descriptor which contained the KeyInfo used. */
-    private KeyDescriptor keyDescriptor;
+    @Nullable private KeyDescriptor keyDescriptor;
 
     /** Role in which credential was resolved. */
-    private RoleDescriptor role;
+    @Nullable private RoleDescriptor role;
 
     /** Encryption methods associated with the credential. */
-    private List<EncryptionMethod> encMethods;
+    @Nullable private List<EncryptionMethod> encMethods;
 
     /**
      * Constructor.
@@ -48,7 +54,7 @@ public class SAMLMDCredentialContext implements CredentialContext {
         keyDescriptor = descriptor;
         if (descriptor != null) {
             // KeyDescriptor / EncryptionMethod
-            encMethods = descriptor.getEncryptionMethods();
+            encMethods = CollectionSupport.copyToList(descriptor.getEncryptionMethods());
             // KeyDescriptor -> RoleDescriptor
             role = (RoleDescriptor) descriptor.getParent();
         }
@@ -59,7 +65,7 @@ public class SAMLMDCredentialContext implements CredentialContext {
      * 
      * @return key descriptor
      */
-    public KeyDescriptor getKeyDescriptor() {
+    @Nullable public KeyDescriptor getKeyDescriptor() {
         return keyDescriptor;
     }
 
@@ -68,7 +74,7 @@ public class SAMLMDCredentialContext implements CredentialContext {
      * 
      * @return a list of SAML metadata encryption method associated with this context
      */
-    public List<EncryptionMethod> getEncryptionMethods() {
+    @Nullable @NotLive @Unmodifiable public List<EncryptionMethod> getEncryptionMethods() {
         return encMethods;
     }
 
@@ -77,7 +83,7 @@ public class SAMLMDCredentialContext implements CredentialContext {
      * 
      * @return role descriptor
      */
-    public RoleDescriptor getRoleDescriptor() {
+    @Nullable public RoleDescriptor getRoleDescriptor() {
         return role;
     }
 
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/SAMLMetadataEncryptionParametersResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/SAMLMetadataEncryptionParametersResolver.java
index f0ae5a118..815887d15 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/SAMLMetadataEncryptionParametersResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/SAMLMetadataEncryptionParametersResolver.java
@@ -18,6 +18,7 @@
 package org.opensaml.saml.security.impl;
 
 import java.security.Key;
+import java.security.PublicKey;
 import java.util.Collections;
 import java.util.List;
 import java.util.Objects;
@@ -29,10 +30,11 @@ import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
 
 import net.shibboleth.shared.annotation.ParameterName;
-import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.collection.Pair;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.logic.PredicateSupport;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.primitive.StringSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
@@ -42,6 +44,7 @@ import org.opensaml.saml.saml2.metadata.EncryptionMethod;
 import org.opensaml.saml.security.SAMLMetadataKeyAgreementEncryptionConfiguration;
 import org.opensaml.saml.security.SAMLMetadataKeyAgreementEncryptionConfiguration.KeyWrap;
 import org.opensaml.security.credential.Credential;
+import org.opensaml.security.credential.CredentialContextSet;
 import org.opensaml.security.credential.CredentialSupport;
 import org.opensaml.security.credential.UsageType;
 import org.opensaml.security.criteria.UsageCriterion;
@@ -52,6 +55,7 @@ import org.opensaml.xmlsec.KeyTransportAlgorithmPredicate;
 import org.opensaml.xmlsec.agreement.KeyAgreementSupport;
 import org.opensaml.xmlsec.algorithm.AlgorithmSupport;
 import org.opensaml.xmlsec.criterion.EncryptionConfigurationCriterion;
+import org.opensaml.xmlsec.encryption.KeySize;
 import org.opensaml.xmlsec.encryption.MGF;
 import org.opensaml.xmlsec.encryption.OAEPparams;
 import org.opensaml.xmlsec.encryption.support.EncryptionConstants;
@@ -60,7 +64,6 @@ import org.opensaml.xmlsec.encryption.support.RSAOAEPParameters;
 import org.opensaml.xmlsec.impl.BasicEncryptionParametersResolver;
 import org.opensaml.xmlsec.signature.DigestMethod;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * A specialization of {@link BasicEncryptionParametersResolver} which resolves
@@ -189,6 +192,7 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
         // either, determined by both metadata and local configuration.
         try {
             for (final Credential credential : getMetadataCredentialResolver().resolve(mdCredResolverCriteria)) {
+                assert credential != null;
                 
                 if (log.isTraceEnabled()) {
                     final Key key = CredentialSupport.extractEncryptionKey(credential);
@@ -200,8 +204,9 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
                     return;
                 }
                 
+                final CredentialContextSet credContextSet = credential.getCredentialContextSet();
                 final SAMLMDCredentialContext metadataCredContext = 
-                        credential.getCredentialContextSet().get(SAMLMDCredentialContext.class);
+                        credContextSet != null ? credContextSet.get(SAMLMDCredentialContext.class) : null;
                 
                 final Pair<String,EncryptionMethod> dataEncryptionAlgorithmAndMethod = resolveDataEncryptionAlgorithm(
                         criteria, includeExcludePredicate, metadataCredContext);
@@ -210,9 +215,12 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
                         credential, criteria, includeExcludePredicate, 
                         dataEncryptionAlgorithmAndMethod.getFirst(), metadataCredContext);
                 if (keyTransportAlgorithmAndMethod.getFirst() == null) {
-                    log.debug("Unable to resolve key transport algorithm for credential with key type '{}', " 
-                            + "considering other credentials", 
-                            CredentialSupport.extractEncryptionKey(credential).getAlgorithm());
+                    if (log.isDebugEnabled()) {
+                        final Key key = CredentialSupport.extractEncryptionKey(credential); 
+                        log.debug("Unable to resolve key transport algorithm for credential with key type '{}', " 
+                                + "considering other credentials", 
+                                key != null ? key.getAlgorithm() : "n/a");
+                    }
                     continue;
                 }
                 
@@ -237,6 +245,7 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
         super.resolveAndPopulateCredentialsAndAlgorithms(params, criteria, includeExcludePredicate);
     }
     
+// Checkstyle: CyclomaticComplexity OFF
     /**
      * 
      * Check for a credential type that implies a key agreement operation, and process if so indicated.
@@ -262,8 +271,9 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
         final SAMLMetadataKeyAgreementEncryptionConfiguration config =
                 getEffectiveKeyAgreementConfiguration(criteria, credential);
         if (config == null) {
+            final PublicKey pkey = credential.getPublicKey();
             log.warn("Unable to get effective KeyAgreementEncryptionConfiguration for credential with key type: {}",
-                    credential.getPublicKey().getAlgorithm());
+                    pkey != null ? pkey.getAlgorithm() : "n/a");
             return false;
         }
         
@@ -273,25 +283,29 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
         final List<String> criteriaDataEncryptionAlgorithms = getEffectiveDataEncryptionAlgorithms(criteria, 
                 includeExcludePredicate);
         
+        final CredentialContextSet credContextSet = credential.getCredentialContextSet();
         final SAMLMDCredentialContext metadataCredContext = 
-                credential.getCredentialContextSet().get(SAMLMDCredentialContext.class);
+                credContextSet != null ? credContextSet.get(SAMLMDCredentialContext.class) : null;
         
         List<String> metadataKeyWrapAlgorithms = Collections.emptyList();
         List<String> metadataDataEncryptionAlgorithms = Collections.emptyList(); 
         if (metadataCredContext != null) {
-            final List<String> metadataAlgorithms = metadataCredContext.getEncryptionMethods().stream()
-                    .map(EncryptionMethod::getAlgorithm)
-                    .filter(Objects::nonNull)
-                    .filter(PredicateSupport.and(getAlgorithmRuntimeSupportedPredicate(), includeExcludePredicate))
-                    .collect(Collectors.toList());
-            
-            metadataKeyWrapAlgorithms = metadataAlgorithms.stream()
-                    .filter(AlgorithmSupport::isSymmetricKeyWrap)
-                    .collect(Collectors.toList());
-            
-            metadataDataEncryptionAlgorithms = metadataAlgorithms.stream()
-                    .filter(AlgorithmSupport::isBlockEncryption)
-                    .collect(Collectors.toList());
+            final List<EncryptionMethod> methods = metadataCredContext.getEncryptionMethods();
+            if (methods != null) {
+                final List<String> metadataAlgorithms = methods.stream()
+                        .map(EncryptionMethod::getAlgorithm)
+                        .filter(Objects::nonNull)
+                        .filter(PredicateSupport.and(getAlgorithmRuntimeSupportedPredicate(), includeExcludePredicate))
+                        .collect(Collectors.toList());
+                
+                metadataKeyWrapAlgorithms = metadataAlgorithms.stream()
+                        .filter(AlgorithmSupport::isSymmetricKeyWrap)
+                        .collect(Collectors.toList());
+                
+                metadataDataEncryptionAlgorithms = metadataAlgorithms.stream()
+                        .filter(AlgorithmSupport::isBlockEncryption)
+                        .collect(Collectors.toList());
+            }
         }
         
         log.debug("Evaling useKeyWrap: # key wrap algos '{}', # direct data algos '{}', config '{}'",
@@ -311,8 +325,9 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
         return checkAndProcessKeyAgreement(params, criteria, credential,
                 concatLists(metadataDataEncryptionAlgorithms, criteriaDataEncryptionAlgorithms),
                 useKeyWrap ? concatLists(metadataKeyWrapAlgorithms, criteriaKeyTransportAlgorithms)
-                        : Collections.emptyList());
+                        : CollectionSupport.emptyList());
     }
+// Checkstyle: CyclomaticComplexity ON
     
     /**
      * Get the effective {@link SAMLMetadataKeyAgreementEncryptionConfiguration} to use with the specified credential.
@@ -336,10 +351,21 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
         config.setAlgorithm(baseConfig.getAlgorithm());
         config.setParameters(baseConfig.getParameters());
         
-        final String keyType = credential.getPublicKey().getAlgorithm();
+        final PublicKey pkey = credential.getPublicKey();
+        if (pkey == null) {
+            log.warn("Key agreement public key was null");
+            return null;
+        }
+        final String keyType = pkey.getAlgorithm();
+        
+        final EncryptionConfigurationCriterion encryptionConfigCriterion =
+                criteria.get(EncryptionConfigurationCriterion.class);
+        if (encryptionConfigCriterion == null) {
+            log.warn("EncryptionConfigurationCriterion was absent");
+            return null;
+        }
         
-        final List<EncryptionConfiguration> encConfigs = criteria.get(EncryptionConfigurationCriterion.class)
-                .getConfigurations();
+        final List<EncryptionConfiguration> encConfigs = encryptionConfigCriterion.getConfigurations();
         
         config.setMetadataUseKeyWrap(
                 encConfigs.stream()
@@ -364,7 +390,7 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
      * @return the concatenation of the supplied lists
      */
     @SafeVarargs
-    private List<String> concatLists(@Nonnull final List<String> ... lists) {
+    @Nonnull private List<String> concatLists(@Nonnull final List<String> ... lists) {
         return Stream.of(lists)
                 .filter(Objects::nonNull)
                 .flatMap(x -> x.stream())
@@ -397,7 +423,8 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
              @Nonnull final Predicate<String> includeExcludePredicate, 
              @Nullable final EncryptionMethod encryptionMethod) {
          
-         if (!AlgorithmSupport.isRSAOAEP(params.getKeyTransportEncryptionAlgorithm())) {
+         final String alg = params.getKeyTransportEncryptionAlgorithm();
+         if (alg == null || !AlgorithmSupport.isRSAOAEP(alg)) {
              return;
          }
          
@@ -406,16 +433,17 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
              return;
          }
          
-         if (params.getRSAOAEPParameters() == null) {
-             params.setRSAOAEPParameters(new RSAOAEPParameters());
+         RSAOAEPParameters oaepParams = params.getRSAOAEPParameters();
+         if (oaepParams == null) {
+             oaepParams = new RSAOAEPParameters();
+             params.setRSAOAEPParameters(oaepParams);
          }
          
-         populateRSAOAEPParamsFromEncryptionMethod(params.getRSAOAEPParameters(), encryptionMethod, 
-                 includeExcludePredicate);
+         populateRSAOAEPParamsFromEncryptionMethod(oaepParams, encryptionMethod, includeExcludePredicate);
         
-         if (params.getRSAOAEPParameters().isComplete()) {
+         if (oaepParams.isComplete()) {
              return;
-         } else if (params.getRSAOAEPParameters().isEmpty()) {
+         } else if (oaepParams.isEmpty()) {
              super.resolveAndPopulateRSAOAEPParams(params, criteria, includeExcludePredicate);
          } else {
              if (isMergeMetadataRSAOAEPParametersWithConfig()) {
@@ -423,7 +451,7 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
              }
          }
     }
-    //CheckStyle: ReturnCount ON
+//CheckStyle: ReturnCount ON
 
     /**
      * Extract {@link DigestMethod}, {@link MGF} and {@link OAEPparams} data present on the supplied
@@ -440,7 +468,7 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
      * @param includeExcludePredicate the include/exclude predicate with which to evaluate the 
      *          candidate data encryption and key transport algorithm URIs
      */
-     // Checkstyle: CyclomaticComplexity OFF -- more readable not split up
+// Checkstyle: CyclomaticComplexity OFF -- more readable not split up
     protected void populateRSAOAEPParamsFromEncryptionMethod(@Nonnull final RSAOAEPParameters params, 
             @Nonnull final EncryptionMethod encryptionMethod, 
             @Nonnull final Predicate<String> includeExcludePredicate) {
@@ -477,7 +505,6 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
         }
         
     }
-    // Checkstyle:CyclomaticComplexity ON
 
     /**
      * Determine the key transport algorithm URI to use with the specified credential, also returning the associated
@@ -505,27 +532,31 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
         if (metadataCredContext != null) {
             final KeyTransportAlgorithmPredicate keyTransportPredicate =
                         resolveKeyTransportAlgorithmPredicate(criteria);
-            for (final EncryptionMethod encryptionMethod : metadataCredContext.getEncryptionMethods()) {
-                final String algorithm = encryptionMethod.getAlgorithm();
-                log.trace("Evaluating SAML metadata EncryptionMethod algorithm for key transport: {}", algorithm);
-                if (isKeyTransportAlgorithm(algorithm) 
-                        && includeExcludePredicate.test(algorithm) 
-                        && getAlgorithmRuntimeSupportedPredicate().test(algorithm)
-                        && credentialSupportsEncryptionMethod(keyTransportCredential, encryptionMethod)
-                        && evaluateEncryptionMethodChildren(encryptionMethod, criteria, includeExcludePredicate)) {
-                    
-                    boolean accepted = true;
-                    if (keyTransportPredicate != null) {
-                        accepted = keyTransportPredicate.test(new KeyTransportAlgorithmPredicate.SelectionInput(
-                                algorithm, dataEncryptionAlgorithm, keyTransportCredential));
-                    }
-                    
-                    if (accepted) {
-                        log.debug("Resolved key transport algorithm URI from SAML metadata EncryptionMethod: {}",
-                                algorithm);
-                        return new Pair<>(algorithm, encryptionMethod);
+            final List<EncryptionMethod> methods = metadataCredContext.getEncryptionMethods();
+            if (methods != null) {
+                for (final EncryptionMethod encryptionMethod : methods) {
+                    final String algorithm = encryptionMethod.getAlgorithm();
+                    log.trace("Evaluating SAML metadata EncryptionMethod algorithm for key transport: {}", algorithm);
+                    if (algorithm != null
+                            && isKeyTransportAlgorithm(algorithm) 
+                            && includeExcludePredicate.test(algorithm) 
+                            && getAlgorithmRuntimeSupportedPredicate().test(algorithm)
+                            && credentialSupportsEncryptionMethod(keyTransportCredential, encryptionMethod)
+                            && evaluateEncryptionMethodChildren(encryptionMethod, criteria, includeExcludePredicate)) {
+                        
+                        boolean accepted = true;
+                        if (keyTransportPredicate != null) {
+                            accepted = keyTransportPredicate.test(new KeyTransportAlgorithmPredicate.SelectionInput(
+                                    algorithm, dataEncryptionAlgorithm, keyTransportCredential));
+                        }
+                        
+                        if (accepted) {
+                            log.debug("Resolved key transport algorithm URI from SAML metadata EncryptionMethod: {}",
+                                    algorithm);
+                            return new Pair<>(algorithm, encryptionMethod);
+                        }
+                        
                     }
-                    
                 }
             }
         }
@@ -538,6 +569,7 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
                         dataEncryptionAlgorithm),
                 null);
     }
+// Checkstyle:CyclomaticComplexity ON
 
     /**
      * Determine the data encryption algorithm URI to use, also returning the associated
@@ -560,16 +592,19 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
             @Nullable final SAMLMDCredentialContext metadataCredContext) {
         
         if (metadataCredContext != null) {
-            for (final EncryptionMethod encryptionMethod : metadataCredContext.getEncryptionMethods()) {
-                final String algorithm = encryptionMethod.getAlgorithm();
-                log.trace("Evaluating SAML metadata EncryptionMethod algorithm for data encryption: {}", algorithm);
-                if (isDataEncryptionAlgorithm(algorithm) 
-                        && includeExcludePredicate.test(algorithm)
-                        && getAlgorithmRuntimeSupportedPredicate().test(algorithm)
-                        && evaluateEncryptionMethodChildren(encryptionMethod, criteria, includeExcludePredicate)) {
-                    log.debug("Resolved data encryption algorithm URI from SAML metadata EncryptionMethod: {}",
-                            algorithm);
-                    return new Pair<>(algorithm, encryptionMethod);
+            final List<EncryptionMethod> methods = metadataCredContext.getEncryptionMethods();
+            if (methods != null) {
+                for (final EncryptionMethod encryptionMethod : methods) {
+                    final String algorithm = encryptionMethod.getAlgorithm();
+                    log.trace("Evaluating SAML metadata EncryptionMethod algorithm for data encryption: {}", algorithm);
+                    if (isDataEncryptionAlgorithm(algorithm) 
+                            && includeExcludePredicate.test(algorithm)
+                            && getAlgorithmRuntimeSupportedPredicate().test(algorithm)
+                            && evaluateEncryptionMethodChildren(encryptionMethod, criteria, includeExcludePredicate)) {
+                        log.debug("Resolved data encryption algorithm URI from SAML metadata EncryptionMethod: {}",
+                                algorithm);
+                        return new Pair<>(algorithm, encryptionMethod);
+                    }
                 }
             }
         }
@@ -596,7 +631,12 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
     protected boolean evaluateEncryptionMethodChildren(@Nonnull final EncryptionMethod encryptionMethod, 
             @Nonnull final CriteriaSet criteria, @Nonnull final Predicate<String> includeExcludePredicate) {
         
-        switch(encryptionMethod.getAlgorithm()) {
+        final String alg = encryptionMethod.getAlgorithm();
+        if (alg == null) {
+            return false;
+        }
+        
+        switch(alg) {
             
             case EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP:
             case EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP11:
@@ -663,12 +703,15 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
      * @return true if credential may be used with the supplied encryption method, false otherwise
      */
     protected boolean credentialSupportsEncryptionMethod(@Nonnull final Credential credential, 
-            @Nonnull @NotEmpty final EncryptionMethod encryptionMethod) {
-        if (!credentialSupportsAlgorithm(credential, encryptionMethod.getAlgorithm())) {
+            @Nonnull final EncryptionMethod encryptionMethod) {
+        
+        final String alg = encryptionMethod.getAlgorithm();
+        if (alg == null || !credentialSupportsAlgorithm(credential, alg)) {
             return false;
         }
         
-        if (encryptionMethod.getKeySize() != null && encryptionMethod.getKeySize().getValue() != null) {
+        final KeySize keySize = encryptionMethod.getKeySize(); 
+        if (keySize != null && keySize.getValue() != null) {
             final Key encryptionKey = CredentialSupport.extractEncryptionKey(credential);
             if (encryptionKey == null) {
                 log.warn("Could not extract encryption key from credential. Failing evaluation");
@@ -681,7 +724,7 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
                 return false;
             }
         
-            if (! keyLength.equals(encryptionMethod.getKeySize().getValue())) {
+            if (!keyLength.equals(keySize.getValue())) {
                 return false;
             }
         }
@@ -691,4 +734,4 @@ public class SAMLMetadataEncryptionParametersResolver extends BasicEncryptionPar
         return true;
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/SAMLMetadataSignatureSigningParametersResolver.java b/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/SAMLMetadataSignatureSigningParametersResolver.java
index de0b98676..868b4787c 100644
--- a/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/SAMLMetadataSignatureSigningParametersResolver.java
+++ b/opensaml-saml-impl/src/main/java/org/opensaml/saml/security/impl/SAMLMetadataSignatureSigningParametersResolver.java
@@ -26,6 +26,7 @@ import javax.annotation.Nullable;
 import javax.xml.namespace.QName;
 
 import net.shibboleth.shared.annotation.constraint.NotEmpty;
+import net.shibboleth.shared.primitive.LoggerFactory;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 import org.opensaml.core.xml.XMLObject;
@@ -41,7 +42,6 @@ import org.opensaml.security.crypto.KeySupport;
 import org.opensaml.xmlsec.SignatureSigningParameters;
 import org.opensaml.xmlsec.impl.BasicSignatureSigningParametersResolver;
 import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * A specialization of {@link BasicSignatureSigningParametersResolver} which also supports input of SAML metadata, 
@@ -66,13 +66,13 @@ public class SAMLMetadataSignatureSigningParametersResolver extends BasicSignatu
     protected void resolveAndPopulateCredentialAndSignatureAlgorithm(@Nonnull final SignatureSigningParameters params, 
             @Nonnull final CriteriaSet criteria, @Nonnull final Predicate<String> includeExcludePredicate) {
         
-        if (!criteria.contains(RoleDescriptorCriterion.class)) {
+        final RoleDescriptorCriterion roleCrit = criteria.get(RoleDescriptorCriterion.class);
+        if (roleCrit == null) {
             super.resolveAndPopulateCredentialAndSignatureAlgorithm(params, criteria, includeExcludePredicate);
             return;
         }
         
-        final List<XMLObject> signingMethods = getExtensions(criteria.get(RoleDescriptorCriterion.class).getRole(),
-                SigningMethod.DEFAULT_ELEMENT_NAME);
+        final List<XMLObject> signingMethods = getExtensions(roleCrit.getRole(), SigningMethod.DEFAULT_ELEMENT_NAME);
         
         if (signingMethods == null || signingMethods.isEmpty()) {
             super.resolveAndPopulateCredentialAndSignatureAlgorithm(params, criteria, includeExcludePredicate);
@@ -94,12 +94,13 @@ public class SAMLMetadataSignatureSigningParametersResolver extends BasicSignatu
             }
             
             for (final Credential credential : credentials) {
+                assert credential != null;
                 
                 if (log.isTraceEnabled()) {
                     final Key key = CredentialSupport.extractSigningKey(credential);
                     log.trace("Evaluating credential of type: {}, with length: {}", 
                             key != null ? key.getAlgorithm() : "n/a",
-                            KeySupport.getKeyLength(key));
+                            key != null ? KeySupport.getKeyLength(key) : "n/a");
                 }
                 
                 if (credentialSupportsSigningMethod(credential, signingMethod)) {
@@ -119,7 +120,6 @@ public class SAMLMetadataSignatureSigningParametersResolver extends BasicSignatu
         
         super.resolveAndPopulateCredentialAndSignatureAlgorithm(params, criteria, includeExcludePredicate);
     }
-// Checkstyle: ReturnCount|CyclomaticComplexity ON
 
     /**
      * Evaluate whether the specified credential is supported for use with the specified {@link SigningMethod}.
@@ -130,11 +130,16 @@ public class SAMLMetadataSignatureSigningParametersResolver extends BasicSignatu
      */
     protected boolean credentialSupportsSigningMethod(@Nonnull final Credential credential, 
             @Nonnull @NotEmpty final SigningMethod signingMethod) {
-        if (!credentialSupportsAlgorithm(credential, signingMethod.getAlgorithm())) {
+        
+        final String signAlg = signingMethod.getAlgorithm();
+        if (signAlg == null || !credentialSupportsAlgorithm(credential, signAlg)) {
             return false;
         }
         
-        if (signingMethod.getMinKeySize() != null  || signingMethod.getMaxKeySize() != null) {
+        final Integer minSize = signingMethod.getMinKeySize();
+        final Integer maxSize = signingMethod.getMaxKeySize();
+        
+        if (minSize != null  || maxSize != null) {
             final Key signingKey = CredentialSupport.extractSigningKey(credential);
             if (signingKey == null) {
                 log.warn("Could not extract signing key from credential. Failing evaluation");
@@ -147,12 +152,12 @@ public class SAMLMetadataSignatureSigningParametersResolver extends BasicSignatu
                 return false;
             }
             
-            if (signingMethod.getMinKeySize() != null && keyLength < signingMethod.getMinKeySize()) {
+            if (minSize != null && keyLength < minSize) {
                 log.trace("Candidate signing credential does not meet minKeySize requirement");
                 return false;
             }
             
-            if (signingMethod.getMaxKeySize() != null && keyLength > signingMethod.getMaxKeySize()) {
+            if (maxSize != null && keyLength > maxSize) {
                 log.trace("Candidate signing credential does not meet maxKeySize requirement");
                 return false;
             }
@@ -160,17 +165,20 @@ public class SAMLMetadataSignatureSigningParametersResolver extends BasicSignatu
         
         return true;
     }
+// Checkstyle: ReturnCount|CyclomaticComplexity ON
 
     /** {@inheritDoc} */
     @Override
     @Nullable protected String resolveReferenceDigestMethod(@Nonnull final CriteriaSet criteria, 
             @Nonnull final Predicate<String> includeExcludePredicate) {
-        if (!criteria.contains(RoleDescriptorCriterion.class)) {
+        
+        final RoleDescriptorCriterion roleCrit = criteria.get(RoleDescriptorCriterion.class);
+        
+        if (roleCrit == null) {
             return super.resolveReferenceDigestMethod(criteria, includeExcludePredicate);
         }
         
-        final List<XMLObject> digestMethods = getExtensions(criteria.get(RoleDescriptorCriterion.class).getRole(),
-                DigestMethod.DEFAULT_ELEMENT_NAME);
+        final List<XMLObject> digestMethods = getExtensions(roleCrit.getRole(), DigestMethod.DEFAULT_ELEMENT_NAME);
         
         if (digestMethods == null || digestMethods.isEmpty()) {
             return super.resolveReferenceDigestMethod(criteria, includeExcludePredicate);
@@ -218,8 +226,8 @@ public class SAMLMetadataSignatureSigningParametersResolver extends BasicSignatu
             }
         }
         
-        if (roleDescriptor.getParent() instanceof EntityDescriptor) {
-            extensions = ((EntityDescriptor)roleDescriptor.getParent()).getExtensions();
+        if (roleDescriptor.getParent() instanceof EntityDescriptor entity) {
+            extensions = entity.getExtensions();
             if (extensions != null) {
                 result = extensions.getUnknownXMLObjects(extensionName);
                 if (!result.isEmpty()) {
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/messaging/context/tests/SAMLMessageInfoContextTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/messaging/context/tests/SAMLMessageInfoContextTest.java
index 5f15c6cf4..e143c40b3 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/messaging/context/tests/SAMLMessageInfoContextTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/messaging/context/tests/SAMLMessageInfoContextTest.java
@@ -35,6 +35,7 @@ import org.testng.annotations.Test;
  * Note: this test appears in the -impl module rather than the -api module because
  * we need to build actual SAMLObject instances. Can't have circular dependencies in Maven.
  */
+ at SuppressWarnings("javadoc")
 public class SAMLMessageInfoContextTest extends XMLObjectBaseTestCase {
     
     private String id;
@@ -57,7 +58,7 @@ public class SAMLMessageInfoContextTest extends XMLObjectBaseTestCase {
     @Test
     public void testNonMessageContextParent() {
         TestContext testContext = new TestContext();
-        SAMLMessageInfoContext infoContext =  testContext.getSubcontext(SAMLMessageInfoContext.class, true);
+        final SAMLMessageInfoContext infoContext =  testContext.ensureSubcontext(SAMLMessageInfoContext.class);
         Assert.assertNull(infoContext.getMessageId());
         Assert.assertNull(infoContext.getMessageIssueInstant());
         
@@ -67,7 +68,7 @@ public class SAMLMessageInfoContextTest extends XMLObjectBaseTestCase {
     public void testNonSAMLMessage() {
         final MessageContext messageContext = new MessageContext();
         messageContext.setMessage(new Object());
-        final SAMLMessageInfoContext infoContext =  messageContext.getSubcontext(SAMLMessageInfoContext.class, true);
+        final SAMLMessageInfoContext infoContext =  messageContext.ensureSubcontext(SAMLMessageInfoContext.class);
         Assert.assertNull(infoContext.getMessageId());
         Assert.assertNull(infoContext.getMessageIssueInstant());
     }
@@ -79,7 +80,7 @@ public class SAMLMessageInfoContextTest extends XMLObjectBaseTestCase {
         message.setID(id);
         message.setIssueInstant(issueInstant);
         messageContext.setMessage(message);
-        final SAMLMessageInfoContext infoContext =  messageContext.getSubcontext(SAMLMessageInfoContext.class, true);
+        final SAMLMessageInfoContext infoContext =  messageContext.ensureSubcontext(SAMLMessageInfoContext.class);
         Assert.assertEquals(infoContext.getMessageId(), id);
         Assert.assertEquals(infoContext.getMessageIssueInstant(), issueInstant);
     }
@@ -91,7 +92,7 @@ public class SAMLMessageInfoContextTest extends XMLObjectBaseTestCase {
         message.setID(id);
         message.setIssueInstant(issueInstant);
         messageContext.setMessage(message);
-        final SAMLMessageInfoContext infoContext =  messageContext.getSubcontext(SAMLMessageInfoContext.class, true);
+        final SAMLMessageInfoContext infoContext =  messageContext.ensureSubcontext(SAMLMessageInfoContext.class);
         Assert.assertEquals(infoContext.getMessageId(), id);
         Assert.assertEquals(infoContext.getMessageIssueInstant(), issueInstant);
     }
@@ -103,7 +104,7 @@ public class SAMLMessageInfoContextTest extends XMLObjectBaseTestCase {
         message.setID(id);
         message.setIssueInstant(issueInstant);
         messageContext.setMessage(message);
-        final SAMLMessageInfoContext infoContext =  messageContext.getSubcontext(SAMLMessageInfoContext.class, true);
+        final SAMLMessageInfoContext infoContext =  messageContext.ensureSubcontext(SAMLMessageInfoContext.class);
         Assert.assertEquals(infoContext.getMessageId(), id);
         Assert.assertEquals(infoContext.getMessageIssueInstant(), issueInstant);
     }
@@ -115,7 +116,7 @@ public class SAMLMessageInfoContextTest extends XMLObjectBaseTestCase {
         message.setID(id);
         message.setIssueInstant(issueInstant);
         messageContext.setMessage(message);
-        final SAMLMessageInfoContext infoContext =  messageContext.getSubcontext(SAMLMessageInfoContext.class, true);
+        final SAMLMessageInfoContext infoContext =  messageContext.ensureSubcontext(SAMLMessageInfoContext.class);
         Assert.assertEquals(infoContext.getMessageId(), id);
         Assert.assertEquals(infoContext.getMessageIssueInstant(), issueInstant);
     }
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/testing/SAMLTestSupport.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/testing/SAMLTestSupport.java
index 7814c9202..0a611bd31 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/testing/SAMLTestSupport.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/common/testing/SAMLTestSupport.java
@@ -20,6 +20,8 @@ package org.opensaml.saml.common.testing;
 import java.util.ArrayList;
 import java.util.List;
 
+import javax.annotation.Nonnull;
+
 import org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver;
 import org.opensaml.xmlsec.keyinfo.impl.BasicProviderKeyInfoCredentialResolver;
 import org.opensaml.xmlsec.keyinfo.impl.KeyInfoProvider;
@@ -43,11 +45,11 @@ public final class SAMLTestSupport {
      * 
      * @return a new KeyInfoCredentialResolver instance
      */
-    public static KeyInfoCredentialResolver buildBasicInlineKeyInfoResolver() {
+    @Nonnull public static KeyInfoCredentialResolver buildBasicInlineKeyInfoResolver() {
         return new BasicProviderKeyInfoCredentialResolver(getBasicInlineKeyInfoProviders());
     }
     
-    public static List<KeyInfoProvider> getBasicInlineKeyInfoProviders() {
+    @Nonnull public static List<KeyInfoProvider> getBasicInlineKeyInfoProviders() {
         List<KeyInfoProvider> providers = new ArrayList<>();
         providers.add( new RSAKeyValueProvider() );
         providers.add( new DSAKeyValueProvider() );
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/ext/idpdisco/impl/DiscoveryResponseTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/ext/idpdisco/impl/DiscoveryResponseTest.java
index 490f9495b..532a6b334 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/ext/idpdisco/impl/DiscoveryResponseTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/ext/idpdisco/impl/DiscoveryResponseTest.java
@@ -59,8 +59,8 @@ public class DiscoveryResponseTest extends XMLObjectProviderBaseTestCase {
     /** {@inheritDoc} */
     @Test
     public void testSingleElementUnmarshall() {
-        DiscoveryResponse service = (DiscoveryResponse) unmarshallElement(singleElementFile);
-
+        final DiscoveryResponse service = (DiscoveryResponse) unmarshallElement(singleElementFile);
+        assert service != null;
         Assert.assertEquals(service.getBinding(), expectedBinding, "Binding URI was not expected value");
         Assert.assertEquals(service.getLocation(), expectedLocation, "Location was not expected value");
         Assert.assertEquals(service.getIndex(), expectedIndex, "Index was not expected value");
@@ -69,8 +69,8 @@ public class DiscoveryResponseTest extends XMLObjectProviderBaseTestCase {
     /** {@inheritDoc} */
     @Test
     public void testSingleElementOptionalAttributesUnmarshall() {
-        DiscoveryResponse service = (DiscoveryResponse) unmarshallElement(singleElementOptionalAttributesFile);
-
+        final DiscoveryResponse service = (DiscoveryResponse) unmarshallElement(singleElementOptionalAttributesFile);
+        assert service != null;
         Assert.assertEquals(service.getBinding(), expectedBinding, "Binding URI was not expected value");
         Assert.assertEquals(service.getLocation(), expectedLocation, "Location was not expected value");
         Assert.assertEquals(service.getIndex(), expectedIndex, "Index was not expected value");
@@ -81,7 +81,7 @@ public class DiscoveryResponseTest extends XMLObjectProviderBaseTestCase {
     /** {@inheritDoc} */
     @Test
     public void testSingleElementMarshall() {
-        DiscoveryResponse service = (DiscoveryResponse) buildXMLObject(DiscoveryResponse.DEFAULT_ELEMENT_NAME);
+        final DiscoveryResponse service = (DiscoveryResponse) buildXMLObject(DiscoveryResponse.DEFAULT_ELEMENT_NAME);
 
         service.setBinding(expectedBinding);
         service.setLocation(expectedLocation);
@@ -93,7 +93,7 @@ public class DiscoveryResponseTest extends XMLObjectProviderBaseTestCase {
     /** {@inheritDoc} */
     @Test
     public void testSingleElementOptionalAttributesMarshall() {
-        DiscoveryResponse service = (DiscoveryResponse) buildXMLObject(DiscoveryResponse.DEFAULT_ELEMENT_NAME);
+        final DiscoveryResponse service = (DiscoveryResponse) buildXMLObject(DiscoveryResponse.DEFAULT_ELEMENT_NAME);
 
         service.setBinding(expectedBinding);
         service.setLocation(expectedLocation);
@@ -109,7 +109,7 @@ public class DiscoveryResponseTest extends XMLObjectProviderBaseTestCase {
      */
     @Test
     public void testXSBooleanAttributes() {
-        DiscoveryResponse acs = (DiscoveryResponse) buildXMLObject(DiscoveryResponse.DEFAULT_ELEMENT_NAME);
+        final DiscoveryResponse acs = (DiscoveryResponse) buildXMLObject(DiscoveryResponse.DEFAULT_ELEMENT_NAME);
 
         // isDefault attribute
         acs.setIsDefault(Boolean.TRUE);
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilterTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilterTest.java
index e54e91cd2..0f90c2a69 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilterTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/AlgorithmFilterTest.java
@@ -22,11 +22,11 @@ import static org.testng.Assert.*;
 import java.io.File;
 import java.net.URL;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
 import java.util.function.Predicate;
 
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
@@ -49,6 +49,7 @@ import org.opensaml.xmlsec.signature.support.SignatureConstants;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+ at SuppressWarnings("javadoc")
 public class AlgorithmFilterTest extends XMLObjectBaseTestCase implements Predicate<EntityDescriptor> {
     
     private FilesystemMetadataResolver metadataProvider;
@@ -108,7 +109,7 @@ public class AlgorithmFilterTest extends XMLObjectBaseTestCase implements Predic
         final Collection<XMLObject> algs = List.of(digest1, digest2, signing1, signing2, enc1, digest3, signing3, enc2, enc3);
         
         final AlgorithmFilter filter = new AlgorithmFilter();
-        filter.setRules(Collections.singletonMap(this, algs));
+        filter.setRules(CollectionSupport.singletonMap(this, algs));
         filter.initialize();
         
         metadataProvider.setMetadataFilter(filter);
@@ -117,9 +118,9 @@ public class AlgorithmFilterTest extends XMLObjectBaseTestCase implements Predic
 
         EntityIdCriterion crit = new EntityIdCriterion("https://foo.example.org/sp");
         EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(crit));
-        assertNotNull(entity);
+        assert entity != null;
         final Extensions exts = entity.getExtensions();
-        assertNotNull(exts);
+        assert exts != null;
         
         List<XMLObject> extElements = exts.getUnknownXMLObjects(DigestMethod.DEFAULT_ELEMENT_NAME);
         assertEquals(extElements.size(), 3);
@@ -160,7 +161,7 @@ public class AlgorithmFilterTest extends XMLObjectBaseTestCase implements Predic
 
     /** {@inheritDoc} */
     public boolean test(final EntityDescriptor input) {
-        return input.getEntityID().equals("https://foo.example.org/sp");
+        return input != null && "https://foo.example.org/sp".equals(input.getEntityID());
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/BasicDynamicTrustedNamesStrategyTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/BasicDynamicTrustedNamesStrategyTest.java
index 90f2dd8dc..a4988161e 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/BasicDynamicTrustedNamesStrategyTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/BasicDynamicTrustedNamesStrategyTest.java
@@ -28,6 +28,7 @@ import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+ at SuppressWarnings("javadoc")
 public class BasicDynamicTrustedNamesStrategyTest extends XMLObjectBaseTestCase {
     
     private BasicDynamicTrustedNamesStrategy strategy = new BasicDynamicTrustedNamesStrategy();
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/ByReferenceMetadataFilterTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/ByReferenceMetadataFilterTest.java
index 05e639697..8f1dc26a5 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/ByReferenceMetadataFilterTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/ByReferenceMetadataFilterTest.java
@@ -22,8 +22,6 @@ import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Arrays;
 import java.util.Collection;
-import java.util.Collections;
-import java.util.List;
 import java.util.function.Predicate;
 
 import org.opensaml.core.criterion.EntityIdCriterion;
@@ -33,15 +31,18 @@ import org.opensaml.saml.metadata.resolver.MetadataResolver;
 import org.opensaml.saml.metadata.resolver.impl.FilesystemMetadataResolver;
 import org.opensaml.saml.saml2.core.NameIDType;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 
 /** Unit test for {@link ByReferenceMetadataFilter}. */
+ at SuppressWarnings("javadoc")
 public class ByReferenceMetadataFilterTest extends XMLObjectBaseTestCase implements Predicate<EntityDescriptor> {
     
     protected MetadataResolver resolver;
@@ -75,10 +76,10 @@ public class ByReferenceMetadataFilterTest extends XMLObjectBaseTestCase impleme
     @Test
     public void notApplicable() throws ComponentInitializationException, ResolverException {
         
-        nameIDFilter.setRules(Collections.<Predicate<EntityDescriptor>,Collection<String>>singletonMap(this, formats));
+        nameIDFilter.setRules(CollectionSupport.singletonMap(this, formats));
         nameIDFilter.initialize();
         
-        refFilter.setFilterMappings(Collections.singletonMap("Foo", nameIDFilter));
+        refFilter.setFilterMappings(CollectionSupport.singletonMap("Foo", nameIDFilter));
         
         metadataProvider.initialize();
         
@@ -88,10 +89,10 @@ public class ByReferenceMetadataFilterTest extends XMLObjectBaseTestCase impleme
     @Test
     public void applicable() throws ComponentInitializationException, ResolverException {
         
-        nameIDFilter.setRules(Collections.<Predicate<EntityDescriptor>,Collection<String>>singletonMap(this, formats));
+        nameIDFilter.setRules(CollectionSupport.singletonMap(this, formats));
         nameIDFilter.initialize();
         
-        refFilter.setFilterMappings(Collections.singletonMap(List.of("ICMD", "Foo"), nameIDFilter));
+        refFilter.setFilterMappings(CollectionSupport.singletonMap(CollectionSupport.listOf("ICMD", "Foo"), nameIDFilter));
         
         metadataProvider.initialize();
         
@@ -108,17 +109,21 @@ public class ByReferenceMetadataFilterTest extends XMLObjectBaseTestCase impleme
     private void validate(final boolean applied) throws ResolverException {
         EntityIdCriterion key = new EntityIdCriterion("https://carmenwiki.osu.edu/shibboleth");
         EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(key));
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS).getNameIDFormats().size(), applied ? 3 : 1);
+        assert entity != null;
+        SPSSODescriptor role = entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+        assert role != null;
+        Assert.assertEquals(role.getNameIDFormats().size(), applied ? 3 : 1);
         
         key = new EntityIdCriterion("https://cms.psu.edu/Shibboleth");
         entity = metadataProvider.resolveSingle(new CriteriaSet(key));
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(entity.getSPSSODescriptor(SAMLConstants.SAML11P_NS).getNameIDFormats().size(), 1);
+        assert entity != null;
+        role = entity.getSPSSODescriptor(SAMLConstants.SAML11P_NS);
+        assert role != null;
+        Assert.assertEquals(role.getNameIDFormats().size(), 1);
     }
     
     /** {@inheritDoc} */
     public boolean test(EntityDescriptor input) {
-        return input.getEntityID().equals("https://carmenwiki.osu.edu/shibboleth");
+        return "https://carmenwiki.osu.edu/shibboleth".equals(input.getEntityID());
     }
 }
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 d53c474a6..9c92cb7d8 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
@@ -78,23 +78,27 @@ public class EntitiesDescriptorNameProcessorTest extends XMLObjectBaseTestCase {
         List<EntityGroupName> groups = null;
         
         entityDescriptor = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion("https://idp-top.example.org")));
+        assert entityDescriptor != null;
         groups = entityDescriptor.getObjectMetadata().get(EntityGroupName.class);
         Assert.assertEquals(groups.size(), 1);
         Assert.assertTrue(groups.contains(groupTop));
         
         entityDescriptor = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion("https://idp-sub1.example.org")));
+        assert entityDescriptor != null;
         groups = entityDescriptor.getObjectMetadata().get(EntityGroupName.class);
         Assert.assertEquals(groups.size(), 2);
         Assert.assertTrue(groups.contains(groupTop));
         Assert.assertTrue(groups.contains(groupSub1));
         
         entityDescriptor = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion("https://idp-sub2.example.org")));
+        assert entityDescriptor != null;
         groups = entityDescriptor.getObjectMetadata().get(EntityGroupName.class);
         Assert.assertEquals(groups.size(), 2);
         Assert.assertTrue(groups.contains(groupTop));
         Assert.assertTrue(groups.contains(groupSub2));
         
         entityDescriptor = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion("https://idp-sub2a.example.org")));
+        assert entityDescriptor != null;
         groups = entityDescriptor.getObjectMetadata().get(EntityGroupName.class);
         Assert.assertEquals(groups.size(), 3);
         Assert.assertTrue(groups.contains(groupTop));
@@ -102,4 +106,4 @@ public class EntitiesDescriptorNameProcessorTest extends XMLObjectBaseTestCase {
         Assert.assertTrue(groups.contains(groupSub2A));
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityAttributesFilterTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityAttributesFilterTest.java
index c50f41467..1842e96c2 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityAttributesFilterTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityAttributesFilterTest.java
@@ -24,6 +24,7 @@ import java.util.Collections;
 import java.util.List;
 import java.util.function.Predicate;
 
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
@@ -46,6 +47,7 @@ import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+ at SuppressWarnings("javadoc")
 public class EntityAttributesFilterTest extends XMLObjectBaseTestCase implements Predicate<EntityDescriptor> {
     
     private SAMLObjectBuilder<Attribute> tagBuilder;
@@ -92,7 +94,7 @@ public class EntityAttributesFilterTest extends XMLObjectBaseTestCase implements
         final Collection<Attribute> tags = List.of(tag, tag2);
         
         final EntityAttributesFilter filter = new EntityAttributesFilter();
-        filter.setRules(Collections.singletonMap(this, tags));
+        filter.setRules(CollectionSupport.singletonMap(this, tags));
         filter.initialize();
         
         metadataProvider.setMetadataFilter(filter);
@@ -101,9 +103,9 @@ public class EntityAttributesFilterTest extends XMLObjectBaseTestCase implements
 
         EntityIdCriterion key = new EntityIdCriterion("https://carmenwiki.osu.edu/shibboleth");
         EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(key));
-        Assert.assertNotNull(entity);
+        assert entity != null;
         Extensions exts = entity.getExtensions();
-        Assert.assertNotNull(exts);
+        assert exts != null;
         Collection<XMLObject> extElements = exts.getUnknownXMLObjects(EntityAttributes.DEFAULT_ELEMENT_NAME);
         Assert.assertFalse(extElements.isEmpty());
         EntityAttributes extTags = (EntityAttributes) extElements.iterator().next();
@@ -116,7 +118,7 @@ public class EntityAttributesFilterTest extends XMLObjectBaseTestCase implements
         
         key = new EntityIdCriterion("https://cms.psu.edu/Shibboleth");
         entity = metadataProvider.resolveSingle(new CriteriaSet(key));
-        Assert.assertNotNull(entity);
+        assert entity != null;
         exts = entity.getExtensions();
         Assert.assertNull(exts);
     }
@@ -132,7 +134,7 @@ public class EntityAttributesFilterTest extends XMLObjectBaseTestCase implements
         final Collection<Attribute> tags = Collections.singletonList(tag);
         
         final EntityAttributesFilter filter = new EntityAttributesFilter();
-        filter.setRules(Collections.singletonMap(this, tags));
+        filter.setRules(CollectionSupport.singletonMap(this, tags));
         filter.setAttributeFilter(input -> "foo".equals(input.getName()));
         filter.initialize();
         
@@ -142,9 +144,9 @@ public class EntityAttributesFilterTest extends XMLObjectBaseTestCase implements
 
         EntityIdCriterion key = new EntityIdCriterion("https://carmenwiki.osu.edu/shibboleth");
         EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(key));
-        Assert.assertNotNull(entity);
+        assert entity != null;
         Extensions exts = entity.getExtensions();
-        Assert.assertNotNull(exts);
+        assert exts != null;
         Collection<XMLObject> extElements = exts.getUnknownXMLObjects(EntityAttributes.DEFAULT_ELEMENT_NAME);
         Assert.assertFalse(extElements.isEmpty());
         EntityAttributes extTags = (EntityAttributes) extElements.iterator().next();
@@ -155,7 +157,7 @@ public class EntityAttributesFilterTest extends XMLObjectBaseTestCase implements
 
     /** {@inheritDoc} */
     public boolean test(final EntityDescriptor input) {
-        return input.getEntityID().equals("https://carmenwiki.osu.edu/shibboleth");
+        return "https://carmenwiki.osu.edu/shibboleth".equals(input.getEntityID());
     }
 
 }
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityRoleFilterTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityRoleFilterTest.java
index 4e8526a92..7f4b4cd60 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityRoleFilterTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/EntityRoleFilterTest.java
@@ -40,6 +40,7 @@ import net.shibboleth.shared.testing.RepositorySupport;
 /**
  * Unit tests for {@link EntityRoleFilter}.
  */
+ at SuppressWarnings("javadoc")
 public class EntityRoleFilterTest extends XMLObjectBaseTestCase {
     
     private HttpClient httpClient;
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilterTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilterTest.java
index 5cca0a83a..d576eb70d 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilterTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/NameIDFormatFilterTest.java
@@ -20,11 +20,11 @@ package org.opensaml.saml.metadata.resolver.filter.impl;
 import java.io.File;
 import java.net.URL;
 import java.util.Collection;
-import java.util.Collections;
 import java.util.List;
 import java.util.function.Predicate;
 import java.util.stream.Collectors;
 
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
@@ -37,10 +37,12 @@ import org.opensaml.saml.metadata.resolver.impl.FilesystemMetadataResolverTest;
 import org.opensaml.saml.saml2.core.NameIDType;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import org.opensaml.saml.saml2.metadata.NameIDFormat;
+import org.opensaml.saml.saml2.metadata.SPSSODescriptor;
 import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+ at SuppressWarnings("javadoc")
 public class NameIDFormatFilterTest extends XMLObjectBaseTestCase implements Predicate<EntityDescriptor> {
     
     private FilesystemMetadataResolver metadataProvider;
@@ -69,7 +71,7 @@ public class NameIDFormatFilterTest extends XMLObjectBaseTestCase implements Pre
     @Test
     public void test() throws ComponentInitializationException, ResolverException {
         
-        metadataFilter.setRules(Collections.singletonMap(this, formats));
+        metadataFilter.setRules(CollectionSupport.singletonMap(this, formats));
         metadataFilter.initialize();
         
         metadataProvider.setMetadataFilter(metadataFilter);
@@ -78,22 +80,26 @@ public class NameIDFormatFilterTest extends XMLObjectBaseTestCase implements Pre
 
         EntityIdCriterion key = new EntityIdCriterion("https://carmenwiki.osu.edu/shibboleth");
         EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(key));
-        Assert.assertNotNull(entity);
+        assert entity != null;
         
-        final List<NameIDFormat> attachedFormats = entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS).getNameIDFormats();
+        SPSSODescriptor role = entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+        assert role != null;
+        final List<NameIDFormat> attachedFormats = role.getNameIDFormats();
         Assert.assertEquals(attachedFormats.stream().map(NameIDFormat::getURI).collect(Collectors.toUnmodifiableList()),
                 List.of(NameIDType.PERSISTENT, NameIDType.EMAIL));
                 
         key = new EntityIdCriterion("https://cms.psu.edu/Shibboleth");
         entity = metadataProvider.resolveSingle(new CriteriaSet(key));
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(entity.getSPSSODescriptor(SAMLConstants.SAML11P_NS).getNameIDFormats().size(), 1);
+        assert entity != null;
+        role = entity.getSPSSODescriptor(SAMLConstants.SAML11P_NS);
+        assert role != null;
+        Assert.assertEquals(role.getNameIDFormats().size(), 1);
     }
 
     @Test
     public void testWithRemoval() throws ComponentInitializationException, ResolverException {
         
-        metadataFilter.setRules(Collections.singletonMap(this, formats));
+        metadataFilter.setRules(CollectionSupport.singletonMap(this, formats));
         metadataFilter.setRemoveExistingFormats(true);
         metadataFilter.initialize();
         
@@ -101,15 +107,17 @@ public class NameIDFormatFilterTest extends XMLObjectBaseTestCase implements Pre
         metadataProvider.setId("test");
         metadataProvider.initialize();
 
-        EntityIdCriterion key = new EntityIdCriterion("https://carmenwiki.osu.edu/shibboleth");
-        EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(key));
-        Assert.assertNotNull(entity);
-        Assert.assertEquals(entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS).getNameIDFormats().size(), 2);
+        final EntityIdCriterion key = new EntityIdCriterion("https://carmenwiki.osu.edu/shibboleth");
+        final EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(key));
+        assert entity != null;
+        final SPSSODescriptor role = entity.getSPSSODescriptor(SAMLConstants.SAML20P_NS);
+        assert role != null;
+        Assert.assertEquals(role.getNameIDFormats().size(), 2);
     }
 
     /** {@inheritDoc} */
     public boolean test(EntityDescriptor input) {
-        return input.getEntityID().equals("https://carmenwiki.osu.edu/shibboleth");
+        return "https://carmenwiki.osu.edu/shibboleth".equals(input.getEntityID());
     }
 
 }
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/NodeProcessingMetadataFilterTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/NodeProcessingMetadataFilterTest.java
index 7476941c3..3407bffec 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/NodeProcessingMetadataFilterTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/NodeProcessingMetadataFilterTest.java
@@ -37,6 +37,7 @@ import org.testng.annotations.Test;
 
 import net.shibboleth.shared.component.ComponentInitializationException;
 
+ at SuppressWarnings("javadoc")
 public class NodeProcessingMetadataFilterTest extends XMLObjectBaseTestCase {
     
     private FilesystemMetadataResolver metadataProvider;
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/PredicateFilterTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/PredicateFilterTest.java
index ccebd848b..83e9cf5ca 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/PredicateFilterTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/PredicateFilterTest.java
@@ -37,6 +37,7 @@ import org.testng.annotations.Test;
 /**
  * Unit tests for {@link PredicateFilter}.
  */
+ at SuppressWarnings("javadoc")
 public class PredicateFilterTest extends XMLObjectBaseTestCase {
 
     private ResourceBackedMetadataResolver metadataProvider;
@@ -59,21 +60,21 @@ public class PredicateFilterTest extends XMLObjectBaseTestCase {
     }
     
     @Test
-    public void testBlacklist() throws Exception {
+    public void testDenyList() throws Exception {
         
-        final String whitelisted = "urn:mace:incommon:dartmouth.edu";
-        final String blacklisted = "urn:mace:incommon:osu.edu";
+        final String allowed = "urn:mace:incommon:dartmouth.edu";
+        final String denied = "urn:mace:incommon:osu.edu";
         final String osu = "urn:mace:incommon:osu.edu";
 
-        final EntityIdPredicate condition = new EntityIdPredicate(Collections.singletonList(blacklisted));
+        final EntityIdPredicate condition = new EntityIdPredicate(Collections.singletonList(denied));
         
         metadataProvider.setMetadataFilter(new PredicateFilter(Direction.EXCLUDE, condition));
         metadataProvider.initialize();
         
-        EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion(blacklisted)));
+        EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion(denied)));
         Assert.assertNull(entity);
         
-        entity = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion(whitelisted)));
+        entity = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion(allowed)));
         Assert.assertNotNull(entity);
         
         singleEntityProvider.setMetadataFilter(new PredicateFilter(Direction.EXCLUDE, condition));
@@ -85,21 +86,21 @@ public class PredicateFilterTest extends XMLObjectBaseTestCase {
     }
     
     @Test
-    public void testWhitelist() throws Exception {
+    public void testAllowList() throws Exception {
         
-        final String whitelisted = "urn:mace:incommon:dartmouth.edu";
-        final String blacklisted = "urn:mace:incommon:osu.edu";
+        final String allowed = "urn:mace:incommon:dartmouth.edu";
+        final String denied = "urn:mace:incommon:osu.edu";
         final String osu = "urn:mace:incommon:osu.edu";
 
-        final EntityIdPredicate condition = new EntityIdPredicate(Collections.singletonList(whitelisted));
+        final EntityIdPredicate condition = new EntityIdPredicate(Collections.singletonList(allowed));
         
         metadataProvider.setMetadataFilter(new PredicateFilter(Direction.INCLUDE, condition));
         metadataProvider.initialize();
         
-        EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion(blacklisted)));
+        EntityDescriptor entity = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion(denied)));
         Assert.assertNull(entity);
         
-        entity = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion(whitelisted)));
+        entity = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion(allowed)));
         Assert.assertNotNull(entity);
         
         singleEntityProvider.setMetadataFilter(new PredicateFilter(Direction.INCLUDE,  new EntityIdPredicate(Collections.singletonList(osu))));
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilTest.java
index 9404ed7ef..782e57560 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/RequiredValidUntilTest.java
@@ -36,6 +36,7 @@ import org.testng.annotations.Test;
 import net.shibboleth.shared.component.ComponentInitializationException;
 
 /** Unit test for {@link RequiredValidUntilFilter}. */
+ at SuppressWarnings("javadoc")
 public class RequiredValidUntilTest extends XMLObjectBaseTestCase {
 
     private File metadataFile;
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SchemaValidationFilterTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SchemaValidationFilterTest.java
index eb565c40e..44d2ee835 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SchemaValidationFilterTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SchemaValidationFilterTest.java
@@ -31,6 +31,7 @@ import net.shibboleth.shared.spring.resource.ResourceHelper;
 /**
  * Unit tests for {@link SchemaValidationFilter}.
  */
+ at SuppressWarnings("javadoc")
 public class SchemaValidationFilterTest extends XMLObjectBaseTestCase {
 
     @Test
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/ScriptedFunctionTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/ScriptedFunctionTest.java
index f27f1332d..7e828c34c 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/ScriptedFunctionTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/ScriptedFunctionTest.java
@@ -35,9 +35,6 @@ import org.testng.annotations.Test;
 import net.shibboleth.shared.resource.Resource;
 import net.shibboleth.shared.spring.resource.ResourceHelper;
 
-/**
- *
- */
 @SuppressWarnings("javadoc")
 public class ScriptedFunctionTest extends XMLObjectBaseTestCase {
     
@@ -54,6 +51,7 @@ public class ScriptedFunctionTest extends XMLObjectBaseTestCase {
     @Test public void inlineScript() throws ScriptException {
         
         final Set<String> s = ScriptedTrustedNamesFunction.inlineScript(SCRIPT_8).apply(makeObject());
+        assert s != null;
         Assert.assertEquals(s.size(), 1);
         Assert.assertTrue(s.contains("String"));
    }
@@ -62,7 +60,7 @@ public class ScriptedFunctionTest extends XMLObjectBaseTestCase {
     @Test public void fileScript() throws ScriptException, IOException {
         final Resource r = ResourceHelper.of(new ClassPathResource(FILE_8));
         final Set<String> result = ScriptedTrustedNamesFunction.resourceScript(r).apply(makeObject());
-
+        assert result != null;
         Assert.assertEquals(result.size(), 1);
         Assert.assertTrue(result.contains("String"));
     }
@@ -73,7 +71,9 @@ public class ScriptedFunctionTest extends XMLObjectBaseTestCase {
         what.setCustomObject(Collections.singleton("String"));
         
         final Set<String> s = what.apply(makeObject());
+        assert s != null;
         Assert.assertEquals(s.size(), 1);
         Assert.assertTrue(s.contains("String"));
    }
-}
+
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SignatureValidationFilterExplicitKeyTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SignatureValidationFilterExplicitKeyTest.java
index 556cfde4a..118f2c916 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SignatureValidationFilterExplicitKeyTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SignatureValidationFilterExplicitKeyTest.java
@@ -53,6 +53,7 @@ import org.w3c.dom.Document;
 /**
  * Unit tests for {@link SignatureValidationFilter}.
  */
+ at SuppressWarnings("javadoc")
 public class SignatureValidationFilterExplicitKeyTest extends XMLObjectBaseTestCase {
     
     private final String switchMDFileValid = "/org/opensaml/saml/saml2/metadata/provider/metadata.aaitest_signed.xml";
@@ -119,7 +120,7 @@ public class SignatureValidationFilterExplicitKeyTest extends XMLObjectBaseTestC
 
     @Test
     public void testValidSWITCHStandalone() throws UnmarshallingException {
-        XMLObject xmlObject = unmarshallerFactory.getUnmarshaller(switchMDDocumentValid
+        XMLObject xmlObject = unmarshallerFactory.ensureUnmarshaller(switchMDDocumentValid
                 .getDocumentElement()).unmarshall(switchMDDocumentValid.getDocumentElement());
         
         SignatureValidationFilter filter = new SignatureValidationFilter(switchSigTrustEngine);
@@ -132,7 +133,7 @@ public class SignatureValidationFilterExplicitKeyTest extends XMLObjectBaseTestC
     
     @Test(expectedExceptions=FilterException.class)
     public void testSWITCHStandaloneBlacklistedSignatureAlgorithm() throws UnmarshallingException, FilterException {
-        XMLObject xmlObject = unmarshallerFactory.getUnmarshaller(switchMDDocumentValid
+        XMLObject xmlObject = unmarshallerFactory.ensureUnmarshaller(switchMDDocumentValid
                 .getDocumentElement()).unmarshall(switchMDDocumentValid.getDocumentElement());
         
         SignatureValidationFilter filter = new SignatureValidationFilter(switchSigTrustEngine);
@@ -147,7 +148,7 @@ public class SignatureValidationFilterExplicitKeyTest extends XMLObjectBaseTestC
     
     @Test
     public void testInvalidSWITCHStandalone() throws UnmarshallingException {
-        XMLObject xmlObject = unmarshallerFactory.getUnmarshaller(switchMDDocumentInvalid
+        XMLObject xmlObject = unmarshallerFactory.ensureUnmarshaller(switchMDDocumentInvalid
                 .getDocumentElement()).unmarshall(switchMDDocumentInvalid.getDocumentElement());
         
         SignatureValidationFilter filter = new SignatureValidationFilter(switchSigTrustEngine);
@@ -162,7 +163,7 @@ public class SignatureValidationFilterExplicitKeyTest extends XMLObjectBaseTestC
     @Test
     public void testInvalidSWITCHStandaloneWithRootSkip() throws UnmarshallingException {
         // Goal here is to test the root signature skip (indicated by filter context data) by using a known invalid root signature.
-        XMLObject xmlObject = unmarshallerFactory.getUnmarshaller(switchMDDocumentInvalid
+        XMLObject xmlObject = unmarshallerFactory.ensureUnmarshaller(switchMDDocumentInvalid
                 .getDocumentElement()).unmarshall(switchMDDocumentInvalid.getDocumentElement());
 
         MetadataSource metadataSource = new MetadataSource();
@@ -186,7 +187,7 @@ public class SignatureValidationFilterExplicitKeyTest extends XMLObjectBaseTestC
         
         Document mdDoc = parserPool.parse(SignatureValidationFilterExplicitKeyTest.class.getResourceAsStream(openIDFileValid));
         XMLObject xmlObject = 
-            unmarshallerFactory.getUnmarshaller(mdDoc.getDocumentElement()).unmarshall(mdDoc.getDocumentElement());
+            unmarshallerFactory.ensureUnmarshaller(mdDoc.getDocumentElement()).unmarshall(mdDoc.getDocumentElement());
         Assert.assertTrue(xmlObject instanceof EntityDescriptor);
         EntityDescriptor ed = (EntityDescriptor) xmlObject;
         Assert.assertTrue(ed.isSigned());
@@ -209,7 +210,7 @@ public class SignatureValidationFilterExplicitKeyTest extends XMLObjectBaseTestC
         
         Document mdDoc = parserPool.parse(SignatureValidationFilterExplicitKeyTest.class.getResourceAsStream(openIDFileInvalid));
         XMLObject xmlObject = 
-            unmarshallerFactory.getUnmarshaller(mdDoc.getDocumentElement()).unmarshall(mdDoc.getDocumentElement());
+            unmarshallerFactory.ensureUnmarshaller(mdDoc.getDocumentElement()).unmarshall(mdDoc.getDocumentElement());
         Assert.assertTrue(xmlObject instanceof EntityDescriptor);
         EntityDescriptor ed = (EntityDescriptor) xmlObject;
         Assert.assertTrue(ed.isSigned());
@@ -234,7 +235,7 @@ public class SignatureValidationFilterExplicitKeyTest extends XMLObjectBaseTestC
 
         Document mdDoc = parserPool.parse(SignatureValidationFilterExplicitKeyTest.class.getResourceAsStream(openIDFileInvalid));
         XMLObject xmlObject =
-            unmarshallerFactory.getUnmarshaller(mdDoc.getDocumentElement()).unmarshall(mdDoc.getDocumentElement());
+            unmarshallerFactory.ensureUnmarshaller(mdDoc.getDocumentElement()).unmarshall(mdDoc.getDocumentElement());
         Assert.assertTrue(xmlObject instanceof EntityDescriptor);
         EntityDescriptor ed = (EntityDescriptor) xmlObject;
         Assert.assertTrue(ed.isSigned());
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SignatureValidationFilterPKIXTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SignatureValidationFilterPKIXTest.java
index 76709c309..3bf268265 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SignatureValidationFilterPKIXTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/filter/impl/SignatureValidationFilterPKIXTest.java
@@ -59,6 +59,7 @@ import org.testng.annotations.Test;
 import org.testng.collections.Lists;
 import org.w3c.dom.Element;
 
+ at SuppressWarnings("javadoc")
 public class SignatureValidationFilterPKIXTest extends XMLObjectBaseTestCase {
     
     private static final String DATA_PATH = "/org/opensaml/saml/metadata/resolver/filter/impl/";
@@ -102,6 +103,7 @@ public class SignatureValidationFilterPKIXTest extends XMLObjectBaseTestCase {
             Assert.fail("Not a signable SAML object");
         }
         SignableSAMLObject signableSAML = (SignableSAMLObject) unsignedObject;
+        assert signableSAML != null;
         
         SignatureSigningParameters params = new SignatureSigningParameters();
         params.setSigningCredential(signingCredential);
@@ -124,7 +126,7 @@ public class SignatureValidationFilterPKIXTest extends XMLObjectBaseTestCase {
         Signer.signObject(signature);
         
         // Unmarshall a new tree around the signed DOM to avoid any XMLSignature weirdness
-        return unmarshallerFactory.getUnmarshaller(dom).unmarshall(dom);
+        return unmarshallerFactory.ensureUnmarshaller(dom).unmarshall(dom);
     }
 
     private SignatureTrustEngine buildTrustEngine() {
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicHTTPMetadataResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicHTTPMetadataResolverTest.java
index 4e5f4b6b6..5362d900c 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicHTTPMetadataResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicHTTPMetadataResolverTest.java
@@ -19,6 +19,9 @@ package org.opensaml.saml.metadata.resolver.impl;
 
 import java.io.ByteArrayOutputStream;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
 import org.apache.hc.client5.http.classic.HttpClient;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpStatus;
@@ -37,10 +40,12 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
 import net.shibboleth.shared.httpclient.HttpClientBuilder;
+import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.Criterion;
 import net.shibboleth.shared.resolver.ResolverException;
 
+ at SuppressWarnings("javadoc")
 public class AbstractDynamicHTTPMetadataResolverTest extends XMLObjectBaseTestCase {
     
     private MockDynamicHTTPMetadataResolver resolver;
@@ -108,7 +113,7 @@ public class AbstractDynamicHTTPMetadataResolverTest extends XMLObjectBaseTestCa
         CriteriaSet criteriaSet = new CriteriaSet(new RequestURLCriterion(requestURL));
         
         EntityDescriptor ed = resolver.resolveSingle(criteriaSet);
-        Assert.assertNotNull(ed);
+        assert ed != null;
         Assert.assertEquals(ed.getEntityID(), entityID);
         Assert.assertNull(ed.getDOM());
     }
@@ -156,13 +161,15 @@ public class AbstractDynamicHTTPMetadataResolverTest extends XMLObjectBaseTestCa
     
     public static class MockDynamicHTTPMetadataResolver extends AbstractDynamicHTTPMetadataResolver {
         
-        public MockDynamicHTTPMetadataResolver(HttpClient client) {
+        public MockDynamicHTTPMetadataResolver(@Nonnull HttpClient client) {
             super(null, client);
         }
 
         /** {@inheritDoc} */
-        protected String buildRequestURL(CriteriaSet criteria) {
-            return criteria.get(RequestURLCriterion.class).requestURL;
+        @Nonnull protected String buildRequestURL(@Nullable CriteriaSet criteria) {
+            assert criteria != null;
+            return Constraint.isNotNull(
+                    criteria.get(RequestURLCriterion.class), "RequestURLCriterion was absent").requestURL;
         }
         
     }
@@ -174,4 +181,4 @@ public class AbstractDynamicHTTPMetadataResolverTest extends XMLObjectBaseTestCa
         }
     }
     
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicMetadataResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicMetadataResolverTest.java
index acf29aa58..4db0e30dd 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicMetadataResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/AbstractDynamicMetadataResolverTest.java
@@ -34,6 +34,8 @@ import java.util.Timer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 
+import javax.annotation.Nullable;
+
 import org.opensaml.core.criterion.EntityIdCriterion;
 import org.opensaml.core.testing.XMLObjectBaseTestCase;
 import org.opensaml.core.xml.XMLObject;
@@ -78,9 +80,11 @@ import com.google.common.collect.Iterables;
 
 import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
+import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 
+ at SuppressWarnings("javadoc")
 public class AbstractDynamicMetadataResolverTest extends XMLObjectBaseTestCase {
     
     private Map<String, EntityDescriptor> sourceMap;
@@ -169,7 +173,7 @@ public class AbstractDynamicMetadataResolverTest extends XMLObjectBaseTestCase {
         resolver = new MockDynamicResolver(sourceMap);
         resolver.setId("test123");
         resolver.setActivationCondition(prc -> {return allowActivation;});
-        resolver.setParserPool(XMLObjectProviderRegistrySupport.getParserPool());
+        resolver.setParserPool(Constraint.isNotNull(XMLObjectProviderRegistrySupport.getParserPool(), "ParserPool missing"));
         
         allowActivation = true;
     }
@@ -349,7 +353,7 @@ public class AbstractDynamicMetadataResolverTest extends XMLObjectBaseTestCase {
         
         EntityDescriptor result = resolver.resolveSingle(new CriteriaSet(new EntityIdCriterion(id1)));
         
-        Assert.assertNotNull(result);
+        assert result != null;
         Assert.assertNull(result.getDOM());
     }
     
@@ -493,7 +497,7 @@ public class AbstractDynamicMetadataResolverTest extends XMLObjectBaseTestCase {
         
         for (final String entityID : List.of(id1, id2, id3)) {
             EntityDescriptor ed = resolver.resolveSingle(new CriteriaSet(new EntityIdCriterion(entityID)));
-            Assert.assertNotNull(ed);
+            assert ed != null;
             Assert.assertEquals(ed.getEntityID(), entityID);
             Assert.assertNull(ed.getDOM());
         }
@@ -699,7 +703,8 @@ public class AbstractDynamicMetadataResolverTest extends XMLObjectBaseTestCase {
             originSourceMap = map;
         }
 
-        protected XMLObject fetchFromOriginSource(CriteriaSet criteria) throws IOException {
+        protected XMLObject fetchFromOriginSource(@Nullable CriteriaSet criteria) throws IOException {
+            
             if (criteria.contains(EntityIdCriterion.class)) {
                 return originSourceMap.get(criteria.get(EntityIdCriterion.class).getEntityId());
             } else if (secondaryLookup && criteria.contains(SimpleStringCriterion.class)) {
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/ChainingMetadataResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/ChainingMetadataResolverTest.java
index c34f43f5e..e0acf09ee 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/ChainingMetadataResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/ChainingMetadataResolverTest.java
@@ -38,6 +38,7 @@ import com.google.common.base.Predicates;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
+ at SuppressWarnings("javadoc")
 public class ChainingMetadataResolverTest extends XMLObjectBaseTestCase {
 
     private ChainingMetadataResolver metadataProvider;
@@ -94,11 +95,11 @@ public class ChainingMetadataResolverTest extends XMLObjectBaseTestCase {
         metadataProvider.initialize();
         
         EntityDescriptor descriptor = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion(entityID)));
-        Assert.assertNotNull(descriptor, "Retrieved entity descriptor was null");
+        assert descriptor != null;
         Assert.assertEquals(descriptor.getEntityID(), entityID, "Entity's ID does not match requested ID");
 
         EntityDescriptor descriptor2 = metadataProvider.resolveSingle(new CriteriaSet(new EntityIdCriterion(entityID2)));
-        Assert.assertNotNull(descriptor2, "Retrieved entity descriptor was null");
+        assert descriptor2 != null;
         Assert.assertEquals(descriptor2.getEntityID(), entityID2, "Entity's ID does not match requested ID");
     }
 
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/DOMMetadataResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/DOMMetadataResolverTest.java
index 549b7853e..45029d665 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/DOMMetadataResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/DOMMetadataResolverTest.java
@@ -36,6 +36,7 @@ import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 import org.w3c.dom.Document;
 
+ at SuppressWarnings("javadoc")
 public class DOMMetadataResolverTest extends XMLObjectBaseTestCase {
 
     private DOMMetadataResolver metadataProvider;
@@ -73,7 +74,7 @@ public class DOMMetadataResolverTest extends XMLObjectBaseTestCase {
         allowActivation = true;
         
         EntityDescriptor descriptor = metadataProvider.resolveSingle(criteriaSet);
-        Assert.assertNotNull(descriptor, "Retrieved entity descriptor was null");
+        assert descriptor != null;
         Assert.assertEquals(descriptor.getEntityID(), entityID, "Entity's ID does not match requested ID");
 
         allowActivation = false;
@@ -94,7 +95,7 @@ public class DOMMetadataResolverTest extends XMLObjectBaseTestCase {
             metadataProvider.setParserPool(parserPool);
             metadataProvider.setId("test");
             metadataProvider.initialize();
-        } catch (ComponentInitializationException e) {
+        } catch (final ComponentInitializationException e) {
             Assert.fail("DOM metadata provider init failed due to filter exception and fail fast = false");
         }
         
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/DefaultLocalDynamicSourceKeyGeneratorTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/DefaultLocalDynamicSourceKeyGeneratorTest.java
index e61924475..fe59df571 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/DefaultLocalDynamicSourceKeyGeneratorTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/DefaultLocalDynamicSourceKeyGeneratorTest.java
@@ -35,9 +35,7 @@ import com.google.common.io.BaseEncoding;
 
 import net.shibboleth.shared.resolver.CriteriaSet;
 
-/**
- *
- */
+ at SuppressWarnings("javadoc")
 public class DefaultLocalDynamicSourceKeyGeneratorTest {
     
     private String controlValue;
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/EntityIDDigestGeneratorTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/EntityIDDigestGeneratorTest.java
index 07a505446..4c39cb95d 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/EntityIDDigestGeneratorTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/EntityIDDigestGeneratorTest.java
@@ -29,9 +29,7 @@ import net.shibboleth.shared.codec.StringDigester;
 import net.shibboleth.shared.codec.StringDigester.OutputFormat;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
-/**
- *
- */
+ at SuppressWarnings("javadoc")
 public class EntityIDDigestGeneratorTest {
     
     private String controlValue;
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolverTest.java
index 2a387bcab..baf8f165e 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FileBackedHTTPMetadataResolverTest.java
@@ -51,6 +51,7 @@ import net.shibboleth.shared.testing.RepositorySupport;
 /**
  * Test case for {@link FileBackedHTTPMetadataResolver}.
  */
+ at SuppressWarnings("javadoc")
 public class FileBackedHTTPMetadataResolverTest extends XMLObjectBaseTestCase {
     
     private HttpClientBuilder httpClientBuilder;
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FilesystemMetadataResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FilesystemMetadataResolverTest.java
index 51d753e82..690d4e25e 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FilesystemMetadataResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FilesystemMetadataResolverTest.java
@@ -36,6 +36,7 @@ import org.testng.annotations.Test;
 import com.google.common.base.Predicates;
 import com.google.common.io.Files;
 
+ at SuppressWarnings("javadoc")
 public class FilesystemMetadataResolverTest extends XMLObjectBaseTestCase {
 
     private FilesystemMetadataResolver metadataProvider;
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FunctionDrivenDynamicHTTPMetadataResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FunctionDrivenDynamicHTTPMetadataResolverTest.java
index a91937a66..ea0fc953c 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FunctionDrivenDynamicHTTPMetadataResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/FunctionDrivenDynamicHTTPMetadataResolverTest.java
@@ -45,6 +45,7 @@ import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.testing.RepositorySupport;
 import net.shibboleth.shared.testing.VelocityEngine;
 
+ at SuppressWarnings("javadoc")
 public class FunctionDrivenDynamicHTTPMetadataResolverTest extends XMLObjectBaseTestCase {
     
     private FunctionDrivenDynamicHTTPMetadataResolver resolver;
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/HTTPEntityIDRequestURLBuilderTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/HTTPEntityIDRequestURLBuilderTest.java
index 02fe8fdcb..742dc2226 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/HTTPEntityIDRequestURLBuilderTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/HTTPEntityIDRequestURLBuilderTest.java
@@ -17,13 +17,13 @@
 
 package org.opensaml.saml.metadata.resolver.impl;
 
-import net.shibboleth.shared.logic.ConstraintViolationException;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 import org.opensaml.core.criterion.EntityIdCriterion;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
+ at SuppressWarnings("javadoc")
 public class HTTPEntityIDRequestURLBuilderTest {
     
     private HTTPEntityIDRequestURLBuilder function = new HTTPEntityIDRequestURLBuilder();
@@ -46,9 +46,9 @@ public class HTTPEntityIDRequestURLBuilderTest {
         Assert.assertNull(function.apply(new CriteriaSet()));
     }
     
-    @Test(expectedExceptions=ConstraintViolationException.class)
+    @Test
     public void testNullEntityID() {
-        function.apply(null);
+        Assert.assertNull(function.apply(null));
     }
 
 }
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/LocalDynamicMetadataResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/LocalDynamicMetadataResolverTest.java
index 2d50ae87c..5d51c4a68 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/LocalDynamicMetadataResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/LocalDynamicMetadataResolverTest.java
@@ -39,13 +39,13 @@ import com.google.common.util.concurrent.Uninterruptibles;
 import net.shibboleth.shared.codec.StringDigester;
 import net.shibboleth.shared.codec.StringDigester.OutputFormat;
 import net.shibboleth.shared.component.ComponentInitializationException;
-import net.shibboleth.shared.logic.ConstraintViolationException;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 
 /**
  * Unit test for {@link LocalDynamicMetadataResolver}.
  */
+ at SuppressWarnings("javadoc")
 public class LocalDynamicMetadataResolverTest extends XMLObjectBaseTestCase {
     
     private LocalDynamicMetadataResolver resolver;
@@ -179,9 +179,4 @@ public class LocalDynamicMetadataResolverTest extends XMLObjectBaseTestCase {
         Assert.assertSame(resolver.resolveSingle(new CriteriaSet(new EntityIdCriterion(entityID1))), entity1);
     }
     
-    @Test(expectedExceptions=ConstraintViolationException.class)
-    public void testCtorMissingManager() {
-        resolver = new LocalDynamicMetadataResolver(null);
-    }
-    
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/MetadataQueryProtocolRequestURLBuilderTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/MetadataQueryProtocolRequestURLBuilderTest.java
index 8bca63e82..41c6ba2e6 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/MetadataQueryProtocolRequestURLBuilderTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/MetadataQueryProtocolRequestURLBuilderTest.java
@@ -17,6 +17,9 @@
 
 package org.opensaml.saml.metadata.resolver.impl;
 
+import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
+
 import org.opensaml.core.criterion.EntityIdCriterion;
 import org.opensaml.saml.metadata.resolver.impl.MetadataQueryProtocolRequestURLBuilder.MetadataQueryProtocolURLBuilder;
 import org.opensaml.saml.metadata.resolver.index.impl.SimpleStringCriterion;
@@ -25,9 +28,9 @@ import org.testng.annotations.Test;
 
 import com.google.common.collect.Lists;
 
-import net.shibboleth.shared.logic.ConstraintViolationException;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
+ at SuppressWarnings("javadoc")
 public class MetadataQueryProtocolRequestURLBuilderTest {
     
     private MetadataQueryProtocolRequestURLBuilder function;
@@ -46,10 +49,10 @@ public class MetadataQueryProtocolRequestURLBuilderTest {
         Assert.assertEquals(function.apply(new CriteriaSet(new EntityIdCriterion("http://example.org/idp"))), "http://metadata.example.org/service/entities/http:%2F%2Fexample.org%2Fidp");
     }
     
-    @Test(expectedExceptions=ConstraintViolationException.class)
+    @Test
     public void testNullCriteria() {
         function = new MetadataQueryProtocolRequestURLBuilder("http://metadata.example.org/service/");
-        function.apply(null);
+        Assert.assertNull(function.apply(null));
     }
     
     @Test
@@ -74,12 +77,12 @@ public class MetadataQueryProtocolRequestURLBuilderTest {
         
         private String suffix;
         
-        public MockURLBuilder(String s) {
+        public MockURLBuilder(@Nullable String s) {
             suffix = s;
         }
 
         /** {@inheritDoc} */
-        public String buildURL(String baseURL, CriteriaSet criteria) {
+        public String buildURL(@Nonnull String baseURL, @Nullable CriteriaSet criteria) {
             if (suffix == null) {
                 return null;
             }
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/PredicateFilteringTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/PredicateFilteringTest.java
index 6c3b37d9a..3abb53a20 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/PredicateFilteringTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/PredicateFilteringTest.java
@@ -43,6 +43,7 @@ import net.shibboleth.shared.resolver.ResolverException;
  * Test metadata predicate-based filtering code implemented in {@link AbstractMetadataResolver} 
  * and {@link AbstractBatchMetadataResolver}, using {@link FilesystemMetadataResolver}.
  */
+ at SuppressWarnings("javadoc")
 public class PredicateFilteringTest extends XMLObjectBaseTestCase {
     
     private FilesystemMetadataResolver metadataProvider;
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/PredicateRoleDescriptorResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/PredicateRoleDescriptorResolverTest.java
index dd0406f44..65e17cb38 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/PredicateRoleDescriptorResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/PredicateRoleDescriptorResolverTest.java
@@ -41,15 +41,13 @@ import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.resolver.CriteriaSet;
 import net.shibboleth.shared.resolver.ResolverException;
 
-/**
- *
- */
+ at SuppressWarnings("javadoc")
 public class PredicateRoleDescriptorResolverTest extends XMLObjectBaseTestCase {
     
     @Test
     public void testNoEntitiesResolveSingle() throws ResolverException, ComponentInitializationException {
         PredicateRoleDescriptorResolver roleResolver = 
-                new PredicateRoleDescriptorResolver(new StaticMetadataResolver(Lists.<EntityDescriptor>newArrayList()));
+                new PredicateRoleDescriptorResolver(new StaticMetadataResolver(Lists.newArrayList()));
         roleResolver.initialize();
         
         RoleDescriptor roleDescriptor = roleResolver.resolveSingle(new CriteriaSet(
@@ -60,7 +58,7 @@ public class PredicateRoleDescriptorResolverTest extends XMLObjectBaseTestCase {
     @Test
     public void testNoEntitiesResolveMulti() throws ResolverException, ComponentInitializationException {
         PredicateRoleDescriptorResolver roleResolver = 
-                new PredicateRoleDescriptorResolver(new StaticMetadataResolver(Lists.<EntityDescriptor>newArrayList()));
+                new PredicateRoleDescriptorResolver(new StaticMetadataResolver(Lists.newArrayList()));
         roleResolver.initialize();
         
         Iterable<RoleDescriptor> roleDescriptors = roleResolver.resolve(new CriteriaSet(
@@ -77,7 +75,7 @@ public class PredicateRoleDescriptorResolverTest extends XMLObjectBaseTestCase {
         
         RoleDescriptor roleDescriptor = roleResolver.resolveSingle(new CriteriaSet(
                 new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME)));
-        Assert.assertNotNull(roleDescriptor, "Resolved RoleDescriptor was null");
+        assert roleDescriptor != null;
         Assert.assertEquals(SPSSODescriptor.DEFAULT_ELEMENT_NAME, roleDescriptor.getElementQName(),
                 "Saw incorrect role type");
     }
@@ -147,7 +145,7 @@ public class PredicateRoleDescriptorResolverTest extends XMLObjectBaseTestCase {
                 new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME),
                 new ProtocolCriterion(SAMLConstants.SAML20P_NS)));
         
-        Assert.assertNotNull(roleDescriptor, "Resolved RoleDescriptor was null");
+        assert roleDescriptor != null;
         Assert.assertEquals(SPSSODescriptor.DEFAULT_ELEMENT_NAME, roleDescriptor.getElementQName(),
                 "Saw incorrect role type");
         Assert.assertTrue(roleDescriptor.getSupportedProtocols().contains(SAMLConstants.SAML20P_NS),
@@ -246,7 +244,7 @@ public class PredicateRoleDescriptorResolverTest extends XMLObjectBaseTestCase {
                 new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME),
                 new ProtocolCriterion(SAMLConstants.SAML20P_NS)));
         
-        Assert.assertNotNull(roleDescriptor, "Resolved RoleDescriptor was null");
+        assert roleDescriptor != null;
         Assert.assertEquals(SPSSODescriptor.DEFAULT_ELEMENT_NAME, roleDescriptor.getElementQName(),
                 "Saw incorrect role type");
         Assert.assertTrue(roleDescriptor.getSupportedProtocols().contains(SAMLConstants.SAML20P_NS),
@@ -284,7 +282,7 @@ public class PredicateRoleDescriptorResolverTest extends XMLObjectBaseTestCase {
         
         RoleDescriptor roleDescriptor = roleResolver.resolveSingle(new CriteriaSet(
                 new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME)));
-        Assert.assertNotNull(roleDescriptor, "Resolved RoleDescriptor was null");
+        assert roleDescriptor != null;
         Assert.assertEquals(SPSSODescriptor.DEFAULT_ELEMENT_NAME, roleDescriptor.getElementQName(),
                 "Saw incorrect role type");
     }
@@ -394,21 +392,21 @@ public class PredicateRoleDescriptorResolverTest extends XMLObjectBaseTestCase {
 
     public static class StaticMetadataResolver implements MetadataResolver {
         
-        private List<EntityDescriptor> entityDescriptors;
+        @Nonnull private List<EntityDescriptor> entityDescriptors;
         
-        public StaticMetadataResolver(List<EntityDescriptor> descriptors) {
+        public StaticMetadataResolver(@Nonnull final List<EntityDescriptor> descriptors) {
             entityDescriptors = descriptors;
         }
             
         @Nullable public String getId() { return "foo"; }
 
         @Nullable
-        public EntityDescriptor resolveSingle(CriteriaSet criteria) throws ResolverException {
+        public EntityDescriptor resolveSingle(@Nullable CriteriaSet criteria) throws ResolverException {
             return entityDescriptors.get(0);
         }
 
         @Nonnull
-        public Iterable<EntityDescriptor> resolve(CriteriaSet criteria) throws ResolverException {
+        public Iterable<EntityDescriptor> resolve(@Nullable CriteriaSet criteria) throws ResolverException {
             return entityDescriptors;
         }
 
@@ -422,7 +420,7 @@ public class PredicateRoleDescriptorResolverTest extends XMLObjectBaseTestCase {
             return null;
         }
 
-        public void setMetadataFilter(MetadataFilter newFilter) { }
+        public void setMetadataFilter(@Nullable final MetadataFilter newFilter) { }
     }
     
     public static class BooleanPredicateCriterion implements EvaluableRoleDescriptorCriterion {
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/RegexRequestURLBuilderTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/RegexRequestURLBuilderTest.java
index e0a5b5d23..b65bffc4d 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/RegexRequestURLBuilderTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/RegexRequestURLBuilderTest.java
@@ -23,6 +23,7 @@ import org.testng.annotations.Test;
 
 import net.shibboleth.shared.resolver.CriteriaSet;
 
+ at SuppressWarnings("javadoc")
 public class RegexRequestURLBuilderTest {
     
     private RegexRequestURLBuilder function;
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/ResourceBackedMetadataResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/ResourceBackedMetadataResolverTest.java
index 54ecb96a4..29a1f8088 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/ResourceBackedMetadataResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/ResourceBackedMetadataResolverTest.java
@@ -90,7 +90,7 @@ public class ResourceBackedMetadataResolverTest extends XMLObjectBaseTestCase {
     @Test
     public void testGetEntityDescriptor() throws ResolverException {
         final EntityDescriptor descriptor = metadataProvider.resolveSingle(criteriaSet);
-        Assert.assertNotNull(descriptor, "Retrieved entity descriptor was null");
+        assert descriptor != null;
         Assert.assertEquals(descriptor.getEntityID(), entityID, "Entity's ID does not match requested ID");
     }
     
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/SAMLArtifactURLBuilderTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/SAMLArtifactURLBuilderTest.java
index 62151f424..7d17fbc01 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/SAMLArtifactURLBuilderTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/SAMLArtifactURLBuilderTest.java
@@ -36,9 +36,7 @@ import com.google.common.io.BaseEncoding;
 
 import net.shibboleth.shared.resolver.CriteriaSet;
 
-/**
- *
- */
+ at SuppressWarnings("javadoc")
 public class SAMLArtifactURLBuilderTest {
     
     private SAMLArtifactURLBuilder builder = new SAMLArtifactURLBuilder();
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/TemplateRequestURLBuilderTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/TemplateRequestURLBuilderTest.java
index b550107b1..3480970d5 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/TemplateRequestURLBuilderTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/impl/TemplateRequestURLBuilderTest.java
@@ -19,7 +19,6 @@ package org.opensaml.saml.metadata.resolver.impl;
 
 import java.util.function.Function;
 
-import net.shibboleth.shared.logic.ConstraintViolationException;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
 import org.apache.velocity.app.VelocityEngine;
@@ -29,6 +28,7 @@ import org.testng.Assert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+ at SuppressWarnings("javadoc")
 public class TemplateRequestURLBuilderTest {
     
     private VelocityEngine engine;
@@ -77,10 +77,10 @@ public class TemplateRequestURLBuilderTest {
         Assert.assertEquals(function.apply(new CriteriaSet(new EntityIdCriterion("http://example.org/idp"))), "HTTP://EXAMPLE.ORG/IDP");
     }
     
-    @Test(expectedExceptions=ConstraintViolationException.class)
+    @Test
     public void testNullEntityID() {
         function = new TemplateRequestURLBuilder(engine, "http://metadata.example.org/?entity=${entityID}", EncodingStyle.form);
-        function.apply(null);
+        Assert.assertNull(function.apply(null));
     }
 
 
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/ConstantEntityDescriptorFunction.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/ConstantEntityDescriptorFunction.java
index 0a50a9d69..d0c3d3c40 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/ConstantEntityDescriptorFunction.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/ConstantEntityDescriptorFunction.java
@@ -31,6 +31,7 @@ import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 import net.shibboleth.shared.logic.Constraint;
 import net.shibboleth.shared.primitive.StringSupport;
 
+ at SuppressWarnings("javadoc")
 public class ConstantEntityDescriptorFunction implements Function<EntityDescriptor, Set<MetadataIndexKey>> {
     
     private String value;
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/EndpointMetadataIndexTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/EndpointMetadataIndexTest.java
index 1f8fa086d..45ca80509 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/EndpointMetadataIndexTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/EndpointMetadataIndexTest.java
@@ -49,9 +49,7 @@ import com.google.common.base.Predicates;
 
 import net.shibboleth.shared.resolver.CriteriaSet;
 
-/**
- *
- */
+ at SuppressWarnings("javadoc")
 public class EndpointMetadataIndexTest extends XMLObjectBaseTestCase {
     
     private String entityID = "https://www.example.com/saml";
@@ -123,7 +121,7 @@ public class EndpointMetadataIndexTest extends XMLObjectBaseTestCase {
         endpoint.setLocation(location1);
         criteriaSet.add(new EndpointCriterion<>(endpoint));
         keys = metadataIndex.generateKeys(criteriaSet);
-        Assert.assertNotNull(keys);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(endpointKey1));
         
@@ -135,7 +133,7 @@ public class EndpointMetadataIndexTest extends XMLObjectBaseTestCase {
         endpoint.setResponseLocation(responseLocation1);
         criteriaSet.add(new EndpointCriterion<>(endpoint));
         keys = metadataIndex.generateKeys(criteriaSet);
-        Assert.assertNotNull(keys);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 2);
         Assert.assertTrue(keys.contains(endpointKey1));
         Assert.assertTrue(keys.contains(responseEndpointKey1));
@@ -148,7 +146,7 @@ public class EndpointMetadataIndexTest extends XMLObjectBaseTestCase {
         criteriaSet.add(new EndpointCriterion<>(endpoint));
         criteriaSet.add(new StartsWithLocationCriterion());
         keys = metadataIndex.generateKeys(criteriaSet);
-        Assert.assertNotNull(keys);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 10);
         Assert.assertTrue(keys.contains(new EndpointMetadataIndex.EndpointMetadataIndexKey(SPSSODescriptor.DEFAULT_ELEMENT_NAME, AssertionConsumerService.DEFAULT_ELEMENT_NAME, 
                 "https://www.example.com/cas/someEndpoint1/foo/bar/", false)));
@@ -180,8 +178,8 @@ public class EndpointMetadataIndexTest extends XMLObjectBaseTestCase {
     public void testGenerateKeysFromDescriptorAlwaysFalseSelector() {
         EndpointMetadataIndex metadataIndex = new EndpointMetadataIndex(Predicates.alwaysFalse());
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
-        
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 0);
     }
     
@@ -189,8 +187,8 @@ public class EndpointMetadataIndexTest extends XMLObjectBaseTestCase {
     public void testGenerateKeysFromDescriptorDefaultCtor() {
         EndpointMetadataIndex metadataIndex = new EndpointMetadataIndex();
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
-        
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 2);
         Assert.assertTrue(keys.contains(endpointKey1));
         Assert.assertTrue(keys.contains(endpointKey2));
@@ -202,8 +200,8 @@ public class EndpointMetadataIndexTest extends XMLObjectBaseTestCase {
         
         EndpointMetadataIndex metadataIndex = new EndpointMetadataIndex();
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
-        
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 3);
         Assert.assertTrue(keys.contains(endpointKey1));
         Assert.assertTrue(keys.contains(endpointKey2));
@@ -216,8 +214,8 @@ public class EndpointMetadataIndexTest extends XMLObjectBaseTestCase {
         
         EndpointMetadataIndex metadataIndex = new EndpointMetadataIndex();
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
-        
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 3);
         Assert.assertTrue(keys.contains(endpointKey1));
         Assert.assertTrue(keys.contains(endpointKey2));
@@ -232,8 +230,8 @@ public class EndpointMetadataIndexTest extends XMLObjectBaseTestCase {
         EndpointMetadataIndex metadataIndex = 
                 new EndpointMetadataIndex(new EndpointMetadataIndex.DefaultEndpointSelectionPredicate(indexableEndpoints));
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
-        
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(endpointKey1));
     }
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/FunctionDrivenMetadataIndexTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/FunctionDrivenMetadataIndexTest.java
index 8f7e87f2e..38a19f7e9 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/FunctionDrivenMetadataIndexTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/FunctionDrivenMetadataIndexTest.java
@@ -30,10 +30,7 @@ import org.testng.annotations.Test;
 
 import net.shibboleth.shared.resolver.CriteriaSet;
 
-
-/**
- *
- */
+ at SuppressWarnings("javadoc")
 public class FunctionDrivenMetadataIndexTest extends OpenSAMLInitBaseTestCase {
     
     private FunctionDrivenMetadataIndex metadataIndex;
@@ -47,21 +44,21 @@ public class FunctionDrivenMetadataIndexTest extends OpenSAMLInitBaseTestCase {
         
         a = (EntityDescriptor) XMLObjectSupport.buildXMLObject(EntityDescriptor.DEFAULT_ELEMENT_NAME);
         a.setEntityID("urn:test:a");
-        keyA = new SimpleStringMetadataIndexKey(a.getEntityID().toUpperCase());
+        keyA = new SimpleStringMetadataIndexKey("urn:test:a".toUpperCase());
         
         b = (EntityDescriptor) XMLObjectSupport.buildXMLObject(EntityDescriptor.DEFAULT_ELEMENT_NAME);
         b.setEntityID("urn:test:b");
-        new SimpleStringMetadataIndexKey(b.getEntityID().toUpperCase());
+        new SimpleStringMetadataIndexKey("urn:test:b".toUpperCase());
         
         c = (EntityDescriptor) XMLObjectSupport.buildXMLObject(EntityDescriptor.DEFAULT_ELEMENT_NAME);
         c.setEntityID("urn:test:c");
-        new SimpleStringMetadataIndexKey(c.getEntityID().toUpperCase());
+        new SimpleStringMetadataIndexKey("urn:test:c".toUpperCase());
     }
     
     @Test
     public void testGenerateKeysFromDescriptor() {
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(a);
-        
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(a);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(keyA));
     }
@@ -72,8 +69,8 @@ public class FunctionDrivenMetadataIndexTest extends OpenSAMLInitBaseTestCase {
         
         criteriaSet.add(new SimpleStringCriterion("URN:TEST:A"));
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(criteriaSet);
-        
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(criteriaSet);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(keyA));
     }
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexManagerTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexManagerTest.java
index fd039f9f1..399ee60aa 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexManagerTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexManagerTest.java
@@ -37,9 +37,7 @@ import org.testng.annotations.Test;
 import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
-/**
- *
- */
+ at SuppressWarnings("javadoc")
 public class MetadataIndexManagerTest extends XMLObjectBaseTestCase {
     
     private EntityDescriptor a, b, c;
@@ -58,18 +56,18 @@ public class MetadataIndexManagerTest extends XMLObjectBaseTestCase {
         a = (EntityDescriptor) XMLObjectSupport.buildXMLObject(EntityDescriptor.DEFAULT_ELEMENT_NAME);
         a.setEntityID("urn:test:a");
         a.getRoleDescriptors().add((RoleDescriptor) XMLObjectSupport.buildXMLObject(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
-        critAEntity = new SimpleStringCriterion(a.getEntityID().toUpperCase());
+        critAEntity = new SimpleStringCriterion("urn:test:a".toUpperCase());
         
         b = (EntityDescriptor) XMLObjectSupport.buildXMLObject(EntityDescriptor.DEFAULT_ELEMENT_NAME);
         b.setEntityID("urn:test:b");
         b.getRoleDescriptors().add((RoleDescriptor) XMLObjectSupport.buildXMLObject(IDPSSODescriptor.DEFAULT_ELEMENT_NAME));
         b.getRoleDescriptors().add((RoleDescriptor) XMLObjectSupport.buildXMLObject(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
-        critBEntity = new SimpleStringCriterion(b.getEntityID().toUpperCase());
+        critBEntity = new SimpleStringCriterion("urn:test:b".toUpperCase());
         
         c = (EntityDescriptor) XMLObjectSupport.buildXMLObject(EntityDescriptor.DEFAULT_ELEMENT_NAME);
         c.setEntityID("urn:test:c");
         c.getRoleDescriptors().add((RoleDescriptor) XMLObjectSupport.buildXMLObject(IDPSSODescriptor.DEFAULT_ELEMENT_NAME));
-        critCEntity = new SimpleStringCriterion(c.getEntityID().toUpperCase());
+        critCEntity = new SimpleStringCriterion("urn:test:c".toUpperCase());
         
         criteriaSet = new CriteriaSet();
         
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexStoreTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexStoreTest.java
index 4b7771c51..0bdfdc2f0 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexStoreTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexStoreTest.java
@@ -28,9 +28,7 @@ import org.testng.Assert;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
-/**
- *
- */
+ at SuppressWarnings("javadoc")
 public class MetadataIndexStoreTest extends OpenSAMLInitBaseTestCase {
     
     private MetadataIndexStore<EntityDescriptor> store;
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexSupportTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexSupportTest.java
index 8003a1a45..a678e7b73 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexSupportTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexSupportTest.java
@@ -22,16 +22,11 @@ import java.net.MalformedURLException;
 import org.testng.Assert;
 import org.testng.annotations.Test;
 
-
+ at SuppressWarnings("javadoc")
 public class MetadataIndexSupportTest {
     
     @Test
     public void testCanonicalizeLocationURI() throws MalformedURLException {
-        try {
-            MetadataIndexSupport.canonicalizeLocationURI(null);
-            Assert.fail("Should have failed on null/empty input");
-        } catch (MalformedURLException e) {
-        }
         try {
             MetadataIndexSupport.canonicalizeLocationURI("");
             Assert.fail("Should have failed on null/empty input");
@@ -65,5 +60,4 @@ public class MetadataIndexSupportTest {
         Assert.assertNull(MetadataIndexSupport.trimURLPathSegment("/"));
     }
     
-
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexingTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexingTest.java
index 28bef5619..3d41f5286 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexingTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/MetadataIndexingTest.java
@@ -47,6 +47,7 @@ import net.shibboleth.shared.resolver.ResolverException;
  * Test metadata indexing implemented in {@link AbstractBatchMetadataResolver}, using
  * {@link FilesystemMetadataResolver}.
  */
+ at SuppressWarnings("javadoc")
 public class MetadataIndexingTest extends XMLObjectBaseTestCase {
     
     private FilesystemMetadataResolver metadataProvider;
@@ -106,7 +107,7 @@ public class MetadataIndexingTest extends XMLObjectBaseTestCase {
         criteriaSet.clear();
         criteriaSet.add(new ArtifactCriterion(new SAML2ArtifactType0004(new byte[] {0, 0} , artifactSourceID, messageHandle)));
         descriptor = metadataProvider.resolveSingle(criteriaSet);
-        Assert.assertNotNull(descriptor, "Retrieved entity descriptor was null");
+        assert descriptor != null;
         Assert.assertEquals(descriptor.getEntityID(), entityID, "Entity's ID does not match requested ID");
     }
     
@@ -127,7 +128,7 @@ public class MetadataIndexingTest extends XMLObjectBaseTestCase {
         criteriaSet.clear();
         criteriaSet.add(new SimpleStringCriterion(entityID.toUpperCase()));
         descriptor = metadataProvider.resolveSingle(criteriaSet);
-        Assert.assertNotNull(descriptor, "Retrieved entity descriptor was null");
+        assert descriptor != null;
         Assert.assertEquals(descriptor.getEntityID(), entityID, "Entity's ID does not match requested ID");
     }
     
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/RoleMetadataIndexTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/RoleMetadataIndexTest.java
index bea7e7111..6330284c5 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/RoleMetadataIndexTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/RoleMetadataIndexTest.java
@@ -21,6 +21,7 @@ import java.util.List;
 import java.util.Set;
 
 import javax.annotation.Nonnull;
+import javax.annotation.Nullable;
 import javax.xml.namespace.QName;
 
 import org.opensaml.core.testing.XMLObjectBaseTestCase;
@@ -37,12 +38,10 @@ import org.testng.Assert;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.resolver.CriteriaSet;
 
-
-/**
- *
- */
+ at SuppressWarnings("javadoc")
 public class RoleMetadataIndexTest extends XMLObjectBaseTestCase {
     
     private RoleMetadataIndex metadataIndex;
@@ -85,19 +84,23 @@ public class RoleMetadataIndexTest extends XMLObjectBaseTestCase {
         Set<MetadataIndexKey> keys = null;
         
         keys = metadataIndex.generateKeys(idp);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(keyIDP));
         
         keys = metadataIndex.generateKeys(sp);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(keySP));
         
         keys = metadataIndex.generateKeys(idpAndSp);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 2);
         Assert.assertTrue(keys.contains(keyIDP));
         Assert.assertTrue(keys.contains(keySP));
         
         keys = metadataIndex.generateKeys(custom);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(keyCustom));
     }
@@ -110,18 +113,21 @@ public class RoleMetadataIndexTest extends XMLObjectBaseTestCase {
         criteriaSet.clear();
         criteriaSet.add(new EntityRoleCriterion(IDPSSODescriptor.DEFAULT_ELEMENT_NAME));
         keys = metadataIndex.generateKeys(criteriaSet);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(keyIDP));
         
         criteriaSet.clear();
         criteriaSet.add(new EntityRoleCriterion(SPSSODescriptor.DEFAULT_ELEMENT_NAME));
         keys = metadataIndex.generateKeys(criteriaSet);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(keySP));
         
         criteriaSet.clear();
         criteriaSet.add(new EntityRoleCriterion(MyCustomRoleType.TYPE_NAME));
         keys = metadataIndex.generateKeys(criteriaSet);
+        assert keys != null;
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(keyCustom));
     }
@@ -130,20 +136,21 @@ public class RoleMetadataIndexTest extends XMLObjectBaseTestCase {
         
         @Nonnull public static final QName TYPE_NAME = new QName("urn:test:metadata", "MyCustomRoleType", "custom");
 
-        protected MyCustomRoleType(String namespaceURI, String elementLocalName, String namespacePrefix) {
+        protected MyCustomRoleType(@Nullable final String namespaceURI, @Nonnull final String elementLocalName,
+                @Nullable final String namespacePrefix) {
             super(namespaceURI, elementLocalName, namespacePrefix);
         }
 
         /** {@inheritDoc} */
-        public List<Endpoint> getEndpoints() {
-            return null;
+        @Nonnull public List<Endpoint> getEndpoints() {
+            return CollectionSupport.emptyList();
         }
 
         /** {@inheritDoc} */
-        public List<Endpoint> getEndpoints(QName type) {
-            return null;
+        @Nonnull public List<Endpoint> getEndpoints(@Nonnull final QName type) {
+            return CollectionSupport.emptyList();
         }
         
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/SAMLArtifactMetadataIndexTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/SAMLArtifactMetadataIndexTest.java
index d61cc46f8..bb05e0321 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/SAMLArtifactMetadataIndexTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/SAMLArtifactMetadataIndexTest.java
@@ -49,10 +49,7 @@ import org.testng.annotations.Test;
 
 import net.shibboleth.shared.resolver.CriteriaSet;
 
-
-/**
- *
- */
+ at SuppressWarnings("javadoc")
 public class SAMLArtifactMetadataIndexTest extends XMLObjectBaseTestCase {
     
     private SAMLArtifactMetadataIndex metadataIndex;
@@ -119,7 +116,8 @@ public class SAMLArtifactMetadataIndexTest extends XMLObjectBaseTestCase {
     
     @Test
     public void testGenerateKeysFromDescriptorEntityIDOnly() {
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        assert keys != null;
         
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(entityIDSourceIDKey));
@@ -134,7 +132,8 @@ public class SAMLArtifactMetadataIndexTest extends XMLObjectBaseTestCase {
         roleDescriptor1.getArtifactResolutionServices().add(ars1);
         descriptor.getRoleDescriptors().add(roleDescriptor1);
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        assert keys != null;
         
         Assert.assertEquals(keys.size(), 2);
         Assert.assertTrue(keys.contains(entityIDSourceIDKey));
@@ -157,7 +156,8 @@ public class SAMLArtifactMetadataIndexTest extends XMLObjectBaseTestCase {
         roleDescriptor2.getArtifactResolutionServices().add(ars2);
         descriptor.getRoleDescriptors().add(roleDescriptor2);
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        assert keys != null;
         
         Assert.assertEquals(keys.size(), 3);
         Assert.assertTrue(keys.contains(entityIDSourceIDKey));
@@ -173,7 +173,8 @@ public class SAMLArtifactMetadataIndexTest extends XMLObjectBaseTestCase {
         roleDescriptor1.setExtensions(extensions1);
         descriptor.getRoleDescriptors().add(roleDescriptor1);
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        assert keys != null;
         
         Assert.assertEquals(keys.size(), 2);
         Assert.assertTrue(keys.contains(entityIDSourceIDKey));
@@ -195,7 +196,8 @@ public class SAMLArtifactMetadataIndexTest extends XMLObjectBaseTestCase {
         roleDescriptor2.setExtensions(extensions2);
         descriptor.getRoleDescriptors().add(roleDescriptor2);
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        assert keys != null;
         
         Assert.assertEquals(keys.size(), 4);
         Assert.assertTrue(keys.contains(entityIDSourceIDKey));
@@ -218,7 +220,8 @@ public class SAMLArtifactMetadataIndexTest extends XMLObjectBaseTestCase {
         
         descriptor.getRoleDescriptors().add(roleDescriptor1);
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(descriptor);
+        assert keys != null;
         
         Assert.assertEquals(keys.size(), 3);
         Assert.assertTrue(keys.contains(entityIDSourceIDKey));
@@ -232,7 +235,8 @@ public class SAMLArtifactMetadataIndexTest extends XMLObjectBaseTestCase {
         
         criteriaSet.add(new ArtifactCriterion(sourceIDArtifact));
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(criteriaSet);
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(criteriaSet);
+        assert keys != null;
         
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(entityIDSourceIDKey));
@@ -244,7 +248,8 @@ public class SAMLArtifactMetadataIndexTest extends XMLObjectBaseTestCase {
         
         criteriaSet.add(new ArtifactCriterion(sourceLocationArtifact1));
         
-        Set<MetadataIndexKey> keys = metadataIndex.generateKeys(criteriaSet);
+        final Set<MetadataIndexKey> keys = metadataIndex.generateKeys(criteriaSet);
+        assert keys != null;
         
         Assert.assertEquals(keys.size(), 1);
         Assert.assertTrue(keys.contains(sourceLocationKey1));
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/SimpleStringCriteriaFunction.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/SimpleStringCriteriaFunction.java
index dbe2a75f3..fcdb2476b 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/SimpleStringCriteriaFunction.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/SimpleStringCriteriaFunction.java
@@ -29,6 +29,7 @@ import org.opensaml.saml.metadata.resolver.index.SimpleStringMetadataIndexKey;
 
 import net.shibboleth.shared.resolver.CriteriaSet;
 
+ at SuppressWarnings("javadoc")
 public class SimpleStringCriteriaFunction implements Function<CriteriaSet, Set<MetadataIndexKey>> {
     
     @Nullable public Set<MetadataIndexKey> apply(@Nullable CriteriaSet input) {
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/SimpleStringCriterion.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/SimpleStringCriterion.java
index 09813e985..b94c1baed 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/SimpleStringCriterion.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/SimpleStringCriterion.java
@@ -26,6 +26,7 @@ import net.shibboleth.shared.resolver.Criterion;
 
 import com.google.common.base.MoreObjects;
 
+ at SuppressWarnings("javadoc")
 public class SimpleStringCriterion implements Criterion {
     @Nonnull @NotEmpty private final String value;
 
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/UppercaseEntityIdDescriptorFunction.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/UppercaseEntityIdDescriptorFunction.java
index 4e84e0b14..cf0c81e15 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/UppercaseEntityIdDescriptorFunction.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/metadata/resolver/index/impl/UppercaseEntityIdDescriptorFunction.java
@@ -17,7 +17,6 @@
 
 package org.opensaml.saml.metadata.resolver.index.impl;
 
-import java.util.Collections;
 import java.util.HashSet;
 import java.util.Set;
 import java.util.function.Function;
@@ -28,15 +27,24 @@ import org.opensaml.saml.metadata.resolver.index.MetadataIndexKey;
 import org.opensaml.saml.metadata.resolver.index.SimpleStringMetadataIndexKey;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
 
+import net.shibboleth.shared.collection.CollectionSupport;
+
+ at SuppressWarnings("javadoc")
 public class UppercaseEntityIdDescriptorFunction implements Function<EntityDescriptor, Set<MetadataIndexKey>> {
     
     @Nullable public Set<MetadataIndexKey> apply(@Nullable EntityDescriptor input) {
         if (input == null) {
-            return Collections.emptySet();
+            return CollectionSupport.emptySet();
+        }
+        
+        final String entityID = input.getEntityID();
+        if (entityID == null) {
+            return CollectionSupport.emptySet();
         }
+        
         HashSet<MetadataIndexKey> result = new HashSet<>();
         if (input != null) {
-            result.add(new SimpleStringMetadataIndexKey(input.getEntityID().toUpperCase()));
+            result.add(new SimpleStringMetadataIndexKey(entityID.toUpperCase()));
         }
         return result;
     }
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/InlineSelfEncryptionParametersStrategyTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/InlineSelfEncryptionParametersStrategyTest.java
index 5f7cf62a2..2a684d690 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/InlineSelfEncryptionParametersStrategyTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/InlineSelfEncryptionParametersStrategyTest.java
@@ -45,11 +45,10 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.collection.Pair;
 
-/**
- *
- */
+ at SuppressWarnings("javadoc")
 public class InlineSelfEncryptionParametersStrategyTest extends OpenSAMLInitBaseTestCase {
     
     private Credential cred1, cred2;
@@ -80,10 +79,9 @@ public class InlineSelfEncryptionParametersStrategyTest extends OpenSAMLInitBase
     
     @Test
     public void testNoCreds() {
-        InlineSelfEncryptionParametersStrategy strategy = new InlineSelfEncryptionParametersStrategy(credResolver, paramsResolver);
-        List<EncryptionParameters> encParameters = strategy.apply(new Pair<ProfileRequestContext, EncryptionParameters>(prc, null));
-        
-        Assert.assertNotNull(encParameters);
+        final InlineSelfEncryptionParametersStrategy strategy = new InlineSelfEncryptionParametersStrategy(credResolver, paramsResolver);
+        final List<EncryptionParameters> encParameters = strategy.apply(new Pair<ProfileRequestContext, EncryptionParameters>(prc, null));
+        assert encParameters != null;
         Assert.assertTrue(encParameters.isEmpty());
     }
     
@@ -91,15 +89,18 @@ public class InlineSelfEncryptionParametersStrategyTest extends OpenSAMLInitBase
     public void testSingleCred() {
         resolverCreds.add(cred1);
         
-        InlineSelfEncryptionParametersStrategy strategy = new InlineSelfEncryptionParametersStrategy(credResolver, paramsResolver);
-        List<EncryptionParameters> encParameters = strategy.apply(new Pair<ProfileRequestContext, EncryptionParameters>(prc, null));
+        final InlineSelfEncryptionParametersStrategy strategy = new InlineSelfEncryptionParametersStrategy(credResolver, paramsResolver);
+        final List<EncryptionParameters> encParameters = strategy.apply(new Pair<ProfileRequestContext, EncryptionParameters>(prc, null));
         
-        Assert.assertNotNull(encParameters);
+        assert encParameters != null;
         Assert.assertEquals(encParameters.size(), 1);
         Assert.assertSame(encParameters.get(0).getKeyTransportEncryptionCredential(), cred1);
         Assert.assertEquals(encParameters.get(0).getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP);
-        Assert.assertEquals(encParameters.get(0).getRSAOAEPParameters().getDigestMethod(), SignatureConstants.ALGO_ID_DIGEST_SHA1);
-        Assert.assertEquals(encParameters.get(0).getRSAOAEPParameters().getMaskGenerationFunction(), EncryptionConstants.ALGO_ID_MGF1_SHA1);
+        
+        final RSAOAEPParameters oaep = encParameters.get(0).getRSAOAEPParameters();
+        assert oaep != null;
+        Assert.assertEquals(oaep.getDigestMethod(), SignatureConstants.ALGO_ID_DIGEST_SHA1);
+        Assert.assertEquals(oaep.getMaskGenerationFunction(), EncryptionConstants.ALGO_ID_MGF1_SHA1);
     }
     
     @Test
@@ -107,42 +108,52 @@ public class InlineSelfEncryptionParametersStrategyTest extends OpenSAMLInitBase
         resolverCreds.add(cred1);
         resolverCreds.add(cred2);
         
-        InlineSelfEncryptionParametersStrategy strategy = new InlineSelfEncryptionParametersStrategy(credResolver, paramsResolver);
-        List<EncryptionParameters> encParameters = strategy.apply(new Pair<ProfileRequestContext, EncryptionParameters>(prc, null));
+        final InlineSelfEncryptionParametersStrategy strategy = new InlineSelfEncryptionParametersStrategy(credResolver, paramsResolver);
+        final List<EncryptionParameters> encParameters = strategy.apply(new Pair<ProfileRequestContext, EncryptionParameters>(prc, null));
         
-        Assert.assertNotNull(encParameters);
+        assert encParameters != null;
         Assert.assertEquals(encParameters.size(), 2);
         Assert.assertSame(encParameters.get(0).getKeyTransportEncryptionCredential(), cred1);
         Assert.assertEquals(encParameters.get(0).getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP);
-        Assert.assertEquals(encParameters.get(0).getRSAOAEPParameters().getDigestMethod(), SignatureConstants.ALGO_ID_DIGEST_SHA1);
+        
+        final RSAOAEPParameters oaep1 = encParameters.get(0).getRSAOAEPParameters();
+        assert oaep1 != null;
+        Assert.assertEquals(oaep1.getDigestMethod(), SignatureConstants.ALGO_ID_DIGEST_SHA1);
+        
         Assert.assertSame(encParameters.get(1).getKeyTransportEncryptionCredential(), cred2);
         Assert.assertEquals(encParameters.get(1).getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP);
-        Assert.assertEquals(encParameters.get(1).getRSAOAEPParameters().getDigestMethod(), SignatureConstants.ALGO_ID_DIGEST_SHA1);
+        
+        final RSAOAEPParameters oaep2 = encParameters.get(0).getRSAOAEPParameters();
+        assert oaep2 != null;
+        Assert.assertEquals(oaep2.getDigestMethod(), SignatureConstants.ALGO_ID_DIGEST_SHA1);
     }
     
     @Test
     public void testConfigLookup() {
         resolverCreds.add(cred1);
         
-        Function<ProfileRequestContext, List<EncryptionConfiguration>> configStrategy = new Function<>() {
+        final Function<ProfileRequestContext, List<EncryptionConfiguration>> configStrategy = new Function<>() {
             public List<EncryptionConfiguration> apply(@Nullable ProfileRequestContext input) {
-                BasicEncryptionConfiguration selfConfig = new BasicEncryptionConfiguration();
-                RSAOAEPParameters rsaParams = new RSAOAEPParameters();
+                final BasicEncryptionConfiguration selfConfig = new BasicEncryptionConfiguration();
+                final RSAOAEPParameters rsaParams = new RSAOAEPParameters();
                 rsaParams.setDigestMethod(EncryptionConstants.ALGO_ID_DIGEST_SHA256);
                 selfConfig.setRSAOAEPParameters(rsaParams);
                 selfConfig.setRSAOAEPParametersMerge(true);
-                return List.of(selfConfig, SecurityConfigurationSupport.getGlobalEncryptionConfiguration());
+                return CollectionSupport.listOf(selfConfig, SecurityConfigurationSupport.getGlobalEncryptionConfiguration());
         }};
         
-        InlineSelfEncryptionParametersStrategy strategy = new InlineSelfEncryptionParametersStrategy(credResolver, paramsResolver, configStrategy);
-        List<EncryptionParameters> encParameters = strategy.apply(new Pair<ProfileRequestContext, EncryptionParameters>(prc, null));
+        final InlineSelfEncryptionParametersStrategy strategy = new InlineSelfEncryptionParametersStrategy(credResolver, paramsResolver, configStrategy);
+        final List<EncryptionParameters> encParameters = strategy.apply(new Pair<ProfileRequestContext, EncryptionParameters>(prc, null));
         
-        Assert.assertNotNull(encParameters);
+        assert encParameters != null;
         Assert.assertEquals(encParameters.size(), 1);
         Assert.assertSame(encParameters.get(0).getKeyTransportEncryptionCredential(), cred1);
         Assert.assertEquals(encParameters.get(0).getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP);
-        Assert.assertEquals(encParameters.get(0).getRSAOAEPParameters().getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
+        
+        final RSAOAEPParameters oaep = encParameters.get(0).getRSAOAEPParameters();
+        assert oaep != null;
+        Assert.assertEquals(oaep.getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
     }
     
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/MetadataCredentialResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/MetadataCredentialResolverTest.java
index c2dc75b1e..1ca6ff9a0 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/MetadataCredentialResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/MetadataCredentialResolverTest.java
@@ -24,6 +24,7 @@ import java.util.ArrayList;
 import java.util.HashSet;
 import java.util.List;
 
+import javax.annotation.Nonnull;
 import javax.xml.namespace.QName;
 
 import net.shibboleth.shared.codec.EncodingException;
@@ -41,11 +42,13 @@ import org.opensaml.saml.metadata.resolver.impl.DOMMetadataResolver;
 import org.opensaml.saml.metadata.resolver.impl.PredicateRoleDescriptorResolver;
 import org.opensaml.saml.saml2.metadata.EntitiesDescriptor;
 import org.opensaml.saml.saml2.metadata.EntityDescriptor;
+import org.opensaml.saml.saml2.metadata.Extensions;
 import org.opensaml.saml.saml2.metadata.IDPSSODescriptor;
 import org.opensaml.saml.saml2.metadata.KeyDescriptor;
 import org.opensaml.saml.saml2.metadata.RoleDescriptor;
 import org.opensaml.security.SecurityException;
 import org.opensaml.security.credential.Credential;
+import org.opensaml.security.credential.CredentialContextSet;
 import org.opensaml.security.credential.UsageType;
 import org.opensaml.security.criteria.UsageCriterion;
 import org.opensaml.security.crypto.KeySupport;
@@ -167,9 +170,9 @@ public class MetadataCredentialResolverTest extends XMLObjectBaseTestCase {
         idpRSACert = X509Support.decodeCertificate(idpRSACertBase64);
         X509Support.decodeCertificate(keyAuthorityCertBase64);
         
-        Document mdDoc = parserPool.parse(MetadataCredentialResolverTest.class.getResourceAsStream(mdFileName));
+        final Document mdDoc = parserPool.parse(MetadataCredentialResolverTest.class.getResourceAsStream(mdFileName));
         
-        DOMMetadataResolver mdProvider = new DOMMetadataResolver(mdDoc.getDocumentElement());
+        final DOMMetadataResolver mdProvider = new DOMMetadataResolver(mdDoc.getDocumentElement());
         mdProvider.setId("test");
         mdProvider.initialize();
         
@@ -207,9 +210,11 @@ public class MetadataCredentialResolverTest extends XMLObjectBaseTestCase {
         
         Assert.assertEquals(resolved.size(), 3, "Incorrect number of credentials resolved");
         
-        for (Credential credential : resolved) {
+        for (final Credential credential : resolved) {
             X509Credential x509Cred;
-            switch(credential.getUsageType()) {
+            final UsageType usage = credential.getUsageType();
+            assert usage != null;
+            switch(usage) {
                 case SIGNING:
                     x509Cred = (X509Credential) credential;
                     Assert.assertEquals(x509Cred.getEntityCertificate(), idpDSACert, "Unexpected value for certificate");
@@ -247,9 +252,11 @@ public class MetadataCredentialResolverTest extends XMLObjectBaseTestCase {
         
         Assert.assertEquals(resolved.size(), 2, "Incorrect number of credentials resolved");
         
-        for (Credential credential : resolved) {
+        for (final Credential credential : resolved) {
             X509Credential x509Cred;
-            switch(credential.getUsageType()) {
+            final UsageType usage = credential.getUsageType();
+            assert usage != null;
+            switch(usage) {
                 case SIGNING:
                     Assert.fail("Credential with invalid usage was resolved");
                     break;
@@ -286,9 +293,11 @@ public class MetadataCredentialResolverTest extends XMLObjectBaseTestCase {
         
         Assert.assertEquals(resolved.size(), 2, "Incorrect number of credentials resolved");
         
-        for (Credential credential : resolved) {
+        for (final Credential credential : resolved) {
             X509Credential x509Cred;
-            switch(credential.getUsageType()) {
+            final UsageType usage = credential.getUsageType();
+            assert usage != null;
+            switch(usage) {
                 case SIGNING:
                     x509Cred = (X509Credential) credential;
                     Assert.assertEquals(x509Cred.getEntityCertificate(), idpDSACert, "Unexpected value for certificate");
@@ -324,9 +333,11 @@ public class MetadataCredentialResolverTest extends XMLObjectBaseTestCase {
         
         Assert.assertEquals(resolved.size(), 2, "Incorrect number of credentials resolved");
         
-        for (Credential credential : resolved) {
+        for (final Credential credential : resolved) {
             X509Credential x509Cred;
-            switch(credential.getUsageType()) {
+            final UsageType usage = credential.getUsageType();
+            assert usage != null;
+            switch(usage) {
                 case SIGNING:
                     x509Cred = (X509Credential) credential;
                     Assert.assertEquals(x509Cred.getEntityCertificate(), idpDSACert, "Unexpected value for certificate");
@@ -364,9 +375,11 @@ public class MetadataCredentialResolverTest extends XMLObjectBaseTestCase {
         
         Assert.assertEquals(resolved.size(), 1, "Incorrect number of credentials resolved");
         
-        for (Credential credential : resolved) {
+        for (final Credential credential : resolved) {
             X509Credential x509Cred;
-            switch(credential.getUsageType()) {
+            final UsageType usage = credential.getUsageType();
+            assert usage != null;
+            switch(usage) {
                 case SIGNING:
                     x509Cred = (X509Credential) credential;
                     Assert.assertEquals(x509Cred.getEntityCertificate(), idpDSACert, "Unexpected value for certificate");
@@ -402,8 +415,10 @@ public class MetadataCredentialResolverTest extends XMLObjectBaseTestCase {
         
         Assert.assertEquals(resolved.size(), 1, "Incorrect number of credentials resolved");
         
-        for (Credential credential : resolved) {
-            switch(credential.getUsageType()) {
+        for (final Credential credential : resolved) {
+            final UsageType usage = credential.getUsageType();
+            assert usage != null;
+            switch(usage) {
                 case SIGNING:
                     Assert.fail("Credential was resolved from invalid protocol or usage");
                     break;
@@ -439,9 +454,11 @@ public class MetadataCredentialResolverTest extends XMLObjectBaseTestCase {
         
         Assert.assertEquals(resolved.size(), 1, "Incorrect number of credentials resolved");
         
-        for (Credential credential : resolved) {
+        for (final Credential credential : resolved) {
             X509Credential x509Cred;
-            switch(credential.getUsageType()) {
+            final UsageType usage = credential.getUsageType();
+            assert usage != null;
+            switch(usage) {
                 case SIGNING:
                     Assert.fail("Credential was resolved from invalid protocol");
                     break;
@@ -477,9 +494,11 @@ public class MetadataCredentialResolverTest extends XMLObjectBaseTestCase {
         
         Assert.assertEquals(resolved.size(), 1, "Incorrect number of credentials resolved");
         
-        for (Credential credential : resolved) {
+        for (final Credential credential : resolved) {
             X509Credential x509Cred;
-            switch(credential.getUsageType()) {
+            final UsageType usage = credential.getUsageType();
+            assert usage != null;
+            switch(usage) {
                 case SIGNING:
                     Assert.fail("Credential was resolved from invalid protocol or usage");
                     break;
@@ -515,9 +534,11 @@ public class MetadataCredentialResolverTest extends XMLObjectBaseTestCase {
         
         Assert.assertEquals(resolved.size(), 1, "Incorrect number of credentials resolved");
         
-        for (Credential credential : resolved) {
+        for (final Credential credential : resolved) {
             X509Credential x509Cred;
-            switch(credential.getUsageType()) {
+            final UsageType usage = credential.getUsageType();
+            assert usage != null;
+            switch(usage) {
                 case SIGNING:
                     Assert.fail("Credential was resolved from invalid protocol or usage");
                     break;
@@ -608,9 +629,11 @@ public class MetadataCredentialResolverTest extends XMLObjectBaseTestCase {
         
         Assert.assertEquals(resolved.size(), 2);
         
-        for (Credential credential : resolved) {
+        for (final Credential credential : resolved) {
             X509Credential x509Cred;
-            switch(credential.getUsageType()) {
+            final UsageType usage = credential.getUsageType();
+            assert usage != null;
+            switch(usage) {
                 case SIGNING:
                     x509Cred = (X509Credential) credential;
                     Assert.assertEquals(x509Cred.getEntityCertificate(), idpRSACert, "Unexpected value for certificate");
@@ -672,27 +695,34 @@ public class MetadataCredentialResolverTest extends XMLObjectBaseTestCase {
      * @param role the expected type of role from the context role descriptor data
      * @param checkEntitiesDesc whether to check for and validate an EntitiesDescriptor grandparent
      */
-    private void checkContextAndID(Credential credential, String entityID, QName role, boolean checkEntitiesDesc) {
+    private void checkContextAndID(@Nonnull final Credential credential, @Nonnull String entityID, @Nonnull QName role,
+            boolean checkEntitiesDesc) {
         Assert.assertEquals(credential.getEntityId(), entityID, "Unexpected value found for credential entityID");
         
-        SAMLMDCredentialContext mdContext = credential.getCredentialContextSet().get(SAMLMDCredentialContext.class);
-        Assert.assertNotNull(mdContext, "SAMLMDCredentialContext was not available");
+        final CredentialContextSet contextSet = credential.getCredentialContextSet();
+        assert contextSet != null;
+        SAMLMDCredentialContext mdContext = contextSet.get(SAMLMDCredentialContext.class);
+        assert mdContext != null;
         
         Assert.assertNotNull(mdContext.getRoleDescriptor());
-        RoleDescriptor contextRole = mdContext.getRoleDescriptor();
+        final RoleDescriptor contextRole = mdContext.getRoleDescriptor();
+        assert contextRole != null;
         Assert.assertEquals(contextRole.getElementQName(), role, "Unexpected value for context role descriptor");
         
         Assert.assertTrue(contextRole.getParent() instanceof EntityDescriptor);
-        EntityDescriptor entityDescriptor = (EntityDescriptor) mdContext.getRoleDescriptor().getParent();
+        final EntityDescriptor entityDescriptor = (EntityDescriptor) contextRole.getParent();
+        assert entityDescriptor != null;
         Assert.assertEquals(entityDescriptor.getEntityID(), entityID, "Unexpected value for entity descriptor entity ID");
         
         if (checkEntitiesDesc) {
             Assert.assertTrue(entityDescriptor.getParent() instanceof EntitiesDescriptor);
-            EntitiesDescriptor entitiesDescriptor = (EntitiesDescriptor) entityDescriptor.getParent();
+            final EntitiesDescriptor entitiesDescriptor = (EntitiesDescriptor) entityDescriptor.getParent();
+            assert entitiesDescriptor != null;
             
-            Assert.assertNotNull(entitiesDescriptor.getExtensions());
-            Assert.assertNotNull(entitiesDescriptor.getExtensions().getUnknownXMLObjects().get(0));
+            final Extensions exts = entitiesDescriptor.getExtensions();
+            assert exts != null;
+            Assert.assertNotNull(exts.getUnknownXMLObjects().get(0));
         }
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/SAMLMetadataEncryptionParametersResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/SAMLMetadataEncryptionParametersResolverTest.java
index 75e3511b0..119cd0855 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/SAMLMetadataEncryptionParametersResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/SAMLMetadataEncryptionParametersResolverTest.java
@@ -26,16 +26,17 @@ import java.security.cert.CertificateEncodingException;
 import java.security.cert.X509Certificate;
 import java.security.spec.ECGenParameterSpec;
 import java.util.ArrayList;
-import java.util.Collections;
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
-import javax.annotation.Nullable;
+import javax.crypto.SecretKey;
 
 import net.shibboleth.shared.codec.EncodingException;
+import net.shibboleth.shared.collection.CollectionSupport;
 import net.shibboleth.shared.component.ComponentInitializationException;
 import net.shibboleth.shared.logic.ConstraintViolationException;
 import net.shibboleth.shared.resolver.CriteriaSet;
@@ -62,6 +63,7 @@ import org.opensaml.security.testing.SecurityProviderTestSupport;
 import org.opensaml.xmlsec.EncryptionParameters;
 import org.opensaml.xmlsec.KeyTransportAlgorithmPredicate;
 import org.opensaml.xmlsec.agreement.KeyAgreementCredential;
+import org.opensaml.xmlsec.agreement.KeyAgreementParameter;
 import org.opensaml.xmlsec.algorithm.AlgorithmRegistry;
 import org.opensaml.xmlsec.algorithm.AlgorithmSupport;
 import org.opensaml.xmlsec.config.GlobalAlgorithmRegistryInitializer;
@@ -89,6 +91,7 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+ at SuppressWarnings("javadoc")
 public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseTestCase {
     
     private MetadataCredentialResolver mdCredResolver;
@@ -158,7 +161,7 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         config3 = new BasicEncryptionConfiguration();
         
         // Set these as defaults on the last config in the chain, just so don't have to set in every test.
-        config3.setDataEncryptionAlgorithms(List.of(
+        config3.setDataEncryptionAlgorithms(CollectionSupport.listOf(
                 defaultAES128DataAlgo,
                 defaultAES192DataAlgo,
                 defaultAES256DataAlgo,
@@ -167,7 +170,7 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
                 EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192_GCM,
                 EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM
                 ));
-        config3.setKeyTransportEncryptionAlgorithms(List.of(
+        config3.setKeyTransportEncryptionAlgorithms(CollectionSupport.listOf(
                 defaultRSAKeyTransportAlgo, 
                 EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15,
                 EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP11,
@@ -185,7 +188,7 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         concatKDF.setPartyUInfo("00");
         concatKDF.setPartyVInfo("00");
         ecConfig.setParameters(Set.of(concatKDF));
-        config3.setKeyAgreementConfigurations(Map.of("EC", ecConfig));
+        config3.setKeyAgreementConfigurations(CollectionSupport.singletonMap("EC", ecConfig));
         
         BasicKeyInfoGeneratorFactory basicFactory1 = new BasicKeyInfoGeneratorFactory();
         X509KeyInfoGeneratorFactory x509Factory1 = new X509KeyInfoGeneratorFactory();
@@ -218,10 +221,12 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
     public void testBasic() throws ResolverException {
         roleDesc.getKeyDescriptors().add(buildKeyDescriptor(rsaCred1KeyName, UsageType.ENCRYPTION, rsaCred1.getPublicKey()));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), defaultRSAKeyTransportAlgo);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         
@@ -229,8 +234,9 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), defaultAES128DataAlgo);
         Assert.assertNull(params.getDataKeyInfoGenerator());
         
-        Assert.assertNotNull(params.getRSAOAEPParameters());
-        Assert.assertTrue(params.getRSAOAEPParameters().isEmpty());
+        final RSAOAEPParameters oaep = params.getRSAOAEPParameters();
+        assert oaep != null;
+        Assert.assertTrue(oaep.isEmpty());
     }
     
     @Test
@@ -238,10 +244,12 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         roleDesc.getKeyDescriptors().add(buildKeyDescriptor(rsaCred1KeyName, UsageType.ENCRYPTION, rsaCred1.getPublicKey()));
         config3.setRSAOAEPParameters(new RSAOAEPParameters(EncryptionConstants.ALGO_ID_DIGEST_SHA256, null, "oaep-params-3"));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), defaultRSAKeyTransportAlgo);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         
@@ -249,23 +257,26 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), defaultAES128DataAlgo);
         Assert.assertNull(params.getDataKeyInfoGenerator());
         
-        Assert.assertNotNull(params.getRSAOAEPParameters());
-        Assert.assertEquals(params.getRSAOAEPParameters().getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
-        Assert.assertNull(params.getRSAOAEPParameters().getMaskGenerationFunction());
-        Assert.assertEquals(params.getRSAOAEPParameters().getOAEPParams(), "oaep-params-3");
+        final RSAOAEPParameters oaep = params.getRSAOAEPParameters();
+        assert oaep != null;
+        Assert.assertEquals(oaep.getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
+        Assert.assertNull(oaep.getMaskGenerationFunction());
+        Assert.assertEquals(oaep.getOAEPParams(), "oaep-params-3");
     }
     
     @Test
     public void testWithAlgorithmOverrides() throws ResolverException {
         roleDesc.getKeyDescriptors().add(buildKeyDescriptor(rsaCred1KeyName, UsageType.ENCRYPTION, rsaCred1.getPublicKey()));
         
-        config2.setDataEncryptionAlgorithms(Collections.singletonList(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256));
-        config2.setKeyTransportEncryptionAlgorithms(Collections.singletonList(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15));
-        
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        config2.setDataEncryptionAlgorithms(CollectionSupport.singletonList(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256));
+        config2.setKeyTransportEncryptionAlgorithms(CollectionSupport.singletonList(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15));
         
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         
@@ -280,10 +291,12 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         
         config1.setExcludedAlgorithms(List.of(defaultRSAKeyTransportAlgo, defaultAES128DataAlgo, defaultAES192DataAlgo));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         
@@ -298,10 +311,12 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         
         config1.setIncludedAlgorithms(List.of(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256, EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         
@@ -316,17 +331,21 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         
         resolver.setAutoGenerateDataEncryptionCredential(true);
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), defaultRSAKeyTransportAlgo);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         
-        Assert.assertNotNull(params.getDataEncryptionCredential());
-        Assert.assertNotNull(params.getDataEncryptionCredential().getSecretKey());
+        final Credential dataEncCred = params.getDataEncryptionCredential();
+        assert dataEncCred != null;
+        final SecretKey skey = dataEncCred.getSecretKey();
+        assert skey != null;
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), defaultAES128DataAlgo);
-        Assert.assertEquals(KeySupport.getKeyLength(params.getDataEncryptionCredential().getSecretKey()), Integer.valueOf(128));
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(128));
         Assert.assertNotNull(params.getDataKeyInfoGenerator());
     }
     
@@ -337,10 +356,12 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         keyDescriptor.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256));
         roleDesc.getKeyDescriptors().add(keyDescriptor);
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         
@@ -365,23 +386,29 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         keyDescriptor.getEncryptionMethods().clear();
         keyDescriptor.getEncryptionMethods().add(rsaEncryptionMethod);
         params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
         Assert.assertNull(params.getRSAOAEPParameters());
         
-        // Should resolve empty instance
+        // Should resolve empty instance (need to rebuild credential again to avoid test contamination).
         rsaEncryptionMethod = buildEncryptionMethod(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP);
-        keyDescriptor.getEncryptionMethods().clear();
+        keyDescriptor = buildKeyDescriptor(rsaCred1KeyName, UsageType.ENCRYPTION, rsaCred1.getPublicKey());
         keyDescriptor.getEncryptionMethods().add(rsaEncryptionMethod);
+        roleDesc.getKeyDescriptors().clear();
+        roleDesc.getKeyDescriptors().add(keyDescriptor);
+
         params = resolver.resolveSingle(criteriaSet);
-        Assert.assertNotNull(params.getRSAOAEPParameters());
-        Assert.assertTrue(params.getRSAOAEPParameters().isEmpty());
+        assert params != null;
+
+        RSAOAEPParameters oaep = params.getRSAOAEPParameters();
+        assert oaep != null;
+        Assert.assertTrue(oaep.isEmpty());
         
         
         // Load BouncyCastle so can really test RSA OAEP 1.1 stuff.
-        AlgorithmRegistry originalRegistry = AlgorithmSupport.getGlobalAlgorithmRegistry();
-        Assert.assertNotNull(originalRegistry);
+        AlgorithmRegistry originalRegistry = AlgorithmSupport.ensureGlobalAlgorithmRegistry();
         providerSupport.loadBC();
         new GlobalAlgorithmRegistryInitializer().init();
-        resolver.setAlgorithmRegistry(AlgorithmSupport.getGlobalAlgorithmRegistry());
+        resolver.setAlgorithmRegistry(AlgorithmSupport.ensureGlobalAlgorithmRegistry());
         
         try {
             // Should resolve digest from metadata
@@ -389,13 +416,17 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
             digestMethod = buildXMLObject(DigestMethod.DEFAULT_ELEMENT_NAME);
             digestMethod.setAlgorithm(EncryptionConstants.ALGO_ID_DIGEST_SHA256);
             rsaEncryptionMethod.getUnknownXMLObjects().add(digestMethod);
-            keyDescriptor.getEncryptionMethods().clear();
+            keyDescriptor = buildKeyDescriptor(rsaCred1KeyName, UsageType.ENCRYPTION, rsaCred1.getPublicKey());
             keyDescriptor.getEncryptionMethods().add(rsaEncryptionMethod);
+            roleDesc.getKeyDescriptors().clear();
+            roleDesc.getKeyDescriptors().add(keyDescriptor);
             params = resolver.resolveSingle(criteriaSet);
-            Assert.assertNotNull(params.getRSAOAEPParameters());
-            Assert.assertEquals(params.getRSAOAEPParameters().getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
-            Assert.assertNull(params.getRSAOAEPParameters().getMaskGenerationFunction());
-            Assert.assertNull(params.getRSAOAEPParameters().getOAEPParams());
+            assert params != null;
+            oaep = params.getRSAOAEPParameters();
+            assert oaep != null;
+            Assert.assertEquals(oaep.getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
+            Assert.assertNull(oaep.getMaskGenerationFunction());
+            Assert.assertNull(oaep.getOAEPParams());
             
             // Should resolve all values from metadata
             rsaEncryptionMethod = buildEncryptionMethod(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP11);
@@ -408,13 +439,17 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
             oaepParams = buildXMLObject(OAEPparams.DEFAULT_ELEMENT_NAME);
             oaepParams.setValue("oaep-params-md");
             rsaEncryptionMethod.setOAEPparams(oaepParams);
-            keyDescriptor.getEncryptionMethods().clear();
+            keyDescriptor = buildKeyDescriptor(rsaCred1KeyName, UsageType.ENCRYPTION, rsaCred1.getPublicKey());
             keyDescriptor.getEncryptionMethods().add(rsaEncryptionMethod);
+            roleDesc.getKeyDescriptors().clear();
+            roleDesc.getKeyDescriptors().add(keyDescriptor);
             params = resolver.resolveSingle(criteriaSet);
-            Assert.assertNotNull(params.getRSAOAEPParameters());
-            Assert.assertEquals(params.getRSAOAEPParameters().getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
-            Assert.assertEquals(params.getRSAOAEPParameters().getMaskGenerationFunction(), EncryptionConstants.ALGO_ID_MGF1_SHA256);
-            Assert.assertEquals(params.getRSAOAEPParameters().getOAEPParams(), "oaep-params-md");
+            assert params != null;
+            oaep = params.getRSAOAEPParameters();
+            assert oaep != null;
+            Assert.assertEquals(oaep.getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
+            Assert.assertEquals(oaep.getMaskGenerationFunction(), EncryptionConstants.ALGO_ID_MGF1_SHA256);
+            Assert.assertEquals(oaep.getOAEPParams(), "oaep-params-md");
             
             // Should resolve digest from metadata, should NOT resolve OAEPParms from config by default
             config3.setRSAOAEPParameters(new RSAOAEPParameters(SignatureConstants.ALGO_ID_DIGEST_SHA1, null, "oaep-params-3"));
@@ -422,13 +457,17 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
             digestMethod = buildXMLObject(DigestMethod.DEFAULT_ELEMENT_NAME);
             digestMethod.setAlgorithm(EncryptionConstants.ALGO_ID_DIGEST_SHA256);
             rsaEncryptionMethod.getUnknownXMLObjects().add(digestMethod);
-            keyDescriptor.getEncryptionMethods().clear();
+            keyDescriptor = buildKeyDescriptor(rsaCred1KeyName, UsageType.ENCRYPTION, rsaCred1.getPublicKey());
             keyDescriptor.getEncryptionMethods().add(rsaEncryptionMethod);
+            roleDesc.getKeyDescriptors().clear();
+            roleDesc.getKeyDescriptors().add(keyDescriptor);
             params = resolver.resolveSingle(criteriaSet);
-            Assert.assertNotNull(params.getRSAOAEPParameters());
-            Assert.assertEquals(params.getRSAOAEPParameters().getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
-            Assert.assertNull(params.getRSAOAEPParameters().getMaskGenerationFunction());
-            Assert.assertNull(params.getRSAOAEPParameters().getOAEPParams());
+            assert params != null;
+            oaep = params.getRSAOAEPParameters();
+            assert oaep != null;
+            Assert.assertEquals(oaep.getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
+            Assert.assertNull(oaep.getMaskGenerationFunction());
+            Assert.assertNull(oaep.getOAEPParams());
             
             // Should resolve digest from metadata, should resolve OAEPParms from config3
             config3.setRSAOAEPParameters(new RSAOAEPParameters(SignatureConstants.ALGO_ID_DIGEST_SHA1, null, "oaep-params-3"));
@@ -437,13 +476,17 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
             digestMethod = buildXMLObject(DigestMethod.DEFAULT_ELEMENT_NAME);
             digestMethod.setAlgorithm(EncryptionConstants.ALGO_ID_DIGEST_SHA256);
             rsaEncryptionMethod.getUnknownXMLObjects().add(digestMethod);
-            keyDescriptor.getEncryptionMethods().clear();
+            keyDescriptor = buildKeyDescriptor(rsaCred1KeyName, UsageType.ENCRYPTION, rsaCred1.getPublicKey());
             keyDescriptor.getEncryptionMethods().add(rsaEncryptionMethod);
+            roleDesc.getKeyDescriptors().clear();
+            roleDesc.getKeyDescriptors().add(keyDescriptor);
             params = resolver.resolveSingle(criteriaSet);
-            Assert.assertNotNull(params.getRSAOAEPParameters());
-            Assert.assertEquals(params.getRSAOAEPParameters().getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
-            Assert.assertNull(params.getRSAOAEPParameters().getMaskGenerationFunction());
-            Assert.assertEquals(params.getRSAOAEPParameters().getOAEPParams(), "oaep-params-3");
+            assert params != null;
+            oaep = params.getRSAOAEPParameters();
+            assert oaep != null;
+            Assert.assertEquals(oaep.getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
+            Assert.assertNull(oaep.getMaskGenerationFunction());
+            Assert.assertEquals(oaep.getOAEPParams(), "oaep-params-3");
         
         } finally {
             providerSupport.unloadBC();
@@ -470,6 +513,7 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         
         // Without the predicate, for control
         EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256);
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP);
         
@@ -477,18 +521,22 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         
         // Explicit preference with predicate, mapping # 1
         params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256);
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15);
         
-        // Change algo ordering
-        keyDescriptor.getEncryptionMethods().clear();
+        // Change algo ordering (but don't depend on the underlying credential context to be live).
+        keyDescriptor = buildKeyDescriptor(rsaCred1KeyName, UsageType.ENCRYPTION, rsaCred1.getPublicKey());
         keyDescriptor.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15));
         keyDescriptor.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP));
         keyDescriptor.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192));
         keyDescriptor.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES128));
+        roleDesc.getKeyDescriptors().clear();
+        roleDesc.getKeyDescriptors().add(keyDescriptor);
         
         // Explicit preference with predicate, mapping # 2
         params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192);
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP);
         
@@ -503,10 +551,12 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         
         config1.setExcludedAlgorithms(List.of(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSA15, EncryptionConstants.ALGO_ID_BLOCKCIPHER_TRIPLEDES));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), defaultRSAKeyTransportAlgo);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         
@@ -524,10 +574,12 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         
         config1.setIncludedAlgorithms(List.of(EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP, EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES192));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         
@@ -561,16 +613,20 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         
         config1.setExcludedAlgorithms(List.of(SignatureConstants.ALGO_ID_DIGEST_SHA1));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYTRANSPORT_RSAOAEP);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
-        Assert.assertNotNull(params.getRSAOAEPParameters());
-        Assert.assertEquals(params.getRSAOAEPParameters().getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
-        Assert.assertNull(params.getRSAOAEPParameters().getMaskGenerationFunction());
-        Assert.assertNull(params.getRSAOAEPParameters().getOAEPParams());
+        
+        final RSAOAEPParameters oaep = params.getRSAOAEPParameters();
+        assert oaep != null;
+        Assert.assertEquals(oaep.getDigestMethod(), EncryptionConstants.ALGO_ID_DIGEST_SHA256);
+        Assert.assertNull(oaep.getMaskGenerationFunction());
+        Assert.assertNull(oaep.getOAEPParams());
         
         Assert.assertNull(params.getDataEncryptionCredential());
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), defaultAES128DataAlgo);
@@ -582,18 +638,22 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         KeyDescriptor kd = buildKeyDescriptor(ecCred1KeyName, UsageType.ENCRYPTION, ecCred1.getPublicKey());
         roleDesc.getKeyDescriptors().add(kd);
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
         Assert.assertNull(params.getKeyTransportEncryptionCredential());
         Assert.assertNull(params.getKeyTransportEncryptionAlgorithm());
         Assert.assertNull(params.getKeyTransportKeyInfoGenerator());
         
         Assert.assertNotNull(params.getDataEncryptionCredential());
         Assert.assertTrue(KeyAgreementCredential.class.isInstance(params.getDataEncryptionCredential()));
-        Assert.assertNotNull(params.getDataEncryptionCredential().getSecretKey());
-        Assert.assertEquals(params.getDataEncryptionCredential().getSecretKey().getAlgorithm(), "AES");
-        Assert.assertEquals(KeySupport.getKeyLength(params.getDataEncryptionCredential().getSecretKey()), Integer.valueOf(128));
+        
+        final Credential dataEncCred = params.getDataEncryptionCredential();
+        assert dataEncCred != null;
+        final SecretKey skey = dataEncCred.getSecretKey();
+        assert skey != null;
+        Assert.assertEquals(skey.getAlgorithm(), "AES");
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(128));
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), defaultAES128DataAlgo);
         Assert.assertNotNull(params.getDataKeyInfoGenerator());
         Assert.assertTrue(KeyAgreementKeyInfoGenerator.class.isInstance(params.getDataKeyInfoGenerator()));
@@ -608,14 +668,17 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         ecConfig.setMetadataUseKeyWrap(KeyWrap.Always);
         config2.setKeyAgreementConfigurations(Map.of("EC", ecConfig));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
         Assert.assertNotNull(params.getKeyTransportEncryptionCredential());
         Assert.assertTrue(KeyAgreementCredential.class.isInstance(params.getKeyTransportEncryptionCredential()));
-        Assert.assertNotNull(params.getKeyTransportEncryptionCredential().getSecretKey());
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getSecretKey().getAlgorithm(), "AES");
-        Assert.assertEquals(KeySupport.getKeyLength(params.getKeyTransportEncryptionCredential().getSecretKey()), Integer.valueOf(128));
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        SecretKey skey = keyTransportCred.getSecretKey();
+        assert skey != null;
+        Assert.assertEquals(skey.getAlgorithm(), "AES");
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(128));
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYWRAP_AES128);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         Assert.assertTrue(KeyAgreementKeyInfoGenerator.class.isInstance(params.getKeyTransportKeyInfoGenerator()));
@@ -634,17 +697,22 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         ecConfig.setMetadataUseKeyWrap(KeyWrap.Never);
         config2.setKeyAgreementConfigurations(Map.of("EC", ecConfig));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
         Assert.assertNull(params.getKeyTransportEncryptionCredential());
         Assert.assertNull(params.getKeyTransportEncryptionAlgorithm());
         Assert.assertNull(params.getKeyTransportKeyInfoGenerator());
         
         Assert.assertNotNull(params.getDataEncryptionCredential());
         Assert.assertTrue(KeyAgreementCredential.class.isInstance(params.getDataEncryptionCredential()));
-        Assert.assertNotNull(params.getDataEncryptionCredential().getSecretKey());
-        Assert.assertEquals(params.getDataEncryptionCredential().getSecretKey().getAlgorithm(), "AES");
-        Assert.assertEquals(KeySupport.getKeyLength(params.getDataEncryptionCredential().getSecretKey()), Integer.valueOf(128));
+
+        final Credential dataEncCred = params.getDataEncryptionCredential();
+        assert dataEncCred != null;
+        final SecretKey skey = dataEncCred.getSecretKey();
+        assert skey != null;
+        Assert.assertEquals(skey.getAlgorithm(), "AES");
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(128));
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), defaultAES128DataAlgo);
         Assert.assertNotNull(params.getDataKeyInfoGenerator());
         Assert.assertTrue(KeyAgreementKeyInfoGenerator.class.isInstance(params.getDataKeyInfoGenerator()));
@@ -659,14 +727,17 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         ecConfig.setMetadataUseKeyWrap(KeyWrap.IfNotIndicated);
         config2.setKeyAgreementConfigurations(Map.of("EC", ecConfig));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
         Assert.assertNotNull(params.getKeyTransportEncryptionCredential());
         Assert.assertTrue(KeyAgreementCredential.class.isInstance(params.getKeyTransportEncryptionCredential()));
-        Assert.assertNotNull(params.getKeyTransportEncryptionCredential().getSecretKey());
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getSecretKey().getAlgorithm(), "AES");
-        Assert.assertEquals(KeySupport.getKeyLength(params.getKeyTransportEncryptionCredential().getSecretKey()), Integer.valueOf(128));
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        SecretKey skey = keyTransportCred.getSecretKey();
+        assert skey != null;
+        Assert.assertEquals(skey.getAlgorithm(), "AES");
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(128));
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYWRAP_AES128);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         Assert.assertTrue(KeyAgreementKeyInfoGenerator.class.isInstance(params.getKeyTransportKeyInfoGenerator()));
@@ -682,18 +753,21 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         kd.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM));
         roleDesc.getKeyDescriptors().add(kd);
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
         Assert.assertNull(params.getKeyTransportEncryptionCredential());
         Assert.assertNull(params.getKeyTransportEncryptionAlgorithm());
         Assert.assertNull(params.getKeyTransportKeyInfoGenerator());
         
         Assert.assertNotNull(params.getDataEncryptionCredential());
         Assert.assertTrue(KeyAgreementCredential.class.isInstance(params.getDataEncryptionCredential()));
-        Assert.assertNotNull(params.getDataEncryptionCredential().getSecretKey());
-        Assert.assertEquals(params.getDataEncryptionCredential().getSecretKey().getAlgorithm(), "AES");
-        Assert.assertEquals(KeySupport.getKeyLength(params.getDataEncryptionCredential().getSecretKey()), Integer.valueOf(256));
+        final Credential dataEncCred = params.getDataEncryptionCredential();
+        assert dataEncCred != null;
+        final SecretKey skey = dataEncCred.getSecretKey();
+        assert skey != null;
+        Assert.assertEquals(skey.getAlgorithm(), "AES");
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(256));
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM);
         Assert.assertNotNull(params.getDataKeyInfoGenerator());
         Assert.assertTrue(KeyAgreementKeyInfoGenerator.class.isInstance(params.getDataKeyInfoGenerator()));
@@ -709,14 +783,17 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         ecConfig.setMetadataUseKeyWrap(KeyWrap.Always);
         config2.setKeyAgreementConfigurations(Map.of("EC", ecConfig));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
         Assert.assertNotNull(params.getKeyTransportEncryptionCredential());
         Assert.assertTrue(KeyAgreementCredential.class.isInstance(params.getKeyTransportEncryptionCredential()));
-        Assert.assertNotNull(params.getKeyTransportEncryptionCredential().getSecretKey());
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getSecretKey().getAlgorithm(), "AES");
-        Assert.assertEquals(KeySupport.getKeyLength(params.getKeyTransportEncryptionCredential().getSecretKey()), Integer.valueOf(128));
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        SecretKey skey = keyTransportCred.getSecretKey();
+        assert skey != null;
+        Assert.assertEquals(skey.getAlgorithm(), "AES");
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(128));
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYWRAP_AES128);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         Assert.assertTrue(KeyAgreementKeyInfoGenerator.class.isInstance(params.getKeyTransportKeyInfoGenerator()));
@@ -733,13 +810,17 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         kd.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_KEYWRAP_AES256));
         roleDesc.getKeyDescriptors().add(kd);
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
         Assert.assertNotNull(params.getKeyTransportEncryptionCredential());
         Assert.assertTrue(KeyAgreementCredential.class.isInstance(params.getKeyTransportEncryptionCredential()));
-        Assert.assertNotNull(params.getKeyTransportEncryptionCredential().getSecretKey());
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getSecretKey().getAlgorithm(), "AES");
-        Assert.assertEquals(KeySupport.getKeyLength(params.getKeyTransportEncryptionCredential().getSecretKey()), Integer.valueOf(256));
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        SecretKey skey = keyTransportCred.getSecretKey();
+        assert skey != null;
+        Assert.assertEquals(skey.getAlgorithm(), "AES");
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(256));
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYWRAP_AES256);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         Assert.assertTrue(KeyAgreementKeyInfoGenerator.class.isInstance(params.getKeyTransportKeyInfoGenerator()));
@@ -759,7 +840,8 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         ecConfig.setMetadataUseKeyWrap(KeyWrap.Never);
         config2.setKeyAgreementConfigurations(Map.of("EC", ecConfig));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
         
         Assert.assertNull(params.getKeyTransportEncryptionCredential());
         Assert.assertNull(params.getKeyTransportEncryptionAlgorithm());
@@ -767,9 +849,12 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         
         Assert.assertNotNull(params.getDataEncryptionCredential());
         Assert.assertTrue(KeyAgreementCredential.class.isInstance(params.getDataEncryptionCredential()));
-        Assert.assertNotNull(params.getDataEncryptionCredential().getSecretKey());
-        Assert.assertEquals(params.getDataEncryptionCredential().getSecretKey().getAlgorithm(), "AES");
-        Assert.assertEquals(KeySupport.getKeyLength(params.getDataEncryptionCredential().getSecretKey()), Integer.valueOf(128));
+        final Credential dataEncCred = params.getDataEncryptionCredential();
+        assert dataEncCred != null;
+        final SecretKey skey = dataEncCred.getSecretKey();
+        assert skey != null;
+        Assert.assertEquals(skey.getAlgorithm(), "AES");
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(128));
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), defaultAES128DataAlgo);
         Assert.assertNotNull(params.getDataKeyInfoGenerator());
         Assert.assertTrue(KeyAgreementKeyInfoGenerator.class.isInstance(params.getDataKeyInfoGenerator()));
@@ -782,13 +867,17 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         kd.getEncryptionMethods().add(buildEncryptionMethod(EncryptionConstants.ALGO_ID_KEYWRAP_AES256));
         roleDesc.getKeyDescriptors().add(kd);
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
         
         Assert.assertNotNull(params.getKeyTransportEncryptionCredential());
         Assert.assertTrue(KeyAgreementCredential.class.isInstance(params.getKeyTransportEncryptionCredential()));
-        Assert.assertNotNull(params.getKeyTransportEncryptionCredential().getSecretKey());
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getSecretKey().getAlgorithm(), "AES");
-        Assert.assertEquals(KeySupport.getKeyLength(params.getKeyTransportEncryptionCredential().getSecretKey()), Integer.valueOf(256));
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        SecretKey skey = keyTransportCred.getSecretKey();
+        assert skey != null;
+        Assert.assertEquals(skey.getAlgorithm(), "AES");
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(256));
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYWRAP_AES256);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         Assert.assertTrue(KeyAgreementKeyInfoGenerator.class.isInstance(params.getKeyTransportKeyInfoGenerator()));
@@ -806,21 +895,27 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         
         resolver.setAutoGenerateDataEncryptionCredential(true);
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
         Assert.assertNotNull(params.getKeyTransportEncryptionCredential());
         Assert.assertTrue(KeyAgreementCredential.class.isInstance(params.getKeyTransportEncryptionCredential()));
-        Assert.assertNotNull(params.getKeyTransportEncryptionCredential().getSecretKey());
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getSecretKey().getAlgorithm(), "AES");
-        Assert.assertEquals(KeySupport.getKeyLength(params.getKeyTransportEncryptionCredential().getSecretKey()), Integer.valueOf(256));
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        SecretKey skey = keyTransportCred.getSecretKey();
+        assert skey != null;
+        Assert.assertEquals(skey.getAlgorithm(), "AES");
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(256));
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_KEYWRAP_AES256);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         Assert.assertTrue(KeyAgreementKeyInfoGenerator.class.isInstance(params.getKeyTransportKeyInfoGenerator()));
         
-        Assert.assertNotNull(params.getDataEncryptionCredential());
-        Assert.assertNotNull(params.getDataEncryptionCredential().getSecretKey());
-        Assert.assertEquals(params.getDataEncryptionCredential().getSecretKey().getAlgorithm(), "AES");
-        Assert.assertEquals(KeySupport.getKeyLength(params.getDataEncryptionCredential().getSecretKey()), Integer.valueOf(128));
+        final Credential dataEncCred = params.getDataEncryptionCredential();
+        assert dataEncCred != null;
+        skey = dataEncCred.getSecretKey();
+        assert skey != null;
+        Assert.assertEquals(skey.getAlgorithm(), "AES");
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(128));
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), defaultAES128DataAlgo);
         Assert.assertNotNull(params.getDataKeyInfoGenerator());
     }
@@ -836,18 +931,20 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         ecConfig.setParameters(Set.of(kdf));
         config2.setKeyAgreementConfigurations(Map.of("EC", ecConfig));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
         Assert.assertNull(params.getKeyTransportEncryptionCredential());
         Assert.assertNull(params.getKeyTransportEncryptionAlgorithm());
         Assert.assertNull(params.getKeyTransportKeyInfoGenerator());
         
         Assert.assertNotNull(params.getDataEncryptionCredential());
         Assert.assertTrue(KeyAgreementCredential.class.isInstance(params.getDataEncryptionCredential()));
-        Assert.assertNotNull(params.getDataEncryptionCredential().getSecretKey());
-        Assert.assertEquals(params.getDataEncryptionCredential().getSecretKey().getAlgorithm(), "AES");
-        Assert.assertEquals(KeySupport.getKeyLength(params.getDataEncryptionCredential().getSecretKey()), Integer.valueOf(256));
+        final Credential dataEncCred = params.getDataEncryptionCredential();
+        assert dataEncCred != null;
+        final SecretKey skey = dataEncCred.getSecretKey();
+        assert skey != null;
+        Assert.assertEquals(skey.getAlgorithm(), "AES");
+        Assert.assertEquals(KeySupport.getKeyLength(skey), Integer.valueOf(256));
         Assert.assertEquals(params.getDataEncryptionAlgorithm(), EncryptionConstants.ALGO_ID_BLOCKCIPHER_AES256_GCM);
         Assert.assertNotNull(params.getDataKeyInfoGenerator());
         Assert.assertTrue(KeyAgreementKeyInfoGenerator.class.isInstance(params.getDataKeyInfoGenerator()));
@@ -859,28 +956,30 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
     
     @Test
     public void testGetEffectiveKeyAgreementConfiguration() {
-        SAMLMetadataKeyAgreementEncryptionConfiguration ecConfig1 = new SAMLMetadataKeyAgreementEncryptionConfiguration();
+        final SAMLMetadataKeyAgreementEncryptionConfiguration ecConfig1 = new SAMLMetadataKeyAgreementEncryptionConfiguration();
         ecConfig1.setMetadataUseKeyWrap(KeyWrap.Always);
         config1.setKeyAgreementConfigurations(Map.of("EC", ecConfig1));
         
-        SAMLMetadataKeyAgreementEncryptionConfiguration ecConfig2 = new SAMLMetadataKeyAgreementEncryptionConfiguration();
+        final SAMLMetadataKeyAgreementEncryptionConfiguration ecConfig2 = new SAMLMetadataKeyAgreementEncryptionConfiguration();
         ecConfig2.setAlgorithm(EncryptionConstants.ALGO_ID_KEYAGREEMENT_ECDH_ES);
         ecConfig2.setParameters(Set.of(new PBKDF2()));
         ecConfig2.setMetadataUseKeyWrap(KeyWrap.IfNotIndicated);
         config2.setKeyAgreementConfigurations(Map.of("EC", ecConfig2));
         
-        SAMLMetadataKeyAgreementEncryptionConfiguration ecConfig3 = new SAMLMetadataKeyAgreementEncryptionConfiguration();
+        final SAMLMetadataKeyAgreementEncryptionConfiguration ecConfig3 = new SAMLMetadataKeyAgreementEncryptionConfiguration();
         ecConfig3.setAlgorithm("SomeAlgo");
         ecConfig3.setParameters(Set.of(new ConcatKDF()));
         ecConfig3.setMetadataUseKeyWrap(KeyWrap.Default);
         config3.setKeyAgreementConfigurations(Map.of("EC", ecConfig3));
         
-        SAMLMetadataKeyAgreementEncryptionConfiguration config = resolver.getEffectiveKeyAgreementConfiguration(criteriaSet, ecCred1);
-        
+        final SAMLMetadataKeyAgreementEncryptionConfiguration config = resolver.getEffectiveKeyAgreementConfiguration(criteriaSet, ecCred1);
+        assert config != null;
         Assert.assertEquals(config.getAlgorithm(), EncryptionConstants.ALGO_ID_KEYAGREEMENT_ECDH_ES);
         Assert.assertEquals(config.getMetadataUseKeyWrap(), KeyWrap.Always);
-        Assert.assertEquals(config.getParameters().size(), 1);
-        Assert.assertTrue(PBKDF2.class.isInstance(config.getParameters().iterator().next()));
+        final Collection<KeyAgreementParameter> agreementParams = config.getParameters();
+        assert agreementParams != null;
+        Assert.assertEquals(agreementParams.size(), 1);
+        Assert.assertTrue(PBKDF2.class.isInstance(agreementParams.iterator().next()));
     }
     
     @Test
@@ -896,12 +995,14 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         Assert.assertEquals(resolver.getDefaultKeyAgreemenUseKeyWrap(), KeyWrap.Default);
         
         SAMLMetadataKeyAgreementEncryptionConfiguration config = resolver.getEffectiveKeyAgreementConfiguration(criteria, ecCred1);
+        assert config != null;
         Assert.assertEquals(config.getMetadataUseKeyWrap(), KeyWrap.Default);
         
         resolver.setDefaultKeyAgreementUseKeyWrap(KeyWrap.Always);
         Assert.assertEquals(resolver.getDefaultKeyAgreemenUseKeyWrap(), KeyWrap.Always);
         
         config = resolver.getEffectiveKeyAgreementConfiguration(criteria, ecCred1);
+        assert config != null;
         Assert.assertEquals(config.getMetadataUseKeyWrap(), KeyWrap.Always);
     }
     
@@ -910,10 +1011,12 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         roleDesc.getKeyDescriptors().add(buildKeyDescriptor(dsaCred1KeyName, UsageType.SIGNING, dsaCred1.getPublicKey()));
         roleDesc.getKeyDescriptors().add(buildKeyDescriptor(rsaCred1KeyName, UsageType.ENCRYPTION, rsaCred1.getPublicKey()));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), defaultRSAKeyTransportAlgo);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         
@@ -944,10 +1047,12 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
     public void testRSACredWithUnspecifiedUse() throws ResolverException {
         roleDesc.getKeyDescriptors().add(buildKeyDescriptor(rsaCred1KeyName, null, rsaCred1.getPublicKey()));
         
-        EncryptionParameters params = resolver.resolveSingle(criteriaSet);
-        
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
+
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), defaultRSAKeyTransportAlgo);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         
@@ -967,6 +1072,7 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         defaultKeyTransportKeyInfoGeneratorManager.setUseDefaultManager(true);
         
         EncryptionParameters params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
         
         Assert.assertNotNull(params.getDataKeyInfoGenerator());
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
@@ -975,6 +1081,7 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         defaultKeyTransportKeyInfoGeneratorManager.setUseDefaultManager(false);
         
         params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
         
         Assert.assertNull(params.getDataKeyInfoGenerator());
         Assert.assertNull(params.getKeyTransportKeyInfoGenerator());
@@ -985,6 +1092,7 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         defaultKeyTransportKeyInfoGeneratorManager.registerFactory("testKeyInfoProfile", new BasicKeyInfoGeneratorFactory());
         
         params = resolver.resolveSingle(criteriaSet);
+        assert params != null;
         
         Assert.assertNotNull(params.getDataKeyInfoGenerator());
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
@@ -1003,9 +1111,12 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
         Assert.assertTrue(iterator.hasNext());
         
         EncryptionParameters params = iterator.next();
+        assert params != null;
         
-        Assert.assertNotNull(params);
-        Assert.assertEquals(params.getKeyTransportEncryptionCredential().getPublicKey(), rsaCred1.getPublicKey());
+        final Credential keyTransportCred = params.getKeyTransportEncryptionCredential();
+        assert keyTransportCred != null;
+        Assert.assertEquals(keyTransportCred.getPublicKey(), rsaCred1.getPublicKey());
+
         Assert.assertEquals(params.getKeyTransportEncryptionAlgorithm(), defaultRSAKeyTransportAlgo);
         Assert.assertNotNull(params.getKeyTransportKeyInfoGenerator());
         
@@ -1119,7 +1230,7 @@ public class SAMLMetadataEncryptionParametersResolverTest extends XMLObjectBaseT
             algoMap = map;
         }
         
-        public boolean test(@Nullable SelectionInput input) {
+        public boolean test(SelectionInput input) {
             return this.algoMap.get(input.getDataEncryptionAlgorithm()).equals(input.getKeyTransportAlgorithm());
         }
     }
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/SAMLMetadataSignatureSigningParametersResolverTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/SAMLMetadataSignatureSigningParametersResolverTest.java
index 6fd7f2add..3c521b327 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/SAMLMetadataSignatureSigningParametersResolverTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/SAMLMetadataSignatureSigningParametersResolverTest.java
@@ -55,6 +55,7 @@ import org.testng.annotations.BeforeClass;
 import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.Test;
 
+ at SuppressWarnings("javadoc")
 public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjectBaseTestCase {
     
     private SAMLMetadataSignatureSigningParametersResolver resolver;
@@ -145,9 +146,9 @@ public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjec
     public void testBasicRSA() throws ResolverException {
         config1.setSigningCredentials(Collections.singletonList(rsaCred2048));
         
-        SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
+        final SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
         
-        Assert.assertNotNull(params);
+        assert params != null;
         Assert.assertEquals(params.getSigningCredential(), rsaCred2048);
         Assert.assertEquals(params.getSignatureAlgorithm(), defaultRSAAlgo);
         Assert.assertEquals(params.getSignatureReferenceDigestMethod(), defaultReferenceDigest);
@@ -162,9 +163,9 @@ public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjec
         
         addRoleDescriptorExtension(roleDesc, buildSigningMethod(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256, null, null));
         
-        SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
+        final SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
         
-        Assert.assertNotNull(params);
+        assert params != null;
         Assert.assertEquals(params.getSigningCredential(), rsaCred2048);
         Assert.assertEquals(params.getSignatureAlgorithm(), SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
         Assert.assertEquals(params.getSignatureReferenceDigestMethod(), defaultReferenceDigest);
@@ -179,9 +180,9 @@ public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjec
         
         addEntityDescriptorExtension(roleDesc, buildSigningMethod(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256, null, null));
         
-        SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
+        final SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
         
-        Assert.assertNotNull(params);
+        assert params != null;
         Assert.assertEquals(params.getSigningCredential(), rsaCred2048);
         Assert.assertEquals(params.getSignatureAlgorithm(), SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
         Assert.assertEquals(params.getSignatureReferenceDigestMethod(), defaultReferenceDigest);
@@ -196,9 +197,9 @@ public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjec
         
         addRoleDescriptorExtension(roleDesc, buildDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256));
         
-        SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
+        final SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
         
-        Assert.assertNotNull(params);
+        assert params != null;
         Assert.assertEquals(params.getSigningCredential(), rsaCred2048);
         Assert.assertEquals(params.getSignatureAlgorithm(), defaultRSAAlgo);
         Assert.assertEquals(params.getSignatureReferenceDigestMethod(), SignatureConstants.ALGO_ID_DIGEST_SHA256);
@@ -213,9 +214,9 @@ public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjec
         
         addEntityDescriptorExtension(roleDesc, buildDigestMethod(SignatureConstants.ALGO_ID_DIGEST_SHA256));
         
-        SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
+        final SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
         
-        Assert.assertNotNull(params);
+        assert params != null;
         Assert.assertEquals(params.getSigningCredential(), rsaCred2048);
         Assert.assertEquals(params.getSignatureAlgorithm(), defaultRSAAlgo);
         Assert.assertEquals(params.getSignatureReferenceDigestMethod(), SignatureConstants.ALGO_ID_DIGEST_SHA256);
@@ -234,9 +235,9 @@ public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjec
         addRoleDescriptorExtension(roleDesc, buildSigningMethod(SignatureConstants.ALGO_ID_SIGNATURE_DSA_SHA1, null, null));
         addRoleDescriptorExtension(roleDesc, buildSigningMethod(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256, null, null));
         
-        SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
+        final SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
         
-        Assert.assertNotNull(params);
+        assert params != null;
         Assert.assertEquals(params.getSigningCredential(), rsaCred2048);
         Assert.assertEquals(params.getSignatureAlgorithm(), SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
         Assert.assertEquals(params.getSignatureReferenceDigestMethod(), defaultReferenceDigest);
@@ -253,9 +254,9 @@ public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjec
         
         addRoleDescriptorExtension(roleDesc, buildDigestMethod(SignatureConstants.ALGO_ID_DIGEST_NOT_RECOMMENDED_MD5));
         
-        SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
+        final SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
         
-        Assert.assertNotNull(params);
+        assert params != null;
         Assert.assertEquals(params.getSigningCredential(), rsaCred2048);
         Assert.assertEquals(params.getSignatureAlgorithm(), defaultRSAAlgo);
         Assert.assertEquals(params.getSignatureReferenceDigestMethod(), defaultReferenceDigest);
@@ -275,9 +276,9 @@ public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjec
             addRoleDescriptorExtension(roleDesc, buildSigningMethod(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256, null, null));
             addRoleDescriptorExtension(roleDesc, buildSigningMethod(SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256, null, null));
             
-            SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
+            final SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
             
-            Assert.assertNotNull(params);
+            assert params != null;
             Assert.assertEquals(params.getSigningCredential(), ecCred);
             Assert.assertEquals(params.getSignatureAlgorithm(), SignatureConstants.ALGO_ID_SIGNATURE_ECDSA_SHA256);
             Assert.assertEquals(params.getSignatureReferenceDigestMethod(), defaultReferenceDigest);
@@ -293,9 +294,9 @@ public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjec
         
         addRoleDescriptorExtension(roleDesc, buildSigningMethod(SignatureConstants.ALGO_ID_SIGNATURE_DSA_SHA1, null, null));
         
-        SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
+        final SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
         
-        Assert.assertNotNull(params);
+        assert params != null;
         Assert.assertEquals(params.getSigningCredential(), dsaCred);
         Assert.assertEquals(params.getSignatureAlgorithm(), defaultDSAAlgo);
         Assert.assertEquals(params.getSignatureReferenceDigestMethod(), defaultReferenceDigest);
@@ -310,9 +311,9 @@ public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjec
         
         addRoleDescriptorExtension(roleDesc, buildSigningMethod(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256, 4096, null));
         
-        SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
+        final SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
         
-        Assert.assertNotNull(params);
+        assert params != null;
         Assert.assertEquals(params.getSigningCredential(), rsaCred4096);
         Assert.assertEquals(params.getSignatureAlgorithm(), SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
         Assert.assertEquals(params.getSignatureReferenceDigestMethod(), defaultReferenceDigest);
@@ -327,9 +328,9 @@ public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjec
         
         addRoleDescriptorExtension(roleDesc, buildSigningMethod(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256, null, 1024));
         
-        SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
+        final SignatureSigningParameters params = resolver.resolveSingle(criteriaSet);
         
-        Assert.assertNotNull(params);
+        assert params != null;
         Assert.assertEquals(params.getSigningCredential(), rsaCred1024);
         Assert.assertEquals(params.getSignatureAlgorithm(), SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256);
         Assert.assertEquals(params.getSignatureReferenceDigestMethod(), defaultReferenceDigest);
@@ -425,6 +426,7 @@ public class SAMLMetadataSignatureSigningParametersResolverTest extends XMLObjec
     
     private void addEntityDescriptorExtension(RoleDescriptor roleDescriptor, XMLObject extension) {
         EntityDescriptor entityDescriptor = (EntityDescriptor) roleDescriptor.getParent();
+        assert entityDescriptor != null;
         Extensions extensions = entityDescriptor.getExtensions();
         if (extensions == null) {
             extensions = buildExtensions();
diff --git a/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/SAMLSignatureProfileValidatorTest.java b/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/SAMLSignatureProfileValidatorTest.java
index 7ab96daca..4a41d919b 100644
--- a/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/SAMLSignatureProfileValidatorTest.java
+++ b/opensaml-saml-impl/src/test/java/org/opensaml/saml/security/impl/SAMLSignatureProfileValidatorTest.java
@@ -18,8 +18,14 @@
 package org.opensaml.saml.security.impl;
 
 import org.testng.annotations.Test;
+
+import net.shibboleth.shared.logic.Constraint;
+
 import org.testng.annotations.BeforeMethod;
 import org.testng.Assert;
+
+import javax.annotation.Nonnull;
+
 import org.opensaml.core.testing.XMLObjectBaseTestCase;
 import org.opensaml.saml.common.SignableSAMLObject;
 import org.opensaml.xmlsec.signature.Signature;
@@ -29,6 +35,7 @@ import org.opensaml.xmlsec.signature.support.SignatureException;
 /**
  * Test the SAML XML Signature profile validator.
  */
+ at SuppressWarnings("javadoc")
 public class SAMLSignatureProfileValidatorTest extends XMLObjectBaseTestCase {
     
     private SAMLSignatureProfileValidator validator;
@@ -107,9 +114,10 @@ public class SAMLSignatureProfileValidatorTest extends XMLObjectBaseTestCase {
      * @param filename file containing a signed SignableSAMLObject as its document element.
      * @return the signature from the indicated element
      */
-    protected Signature getSignature(String filename) {
+    @Nonnull protected Signature getSignature(@Nonnull String filename) {
         SignableSAMLObject signableObj = (SignableSAMLObject) unmarshallElement(filename);
-        return signableObj.getSignature();
+        assert signableObj != null;
+        return Constraint.isNotNull(signableObj.getSignature(), "Signature was null");
     }
     
     /**
@@ -119,10 +127,10 @@ public class SAMLSignatureProfileValidatorTest extends XMLObjectBaseTestCase {
      * @param message failure message if the validation does not pass
      * @param validateTarget the XMLObject to validate
      */
-    protected void assertValidationPass(String message, Signature validateTarget) {
+    protected void assertValidationPass(@Nonnull String message, @Nonnull Signature validateTarget) {
        try {
            validator.validate(validateTarget);
-       } catch (SignatureException e) {
+       } catch (final SignatureException e) {
            Assert.fail(message + " : Expected success, but validation failure raised ValidationException: " + e.getMessage());
        }
     }
@@ -134,13 +142,12 @@ public class SAMLSignatureProfileValidatorTest extends XMLObjectBaseTestCase {
      * @param message failure message if the validation does not fail
      * @param validateTarget XMLObject to validate
      */
-    protected void assertValidationFail(String message, Signature validateTarget) {
+    protected void assertValidationFail(@Nonnull String message, @Nonnull Signature validateTarget) {
        try {
            validator.validate(validateTarget);
            Assert.fail(message + " : Validation success, expected failure to raise ValidationException");
-       } catch (SignatureException e) {
+       } catch (final SignatureException e) {
        }
     }
     
-
-}
+}
\ No newline at end of file
diff --git a/opensaml-security-impl/src/main/java/org/opensaml/security/credential/impl/AbstractCriteriaFilteringCredentialResolver.java b/opensaml-security-impl/src/main/java/org/opensaml/security/credential/impl/AbstractCriteriaFilteringCredentialResolver.java
index 2dd612a44..a50f4a4a3 100644
--- a/opensaml-security-impl/src/main/java/org/opensaml/security/credential/impl/AbstractCriteriaFilteringCredentialResolver.java
+++ b/opensaml-security-impl/src/main/java/org/opensaml/security/credential/impl/AbstractCriteriaFilteringCredentialResolver.java
@@ -137,4 +137,4 @@ public abstract class AbstractCriteriaFilteringCredentialResolver extends Abstra
         return predicates;
     }
 
-}
+}
\ No newline at end of file
diff --git a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/impl/BasicEncryptionParametersResolver.java b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/impl/BasicEncryptionParametersResolver.java
index 794ff5a14..77b6b6653 100644
--- a/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/impl/BasicEncryptionParametersResolver.java
+++ b/opensaml-xmlsec-impl/src/main/java/org/opensaml/xmlsec/impl/BasicEncryptionParametersResolver.java
@@ -746,7 +746,7 @@ public class BasicEncryptionParametersResolver extends AbstractSecurityParameter
      *          
      * @return the selected algorithm URI
      */
-    @Nullable protected String resolveDataEncryptionAlgorithm(@Nonnull final Credential dataEncryptionCredential, 
+    @Nullable protected String resolveDataEncryptionAlgorithm(@Nullable final Credential dataEncryptionCredential, 
             @Nonnull final CriteriaSet criteria, @Nonnull final Predicate<String> includeExcludePredicate) {
         
         return resolveDataEncryptionAlgorithm(dataEncryptionCredential, getEffectiveDataEncryptionAlgorithms(criteria,

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


More information about the commits mailing list