CompositeCredentialsSupport implements CredentialsSupport { @Override @NotNull public Map<String, ?> getAttributes(@NotNull Credentials credentials) { Collection<CredentialsSupport> all = this.credentialSupplier.get(); if (all.isEmpty()) { return ImmutableMap.of(); } else if (all.size() == 1) { return all.iterator().next().getAttributes(credentials); } else { Map<String, Object> attrs = newHashMap(); for (CredentialsSupport c : all) { attrs.putAll(c.getAttributes(credentials)); } return attrs; } } private  CompositeCredentialsSupport(@NotNull Supplier<Collection<CredentialsSupport>> credentialSupplier); static CredentialsSupport newInstance(@NotNull Supplier<Collection<CredentialsSupport>> credentialSupplier); @Override @NotNull Set<Class> getCredentialClasses(); @Override @Nullable String getUserId(@NotNull Credentials credentials); @Override @NotNull Map<String, ?> getAttributes(@NotNull Credentials credentials); @Override boolean setAttributes(@NotNull Credentials credentials, @NotNull Map<String, ?> attributes);  }
@Test public void testGetAttributes() { Map<String, ?> attributes = credentialsSupport.getAttributes(new TestCredentials()); assertNotNull(attributes); assertTrue(attributes.isEmpty()); SimpleCredentials sc = new SimpleCredentials("uid", new char[0]); attributes = credentialsSupport.getAttributes(sc); assertNotNull(attributes); assertTrue(attributes.isEmpty()); Map<String, ?> expected = ImmutableMap.of("a", "a", "b", Boolean.TRUE, "c", new TestCredentials()); for (Map.Entry<String, ?> entry : expected.entrySet()) { sc.setAttribute(entry.getKey(), entry.getValue()); } attributes = credentialsSupport.getAttributes(sc); assertNotNull(attributes); assertEquals(3, attributes.size()); assertEquals(expected, attributes); }