protected void setParts(String wildcardString, boolean caseSensitive) {
        wildcardString = StringUtils.clean(wildcardString);

        if (wildcardString == null || wildcardString.isEmpty()) {
            throw new IllegalArgumentException("Wildcard string cannot be null or empty."
                    + "Make sure permission strings are properly formatted.");
        }

        if (!caseSensitive) {
            wildcardString = wildcardString.toLowerCase();
        }

        List<String> parts = CollectionUtils.asList(wildcardString.split(PART_DIVIDER_TOKEN));

        this.parts = new ArrayList<Set<String>>();
        for (String part : parts) {
            Set<String> subparts = CollectionUtils.asSet(part.split(SUBPART_DIVIDER_TOKEN));

            if (subparts.isEmpty()) {
                throw new IllegalArgumentException("Wildcard string cannot contain parts with only dividers."
                        + "Make sure permission strings are properly formatted.");
            }
            this.parts.add(subparts);
        }

        if (this.parts.isEmpty()) {
            throw new IllegalArgumentException("Wildcard string cannot contain only dividers."
                        + "Make sure permission strings are properly formatted.");
        }
    }
Default no-arg constructor for subclasses only - end-user developers instantiating Permission instances must
provide a wildcard string at a minimum, since Permission instances are immutable once instantiated.
<p/>
Note that the WildcardPermission class is very robust and typically subclasses are not necessary unless you
wish to create type-safe Permission objects that would be used in your application, such as perhaps a
{@code UserPermission}, {@code SystemPermission}, {@code PrinterPermission}, etc.  If you want such type-safe
permission usage, consider subclassing the {@link DomainPermission DomainPermission} class for your needs.
core/src/main/java/org/apache/shiro/authz/permission/WildcardPermission.java