package org.workcraft.gui.properties;

import org.workcraft.types.Pair;

import java.util.*;

public class ModelProperties implements Properties {

    private final LinkedList<PropertyDescriptor> propertyDescriptors = new LinkedList<>();

    public ModelProperties() {
    }

    // Combine descriptors, so several object refer to one property descriptor
    public ModelProperties(Collection<PropertyDescriptor> descriptors) {
        LinkedHashMap<Pair<String, Class<?>>, Set<PropertyDescriptor>> categories = new LinkedHashMap<>();

        for (PropertyDescriptor descriptor: descriptors) {
            if (descriptor.isCombinable()) {
                Pair<String, Class<?>> key = new Pair<>(descriptor.getName(), descriptor.getType());
                Set<PropertyDescriptor> value = categories.get(key);
                if (value == null) {
                    value = new HashSet<>();
                    categories.put(key, value);
                }
                value.add(descriptor);
            }
        }

        for (Pair<String, Class<?>> key: categories.keySet()) {
            final String name = key.getFirst();
            final Class<?> type = key.getSecond();
            final Set<PropertyDescriptor> values = categories.get(key);
            PropertyDescriptor comboDescriptor = new PropertyCombiner(name, type, values);
            propertyDescriptors.add(comboDescriptor);
        }
    }

    public void add(final PropertyDescriptor descriptor) {
        if (descriptor != null) {
            propertyDescriptors.add(descriptor);
        }
    }

    public void addAll(final Collection<PropertyDescriptor> descriptors) {
        if (descriptors != null) {
            propertyDescriptors.addAll(descriptors);
        }
    }

    public void insertOrderedByFirstWord(PropertyDescriptor descriptor) {
        String propertyName = descriptor.getName();
        int spacePos = propertyName.indexOf(' ');
        String prefix = (spacePos < 0) ? propertyName : propertyName.substring(0, spacePos);
        int index = 0;
        int lastIndex = -1;
        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) {
            index++;
            if (propertyDescriptor.getName().startsWith(prefix)) {
                lastIndex = index;
            }
        }
        if (lastIndex < 0) {
            propertyDescriptors.add(descriptor);
        } else {
            propertyDescriptors.add(lastIndex, descriptor);
        }
    }

    public void remove(final PropertyDescriptor descriptor) {
        if (descriptor != null) {
            propertyDescriptors.remove(descriptor);
        }
    }

    public void removeByName(final String propertyName) {
        if (propertyName != null) {
            for (PropertyDescriptor descriptor : new LinkedList<>(propertyDescriptors)) {
                if ((descriptor != null) && propertyName.equals(descriptor.getName())) {
                    remove(descriptor);
                }
            }
        }
    }

    public void rename(final PropertyDescriptor descriptor, final String newPropertyName) {
        if (descriptor != null) {
            PropertyDerivative newDescriptor = new PropertyDerivative(descriptor) {
                @Override
                public String getName() {
                    return newPropertyName;
                }
            };
            remove(descriptor);
            add(newDescriptor);
        }
    }

    public void renameByName(final String propertyName, final String newPropertyName) {
        if (propertyName != null) {
            for (PropertyDescriptor descriptor : new LinkedList<>(propertyDescriptors)) {
                if ((descriptor != null) && propertyName.equals(descriptor.getName())) {
                    rename(descriptor, newPropertyName);
                }
            }
        }
    }

    @Override
    public Collection<PropertyDescriptor> getDescriptors() {
        return Collections.unmodifiableList(propertyDescriptors);
    }

}

@@ -799,165 +799,51 @@
 ies.
-get(key);%0A                if (value == null) %7B%0A                    value = new HashSet%3C%3E();%0A                    categories.put(key, value);%0A                %7D
+computeIfAbsent(key, k -%3E new HashSet%3C%3E());
 %0A   
@@ -1561,32 +1561,32 @@
 tors != null) %7B%0A
+
             prop
@@ -1643,723 +1643,8 @@
  %7D%0A%0A
-    public void insertOrderedByFirstWord(PropertyDescriptor descriptor) %7B%0A        String propertyName = descriptor.getName();%0A        int spacePos = propertyName.indexOf(' ');%0A        String prefix = (spacePos %3C 0) ? propertyName : propertyName.substring(0, spacePos);%0A        int index = 0;%0A        int lastIndex = -1;%0A        for (PropertyDescriptor propertyDescriptor : propertyDescriptors) %7B%0A            index++;%0A            if (propertyDescriptor.getName().startsWith(prefix)) %7B%0A                lastIndex = index;%0A            %7D%0A        %7D%0A        if (lastIndex %3C 0) %7B%0A            propertyDescriptors.add(descriptor);%0A        %7D else %7B%0A            propertyDescriptors.add(lastIndex, descriptor);%0A        %7D%0A    %7D%0A%0A
     

Remove redundant insertOrderedByFirstWord method