public static List<String> getListProperty( String parent, List<String> defaultValues )
    {
        if ( properties == null )
        {
            if ( isSetupMode() )
            {
                return defaultValues;
            }
            properties = JiveProperties.getInstance();
        }

        // Check for a legacy, comma separated value.
        final String legacyValue = JiveGlobals.getProperty( parent );

        // Ensure that properties are ordered.
        final SortedSet<String> propertyNames = new TreeSet<>( properties.getChildrenNames( parent ) );

        if ( propertyNames.isEmpty() )
        {
            if ( legacyValue != null )
            {
                Log.info( "Retrieving a list from property '{}' which is stored in a comma-separated format. Consider using child properties instead, via JiveGlobals.setProperty( String value, List<String> values )", parent );
                return Arrays.asList( legacyValue.split( "\\s*,\\s*" ) );
            }

            // When there are no child properties, return the default values.
            return defaultValues;
        }
        else if ( legacyValue != null )
        {
            // Raise a warning if two competing sets of data are detected.
            Log.warn( "Retrieving a list from property '{}' which is stored using child properties, but also in a legacy format! The data that is in the legacy format (the text value of property '{}') is not returned by this call! Its child property values are used instead. Consider removing the text value of the parent property.", parent, parent );
        }

        // When there are child properties, return its non-null, non-empty values (which might be an empty collection).
        final List<String> values = new ArrayList<>();
        for ( String propertyName : propertyNames )
        {
            final String value = getProperty( propertyName );
            if ( value != null && !value.isEmpty())
            {
                values.add( value );
            }
        }

        return values;
    }
Return all immediate children property values of a parent Jive property as a list of strings, or an default list
if the property does not exist.

This implementation ignores child property values that are empty (these are excluded from the result). When all
child properties are empty, an empty collection (and explicitly not the default values) is returned. This allows
a property to override a default non-empty collection with an empty one.

The child properties that are evaluated in this method are the same child properties as those used by
{@link #getProperties(String)}.

@param parent        the name of the parent property to return the children for.
@param defaultValues values returned if the property doesn't exist.
@return all child property values for the given parent.
xmppserver/src/main/java/org/jivesoftware/util/JiveGlobals.java