// Path: src/main/java/com/roklenarcic/util/strings/threshold/RangeNodeThreshold.java
// public class RangeNodeThreshold implements Thresholder {
// 
//     private double exponent, linearFactor, maxValue, constantFactor;
// 
//     public RangeNodeThreshold() {
//         this(1);
//     }
// 
//     public RangeNodeThreshold(double exponent) {
//         this(exponent, 1, 0.65, 2);
//     }
// 
//     public RangeNodeThreshold(double exponent, double linearFactor, double maxValue, double constantFactor) {
//         super();
//         this.exponent = exponent;
//         this.linearFactor = linearFactor;
//         this.maxValue = maxValue;
//         this.constantFactor = constantFactor;
//     }
// 
//     public boolean isOverThreshold(int nodeSize, int nodeLevel, int keyIntervalSize) {
//         if (keyIntervalSize <= 8) {
//             return true;
//         }
//         int charArrayCost = (nodeSize / 4) + 3; // Char array costs 24 bytes + 2 bytes per char
//         return nodeSize + charArrayCost > keyIntervalSize * (maxValue - linearFactor / Math.pow(constantFactor + nodeLevel, exponent));
//     }
// 
// }
// 
// Path: src/main/java/com/roklenarcic/util/strings/threshold/Thresholder.java
// public interface Thresholder {
//     boolean isOverThreshold(int nodeSize, int nodeLevel, int keyIntervalSize);
// }


import java.util.Arrays;
import com.roklenarcic.util.strings.threshold.RangeNodeThreshold;
import com.roklenarcic.util.strings.threshold.Thresholder;
package com.roklenarcic.util.strings;



// Matches leftmost longest matches. Useful when you want non-overlapping
// matches with a string set that doesn't have strings that are prefix to other strings in the set.
public class LongestMatchSet implements StringSet {

    private boolean caseSensitive = true;
    private TrieNode root;

    public LongestMatchSet(final Iterable<String> keywords, boolean caseSensitive) {
// Path: src/main/java/com/roklenarcic/util/strings/threshold/RangeNodeThreshold.java
// public class RangeNodeThreshold implements Thresholder {
// 
//     private double exponent, linearFactor, maxValue, constantFactor;
// 
//     public RangeNodeThreshold() {
//         this(1);
//     }
// 
//     public RangeNodeThreshold(double exponent) {
//         this(exponent, 1, 0.65, 2);
//     }
// 
//     public RangeNodeThreshold(double exponent, double linearFactor, double maxValue, double constantFactor) {
//         super();
//         this.exponent = exponent;
//         this.linearFactor = linearFactor;
//         this.maxValue = maxValue;
//         this.constantFactor = constantFactor;
//     }
// 
//     public boolean isOverThreshold(int nodeSize, int nodeLevel, int keyIntervalSize) {
//         if (keyIntervalSize <= 8) {
//             return true;
//         }
//         int charArrayCost = (nodeSize / 4) + 3; // Char array costs 24 bytes + 2 bytes per char
//         return nodeSize + charArrayCost > keyIntervalSize * (maxValue - linearFactor / Math.pow(constantFactor + nodeLevel, exponent));
//     }
// 
// }
// 
// Path: src/main/java/com/roklenarcic/util/strings/threshold/Thresholder.java
// public interface Thresholder {
//     boolean isOverThreshold(int nodeSize, int nodeLevel, int keyIntervalSize);
// }


// Path: src/main/java/com/roklenarcic/util/strings/LongestMatchSet.java
import java.util.Arrays;
import com.roklenarcic.util.strings.threshold.RangeNodeThreshold;
import com.roklenarcic.util.strings.threshold.Thresholder;

package com.roklenarcic.util.strings;



// Matches leftmost longest matches. Useful when you want non-overlapping
// matches with a string set that doesn't have strings that are prefix to other strings in the set.
public class LongestMatchSet implements StringSet {

    private boolean caseSensitive = true;
    private TrieNode root;

    public LongestMatchSet(final Iterable<String> keywords, boolean caseSensitive) {
        this(keywords, caseSensitive, new RangeNodeThreshold());