// Path: pie-core/src/main/java/com/coverity/security/pie/core/StringCollapser.java
// public interface StringCollapser {
//     /**
//      * Collapses a security policy according to the concrete implementation's rules. It takes a map from facts to their
//      * children, and returns a collapsed version of that map. For example, given the map:
//      * {
//      *   A => {'X', 'Y'},
//      *   B => {'Z'}
//      * }
//      *
//      * If the implementation determines that the facts A and B should be collapsed to fact C, then this would return
//      * {
//      *   C => {'X', 'Y', 'Z'}
//      * }
//      *
//      * @param input A map from facts to a collection of child facts.
//      * @param <T> The type of the child facts; irrelevant to the internal procedure of collapsing.
//      * @return The collapsed map of facts to their children.
//      */
//     public <T> Map<String, Collection<T>> collapse(Map<String, Collection<T>> input);
// }
// 
// Path: pie-core/src/main/java/com/coverity/security/pie/util/StringUtil.java
// public class StringUtil {
//     public static String join(String s, String[] arr, int off, int end) {
//         if (off < 0 || end > arr.length) {
//             throw new IllegalArgumentException("Invalid indices");
//         }
//         if (end <= off) {
//             return "";
//         }
//         
//         StringBuilder sb = new StringBuilder();
//         for (int i = off; i < end-1; i++) {
//             sb.append(arr[i]).append(s);
//         }
//         sb.append(arr[end-1]);
//         return sb.toString();
//     }
//     
//     public static String join(String s, List<String> strings) {
//         if (strings.size() == 0) {
//             return "";
//         }
//         StringBuilder sb = new StringBuilder();
//         for (int i = 0; i < strings.size()-1; i++) {
//             sb.append(strings.get(i)).append(s);
//         }
//         sb.append(strings.get(strings.size()-1));
//         return sb.toString();
//     }
//     
// 
//     public static String join(String s, String ... strings) {
//         if (strings.length == 0) {
//             return "";
//         }
//         StringBuilder sb = new StringBuilder();
//         for (int i = 0; i < strings.length-1; i++) {
//             sb.append(strings[i]).append(s);
//         }
//         sb.append(strings[strings.length-1]);
//         return sb.toString();
//     }
// }


import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import com.coverity.security.pie.core.StringCollapser;
import com.coverity.security.pie.util.StringUtil;
package com.coverity.security.pie.util.collapser;



/**
 * An implementation of the AbstractPathCollapser which collapses properties. For example, a.b.c.com would match *.c.com
 */
public class PropertyCollapser extends AbstractPathCollapser implements StringCollapser {

    public PropertyCollapser(int collapseThreshold) {
// Path: pie-core/src/main/java/com/coverity/security/pie/core/StringCollapser.java
// public interface StringCollapser {
//     /**
//      * Collapses a security policy according to the concrete implementation's rules. It takes a map from facts to their
//      * children, and returns a collapsed version of that map. For example, given the map:
//      * {
//      *   A => {'X', 'Y'},
//      *   B => {'Z'}
//      * }
//      *
//      * If the implementation determines that the facts A and B should be collapsed to fact C, then this would return
//      * {
//      *   C => {'X', 'Y', 'Z'}
//      * }
//      *
//      * @param input A map from facts to a collection of child facts.
//      * @param <T> The type of the child facts; irrelevant to the internal procedure of collapsing.
//      * @return The collapsed map of facts to their children.
//      */
//     public <T> Map<String, Collection<T>> collapse(Map<String, Collection<T>> input);
// }
// 
// Path: pie-core/src/main/java/com/coverity/security/pie/util/StringUtil.java
// public class StringUtil {
//     public static String join(String s, String[] arr, int off, int end) {
//         if (off < 0 || end > arr.length) {
//             throw new IllegalArgumentException("Invalid indices");
//         }
//         if (end <= off) {
//             return "";
//         }
//         
//         StringBuilder sb = new StringBuilder();
//         for (int i = off; i < end-1; i++) {
//             sb.append(arr[i]).append(s);
//         }
//         sb.append(arr[end-1]);
//         return sb.toString();
//     }
//     
//     public static String join(String s, List<String> strings) {
//         if (strings.size() == 0) {
//             return "";
//         }
//         StringBuilder sb = new StringBuilder();
//         for (int i = 0; i < strings.size()-1; i++) {
//             sb.append(strings.get(i)).append(s);
//         }
//         sb.append(strings.get(strings.size()-1));
//         return sb.toString();
//     }
//     
// 
//     public static String join(String s, String ... strings) {
//         if (strings.length == 0) {
//             return "";
//         }
//         StringBuilder sb = new StringBuilder();
//         for (int i = 0; i < strings.length-1; i++) {
//             sb.append(strings[i]).append(s);
//         }
//         sb.append(strings[strings.length-1]);
//         return sb.toString();
//     }
// }


// Path: pie-core/src/main/java/com/coverity/security/pie/util/collapser/PropertyCollapser.java
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import com.coverity.security.pie.core.StringCollapser;
import com.coverity.security.pie.util.StringUtil;

package com.coverity.security.pie.util.collapser;



/**
 * An implementation of the AbstractPathCollapser which collapses properties. For example, a.b.c.com would match *.c.com
 */
public class PropertyCollapser extends AbstractPathCollapser implements StringCollapser {

    public PropertyCollapser(int collapseThreshold) {
        super("*", "*", collapseThreshold, 0);