public SystemProperty<T> build() throws IllegalArgumentException {
            checkNotNull(key, "The property key has not been set");
            if (PROPERTIES.containsKey(key)) {
                throw new IllegalArgumentException("A SystemProperty already exists with a key of " + key);
            }
            if (!NULLABLE_TYPES.contains(clazz)) {
                checkNotNull(defaultValue, "The properties default value has not been set");
            }
            final Class classToCheck;
            if (Collection.class.isAssignableFrom(clazz)) {
                checkNotNull(collectionType, "A collection type must be built using buildList() or buildSet()");
                classToCheck = collectionType;
            } else {
                classToCheck = clazz;
            }

            if (sorted) {
                if (!Collection.class.isAssignableFrom(clazz)) {
                    throw new IllegalArgumentException("Only Collection properties can be sorted");
                }
                if (!Comparable.class.isAssignableFrom(classToCheck)) {
                    throw new IllegalArgumentException("Only Collection properties containing Comparable elements can be sorted");
                }
            }

            checkNotNull(plugin, "The property plugin has not been set");
            checkNotNull(dynamic, "The property dynamism has not been set");
            if (classToCheck == Duration.class) {
                checkNotNull(chronoUnit, "The ChronoUnit for the Duration property has not been set");
                if (!DURATION_TO_LONG.containsKey(chronoUnit) || !LONG_TO_DURATION.containsKey(chronoUnit)) {
                    throw new IllegalArgumentException("A Duration property cannot be saved with a ChronoUnit of " + chronoUnit);
                }
            } else if (chronoUnit != null) {
                throw new IllegalArgumentException("Only properties of type Duration can have a ChronoUnit set");
            }
            if (minValue != null) {
                if (!Comparable.class.isAssignableFrom(clazz)) {
                    throw new IllegalArgumentException("A minimum value can only be applied to properties that implement Comparable");
                }

                //noinspection unchecked
                if (defaultValue != null && ((Comparable<T>) minValue).compareTo(defaultValue) > 0) {
                    throw new IllegalArgumentException("The minimum value cannot be more than the default value");
                }
            }
            if (maxValue != null) {
                if (!Comparable.class.isAssignableFrom(clazz)) {
                    throw new IllegalArgumentException("A maximum value can only be applied to properties that implement Comparable");
                }

                //noinspection unchecked
                if (defaultValue != null && ((Comparable<T>) maxValue).compareTo(defaultValue) < 0) {
                    throw new IllegalArgumentException("The maximum value cannot be less than the default value");
                }
            }
            if (classToCheck == Class.class) {
                checkNotNull(baseClass, "The base class must be set for properties of type class");
            }
            final SystemProperty<T> property = new SystemProperty<>(this);
            PROPERTIES.put(key, property);
            return property;
        }
Validates the details of the SystemProperty, and generates one if it's valid.

@return A SystemProperty object
@throws IllegalArgumentException if incorrect arguments have been supplied to the builder
xmppserver/src/main/java/org/jivesoftware/util/SystemProperty.java