// Path: domain/src/main/java/com/cesarvaliente/permissionsample/domain/action/ListContactsAction.java
// public interface ListContactsAction {
// 
//     interface DataCallback {
//         void onDataLoaded(List<ContactEntity> contactEntityList);
//     }
// 
//     void getPhoneBookContacts(DataCallback dataCallback);
// }
// 
// Path: domain/src/main/java/com/cesarvaliente/permissionsample/domain/entity/ContactEntity.java
// public class ContactEntity {
// 
//     private String id;
//     private String name;
//     private String email;
//     private String phone;
// 
//     public ContactEntity(String id, String name, String phone) {
//         this.id = id;
//         this.name = name;
//         this.phone = phone;
//     }
// 
//     public String getId() {
//         return id;
//     }
// 
//     public void setId(String id) {
//         this.id = id;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public String getEmail() {
//         return email;
//     }
// 
//     public void setEmail(String email) {
//         this.email = email;
//     }
// 
//     public String getPhone() {
//         return phone;
//     }
// 
//     public void setPhone(String phone) {
//         this.phone = phone;
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder builder = new StringBuilder("ContactEntity --> ");
//         builder.append(name).append(" - ").append(email).append(" - ").append(phone);
//         return builder.toString();
//     }
// }
// 
// Path: action/src/main/java/com/cesarvaliente/permissionssample/action/data/ContactData.java
// public class ContactData {
// 
//     private String id;
//     private String name;
//     private String email;
//     private String phone;
// 
//     public ContactData(String id, String name, String phone) {
//         this.id = id;
//         this.name = name;
//         this.phone = phone;
//     }
// 
//     public String getId() {
//         return id;
//     }
// 
//     public void setId(String id) {
//         this.id = id;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public String getEmail() {
//         return email;
//     }
// 
//     public void setEmail(String email) {
//         this.email = email;
//     }
// 
//     public String getPhone() {
//         return phone;
//     }
// 
//     public void setPhone(String phone) {
//         this.phone = phone;
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder builder = new StringBuilder("ContactData --> ");
//         builder.append(name).append(" - ").append(email).append(" - ").append(phone);
//         return builder.toString();
//     }
// }
// 
// Path: action/src/main/java/com/cesarvaliente/permissionssample/action/data/mapper/ContactDataMapper.java
// public class ContactDataMapper {
// 
//     public static ContactEntity transform(ContactData contactData) {
//         if (contactData == null) {
//             throw new IllegalArgumentException("Contact can not be null");
//         }
//         ContactEntity contactEntity = new ContactEntity(contactData.getId(), contactData.getName(), contactData
//                 .getPhone());
//         contactEntity.setEmail(contactData.getEmail());
// 
//         return contactEntity;
//     }
// 
//     public static List<ContactEntity> transform(List<ContactData> contactDataList) {
//         if (contactDataList == null) {
//             throw new IllegalArgumentException("Contact list can not be null");
//         }
//         List<ContactEntity> contactModels = new ArrayList<>(contactDataList.size());
//         for (ContactData contact : contactDataList) {
//             ContactEntity contactModel = transform(contact);
//             contactModels.add(contactModel);
//         }
//         return contactModels;
//     }
// }


