### Question:
AppcacheLinker extends AbstractLinker { @Nonnull final List<SelectionDescriptor> collectPermutationSelectors( @Nonnull final TreeLogger logger, @Nonnull final Collection<PermutationArtifact> artifacts ) { final List<SelectionDescriptor> descriptors = new ArrayList<>(); for ( final PermutationArtifact artifact : artifacts ) { final Permutation permutation = artifact.getPermutation(); final List<BindingProperty> calculatedBindings = new ArrayList<>(); final HashSet<String> completed = new HashSet<>(); final List<SelectionDescriptor> selectors = permutation.getSelectors(); final SelectionDescriptor firstSelector = selectors.iterator().next(); for ( final BindingProperty p : firstSelector.getBindingProperties() ) { final String key = p.getName(); if ( !completed.contains( key ) ) { final HashSet<String> values = collectValuesForKey( selectors, key ); if ( 1 == selectors.size() || values.size() > 1 ) { calculatedBindings.add( new BindingProperty( key, joinValues( values ) ) ); } completed.add( key ); } } calculatedBindings.sort( ( o1, o2 ) -> o2.getComponents().length - o1.getComponents().length ); descriptors.add( new SelectionDescriptor( permutation.getPermutationName(), calculatedBindings ) ); } logger.log( Type.DEBUG, "Permutation map created with " + descriptors.size() + " descriptors." ); return descriptors; }  @Override String getDescription(); @Override ArtifactSet link( @Nonnull final TreeLogger logger,
                           @Nonnull final LinkerContext context,
                           @Nonnull final ArtifactSet artifacts,
                           final boolean onePermutation );  }### Answer:
@Test public void collectPermutationSelectors() { final AppcacheLinker linker = new AppcacheLinker(); final ArrayList<PermutationArtifact> artifacts = new ArrayList<>(); final ArrayList<BindingProperty> binding0 = new ArrayList<>(); bp( binding0, "user.agent", "ie8" ); bp( binding0, "some.key", "blah" ); bp( binding0, "other.key", "blee" ); final Permutation permutation = addPermutation( artifacts, "X", binding0, new HashSet<>() ); final ArrayList<BindingProperty> binding01 = new ArrayList<>(); bp( binding01, "user.agent", "ie9" ); bp( binding01, "some.key", "blah" ); bp( binding01, "other.key", "blee" ); addSoftPermutation( permutation, binding01, new HashSet<>() ); final ArrayList<BindingProperty> binding02 = new ArrayList<>(); bp( binding02, "user.agent", "ie10" ); bp( binding02, "some.key", "blah" ); bp( binding02, "other.key", "blee" ); addSoftPermutation( permutation, binding02, new HashSet<>() ); final ArrayList<BindingProperty> binding1 = new ArrayList<>(); bp( binding1, "user.agent", "safari" ); addPermutation( artifacts, "Y", binding1, new HashSet<>() ); final ArrayList<BindingProperty> binding2 = new ArrayList<>(); bp( binding2, "user.agent", "gecko_16" ); addPermutation( artifacts, "Z", binding2, new HashSet<>() ); final List<SelectionDescriptor> values = linker.collectPermutationSelectors( TreeLogger.NULL, artifacts ); assertEquals( values.size(), 3 ); final List<BindingProperty> x = ensureBinding( values, "X", 1 ); assertProperty( x.get( 0 ), "user.agent", "ie10,ie9,ie8" ); final List<BindingProperty> z = ensureBinding( values, "Z", 1 ); assertProperty( z.get( 0 ), "user.agent", "gecko_16" ); final List<BindingProperty> y = ensureBinding( values, "Y", 1 ); assertProperty( y.get( 0 ), "user.agent", "safari" ); }