// Path: src/main/java/com/rolfje/anonimatron/synonyms/StringSynonym.java
// public class StringSynonym implements Synonym {
//     private String type;
//     private String from;
//     private String to;
//     private boolean shortlived = false;
// 
//     public StringSynonym() {
//     }
// 
//     public StringSynonym(String type, String from, String to, boolean shortlived) {
//         this.type = type;
//         this.from = from;
//         this.to = to;
//         this.shortlived = shortlived;
//     }
// 
//     @Override
//     public String getType() {
//         return type;
//     }
// 
//     @Override
//     public Object getFrom() {
//         return from;
//     }
// 
//     @Override
//     public Object getTo() {
//         return to;
//     }
// 
//     public void setType(String type) {
//         this.type = type;
//     }
// 
//     public void setFrom(String from) {
//         this.from = from;
//     }
// 
//     public void setTo(String to) {
//         this.to = to;
//     }
// 
//     public void setShortlived(boolean shortlived) {
//         this.shortlived = shortlived;
//     }
// 
//     @Override
//     public boolean isShortLived() {
//         return shortlived;
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         return (obj != null) && (this.getClass() == obj.getClass()) && (this.hashCode() == obj.hashCode());
//     }
// 
//     @Override
//     public int hashCode() {
//         return from.hashCode() + to.hashCode() + type.hashCode();
//     }
// }
// 
// 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 static org.apache.log4j.Logger.getLogger;
import java.util.EnumMap;
import java.util.Locale;
import java.util.Map;
import org.apache.log4j.Logger;
import org.iban4j.CountryCode;
import org.iban4j.Iban;
import org.iban4j.Iban4jException;
import org.iban4j.bban.BbanStructure;
import com.rolfje.anonimatron.synonyms.StringSynonym;
import com.rolfje.anonimatron.synonyms.Synonym;

package com.rolfje.anonimatron.anonymizer;





/**
 * Generates valid International Bank Account Numbers, or {@code IBAN}'s.
 * Tries to use the {@link BankAccountAnonymizer} to generate valid {@code BBAN}'s for the system default country code.
 * If no such anonymizer exists, a random account is generated.
 * <p>
 *
 * @author Erik-Berndt Scheper
 * @see <a href="https://en.wikipedia.org/wiki/International_Bank_Account_Number">https://en.wikipedia.org/wiki/International_Bank_Account_Number</a>
 */
public class IbanAnonymizer implements Anonymizer {

	private static final Logger LOGGER = getLogger(IbanAnonymizer.class);

	private static final String TYPE = "IBAN";

	static final Map<CountryCode, BankAccountAnonymizer> BANK_ACCOUNT_ANONYMIZERS;
	static final CountryCode DEFAULT_COUNTRY_CODE;

	static {
		// initialize bank account anonymizers
		BANK_ACCOUNT_ANONYMIZERS = new EnumMap<>(CountryCode.class);
		BANK_ACCOUNT_ANONYMIZERS.put(CountryCode.NL, new DutchBankAccountAnononymizer());

		// set a default country code to be used when the original iban cannot be parsed
		CountryCode countryCode = CountryCode.getByCode(Locale.getDefault().getCountry());

		if (countryCode != null && BbanStructure.forCountry(countryCode) != null) {
			DEFAULT_COUNTRY_CODE = countryCode;
		} else {
			DEFAULT_COUNTRY_CODE = CountryCode.NL;
		}
	}

	@Override
	public String getType() {
		return TYPE;
	}

	@Override

// Path: src/main/java/com/rolfje/anonimatron/synonyms/StringSynonym.java
// public class StringSynonym implements Synonym {
//     private String type;
//     private String from;
//     private String to;
//     private boolean shortlived = false;
// 
//     public StringSynonym() {
//     }
// 
//     public StringSynonym(String type, String from, String to, boolean shortlived) {
//         this.type = type;
//         this.from = from;
//         this.to = to;
//         this.shortlived = shortlived;
//     }
// 
//     @Override
//     public String getType() {
//         return type;
//     }
// 
//     @Override
//     public Object getFrom() {
//         return from;
//     }
// 
//     @Override
//     public Object getTo() {
//         return to;
//     }
// 
//     public void setType(String type) {
//         this.type = type;
//     }
// 
//     public void setFrom(String from) {
//         this.from = from;
//     }
// 
//     public void setTo(String to) {
//         this.to = to;
//     }
// 
//     public void setShortlived(boolean shortlived) {
//         this.shortlived = shortlived;
//     }
// 
//     @Override
//     public boolean isShortLived() {
//         return shortlived;
//     }
// 
//     @Override
//     public boolean equals(Object obj) {
//         return (obj != null) && (this.getClass() == obj.getClass()) && (this.hashCode() == obj.hashCode());
//     }
// 
//     @Override
//     public int hashCode() {
//         return from.hashCode() + to.hashCode() + type.hashCode();
//     }
// }
// 
// 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/main/java/com/rolfje/anonimatron/anonymizer/IbanAnonymizer.java
import static org.apache.log4j.Logger.getLogger;
import java.util.EnumMap;
import java.util.Locale;
import java.util.Map;
import org.apache.log4j.Logger;
import org.iban4j.CountryCode;
import org.iban4j.Iban;
import org.iban4j.Iban4jException;
import org.iban4j.bban.BbanStructure;
import com.rolfje.anonimatron.synonyms.StringSynonym;
import com.rolfje.anonimatron.synonyms.Synonym;

package com.rolfje.anonimatron.anonymizer;





/**
 * Generates valid International Bank Account Numbers, or {@code IBAN}'s.
 * Tries to use the {@link BankAccountAnonymizer} to generate valid {@code BBAN}'s for the system default country code.
 * If no such anonymizer exists, a random account is generated.
 * <p>
 *
 * @author Erik-Berndt Scheper
 * @see <a href="https://en.wikipedia.org/wiki/International_Bank_Account_Number">https://en.wikipedia.org/wiki/International_Bank_Account_Number</a>
 */
public class IbanAnonymizer implements Anonymizer {

	private static final Logger LOGGER = getLogger(IbanAnonymizer.class);

	private static final String TYPE = "IBAN";

	static final Map<CountryCode, BankAccountAnonymizer> BANK_ACCOUNT_ANONYMIZERS;
	static final CountryCode DEFAULT_COUNTRY_CODE;

	static {
		// initialize bank account anonymizers
		BANK_ACCOUNT_ANONYMIZERS = new EnumMap<>(CountryCode.class);
		BANK_ACCOUNT_ANONYMIZERS.put(CountryCode.NL, new DutchBankAccountAnononymizer());

		// set a default country code to be used when the original iban cannot be parsed
		CountryCode countryCode = CountryCode.getByCode(Locale.getDefault().getCountry());

		if (countryCode != null && BbanStructure.forCountry(countryCode) != null) {
			DEFAULT_COUNTRY_CODE = countryCode;
		} else {
			DEFAULT_COUNTRY_CODE = CountryCode.NL;
		}
	}

	@Override
	public String getType() {
		return TYPE;
	}

	@Override

	public Synonym anonymize(Object from, int size, boolean shortlived) {
