private ObservableList<AbstractDocumentProperty<?>> addListeners(String key, ObservableList<AbstractDocumentProperty<?>> list) {
        // When an observable children list under a specific key is
        // modified, the new children must be inserted into the source
        // equivalent as well.
        list.addListener((ListChangeListener.Change<? extends DocumentProperty> listChange) -> {
            while (listChange.next()) {
                if (listChange.wasAdded()) {

                    // Find or create a children list in the source map
                    // for the specified key
                    @SuppressWarnings("unchecked")
                    final List<Map<String, Object>> source = 
                        (List<Map<String, Object>>) config.computeIfAbsent(
                            key, k -> new CopyOnWriteArrayList<>()
                        );

                    // Add a reference to the map for every child
                    listChange.getAddedSubList().stream()
                        .map(DocumentProperty::getData) // Exactly the same map as is used in the property
                        .forEachOrdered(source::add);
                }
                
                if (listChange.wasRemoved()) {
                    @SuppressWarnings("unchecked")
                    final List<Map<String, Object>> source = 
                        (List<Map<String, Object>>) config.computeIfAbsent(
                            key, k -> new CopyOnWriteArrayList<>()
                        );
                    
                    listChange.getRemoved().stream()
                        .map(DocumentProperty::getData)
                        .forEach(removed -> 
                            source.removeIf(e -> e == removed) // Identity
                        );
                }
            }
            
            invalidate();
        });
        
        return list;
    }
Adds a listener to the specified list so that changes to it are reflected
down to the source map.

@param key   the key where the list is located
@param list  the list to add listeners to
@return      the same list but with listener attached
tool-parent/tool-config/src/main/java/com/speedment/tool/config/AbstractDocumentProperty.java