static String[] mergePropertyNames(String[] localNames,
                                       String[] sourceNames) {
        // Set the output names to the other array if one array is null
        // or zero-length.
        String[] names = null;
        if(localNames == null || localNames.length == 0) {
            names = sourceNames;
        } else if(sourceNames == null || sourceNames.length == 0) {
            names = localNames;
        } else {
            // Merge the name arrays.

            // Allocate a Set.
            Set nameSet = new HashSet((localNames.length+sourceNames.length)/2);

            // Add source names first as they have lower priority.
            int numSourceNames = sourceNames.length;
            for(int i = 0; i < numSourceNames; i++) {
                nameSet.add(new CaselessStringKey(sourceNames[i]));
            }

            // Add local names which will "bump" duplicate source names.
            int numLocalNames = localNames.length;
            for(int i = 0; i < numLocalNames; i++) {
                nameSet.add(new CaselessStringKey(localNames[i]));
            }

            // Convert result to an array of Strings.
            int numNames = nameSet.size();
            CaselessStringKey[] caselessNames = new CaselessStringKey[numNames];
            nameSet.toArray(caselessNames);
            names = new String[numNames];
            for(int i = 0; i < numNames; i++) {
                names[i] = caselessNames[i].getName();
            }
        }

        // Set return value to null if zero-length.
        if(names != null && names.length == 0) {
            names = null;
        }

        return names;
    }