// Path: patternedtextwatcher/src/main/java/com/szagurskii/patternedtextwatcher/Preconditions.java
// static void checkInput(String specialChar, boolean saveInput, boolean fillExtraChars) {
//   if (specialChar == null) {
//     throw new NullPointerException("Special char can't be null.");
//   }
//   if (specialChar.isEmpty()) {
//     throw new IllegalArgumentException("Special char can't be empty.");
//   }
//   if (specialChar.length() > 1) {
//     throw new IllegalArgumentException("Special char must be length = 1.");
//   }
//   if (saveInput && fillExtraChars) {
//     throw new IllegalArgumentException("It is impossible to save input when the characters are " +
//         "filled automatically instead of characters.");
//   }
// }
// 
// Path: patternedtextwatcher/src/main/java/com/szagurskii/patternedtextwatcher/Preconditions.java
// static void checkPatternInInput(String pattern, String specialChar) {
//   if (!pattern.contains(specialChar)) {
//     throw new IllegalStateException("There should be at least one special character in the " +
//         "pattern string.");
//   }
// }
// 
// Path: patternedtextwatcher/src/main/java/com/szagurskii/patternedtextwatcher/Preconditions.java
// static void checkPatternInput(String pattern) {
//   if (pattern == null) {
//     throw new NullPointerException("Pattern can't be null.");
//   }
//   if (pattern.isEmpty()) {
//     throw new IllegalArgumentException("Pattern can't be empty.");
//   }
// }


import android.text.Editable;
import android.text.TextWatcher;
import android.util.SparseArray;
import static com.szagurskii.patternedtextwatcher.Preconditions.checkInput;
import static com.szagurskii.patternedtextwatcher.Preconditions.checkPatternInInput;
import static com.szagurskii.patternedtextwatcher.Preconditions.checkPatternInput;
package com.szagurskii.patternedtextwatcher;



/**
 * A customizable text watcher which can be constructed via {@link Builder}.
 *
 * @author Savelii Zagurskii
 */
public class PatternedTextWatcher implements TextWatcher {

  static final String DEFAULT_CHAR = "#";

  private final int maxLength;
  private final char specialCharacter;

  /** Indexes of secondary characters (not inserted by user). */
  private final SparseArray<Character> patternCharactersByIndex;

  /** Indexes of symbols inserted by user. */
  private final SparseArray<Character> normalCharactersByIndex;

  private final boolean fillExtra;
  private final boolean deleteExtra;
  private final boolean saveInput;
  private final boolean respectPatternLength;
  private final boolean debug;

  private int firstIndexToCheck;
  private int lastIndexToCheck;

  private String lastText;
  private boolean enabled;
  private StringBuilder savedText;

  /**
   * Initialize {@link PatternedTextWatcher} with {@code pattern} and default parameters.
   * For advanced tweaking use {@link Builder}.
   *
   * @param pattern the pattern of the text watcher.
   */
  public PatternedTextWatcher(String pattern) {
    this(new Builder(pattern));
  }

  PatternedTextWatcher(Builder builder) {
// Path: patternedtextwatcher/src/main/java/com/szagurskii/patternedtextwatcher/Preconditions.java
// static void checkInput(String specialChar, boolean saveInput, boolean fillExtraChars) {
//   if (specialChar == null) {
//     throw new NullPointerException("Special char can't be null.");
//   }
//   if (specialChar.isEmpty()) {
//     throw new IllegalArgumentException("Special char can't be empty.");
//   }
//   if (specialChar.length() > 1) {
//     throw new IllegalArgumentException("Special char must be length = 1.");
//   }
//   if (saveInput && fillExtraChars) {
//     throw new IllegalArgumentException("It is impossible to save input when the characters are " +
//         "filled automatically instead of characters.");
//   }
// }
// 
// Path: patternedtextwatcher/src/main/java/com/szagurskii/patternedtextwatcher/Preconditions.java
// static void checkPatternInInput(String pattern, String specialChar) {
//   if (!pattern.contains(specialChar)) {
//     throw new IllegalStateException("There should be at least one special character in the " +
//         "pattern string.");
//   }
// }
// 
// Path: patternedtextwatcher/src/main/java/com/szagurskii/patternedtextwatcher/Preconditions.java
// static void checkPatternInput(String pattern) {
//   if (pattern == null) {
//     throw new NullPointerException("Pattern can't be null.");
//   }
//   if (pattern.isEmpty()) {
//     throw new IllegalArgumentException("Pattern can't be empty.");
//   }
// }


// Path: patternedtextwatcher/src/main/java/com/szagurskii/patternedtextwatcher/PatternedTextWatcher.java
import android.text.Editable;
import android.text.TextWatcher;
import android.util.SparseArray;
import static com.szagurskii.patternedtextwatcher.Preconditions.checkInput;
import static com.szagurskii.patternedtextwatcher.Preconditions.checkPatternInInput;
import static com.szagurskii.patternedtextwatcher.Preconditions.checkPatternInput;

package com.szagurskii.patternedtextwatcher;



/**
 * A customizable text watcher which can be constructed via {@link Builder}.
 *
 * @author Savelii Zagurskii
 */
public class PatternedTextWatcher implements TextWatcher {

  static final String DEFAULT_CHAR = "#";

  private final int maxLength;
  private final char specialCharacter;

  /** Indexes of secondary characters (not inserted by user). */
  private final SparseArray<Character> patternCharactersByIndex;

  /** Indexes of symbols inserted by user. */
  private final SparseArray<Character> normalCharactersByIndex;

  private final boolean fillExtra;
  private final boolean deleteExtra;
  private final boolean saveInput;
  private final boolean respectPatternLength;
  private final boolean debug;

  private int firstIndexToCheck;
  private int lastIndexToCheck;

  private String lastText;
  private boolean enabled;
  private StringBuilder savedText;

  /**
   * Initialize {@link PatternedTextWatcher} with {@code pattern} and default parameters.
   * For advanced tweaking use {@link Builder}.
   *
   * @param pattern the pattern of the text watcher.
   */
  public PatternedTextWatcher(String pattern) {
    this(new Builder(pattern));
  }

  PatternedTextWatcher(Builder builder) {
    checkPatternInput(builder.pattern);