class ChainedProperties {

    public final static int[] fontSizes = {8, 10, 12, 14, 18, 24, 36};

    /**
     * Will be replaced with types alternative
     */
    public ArrayList<Object[]> chain = new ArrayList<>();

    /**
     * Creates a new instance of ChainedProperties
     */
    public ChainedProperties() {
    }

    public String getProperty(String key) {
        return findProperty(key).orElse(null);
    }

    /**
     * Try find property by its name
     *
     * @param key property name
     * @return {@link Optional} containing the value or {@link Optional#empty()} if there is no value or it equals
     * {@code null}
     */
    public Optional<String> findProperty(String key) {
        for (int k = chain.size() - 1; k >= 0; --k) {
            Object[] obj = chain.get(k);
            HashMap prop = (HashMap) obj[1];
            String ret = (String) prop.get(key);
            if (ret != null) {
                return Optional.of(ret);
            }
        }
        return Optional.empty();
    }

    /**
     * Get property by its name or return default value when property is not present or is <CODE>null</CODE>
     *
     * @param key          property name
     * @param defaultValue default property value
     * @return property or default value if it's null
     */
    public String getOrDefault(String key, String defaultValue) {
        return findProperty(key).orElse(defaultValue);
    }

    public boolean hasProperty(String key) {
        for (int k = chain.size() - 1; k >= 0; --k) {
            Object[] obj = (Object[]) chain.get(k);
            HashMap prop = (HashMap) obj[1];
            if (prop.containsKey(key)) {
                return true;
            }
        }
        return false;
    }

    public void addToChain(String key, Map<String, String> prop) {<FILL_FUNCTION_BODY>}

    public void removeChain(String key) {
        for (int k = chain.size() - 1; k >= 0; --k) {
            if (key.equals(((Object[]) chain.get(k))[0])) {
                chain.remove(k);
                return;
            }
        }
    }
}

        // adjust the font size
        String value = prop.get(ElementTags.SIZE);
        if (value != null) {
            if (value.endsWith("pt")) {
                prop.put(ElementTags.SIZE, value.substring(0,
                        value.length() - 2));
            } else {
                int s = 0;
                if (value.startsWith("+") || value.startsWith("-")) {
                    String old = getOrDefault("basefontsize", "12");
                    float f = Float.parseFloat(old);
                    int c = (int) f;
                    for (int k = fontSizes.length - 1; k >= 0; --k) {
                        if (c >= fontSizes[k]) {
                            s = k;
                            break;
                        }
                    }
                    int inc = Integer.parseInt(value.startsWith("+") ? value
                            .substring(1) : value);
                    s += inc;
                } else {
                    try {
                        s = Integer.parseInt(value) - 1;
                    } catch (NumberFormatException nfe) {
                        s = 0;
                    }
                }
                if (s < 0) {
                    s = 0;
                } else if (s >= fontSizes.length) {
                    s = fontSizes.length - 1;
                }
                prop.put(ElementTags.SIZE, Integer.toString(fontSizes[s]));
            }
        }
        chain.add(new Object[]{key, prop});
    
<no_super_class>