@@ -0,0 +1,2611 @@
+package org.mutabilitydetector.issues;%0A%0Aimport static java.util.Arrays.asList;%0Aimport static org.mutabilitydetector.MutabilityReason.ABSTRACT_TYPE_TO_FIELD;%0Aimport static org.mutabilitydetector.locations.Dotted.dotted;%0A%0Aimport java.util.List;%0A%0Aimport org.hamcrest.BaseMatcher;%0Aimport org.hamcrest.Description;%0Aimport org.hamcrest.Matcher;%0Aimport org.mutabilitydetector.MutableReasonDetail;%0Aimport org.mutabilitydetector.locations.Dotted;%0Aimport org.mutabilitydetector.locations.FieldLocation;%0A%0Apublic class AssumeCopiedIntoUnmodifiable extends BaseMatcher%3CMutableReasonDetail%3E %7B%0A%0A    public static class Assuming %7B%0A        private final String fieldName;%0A        public Assuming(String fieldName) %7B%0A            this.fieldName = fieldName;%0A        %7D%0A        public Matcher%3CMutableReasonDetail%3E hasCollectionsUnmodifiableTypeAssignedToIt() %7B%0A            return new AssumeCopiedIntoUnmodifiable(fieldName);%0A        %7D%0A        %0A    %7D%0A%0A    public static AssumeCopiedIntoUnmodifiable.Assuming assuming(String fieldName) %7B%0A        return new Assuming(fieldName);%0A    %7D%0A%0A    private static final List%3CDotted%3E unmodifiableTypes = asList(dotted(%22java.util.List%22), %0A                                                                 dotted(%22java.util.Map%22), %0A                                                                 dotted(%22java.util.Set%22),%0A                                                                 dotted(%22java.util.Collection%22),%0A                                                                 dotted(%22java.util.SortedSet%22),%0A                                                                 dotted(%22java.util.SortedMap%22));%0A%0A    private final String fieldName;%0A    %0A    public AssumeCopiedIntoUnmodifiable(String fieldName) %7B%0A        this.fieldName = fieldName;%0A    %7D%0A    %0A    @Override%0A    public void describeTo(Description description) %7B %7D%0A%0A%0A    private Dotted sniffOutAssignedTypeFromMessage(String message) %7B%0A        return dotted(message.substring(message.lastIndexOf(%22(%22) + 1, message.lastIndexOf(%22)%22)));%0A    %7D%0A%0A%0A    @Override%0A    public boolean matches(Object arg0) %7B%0A        MutableReasonDetail reasonDetail = (MutableReasonDetail) arg0;%0A        if (reasonDetail.reason().isOneOf(ABSTRACT_TYPE_TO_FIELD)) %7B%0A            String potentiallyAbstractField = ((FieldLocation) reasonDetail.codeLocation()).fieldName();%0A            Dotted assignedType = sniffOutAssignedTypeFromMessage(reasonDetail.message());%0A            if (potentiallyAbstractField.equals(fieldName) && unmodifiableTypes.contains(assignedType)) %7B%0A                return true;%0A            %7D%0A        %7D%0A        %0A        return false;%0A    %7D%0A%0A%7D

Extract top level matcher type.