// Path: app/src/main/java/com/kaliturin/blacklist/utils/DatabaseAccessHelper.java
// public static class Contact {
//     public static final int TYPE_BLACK_LIST = 1;
//     public static final int TYPE_WHITE_LIST = 2;
// 
//     public final long id;
//     public final String name;
//     public final int type;
//     public final List<ContactNumber> numbers;
// 
//     Contact(long id, @NonNull String name, int type, @NonNull List<ContactNumber> numbers) {
//         this.id = id;
//         this.name = name;
//         this.type = type;
//         this.numbers = numbers;
//     }
// }
// 
// Path: app/src/main/java/com/kaliturin/blacklist/utils/DatabaseAccessHelper.java
// public static class ContactNumber {
//     public static final int TYPE_EQUALS = 0;
//     public static final int TYPE_CONTAINS = 1;
//     public static final int TYPE_STARTS = 2;
//     public static final int TYPE_ENDS = 3;
// 
//     public final long id;
//     public final String number;
//     public final int type;
//     public final long contactId;
// 
//     public ContactNumber(long id, @NonNull String number, long contactId) {
//         this(id, number, TYPE_EQUALS, contactId);
//     }
// 
//     public ContactNumber(long id, @NonNull String number, int type, long contactId) {
//         this.id = id;
//         this.number = number;
//         this.type = type;
//         this.contactId = contactId;
//     }
// }
// 
// Path: app/src/main/java/com/kaliturin/blacklist/utils/DatabaseAccessHelper.java
// public interface ContactSource {
//     Contact getContact();
// }


import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.database.MatrixCursor;
import android.net.Uri;
import android.provider.CallLog.Calls;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import com.kaliturin.blacklist.utils.DatabaseAccessHelper.Contact;
import com.kaliturin.blacklist.utils.DatabaseAccessHelper.ContactNumber;
import com.kaliturin.blacklist.utils.DatabaseAccessHelper.ContactSource;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
            case FROM_CALLS_LOG:
                return Permissions.READ_CALL_LOG;
            case FROM_SMS_LIST:
                return Permissions.READ_SMS;
            case FROM_BLACK_LIST:
            case FROM_WHITE_LIST:
                return Permissions.WRITE_EXTERNAL_STORAGE;
        }
        return null;
    }

    // Returns contacts from specified source
    @Nullable
    public Cursor getContacts(Context context, ContactSourceType sourceType, @Nullable String filter) {
        // check permission
        final String permission = getPermission(sourceType);
        if (permission == null || !Permissions.isGranted(context, permission)) {
            return null;
        }
        // return contacts
        switch (sourceType) {
            case FROM_CONTACTS:
                return getContacts(filter);
            case FROM_CALLS_LOG:
                return getContactsFromCallsLog(filter);
            case FROM_SMS_LIST:
                return getContactsFromSMSList(filter);
            case FROM_BLACK_LIST: {
                DatabaseAccessHelper db = DatabaseAccessHelper.getInstance(context);
                if (db != null) {
// Path: app/src/main/java/com/kaliturin/blacklist/utils/DatabaseAccessHelper.java
// public static class Contact {
//     public static final int TYPE_BLACK_LIST = 1;
//     public static final int TYPE_WHITE_LIST = 2;
// 
//     public final long id;
//     public final String name;
//     public final int type;
//     public final List<ContactNumber> numbers;
// 
//     Contact(long id, @NonNull String name, int type, @NonNull List<ContactNumber> numbers) {
//         this.id = id;
//         this.name = name;
//         this.type = type;
//         this.numbers = numbers;
//     }
// }
// 
// Path: app/src/main/java/com/kaliturin/blacklist/utils/DatabaseAccessHelper.java
// public static class ContactNumber {
//     public static final int TYPE_EQUALS = 0;
//     public static final int TYPE_CONTAINS = 1;
//     public static final int TYPE_STARTS = 2;
//     public static final int TYPE_ENDS = 3;
// 
//     public final long id;
//     public final String number;
//     public final int type;
//     public final long contactId;
// 
//     public ContactNumber(long id, @NonNull String number, long contactId) {
//         this(id, number, TYPE_EQUALS, contactId);
//     }
// 
//     public ContactNumber(long id, @NonNull String number, int type, long contactId) {
//         this.id = id;
//         this.number = number;
//         this.type = type;
//         this.contactId = contactId;
//     }
// }
// 
// Path: app/src/main/java/com/kaliturin/blacklist/utils/DatabaseAccessHelper.java
// public interface ContactSource {
//     Contact getContact();
// }


// Path: app/src/main/java/com/kaliturin/blacklist/utils/ContactsAccessHelper.java
import android.annotation.TargetApi;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.CursorWrapper;
import android.database.MatrixCursor;
import android.net.Uri;
import android.provider.CallLog.Calls;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import com.kaliturin.blacklist.utils.DatabaseAccessHelper.Contact;
import com.kaliturin.blacklist.utils.DatabaseAccessHelper.ContactNumber;
import com.kaliturin.blacklist.utils.DatabaseAccessHelper.ContactSource;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

            case FROM_CALLS_LOG:
                return Permissions.READ_CALL_LOG;
            case FROM_SMS_LIST:
                return Permissions.READ_SMS;
            case FROM_BLACK_LIST:
            case FROM_WHITE_LIST:
                return Permissions.WRITE_EXTERNAL_STORAGE;
        }
        return null;
    }

    // Returns contacts from specified source
    @Nullable
    public Cursor getContacts(Context context, ContactSourceType sourceType, @Nullable String filter) {
        // check permission
        final String permission = getPermission(sourceType);
        if (permission == null || !Permissions.isGranted(context, permission)) {
            return null;
        }
        // return contacts
        switch (sourceType) {
            case FROM_CONTACTS:
                return getContacts(filter);
            case FROM_CALLS_LOG:
                return getContactsFromCallsLog(filter);
            case FROM_SMS_LIST:
                return getContactsFromSMSList(filter);
            case FROM_BLACK_LIST: {
                DatabaseAccessHelper db = DatabaseAccessHelper.getInstance(context);
                if (db != null) {
                    return db.getContacts(DatabaseAccessHelper.Contact.TYPE_BLACK_LIST, filter);