// Path: src/com/nobigsoftware/util/BuilderCache.java
// public interface BuilderCache
// {
//     /**
//      * Get a cached item.
//      * 
//      * @param key  The key used to identify the item.  The key uniquely identifies all
//      *  of the source information that will go into building the item if this call fails
//      *  to retrieve a cached version.  Typically this will be a cryptographic hash of
//      *  the serialized form of that information.
//      * 
//      * @return  the item that was previously cached under the key, or null if no such item
//      *  can be retrieved.
//      */
//     Serializable getCachedItem(String key);
//     
//     /**
//      * This method may be called when an item is built, providing an opportunity to
//      * cache it.
//      * 
//      * @param key   The key that will be used to identify the item in future calls to {@link #getCachedItem(String)}.
//      *      Only letters, digits, and underscores are valid in keys, and key length is limited to 32 characters.
//      *      The behaviour of this method for invalid keys is undefined.
//      *      <P>
//      *      Keys that differ only by case may or may not be considered equal by this class.
//      * @param item  The item to cache, if desired
//      */
//     void maybeCacheItem(String key, Serializable item);
// }


import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import com.nobigsoftware.util.BuilderCache;

/*
 * Copyright 2015 Matthew Timmermans
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.nobigsoftware.dfalex;



/**
 * Builds search and replace functions that finds patterns in strings and replaces them
 * <P>
 * Given a set of patterns and associated {@link StringReplacement} functions, you can produce an
 * optimized, thread-safe Function&lt;String,String&gt; that will find all occurrences of those patterns and replace
 * them with their replacements.
 * <P>
 * The returned function is thread-safe.
 * <P>
 * NOTE that building a search and replace function is a relatively complex procedure.  You should typically do it only once for each
 * pattern set you want to use.  Usually you would do this in a static initializer.
 * <P>
 * You can provide a cache that can remember and recall built functions, which allows you to build
 * them during your build process in various ways, instead of building them at runtime.  Or you can use
 * the cache to store built functions on the first run of your program so they don't need to be built
 * the next time...  But this is usually unnecessary, since building them is more than fast enough to
 * do during runtime initialization.
 */
public class SearchAndReplaceBuilder
{
    private final DfaBuilder<Integer> m_dfaBuilder;
    private final ArrayList<StringReplacement> m_replacements = new ArrayList<>();
    private DfaState<Integer> m_dfaMemo = null;
    private DfaState<Boolean> m_reverseFinderMemo = null;

    /**
     * Create a new SearchAndReplaceBuilder without a {@link BuilderCache}
     */
    public SearchAndReplaceBuilder()
    {
        m_dfaBuilder = new DfaBuilder<>();
    }
    
    /**
     * Create a new SearchAndReplaceBuilder, with a builder cache to bypass recalculation of pre-built functions
     * 
     * @param cache    The BuilderCache to use
     */

// Path: src/com/nobigsoftware/util/BuilderCache.java
// public interface BuilderCache
// {
//     /**
//      * Get a cached item.
//      * 
//      * @param key  The key used to identify the item.  The key uniquely identifies all
//      *  of the source information that will go into building the item if this call fails
//      *  to retrieve a cached version.  Typically this will be a cryptographic hash of
//      *  the serialized form of that information.
//      * 
//      * @return  the item that was previously cached under the key, or null if no such item
//      *  can be retrieved.
//      */
//     Serializable getCachedItem(String key);
//     
//     /**
//      * This method may be called when an item is built, providing an opportunity to
//      * cache it.
//      * 
//      * @param key   The key that will be used to identify the item in future calls to {@link #getCachedItem(String)}.
//      *      Only letters, digits, and underscores are valid in keys, and key length is limited to 32 characters.
//      *      The behaviour of this method for invalid keys is undefined.
//      *      <P>
//      *      Keys that differ only by case may or may not be considered equal by this class.
//      * @param item  The item to cache, if desired
//      */
//     void maybeCacheItem(String key, Serializable item);
// }


// Path: src/com/nobigsoftware/dfalex/SearchAndReplaceBuilder.java
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.function.Function;
import com.nobigsoftware.util.BuilderCache;

/*
 * Copyright 2015 Matthew Timmermans
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.nobigsoftware.dfalex;



/**
 * Builds search and replace functions that finds patterns in strings and replaces them
 * <P>
 * Given a set of patterns and associated {@link StringReplacement} functions, you can produce an
 * optimized, thread-safe Function&lt;String,String&gt; that will find all occurrences of those patterns and replace
 * them with their replacements.
 * <P>
 * The returned function is thread-safe.
 * <P>
 * NOTE that building a search and replace function is a relatively complex procedure.  You should typically do it only once for each
 * pattern set you want to use.  Usually you would do this in a static initializer.
 * <P>
 * You can provide a cache that can remember and recall built functions, which allows you to build
 * them during your build process in various ways, instead of building them at runtime.  Or you can use
 * the cache to store built functions on the first run of your program so they don't need to be built
 * the next time...  But this is usually unnecessary, since building them is more than fast enough to
 * do during runtime initialization.
 */
public class SearchAndReplaceBuilder
{
    private final DfaBuilder<Integer> m_dfaBuilder;
    private final ArrayList<StringReplacement> m_replacements = new ArrayList<>();
    private DfaState<Integer> m_dfaMemo = null;
    private DfaState<Boolean> m_reverseFinderMemo = null;

    /**
     * Create a new SearchAndReplaceBuilder without a {@link BuilderCache}
     */
    public SearchAndReplaceBuilder()
    {
        m_dfaBuilder = new DfaBuilder<>();
    }
    
    /**
     * Create a new SearchAndReplaceBuilder, with a builder cache to bypass recalculation of pre-built functions
     * 
     * @param cache    The BuilderCache to use
     */

    public SearchAndReplaceBuilder(BuilderCache cache)
