// Path: src/test/java/com/javamonitor/tools/Stopwatch.java
// public final class Stopwatch implements Serializable {
//     private static final long serialVersionUID = 1L;
// 
//     private static final Logger log = Logger.getLogger(Stopwatch.class);
// 
//     private final long start;
//     private long lastTime;
//     private Level loglevel = Level.WARN;
// 
//     private final StringBuilder message = new StringBuilder();
// 
//     /**
//      * Start a new stopwatch, specifying the class we work for.
//      *
//      * @param clazz The class we work for.
//      */
//     public Stopwatch(final Class<?> clazz) {
//         this(clazz.getName());
//     }
// 
//     /**
//      * Start a new stopwatch, with a custom name.
//      *
//      * @param name The name of this Stopwatch
//      */
//     public Stopwatch(final String name) {
//         super();
// 
//         start = System.currentTimeMillis();
//         lastTime = start;
// 
//         message.append("entering ").append(name).append(" took ");
//     }
// 
//     /**
//      * Mark the time of the operation that we are about to perform.
//      *
//      * @param operation The operation we are about to perform.
//      */
//     public void aboutTo(final String operation) {
//         final long now = System.currentTimeMillis();
//         final long timeDiff = now - lastTime;
//         lastTime = now;
// 
//         message.append(timeDiff).append("; ").append(operation)
//                 .append(" took ");
//     }
// 
//     /**
//      * Stop the stopwatch, logging the events in case the time was longer than
//      * the specified threshold time value. This method is typically invoked in a
//      * finally block.
//      *
//      * @param thresholdMillis The threshold above which we print the events.
//      * @return <code>true</code> if the operation completes within the specified time
//      */
//     public boolean stop(final long thresholdMillis) {
//         final long now = System.currentTimeMillis();
//         final long timeDiff = now - lastTime;
//         lastTime = now;
// 
//         long total = now - start;
//         message.append(timeDiff).append(". Total: ").append(total).append(" ms.");
// 
//         if ((total) > thresholdMillis) {
//             log.log(loglevel, message);
//             return false;
//         }
//         return true;
//     }
// 
//     public String getMessage(){
//         return message.toString();
//     }
// 
//     public Stopwatch setLoglevel(Level loglevel) {
//         this.loglevel = loglevel;
//         return this;
//     }
// }
// 
// Path: src/main/java/com/rolfje/anonimatron/synonyms/Synonym.java
// public interface Synonym {
// 
// 	/**
// 	 * Indicates if this Synonym is short-lived or transient, meaning that
//      * it should not be stored in the synonyms file. Transient Synonyms
//      * are not stored, need to be calculated each run time.
// 	 *
// 	 * Transient synonyms are:
// 	 *
// 	 * <ol>
// 	 *     <li>Not stored in memory.</li>
// 	 *     <li>Not stored in the synonym file.</li>
// 	 * </ol>
// 	 *
// 	 * @return <code>true</code> if the synonym should be thrown away
// 	 * after use (not stored in the synonym file).
// 	 */
// 	boolean isShortLived();
// 
// 	/**
// 	 * @return The semantic data type of this Synonym, usually something
// 	 *         descriptive as "NAME" or "STREET".
// 	 */
// 	String getType();
// 
// 	/**
// 	 * @return The data which was in the original database for this Synonym
// 	 */
// 	Object getFrom();
// 
// 	/**
// 	 * 
// 	 * @return The data with which the original data in the database will be or
// 	 *         is replaced when the Anonymizer runs.
// 	 */
// 	Object getTo();
// }