import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.text.TextUtils;
import com.cesarvaliente.permissionsample.domain.action.ListContactsAction;
import com.cesarvaliente.permissionsample.domain.entity.ContactEntity;
import com.cesarvaliente.permissionssample.action.data.ContactData;
import com.cesarvaliente.permissionssample.action.data.mapper.ContactDataMapper;
            do {
                String contactId = contactsCursor.getString(contactsCursor.getColumnIndex(
                        ContactsContract.Contacts._ID));
                Cursor emails = getEmailsCursor(contactId);
                Cursor phones = getPHoneCursor(contactId);

                if (isCursorValid(emails) && isCursorValid(phones)) {
                    String name = contactsCursor.getString(contactsCursor.getColumnIndex(
                            ContactsContract.Data.DISPLAY_NAME));
                    String emailAddress = emails.getString(emails.getColumnIndex(ContactsContract
                            .CommonDataKinds.Email.DATA));
                    String phone = phones.getString(phones.getColumnIndex(
                            ContactsContract.CommonDataKinds.Phone.NUMBER));

                    if (!TextUtils.isEmpty(phone)) {
                        ContactData contactData = new ContactData(contactId, name, phone);
                        contactData.setEmail(emailAddress);
                        contactDataList.add(contactData);
                    }
                }
                closeCursor(emails);
                closeCursor(phones);
            } while (contactsCursor.moveToNext());
        }
        closeCursor(contactsCursor);

        notifyOnSuccess(contactDataList, dataCallback);
    }

    private void notifyOnSuccess(List<ContactData> contactDataList, DataCallback dataCallback) {
// Path: domain/src/main/java/com/cesarvaliente/permissionsample/domain/action/ListContactsAction.java
// public interface ListContactsAction {
// 
//     interface DataCallback {
//         void onDataLoaded(List<ContactEntity> contactEntityList);
//     }
// 
//     void getPhoneBookContacts(DataCallback dataCallback);
// }
// 
// Path: domain/src/main/java/com/cesarvaliente/permissionsample/domain/entity/ContactEntity.java
// public class ContactEntity {
// 
//     private String id;
//     private String name;
//     private String email;
//     private String phone;
// 
//     public ContactEntity(String id, String name, String phone) {
//         this.id = id;
//         this.name = name;
//         this.phone = phone;
//     }
// 
//     public String getId() {
//         return id;
//     }
// 
//     public void setId(String id) {
//         this.id = id;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public String getEmail() {
//         return email;
//     }
// 
//     public void setEmail(String email) {
//         this.email = email;
//     }
// 
//     public String getPhone() {
//         return phone;
//     }
// 
//     public void setPhone(String phone) {
//         this.phone = phone;
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder builder = new StringBuilder("ContactEntity --> ");
//         builder.append(name).append(" - ").append(email).append(" - ").append(phone);
//         return builder.toString();
//     }
// }
// 
// Path: action/src/main/java/com/cesarvaliente/permissionssample/action/data/ContactData.java
// public class ContactData {
// 
//     private String id;
//     private String name;
//     private String email;
//     private String phone;
// 
//     public ContactData(String id, String name, String phone) {
//         this.id = id;
//         this.name = name;
//         this.phone = phone;
//     }
// 
//     public String getId() {
//         return id;
//     }
// 
//     public void setId(String id) {
//         this.id = id;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public String getEmail() {
//         return email;
//     }
// 
//     public void setEmail(String email) {
//         this.email = email;
//     }
// 
//     public String getPhone() {
//         return phone;
//     }
// 
//     public void setPhone(String phone) {
//         this.phone = phone;
//     }
// 
//     @Override
//     public String toString() {
//         StringBuilder builder = new StringBuilder("ContactData --> ");
//         builder.append(name).append(" - ").append(email).append(" - ").append(phone);
//         return builder.toString();
//     }
// }
// 
// Path: action/src/main/java/com/cesarvaliente/permissionssample/action/data/mapper/ContactDataMapper.java
// public class ContactDataMapper {
// 
//     public static ContactEntity transform(ContactData contactData) {
//         if (contactData == null) {
//             throw new IllegalArgumentException("Contact can not be null");
//         }
//         ContactEntity contactEntity = new ContactEntity(contactData.getId(), contactData.getName(), contactData
//                 .getPhone());
//         contactEntity.setEmail(contactData.getEmail());
// 
//         return contactEntity;
//     }
// 
//     public static List<ContactEntity> transform(List<ContactData> contactDataList) {
//         if (contactDataList == null) {
//             throw new IllegalArgumentException("Contact list can not be null");
//         }
//         List<ContactEntity> contactModels = new ArrayList<>(contactDataList.size());
//         for (ContactData contact : contactDataList) {
//             ContactEntity contactModel = transform(contact);
//             contactModels.add(contactModel);
//         }
//         return contactModels;
//     }
// }


// Path: action/src/main/java/com/cesarvaliente/permissionssample/action/impl/ListListContactsActionImpl.java
import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.text.TextUtils;
import com.cesarvaliente.permissionsample.domain.action.ListContactsAction;
import com.cesarvaliente.permissionsample.domain.entity.ContactEntity;
import com.cesarvaliente.permissionssample.action.data.ContactData;
import com.cesarvaliente.permissionssample.action.data.mapper.ContactDataMapper;

            do {
                String contactId = contactsCursor.getString(contactsCursor.getColumnIndex(
                        ContactsContract.Contacts._ID));
                Cursor emails = getEmailsCursor(contactId);
                Cursor phones = getPHoneCursor(contactId);

                if (isCursorValid(emails) && isCursorValid(phones)) {
                    String name = contactsCursor.getString(contactsCursor.getColumnIndex(
                            ContactsContract.Data.DISPLAY_NAME));
                    String emailAddress = emails.getString(emails.getColumnIndex(ContactsContract
                            .CommonDataKinds.Email.DATA));
                    String phone = phones.getString(phones.getColumnIndex(
                            ContactsContract.CommonDataKinds.Phone.NUMBER));

                    if (!TextUtils.isEmpty(phone)) {
                        ContactData contactData = new ContactData(contactId, name, phone);
                        contactData.setEmail(emailAddress);
                        contactDataList.add(contactData);
                    }
                }
                closeCursor(emails);
                closeCursor(phones);
            } while (contactsCursor.moveToNext());
        }
        closeCursor(contactsCursor);

        notifyOnSuccess(contactDataList, dataCallback);
    }

    private void notifyOnSuccess(List<ContactData> contactDataList, DataCallback dataCallback) {
        List<ContactEntity> contactEntityList = ContactDataMapper.transform(contactDataList);