import com.javamonitor.tools.Stopwatch;
import com.rolfje.anonimatron.synonyms.Synonym;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;
    public void testMaskedAnonymize() {
        String original = "ABCDEFGH";
        String mask = "1,1-1*99";
        String expected = "AxCxExGH";

        Synonym synonym = anonymizer.anonymize(
                original, Integer.MAX_VALUE, false,
                getMaskParameters(mask)
        );

        String toString = synonym.getTo().toString();

        assertEquals(original, synonym.getFrom());
        assertNotEquals(synonym.getFrom(), synonym.getTo());
        assertEquals(synonym.getFrom().toString().length(), toString.length());

        char[] toChars = toString.toCharArray();
        char[] expectedChars = expected.toCharArray();

        for (int i = 0; i < expectedChars.length; i++) {
            assertEquals("Character at position " + i + " not what we expected. String is '" + toString + "'", (expectedChars[i] == 'x'), (Character.isDigit(toChars[i])));
        }
    }

    @Test
    public void testMaskedDigitsPerformance() {
        String original = "ABCDEFGH";
        String mask = "1,1-1*99";
        Map<String, String> maskParameters = getMaskParameters(mask);

// Path: src/test/java/com/javamonitor/tools/Stopwatch.java
// public final class Stopwatch implements Serializable {
//     private static final long serialVersionUID = 1L;
// 
//     private static final Logger log = Logger.getLogger(Stopwatch.class);
// 
//     private final long start;
//     private long lastTime;
//     private Level loglevel = Level.WARN;
// 
//     private final StringBuilder message = new StringBuilder();
// 
//     /**
//      * Start a new stopwatch, specifying the class we work for.
//      *
//      * @param clazz The class we work for.
//      */
//     public Stopwatch(final Class<?> clazz) {
//         this(clazz.getName());
//     }
// 
//     /**
//      * Start a new stopwatch, with a custom name.
//      *
//      * @param name The name of this Stopwatch
//      */
//     public Stopwatch(final String name) {
//         super();
// 
//         start = System.currentTimeMillis();
//         lastTime = start;
// 
//         message.append("entering ").append(name).append(" took ");
//     }
// 
//     /**
//      * Mark the time of the operation that we are about to perform.
//      *
//      * @param operation The operation we are about to perform.
//      */
//     public void aboutTo(final String operation) {
//         final long now = System.currentTimeMillis();
//         final long timeDiff = now - lastTime;
//         lastTime = now;
// 
//         message.append(timeDiff).append("; ").append(operation)
//                 .append(" took ");
//     }
// 
//     /**
//      * Stop the stopwatch, logging the events in case the time was longer than
//      * the specified threshold time value. This method is typically invoked in a
//      * finally block.
//      *
//      * @param thresholdMillis The threshold above which we print the events.
//      * @return <code>true</code> if the operation completes within the specified time
//      */
//     public boolean stop(final long thresholdMillis) {
//         final long now = System.currentTimeMillis();
//         final long timeDiff = now - lastTime;
//         lastTime = now;
// 
//         long total = now - start;
//         message.append(timeDiff).append(". Total: ").append(total).append(" ms.");
// 
//         if ((total) > thresholdMillis) {
//             log.log(loglevel, message);
//             return false;
//         }
//         return true;
//     }
// 
//     public String getMessage(){
//         return message.toString();
//     }
// 
//     public Stopwatch setLoglevel(Level loglevel) {
//         this.loglevel = loglevel;
//         return this;
//     }
// }
// 
// Path: src/main/java/com/rolfje/anonimatron/synonyms/Synonym.java
// public interface Synonym {
// 
// 	/**
// 	 * Indicates if this Synonym is short-lived or transient, meaning that
//      * it should not be stored in the synonyms file. Transient Synonyms
//      * are not stored, need to be calculated each run time.
// 	 *
// 	 * Transient synonyms are:
// 	 *
// 	 * <ol>
// 	 *     <li>Not stored in memory.</li>
// 	 *     <li>Not stored in the synonym file.</li>
// 	 * </ol>
// 	 *
// 	 * @return <code>true</code> if the synonym should be thrown away
// 	 * after use (not stored in the synonym file).
// 	 */
// 	boolean isShortLived();
// 
// 	/**
// 	 * @return The semantic data type of this Synonym, usually something
// 	 *         descriptive as "NAME" or "STREET".
// 	 */
// 	String getType();
// 
// 	/**
// 	 * @return The data which was in the original database for this Synonym
// 	 */
// 	Object getFrom();
// 
// 	/**
// 	 * 
// 	 * @return The data with which the original data in the database will be or
// 	 *         is replaced when the Anonymizer runs.
// 	 */
// 	Object getTo();
// }


// Path: src/test/java/com/rolfje/anonimatron/anonymizer/DigitStringAnonymizerTest.java
import com.javamonitor.tools.Stopwatch;
import com.rolfje.anonimatron.synonyms.Synonym;
import org.junit.Before;
import org.junit.Test;
import java.util.HashMap;
import java.util.Map;
import static org.junit.Assert.*;

    public void testMaskedAnonymize() {
        String original = "ABCDEFGH";
        String mask = "1,1-1*99";
        String expected = "AxCxExGH";

        Synonym synonym = anonymizer.anonymize(
                original, Integer.MAX_VALUE, false,
                getMaskParameters(mask)
        );

        String toString = synonym.getTo().toString();

        assertEquals(original, synonym.getFrom());
        assertNotEquals(synonym.getFrom(), synonym.getTo());
        assertEquals(synonym.getFrom().toString().length(), toString.length());

        char[] toChars = toString.toCharArray();
        char[] expectedChars = expected.toCharArray();

        for (int i = 0; i < expectedChars.length; i++) {
            assertEquals("Character at position " + i + " not what we expected. String is '" + toString + "'", (expectedChars[i] == 'x'), (Character.isDigit(toChars[i])));
        }
    }

    @Test
    public void testMaskedDigitsPerformance() {
        String original = "ABCDEFGH";
        String mask = "1,1-1*99";
        Map<String, String> maskParameters = getMaskParameters(mask);

        Stopwatch stopwatchNano = new Stopwatch("Masked performance");