master 661f17d2a445 cached
171 files
231.7 KB
56.9k tokens
591 symbols
1 requests
Download .txt
Showing preview only (280K chars total). Download the full file or copy to clipboard to get everything.
Repository: nenick/android-gradle-template
Branch: master
Commit: 661f17d2a445
Files: 171
Total size: 231.7 KB

Directory structure:
gitextract_0g2gn4nz/

├── .gitignore
├── app/
│   ├── build.generate-database.gradle
│   ├── build.generate-json-objects.gradle
│   ├── build.gradle
│   ├── build.jacoco-test-report.gradle
│   ├── build.robolectric.gradle
│   ├── build.wiremock-replace-ip.gradle
│   ├── lint.xml
│   ├── proguard-rules.pro
│   └── src/
│       ├── gen/
│       │   └── java/
│       │       └── com/
│       │           └── example/
│       │               └── project/
│       │                   ├── database/
│       │                   │   └── provider/
│       │                   │       ├── ExampleProvider.java
│       │                   │       ├── ExampleSQLiteOpenHelper.java
│       │                   │       ├── ExampleSQLiteOpenHelperCallbacks.java
│       │                   │       ├── address/
│       │                   │       │   ├── AddressColumns.java
│       │                   │       │   ├── AddressContentValues.java
│       │                   │       │   ├── AddressCursor.java
│       │                   │       │   ├── AddressModel.java
│       │                   │       │   └── AddressSelection.java
│       │                   │       ├── base/
│       │                   │       │   ├── AbstractContentValues.java
│       │                   │       │   ├── AbstractCursor.java
│       │                   │       │   ├── AbstractSelection.java
│       │                   │       │   ├── BaseContentProvider.java
│       │                   │       │   └── BaseModel.java
│       │                   │       └── contact/
│       │                   │           ├── ContactColumns.java
│       │                   │           ├── ContactContentValues.java
│       │                   │           ├── ContactCursor.java
│       │                   │           ├── ContactModel.java
│       │                   │           └── ContactSelection.java
│       │                   └── network/
│       │                       └── json/
│       │                           ├── ContactJson.java
│       │                           └── ContactListJson.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── example/
│       │   │           └── project/
│       │   │               ├── business/
│       │   │               │   ├── contact/
│       │   │               │   │   ├── CreateContactFunction.java
│       │   │               │   │   ├── DeleteContactFunction.java
│       │   │               │   │   ├── QueryContactFunction.java
│       │   │               │   │   ├── QueryContactListFunction.java
│       │   │               │   │   └── UpdateContactFunction.java
│       │   │               │   └── contact_sync/
│       │   │               │       └── SyncContactsFunction.java
│       │   │               ├── database/
│       │   │               │   ├── ExampleDbProvider.java
│       │   │               │   ├── ExampleSQLiteOpenHelperCallbacks.java
│       │   │               │   └── contact/
│       │   │               │       ├── AddressDb.java
│       │   │               │       └── ContactDb.java
│       │   │               ├── network/
│       │   │               │   └── contact/
│       │   │               │       ├── ContactRestClient.java
│       │   │               │       └── RootUrlInterceptor.java
│       │   │               └── views/
│       │   │                   ├── common/
│       │   │                   │   ├── AppIdlingResources.java
│       │   │                   │   ├── cursorloader/
│       │   │                   │   │   └── CursorAdapterWithCursorLoader.java
│       │   │                   │   ├── mvp/
│       │   │                   │   │   ├── BaseActivityPresenter.java
│       │   │                   │   │   ├── BaseFragmentPresenter.java
│       │   │                   │   │   ├── BasePresenter.java
│       │   │                   │   │   └── BaseView.java
│       │   │                   │   └── testwrapper/
│       │   │                   │       └── ViewFinisher.java
│       │   │                   ├── contact_details/
│       │   │                   │   ├── DetailActivity.java
│       │   │                   │   ├── DetailActivityIntent.java
│       │   │                   │   ├── DetailFragment.java
│       │   │                   │   └── DetailView.java
│       │   │                   ├── contact_edit/
│       │   │                   │   ├── EditActivity.java
│       │   │                   │   ├── EditActivityIntent.java
│       │   │                   │   ├── EditConfirmedListener.java
│       │   │                   │   ├── EditFragment.java
│       │   │                   │   └── EditView.java
│       │   │                   ├── contact_list/
│       │   │                   │   ├── ContactAdapter.java
│       │   │                   │   ├── ContactAdapterLoader.java
│       │   │                   │   ├── ContactListActivity.java
│       │   │                   │   ├── ContactListActivityIntent.java
│       │   │                   │   ├── ContactListFragment.java
│       │   │                   │   ├── ContactListView.java
│       │   │                   │   └── ShowContactListener.java
│       │   │                   └── start/
│       │   │                       └── StartActivity.java
│       │   ├── json/
│       │   │   ├── database/
│       │   │   │   └── schema/
│       │   │   │       ├── _config.json
│       │   │   │       ├── address.json
│       │   │   │       └── contact.json
│       │   │   └── network/
│       │   │       └── schema/
│       │   │           ├── contactJson.json
│       │   │           └── contactListJson.json
│       │   └── res/
│       │       ├── layout/
│       │       │   ├── activity_detail.xml
│       │       │   ├── activity_edit.xml
│       │       │   ├── activity_main.xml
│       │       │   ├── fragment_detail.xml
│       │       │   ├── fragment_edit.xml
│       │       │   └── fragment_list.xml
│       │       ├── layout-land/
│       │       │   └── activity_main.xml
│       │       ├── menu/
│       │       │   └── menu_main.xml
│       │       ├── values/
│       │       │   ├── dimens.xml
│       │       │   ├── string_api_url.xml
│       │       │   ├── strings.xml
│       │       │   ├── strings_details.xml
│       │       │   └── styles.xml
│       │       └── values-w820dp/
│       │           └── dimens.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── example/
│                       └── project/
│                           ├── RoboTestCase.java
│                           ├── business/
│                           │   └── contact/
│                           │       └── QueryContactListFunctionTest.java
│                           ├── database/
│                           │   └── contact/
│                           │       ├── AddressDbInsertTest.java
│                           │       ├── AddressDbTest.java
│                           │       ├── ContactDbInsertTest.java
│                           │       └── ContactDbTest.java
│                           └── views/
│                               ├── contact_edit/
│                               │   ├── EditActivityTest.java
│                               │   └── EditFragmentTest.java
│                               ├── contact_list/
│                               │   ├── ContactListActivityTest.java
│                               │   └── ContactListFragmentTest.java
│                               └── start/
│                                   └── StartActivityTest.java
├── appCt/
│   ├── build.gradle
│   ├── build.jacoco-test-report.gradle
│   ├── build.novoda-android-studio.gradle
│   ├── build.robolectric.gradle
│   └── src/
│       └── test/
│           └── java/
│               ├── android/
│               │   └── database/
│               │       └── ShadowContentObservable.java
│               └── com/
│                   └── example/
│                       └── project/
│                           ├── RobolectricTestCase.java
│                           ├── robolectric/
│                           │   ├── CostomRobolectricTestRunner.java
│                           │   ├── RoboButton.java
│                           │   ├── RoboListView.java
│                           │   ├── RoboListViewEntry.java
│                           │   ├── RoboTextEdit.java
│                           │   └── ShadowBackgroundExecutor.java
│                           ├── testdata/
│                           │   └── TestContactData.java
│                           └── views/
│                               ├── contac_list/
│                               │   ├── ContactListSpec.java
│                               │   └── RoboContactListPage.java
│                               ├── contact_details/
│                               │   └── ContactDetailSpec.java
│                               └── contact_edit/
│                                   ├── ContactCreateSpec.java
│                                   ├── ContactEditSpec.java
│                                   └── RoboContactEditPage.java
├── appIt/
│   ├── build.gradle
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── example/
│                       └── project/
│                           ├── EspressoTestCase.java
│                           ├── espresso/
│                           │   ├── CurrentActivity.java
│                           │   ├── EspButton.java
│                           │   ├── EspListView.java
│                           │   ├── EspMenuItem.java
│                           │   └── EspTextEdit.java
│                           ├── pages/
│                           │   ├── EspContactListPage.java
│                           │   └── EspEditContactPage.java
│                           └── test/
│                               ├── CreateContactTest.java
│                               └── SyncContactsTest.java
├── build.gradle
├── build.jacoco-test-report.gradle
├── circle.yml
├── docs/
│   ├── build.gradle
│   └── src/
│       └── main/
│           └── resources/
│               ├── adjust_project_to_your_needs.md
│               ├── concepts/
│               │   ├── function_class.md
│               │   ├── model_view_presenter.md
│               │   ├── package_structure.md
│               │   ├── project_structure.md
│               │   └── testing.md
│               ├── getting_started.md
│               ├── index.md
│               └── tools/
│                   ├── android_contentprovider_generator.md
│                   ├── androidannotations.md
│                   ├── circleci.md
│                   ├── coveralls.md
│                   ├── espresso.md
│                   ├── espresso_test_module.md
│                   ├── fest_assertions.md
│                   ├── jacoco.md
│                   ├── joda_timedate.md
│                   ├── jsonschema2pojo.md
│                   ├── robolectric.md
│                   ├── robolectric_test_module.md
│                   └── wiremock.md
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── readme.md
├── settings.gradle
├── tools/
│   ├── build.gradle
│   └── src/
│       └── main/
│           └── resources/
│               ├── rename-packages(in development).sh
│               ├── start-wiremock.sh
│               ├── test-all-with-coverage.bat
│               └── test-all-with-coverage.sh
└── wiremock/
    ├── build.gradle
    ├── src/
    │   └── main/
    │       └── resources/
    │           ├── __files/
    │           │   └── contacts-get.json
    │           └── mappings/
    │               ├── contcts-delete.json
    │               ├── contcts-get.json
    │               ├── contcts-post.json
    │               └── contcts-put.json
    └── wiremock-1.57-standalone.jar

================================================
FILE CONTENTS
================================================

================================================
FILE: .gitignore
================================================
.DS_Store
.idea
.gradle
*~
*.iml
**/build
GenerateJsonRestModel/gen/*
local.properties


================================================
FILE: app/build.generate-database.gradle
================================================
def dbSchemaPath = "src/main/json/database/schema"
def dbClassesPath = "src/gen/java"
android.sourceSets.main.java.srcDirs += dbClassesPath
android.sourceSets.main.java.srcDirs += "src/main/json"

task generateDatabaseFiles << {
    def generatorVersion = "1.9.2"

    // download android contentprovider generator
    if (!file("$buildDir/android_contentprovider_generator-${generatorVersion}-bundle.jar").exists()) {
        download {
            src "https://github.com/BoD/android-contentprovider-generator/releases/download/v${generatorVersion}/android_contentprovider_generator-${generatorVersion}-bundle.jar"
            dest buildDir
        }
    }

    // delete last generated files
    // file(dbClassesPath).deleteDir()

    // execute the generator
    exec {
        executable "java"
        args = ["-jar", "$buildDir/android_contentprovider_generator-${generatorVersion}-bundle.jar", "-i", dbSchemaPath, "-o", dbClassesPath]
    }
}

================================================
FILE: app/build.generate-json-objects.gradle
================================================
apply plugin: 'jsonschema2pojo'

dependencies {
    compile 'com.fasterxml.jackson.core:jackson-databind:2.6.1'
    compile 'javax.annotation:javax.annotation-api:1.2'
}

jsonSchema2Pojo {
    source = files("${project.projectDir}/src/main/json/network/schema")
    targetDirectory = file("${project.projectDir}/src/gen/java")
    targetPackage = 'com.example.project.network.json'
    useCommonsLang3 = true
}

================================================
FILE: app/build.gradle
================================================
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        // code generation support for android annotations
        classpath 'com.neenbedankt.gradle.plugins:android-apt:1.4'

        // code generation for json string - object mapping
        classpath 'org.jsonschema2pojo:jsonschema2pojo-gradle-plugin:0.4.14'
    }
}

plugins {
    // provide download task for gradle
    id "de.undercouch.download" version "1.2"
}

apply plugin: 'com.android.application'

// code generation support for android annotations
apply plugin: 'android-apt'

// code generation for json object mapping
apply from: 'build.generate-json-objects.gradle'

// code generation database files
apply from: 'build.generate-database.gradle'

// test support for android specific unit tests like database checks
apply from: 'build.robolectric.gradle'

// support code coverage for the unit tests
apply from: 'build.jacoco-test-report.gradle'

// replace target ip for REST calls to use local wiremock
apply from: "build.wiremock-replace-ip.gradle"

android {
    compileSdkVersion projectAndroidVersion
    buildToolsVersion projectAndroidBuildToolsVersion

    defaultConfig {
        applicationId "com.example.project"
        minSdkVersion projectAndroidMinVersion
        targetSdkVersion projectAndroidVersion
        versionCode 1
        versionName "1.0"
    }

    buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
            buildConfigField "String", "MODULE_PATH", "\"$projectDir\"".replace('\\', '\\\\')
            // avoid warning for "Not all execution paths return a value"
            return true
        }
        debug {
            buildConfigField "String", "MODULE_PATH", "\"$projectDir\"".replace('\\', '\\\\')
            return true
        }
    }

    lintOptions {
        // GradleDependency Current we can't switch to support v23 tools because of robolectric
        disable 'GradleDependency'
    }

    dexOptions {
        if(isCi) {
            // CircleCi allow max 4G memory for all processes together and dex does exceed it
            // with his parallel execution. Shrink the javaMaxHeapSize does it only per dex process
            // but the combination exceed the max memory and to less value let it run for long time.
            // javaMaxHeapSize "1024M"

            // Speed up build for CI by ignoring extra build steps which should speed up build for developers.
            // Also reduce memory usage by avoiding multiple (pre) dex processes.
            incremental false
            preDexLibraries = false
        }
    }

    // instrumentation test module need to access the expected variant, default is only release publish
    publishNonDefault true

    packagingOptions {
        exclude 'META-INF/license.txt'
        exclude 'META-INF/LICENSE.txt'
        exclude 'META-INF/LICENSE'
        exclude 'META-INF/notice.txt'
        exclude 'META-INF/NOTICE.txt'
        exclude 'META-INF/NOTICE'
    }
}

apt {
    arguments {
        androidManifestFile variant.outputs.collect()[0].processResources.manifestFile
    }
}

repositories {
    jcenter()
}

dependencies {
    // ui design and backward compatibility
    compile "com.android.support:appcompat-v7:$projectAndroidSupportToolsVersion"
    compile "com.android.support:design:$projectAndroidSupportToolsVersion"

    // android annotations support
    apt "org.androidannotations:androidannotations:3.3.2"
    compile "org.androidannotations:androidannotations-api:3.3.2"

    // network support with android annotations
    compile "org.springframework.android:spring-android-rest-template:2.0.0.M3"

    // better time handling with DateTime
    compile 'net.danlew:android.joda:2.8.2'

    // java language tools like StringUtils
    compile 'org.apache.commons:commons-lang3:3.4'

    // Use CountIdlingResource class to avoid flaky espresso tests.
    // Interface is provided by own dependency but ready to use implementation comes with contrib library.
    // Looks like contrib library was only intended to be used within test scope.
    // Exclude transitiv dependencies to avoid conflicts with test support libraries.
    compile('com.android.support.test.espresso:espresso-idling-resource:2.2')
    compile('com.android.support.test.espresso:espresso-contrib:2.2') { exclude module: "*" }

    // force test dependencies to use the same support-annotations version
    testCompile "com.android.support:support-annotations:$projectAndroidSupportToolsVersion"

    // basic unit tests support + mocks + fluent assertions + android assertions
    testCompile 'junit:junit:4.12'
    testCompile 'com.squareup.assertj:assertj-android:1.1.0'
    testCompile 'org.mockito:mockito-all:2.0.2-beta'
}



================================================
FILE: app/build.jacoco-test-report.gradle
================================================
apply plugin: "jacoco"

jacoco {
    toolVersion = projectJacocoVersion
}

task jacocoTestReport(type: JacocoReport /*, dependsOn: ['test'] */ ) {
    description = "Generates Jacoco coverage reports: XML and HTML"
    group = "Reporting"
//                outputs.upToDateWhen { false }

    // use hidden configuration, for details look into JacocoPlugin.groovy
    jacocoClasspath = project.configurations['androidJacocoAnt']

    // exclude auto-generated classes and tests
    def fileFilter = ['**/R.class',
                      '**/R$*.class',
                      '**/BuildConfig.*',
                      '**/Manifest*.*',
                      '**/*Test*.*',
                      'android/**/*.*']

    def debugTree = fileTree(dir: "${project.buildDir}/intermediates/classes/debug", excludes: fileFilter)
    def mainSrc = "${project.projectDir}/src/main/java"

    sourceDirectories = files([mainSrc])
    classDirectories = files([debugTree])
    executionData = fileTree(dir: project.projectDir, includes: ['**/*.exec', '**/*.ec'])

    reports {
        xml {
            enabled = true
            destination = "${project.buildDir}/reports/jacoco/test/jacocoTestReport.xml"
        }
        csv.enabled false
        html {
            enabled = true
            destination = "${project.buildDir}/reports/jacoco"
        }
    }
}

================================================
FILE: app/build.robolectric.gradle
================================================
dependencies {
    testCompile 'org.robolectric:shadows-support-v4:3.0'
    testCompile 'org.robolectric:robolectric:3.0'
}

afterEvaluate {

    def isLintRun = false
    def isTestRun = false

    gradle.startParameter.taskNames.each {
        if (it.contains("lint")) {
            isLintRun = true
        }
        if (it.contains("test")) {
            isTestRun = true
        }
    }

    if (isLintRun && isTestRun) {
        println "WARNING: tests for release type are disabled for supporting jacoco"
        println "WARNING: run test and lint at same time is not supported"
        exit 1
    }

    if (isTestRun) {
        tasks.each {
            if (it.name.contains("Release")) {
                it.enabled = false
            }
        }
    }
}

================================================
FILE: app/build.wiremock-replace-ip.gradle
================================================
// may be used to check if wiremock is running
Process p1 = Runtime.getRuntime().exec("curl " + obtainCurrentIpAddress() + ":1337/");
int returnVal = p1.waitFor();
boolean reachable = (returnVal == 0);
println "\n Wiremock is reachable $reachable\n"

// replace the #const_wiremock_ip# with your current ip address for test with wiremock
android.applicationVariants.all { variant ->
    variant.mergeResources.doLast {
        def String localIp = obtainCurrentIpAddress()
        File valuesFile = file("${buildDir}/intermediates/res/merged/debug/values/values.xml")
        if (valuesFile.exists()) {
            String content = valuesFile.getText('UTF-8')
            content = content.replaceAll("#const_wiremock_ip#", localIp)
            valuesFile.write(content, 'UTF-8')
        } else {
            println "Warning: value.xml not found for replace current ip"
        }
    }
}

def String obtainCurrentIpAddress() {

    def wantedInterfaceDisplayName = System.getenv("TEST_MOCK_IFACE");

    if ((wantedInterfaceDisplayName != null) && (!wantedInterfaceDisplayName.isEmpty())) {
        println "\n Interface wanted: " + wantedInterfaceDisplayName
    } else {
        println "\n No interface wanted, you can select one by setting the interface name to environment variable TEST_MOCK_IFACE"
    }

    def ipAddress = null;

    Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces();
    while (networkInterfaces.hasMoreElements()) {
        NetworkInterface networkInterface = (NetworkInterface) networkInterfaces.nextElement();

        Enumeration inetAddresses = networkInterface.getInetAddresses();
        InetAddress inetAddress = (InetAddress) inetAddresses.nextElement();
        println " Found network [${networkInterface.getDisplayName()}] with IP ${inetAddress.getHostAddress()}"

        if (wantedInterfaceDisplayName?.trim() && !wantedInterfaceDisplayName.equalsIgnoreCase(networkInterface.displayName)) {
            continue;
        }

        if (ipAddress == null) {
            ipAddress = inetAddress.getHostAddress();
            println " Selected network ${ipAddress}"
        }
    }

    ipAddress
}



================================================
FILE: app/lint.xml
================================================
<?xml version="1.0" encoding="UTF-8"?>
<lint>
    <issue id="all">
        <ignore regexp="src/gen/java/*" />
    </issue>
</lint>

================================================
FILE: app/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/nicokuechler/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
#   public *;
#}
-dontwarn org.androidannotations.api.rest.*


================================================
FILE: app/src/gen/java/com/example/project/database/provider/ExampleProvider.java
================================================
package com.example.project.database.provider;

import java.util.Arrays;

import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.util.Log;

import com.example.project.BuildConfig;
import com.example.project.database.provider.base.BaseContentProvider;
import com.example.project.database.provider.address.AddressColumns;
import com.example.project.database.provider.contact.ContactColumns;

public class ExampleProvider extends BaseContentProvider {
    private static final String TAG = ExampleProvider.class.getSimpleName();

    private static final boolean DEBUG = BuildConfig.DEBUG;

    private static final String TYPE_CURSOR_ITEM = "vnd.android.cursor.item/";
    private static final String TYPE_CURSOR_DIR = "vnd.android.cursor.dir/";

    public static final String AUTHORITY = "com.example.project";
    public static final String CONTENT_URI_BASE = "content://" + AUTHORITY;

    private static final int URI_TYPE_ADDRESS = 0;
    private static final int URI_TYPE_ADDRESS_ID = 1;

    private static final int URI_TYPE_CONTACT = 2;
    private static final int URI_TYPE_CONTACT_ID = 3;



    private static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);

    static {
        URI_MATCHER.addURI(AUTHORITY, AddressColumns.TABLE_NAME, URI_TYPE_ADDRESS);
        URI_MATCHER.addURI(AUTHORITY, AddressColumns.TABLE_NAME + "/#", URI_TYPE_ADDRESS_ID);
        URI_MATCHER.addURI(AUTHORITY, ContactColumns.TABLE_NAME, URI_TYPE_CONTACT);
        URI_MATCHER.addURI(AUTHORITY, ContactColumns.TABLE_NAME + "/#", URI_TYPE_CONTACT_ID);
    }

    @Override
    protected SQLiteOpenHelper createSqLiteOpenHelper() {
        return ExampleSQLiteOpenHelper.getInstance(getContext());
    }

    @Override
    protected boolean hasDebug() {
        return DEBUG;
    }

    @Override
    public String getType(Uri uri) {
        int match = URI_MATCHER.match(uri);
        switch (match) {
            case URI_TYPE_ADDRESS:
                return TYPE_CURSOR_DIR + AddressColumns.TABLE_NAME;
            case URI_TYPE_ADDRESS_ID:
                return TYPE_CURSOR_ITEM + AddressColumns.TABLE_NAME;

            case URI_TYPE_CONTACT:
                return TYPE_CURSOR_DIR + ContactColumns.TABLE_NAME;
            case URI_TYPE_CONTACT_ID:
                return TYPE_CURSOR_ITEM + ContactColumns.TABLE_NAME;

        }
        return null;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        if (DEBUG) Log.d(TAG, "insert uri=" + uri + " values=" + values);
        return super.insert(uri, values);
    }

    @Override
    public int bulkInsert(Uri uri, ContentValues[] values) {
        if (DEBUG) Log.d(TAG, "bulkInsert uri=" + uri + " values.length=" + values.length);
        return super.bulkInsert(uri, values);
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        if (DEBUG) Log.d(TAG, "update uri=" + uri + " values=" + values + " selection=" + selection + " selectionArgs=" + Arrays.toString(selectionArgs));
        return super.update(uri, values, selection, selectionArgs);
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        if (DEBUG) Log.d(TAG, "delete uri=" + uri + " selection=" + selection + " selectionArgs=" + Arrays.toString(selectionArgs));
        return super.delete(uri, selection, selectionArgs);
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        if (DEBUG)
            Log.d(TAG, "query uri=" + uri + " selection=" + selection + " selectionArgs=" + Arrays.toString(selectionArgs) + " sortOrder=" + sortOrder
                    + " groupBy=" + uri.getQueryParameter(QUERY_GROUP_BY) + " having=" + uri.getQueryParameter(QUERY_HAVING) + " limit=" + uri.getQueryParameter(QUERY_LIMIT));
        return super.query(uri, projection, selection, selectionArgs, sortOrder);
    }

    @Override
    protected QueryParams getQueryParams(Uri uri, String selection, String[] projection) {
        QueryParams res = new QueryParams();
        String id = null;
        int matchedId = URI_MATCHER.match(uri);
        switch (matchedId) {
            case URI_TYPE_ADDRESS:
            case URI_TYPE_ADDRESS_ID:
                res.table = AddressColumns.TABLE_NAME;
                res.idColumn = AddressColumns._ID;
                res.tablesWithJoins = AddressColumns.TABLE_NAME;
                if (ContactColumns.hasColumns(projection)) {
                    res.tablesWithJoins += " LEFT OUTER JOIN " + ContactColumns.TABLE_NAME + " AS " + AddressColumns.PREFIX_CONTACT + " ON " + AddressColumns.TABLE_NAME + "." + AddressColumns.CONTACT_ID + "=" + AddressColumns.PREFIX_CONTACT + "." + ContactColumns._ID;
                }
                res.orderBy = AddressColumns.DEFAULT_ORDER;
                break;

            case URI_TYPE_CONTACT:
            case URI_TYPE_CONTACT_ID:
                res.table = ContactColumns.TABLE_NAME;
                res.idColumn = ContactColumns._ID;
                res.tablesWithJoins = ContactColumns.TABLE_NAME;
                res.orderBy = ContactColumns.DEFAULT_ORDER;
                break;

            default:
                throw new IllegalArgumentException("The uri '" + uri + "' is not supported by this ContentProvider");
        }

        switch (matchedId) {
            case URI_TYPE_ADDRESS_ID:
            case URI_TYPE_CONTACT_ID:
                id = uri.getLastPathSegment();
        }
        if (id != null) {
            if (selection != null) {
                res.selection = res.table + "." + res.idColumn + "=" + id + " and (" + selection + ")";
            } else {
                res.selection = res.table + "." + res.idColumn + "=" + id;
            }
        } else {
            res.selection = selection;
        }
        return res;
    }
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/ExampleSQLiteOpenHelper.java
================================================
package com.example.project.database.provider;

import android.annotation.TargetApi;
import android.content.Context;
import android.database.DatabaseErrorHandler;
import android.database.DefaultDatabaseErrorHandler;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Build;
import android.util.Log;

import com.example.project.BuildConfig;
import com.example.project.database.provider.address.AddressColumns;
import com.example.project.database.provider.contact.ContactColumns;

public class ExampleSQLiteOpenHelper extends SQLiteOpenHelper {
    private static final String TAG = ExampleSQLiteOpenHelper.class.getSimpleName();

    public static final String DATABASE_FILE_NAME = "example.db";
    private static final int DATABASE_VERSION = 1;
    private static ExampleSQLiteOpenHelper sInstance;
    private final Context mContext;
    private final ExampleSQLiteOpenHelperCallbacks mOpenHelperCallbacks;

    // @formatter:off
    public static final String SQL_CREATE_TABLE_ADDRESS = "CREATE TABLE IF NOT EXISTS "
            + AddressColumns.TABLE_NAME + " ( "
            + AddressColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
            + AddressColumns.CONTACT_ID + " INTEGER NOT NULL, "
            + AddressColumns.STREET + " TEXT, "
            + AddressColumns.NUMBER + " TEXT, "
            + AddressColumns.CITY + " TEXT, "
            + AddressColumns.COUNTRY + " TEXT, "
            + AddressColumns.STATE + " TEXT, "
            + AddressColumns.POSTALCODE + " TEXT "
            + ", CONSTRAINT fk_contact_id FOREIGN KEY (" + AddressColumns.CONTACT_ID + ") REFERENCES contact (_id) ON DELETE CASCADE"
            + " );";

    public static final String SQL_CREATE_TABLE_CONTACT = "CREATE TABLE IF NOT EXISTS "
            + ContactColumns.TABLE_NAME + " ( "
            + ContactColumns._ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
            + ContactColumns.UID + " TEXT, "
            + ContactColumns.FIRST_NAME + " TEXT, "
            + ContactColumns.LAST_NAME + " TEXT, "
            + ContactColumns.BIRTHDATE + " INTEGER "
            + ", CONSTRAINT first_or_last_name_must_be_given CHECK((first_name <> '' AND first_name IS NOT NULL) OR (last_name <> '' AND last_name IS NOT NULL)) ON CONFLICT FAIL"
            + " );";

    // @formatter:on

    public static ExampleSQLiteOpenHelper getInstance(Context context) {
        // Use the application context, which will ensure that you
        // don't accidentally leak an Activity's context.
        // See this article for more information: http://bit.ly/6LRzfx
        if (sInstance == null) {
            sInstance = newInstance(context.getApplicationContext());
        }
        return sInstance;
    }

    private static ExampleSQLiteOpenHelper newInstance(Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.HONEYCOMB) {
            return newInstancePreHoneycomb(context);
        }
        return newInstancePostHoneycomb(context);
    }


    /*
     * Pre Honeycomb.
     */
    private static ExampleSQLiteOpenHelper newInstancePreHoneycomb(Context context) {
        return new ExampleSQLiteOpenHelper(context);
    }

    private ExampleSQLiteOpenHelper(Context context) {
        super(context, DATABASE_FILE_NAME, null, DATABASE_VERSION);
        mContext = context;
        mOpenHelperCallbacks = new ExampleSQLiteOpenHelperCallbacks();
    }


    /*
     * Post Honeycomb.
     */
    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private static ExampleSQLiteOpenHelper newInstancePostHoneycomb(Context context) {
        return new ExampleSQLiteOpenHelper(context, new DefaultDatabaseErrorHandler());
    }

    @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    private ExampleSQLiteOpenHelper(Context context, DatabaseErrorHandler errorHandler) {
        super(context, DATABASE_FILE_NAME, null, DATABASE_VERSION, errorHandler);
        mContext = context;
        mOpenHelperCallbacks = new ExampleSQLiteOpenHelperCallbacks();
    }


    @Override
    public void onCreate(SQLiteDatabase db) {
        if (BuildConfig.DEBUG) Log.d(TAG, "onCreate");
        mOpenHelperCallbacks.onPreCreate(mContext, db);
        db.execSQL(SQL_CREATE_TABLE_ADDRESS);
        db.execSQL(SQL_CREATE_TABLE_CONTACT);
        mOpenHelperCallbacks.onPostCreate(mContext, db);
    }

    @Override
    public void onOpen(SQLiteDatabase db) {
        super.onOpen(db);
        if (!db.isReadOnly()) {
            setForeignKeyConstraintsEnabled(db);
        }
        mOpenHelperCallbacks.onOpen(mContext, db);
    }

    private void setForeignKeyConstraintsEnabled(SQLiteDatabase db) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
            setForeignKeyConstraintsEnabledPreJellyBean(db);
        } else {
            setForeignKeyConstraintsEnabledPostJellyBean(db);
        }
    }

    private void setForeignKeyConstraintsEnabledPreJellyBean(SQLiteDatabase db) {
        db.execSQL("PRAGMA foreign_keys=ON;");
    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void setForeignKeyConstraintsEnabledPostJellyBean(SQLiteDatabase db) {
        db.setForeignKeyConstraintsEnabled(true);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        mOpenHelperCallbacks.onUpgrade(mContext, db, oldVersion, newVersion);
    }
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/ExampleSQLiteOpenHelperCallbacks.java
================================================
package com.example.project.database.provider;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;

import android.util.Log;

import com.example.project.BuildConfig;

/**
 * Implement your custom database creation or upgrade code here.
 *
 * This file will not be overwritten if you re-run the content provider generator.
 */
public class ExampleSQLiteOpenHelperCallbacks {
    private static final String TAG = ExampleSQLiteOpenHelperCallbacks.class.getSimpleName();

    public void onOpen(final Context context, final SQLiteDatabase db) {
        if (BuildConfig.DEBUG) Log.d(TAG, "onOpen");
        // Insert your db open code here.
    }

    public void onPreCreate(final Context context, final SQLiteDatabase db) {
        if (BuildConfig.DEBUG) Log.d(TAG, "onPreCreate");
        // Insert your db creation code here. This is called before your tables are created.
    }

    public void onPostCreate(final Context context, final SQLiteDatabase db) {
        if (BuildConfig.DEBUG) Log.d(TAG, "onPostCreate");
        // Insert your db creation code here. This is called after your tables are created.
    }

    public void onUpgrade(final Context context, final SQLiteDatabase db, final int oldVersion, final int newVersion) {
        if (BuildConfig.DEBUG) Log.d(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion);
        // Insert your upgrading code here.
    }
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/address/AddressColumns.java
================================================
package com.example.project.database.provider.address;

import android.net.Uri;
import android.provider.BaseColumns;

import com.example.project.database.provider.ExampleProvider;
import com.example.project.database.provider.address.AddressColumns;
import com.example.project.database.provider.contact.ContactColumns;

/**
 * Columns for the {@code address} table.
 */
public class AddressColumns implements BaseColumns {
    public static final String TABLE_NAME = "address";
    public static final Uri CONTENT_URI = Uri.parse(ExampleProvider.CONTENT_URI_BASE + "/" + TABLE_NAME);

    /**
     * Primary key.
     */
    public static final String _ID = BaseColumns._ID;

    public static final String CONTACT_ID = "contact_id";

    public static final String STREET = "street";

    public static final String NUMBER = "number";

    public static final String CITY = "city";

    public static final String COUNTRY = "country";

    public static final String STATE = "state";

    public static final String POSTALCODE = "postalcode";


    public static final String DEFAULT_ORDER = TABLE_NAME + "." +_ID;

    // @formatter:off
    public static final String[] ALL_COLUMNS = new String[] {
            _ID,
            CONTACT_ID,
            STREET,
            NUMBER,
            CITY,
            COUNTRY,
            STATE,
            POSTALCODE
    };
    // @formatter:on

    public static boolean hasColumns(String[] projection) {
        if (projection == null) return true;
        for (String c : projection) {
            if (c.equals(CONTACT_ID) || c.contains("." + CONTACT_ID)) return true;
            if (c.equals(STREET) || c.contains("." + STREET)) return true;
            if (c.equals(NUMBER) || c.contains("." + NUMBER)) return true;
            if (c.equals(CITY) || c.contains("." + CITY)) return true;
            if (c.equals(COUNTRY) || c.contains("." + COUNTRY)) return true;
            if (c.equals(STATE) || c.contains("." + STATE)) return true;
            if (c.equals(POSTALCODE) || c.contains("." + POSTALCODE)) return true;
        }
        return false;
    }

    public static final String PREFIX_CONTACT = TABLE_NAME + "__" + ContactColumns.TABLE_NAME;
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/address/AddressContentValues.java
================================================
package com.example.project.database.provider.address;

import java.util.Date;

import android.content.ContentResolver;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.example.project.database.provider.base.AbstractContentValues;

/**
 * Content values wrapper for the {@code address} table.
 */
public class AddressContentValues extends AbstractContentValues {
    @Override
    public Uri uri() {
        return AddressColumns.CONTENT_URI;
    }

    /**
     * Update row(s) using the values stored by this object and the given selection.
     *
     * @param contentResolver The content resolver to use.
     * @param where The selection to use (can be {@code null}).
     */
    public int update(ContentResolver contentResolver, @Nullable AddressSelection where) {
        return contentResolver.update(uri(), values(), where == null ? null : where.sel(), where == null ? null : where.args());
    }

    public AddressContentValues putContactId(long value) {
        mContentValues.put(AddressColumns.CONTACT_ID, value);
        return this;
    }


    public AddressContentValues putStreet(@Nullable String value) {
        mContentValues.put(AddressColumns.STREET, value);
        return this;
    }

    public AddressContentValues putStreetNull() {
        mContentValues.putNull(AddressColumns.STREET);
        return this;
    }

    public AddressContentValues putNumber(@Nullable String value) {
        mContentValues.put(AddressColumns.NUMBER, value);
        return this;
    }

    public AddressContentValues putNumberNull() {
        mContentValues.putNull(AddressColumns.NUMBER);
        return this;
    }

    public AddressContentValues putCity(@Nullable String value) {
        mContentValues.put(AddressColumns.CITY, value);
        return this;
    }

    public AddressContentValues putCityNull() {
        mContentValues.putNull(AddressColumns.CITY);
        return this;
    }

    public AddressContentValues putCountry(@Nullable String value) {
        mContentValues.put(AddressColumns.COUNTRY, value);
        return this;
    }

    public AddressContentValues putCountryNull() {
        mContentValues.putNull(AddressColumns.COUNTRY);
        return this;
    }

    public AddressContentValues putState(@Nullable String value) {
        mContentValues.put(AddressColumns.STATE, value);
        return this;
    }

    public AddressContentValues putStateNull() {
        mContentValues.putNull(AddressColumns.STATE);
        return this;
    }

    public AddressContentValues putPostalcode(@Nullable String value) {
        mContentValues.put(AddressColumns.POSTALCODE, value);
        return this;
    }

    public AddressContentValues putPostalcodeNull() {
        mContentValues.putNull(AddressColumns.POSTALCODE);
        return this;
    }
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/address/AddressCursor.java
================================================
package com.example.project.database.provider.address;

import java.util.Date;

import android.database.Cursor;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.example.project.database.provider.base.AbstractCursor;
import com.example.project.database.provider.contact.*;

/**
 * Cursor wrapper for the {@code address} table.
 */
public class AddressCursor extends AbstractCursor implements AddressModel {
    public AddressCursor(Cursor cursor) {
        super(cursor);
    }

    /**
     * Primary key.
     */
    public long getId() {
        Long res = getLongOrNull(AddressColumns._ID);
        if (res == null)
            throw new NullPointerException("The value of '_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * Get the {@code contact_id} value.
     */
    public long getContactId() {
        Long res = getLongOrNull(AddressColumns.CONTACT_ID);
        if (res == null)
            throw new NullPointerException("The value of 'contact_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * Get the {@code uid} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getContactUid() {
        String res = getStringOrNull(ContactColumns.UID);
        return res;
    }

    /**
     * Get the {@code first_name} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getContactFirstName() {
        String res = getStringOrNull(ContactColumns.FIRST_NAME);
        return res;
    }

    /**
     * Get the {@code last_name} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getContactLastName() {
        String res = getStringOrNull(ContactColumns.LAST_NAME);
        return res;
    }

    /**
     * Get the {@code birthdate} value.
     * Can be {@code null}.
     */
    @Nullable
    public Date getContactBirthdate() {
        Date res = getDateOrNull(ContactColumns.BIRTHDATE);
        return res;
    }

    /**
     * Get the {@code street} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getStreet() {
        String res = getStringOrNull(AddressColumns.STREET);
        return res;
    }

    /**
     * Get the {@code number} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getNumber() {
        String res = getStringOrNull(AddressColumns.NUMBER);
        return res;
    }

    /**
     * Get the {@code city} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getCity() {
        String res = getStringOrNull(AddressColumns.CITY);
        return res;
    }

    /**
     * Get the {@code country} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getCountry() {
        String res = getStringOrNull(AddressColumns.COUNTRY);
        return res;
    }

    /**
     * Get the {@code state} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getState() {
        String res = getStringOrNull(AddressColumns.STATE);
        return res;
    }

    /**
     * Get the {@code postalcode} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getPostalcode() {
        String res = getStringOrNull(AddressColumns.POSTALCODE);
        return res;
    }
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/address/AddressModel.java
================================================
package com.example.project.database.provider.address;

import com.example.project.database.provider.base.BaseModel;

import java.util.Date;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

/**
 * Data model for the {@code address} table.
 */
public interface AddressModel extends BaseModel {

    /**
     * Get the {@code contact_id} value.
     */
    long getContactId();

    /**
     * Get the {@code street} value.
     * Can be {@code null}.
     */
    @Nullable
    String getStreet();

    /**
     * Get the {@code number} value.
     * Can be {@code null}.
     */
    @Nullable
    String getNumber();

    /**
     * Get the {@code city} value.
     * Can be {@code null}.
     */
    @Nullable
    String getCity();

    /**
     * Get the {@code country} value.
     * Can be {@code null}.
     */
    @Nullable
    String getCountry();

    /**
     * Get the {@code state} value.
     * Can be {@code null}.
     */
    @Nullable
    String getState();

    /**
     * Get the {@code postalcode} value.
     * Can be {@code null}.
     */
    @Nullable
    String getPostalcode();
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/address/AddressSelection.java
================================================
package com.example.project.database.provider.address;

import java.util.Date;

import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;

import com.example.project.database.provider.base.AbstractSelection;
import com.example.project.database.provider.contact.*;

/**
 * Selection for the {@code address} table.
 */
public class AddressSelection extends AbstractSelection<AddressSelection> {
    @Override
    protected Uri baseUri() {
        return AddressColumns.CONTENT_URI;
    }

    /**
     * Query the given content resolver using this selection.
     *
     * @param contentResolver The content resolver to query.
     * @param projection A list of which columns to return. Passing null will return all columns, which is inefficient.
     * @param sortOrder How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort
     *            order, which may be unordered.
     * @return A {@code AddressCursor} object, which is positioned before the first entry, or null.
     */
    public AddressCursor query(ContentResolver contentResolver, String[] projection, String sortOrder) {
        Cursor cursor = contentResolver.query(uri(), projection, sel(), args(), sortOrder);
        if (cursor == null) return null;
        return new AddressCursor(cursor);
    }

    /**
     * Equivalent of calling {@code query(contentResolver, projection, null)}.
     */
    public AddressCursor query(ContentResolver contentResolver, String[] projection) {
        return query(contentResolver, projection, null);
    }

    /**
     * Equivalent of calling {@code query(contentResolver, projection, null, null)}.
     */
    public AddressCursor query(ContentResolver contentResolver) {
        return query(contentResolver, null, null);
    }


    public AddressSelection id(long... value) {
        addEquals("address." + AddressColumns._ID, toObjectArray(value));
        return this;
    }

    public AddressSelection contactId(long... value) {
        addEquals(AddressColumns.CONTACT_ID, toObjectArray(value));
        return this;
    }

    public AddressSelection contactIdNot(long... value) {
        addNotEquals(AddressColumns.CONTACT_ID, toObjectArray(value));
        return this;
    }

    public AddressSelection contactIdGt(long value) {
        addGreaterThan(AddressColumns.CONTACT_ID, value);
        return this;
    }

    public AddressSelection contactIdGtEq(long value) {
        addGreaterThanOrEquals(AddressColumns.CONTACT_ID, value);
        return this;
    }

    public AddressSelection contactIdLt(long value) {
        addLessThan(AddressColumns.CONTACT_ID, value);
        return this;
    }

    public AddressSelection contactIdLtEq(long value) {
        addLessThanOrEquals(AddressColumns.CONTACT_ID, value);
        return this;
    }

    public AddressSelection contactUid(String... value) {
        addEquals(ContactColumns.UID, value);
        return this;
    }

    public AddressSelection contactUidNot(String... value) {
        addNotEquals(ContactColumns.UID, value);
        return this;
    }

    public AddressSelection contactUidLike(String... value) {
        addLike(ContactColumns.UID, value);
        return this;
    }

    public AddressSelection contactUidContains(String... value) {
        addContains(ContactColumns.UID, value);
        return this;
    }

    public AddressSelection contactUidStartsWith(String... value) {
        addStartsWith(ContactColumns.UID, value);
        return this;
    }

    public AddressSelection contactUidEndsWith(String... value) {
        addEndsWith(ContactColumns.UID, value);
        return this;
    }

    public AddressSelection contactFirstName(String... value) {
        addEquals(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public AddressSelection contactFirstNameNot(String... value) {
        addNotEquals(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public AddressSelection contactFirstNameLike(String... value) {
        addLike(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public AddressSelection contactFirstNameContains(String... value) {
        addContains(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public AddressSelection contactFirstNameStartsWith(String... value) {
        addStartsWith(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public AddressSelection contactFirstNameEndsWith(String... value) {
        addEndsWith(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public AddressSelection contactLastName(String... value) {
        addEquals(ContactColumns.LAST_NAME, value);
        return this;
    }

    public AddressSelection contactLastNameNot(String... value) {
        addNotEquals(ContactColumns.LAST_NAME, value);
        return this;
    }

    public AddressSelection contactLastNameLike(String... value) {
        addLike(ContactColumns.LAST_NAME, value);
        return this;
    }

    public AddressSelection contactLastNameContains(String... value) {
        addContains(ContactColumns.LAST_NAME, value);
        return this;
    }

    public AddressSelection contactLastNameStartsWith(String... value) {
        addStartsWith(ContactColumns.LAST_NAME, value);
        return this;
    }

    public AddressSelection contactLastNameEndsWith(String... value) {
        addEndsWith(ContactColumns.LAST_NAME, value);
        return this;
    }

    public AddressSelection contactBirthdate(Date... value) {
        addEquals(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public AddressSelection contactBirthdateNot(Date... value) {
        addNotEquals(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public AddressSelection contactBirthdate(Long... value) {
        addEquals(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public AddressSelection contactBirthdateAfter(Date value) {
        addGreaterThan(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public AddressSelection contactBirthdateAfterEq(Date value) {
        addGreaterThanOrEquals(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public AddressSelection contactBirthdateBefore(Date value) {
        addLessThan(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public AddressSelection contactBirthdateBeforeEq(Date value) {
        addLessThanOrEquals(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public AddressSelection street(String... value) {
        addEquals(AddressColumns.STREET, value);
        return this;
    }

    public AddressSelection streetNot(String... value) {
        addNotEquals(AddressColumns.STREET, value);
        return this;
    }

    public AddressSelection streetLike(String... value) {
        addLike(AddressColumns.STREET, value);
        return this;
    }

    public AddressSelection streetContains(String... value) {
        addContains(AddressColumns.STREET, value);
        return this;
    }

    public AddressSelection streetStartsWith(String... value) {
        addStartsWith(AddressColumns.STREET, value);
        return this;
    }

    public AddressSelection streetEndsWith(String... value) {
        addEndsWith(AddressColumns.STREET, value);
        return this;
    }

    public AddressSelection number(String... value) {
        addEquals(AddressColumns.NUMBER, value);
        return this;
    }

    public AddressSelection numberNot(String... value) {
        addNotEquals(AddressColumns.NUMBER, value);
        return this;
    }

    public AddressSelection numberLike(String... value) {
        addLike(AddressColumns.NUMBER, value);
        return this;
    }

    public AddressSelection numberContains(String... value) {
        addContains(AddressColumns.NUMBER, value);
        return this;
    }

    public AddressSelection numberStartsWith(String... value) {
        addStartsWith(AddressColumns.NUMBER, value);
        return this;
    }

    public AddressSelection numberEndsWith(String... value) {
        addEndsWith(AddressColumns.NUMBER, value);
        return this;
    }

    public AddressSelection city(String... value) {
        addEquals(AddressColumns.CITY, value);
        return this;
    }

    public AddressSelection cityNot(String... value) {
        addNotEquals(AddressColumns.CITY, value);
        return this;
    }

    public AddressSelection cityLike(String... value) {
        addLike(AddressColumns.CITY, value);
        return this;
    }

    public AddressSelection cityContains(String... value) {
        addContains(AddressColumns.CITY, value);
        return this;
    }

    public AddressSelection cityStartsWith(String... value) {
        addStartsWith(AddressColumns.CITY, value);
        return this;
    }

    public AddressSelection cityEndsWith(String... value) {
        addEndsWith(AddressColumns.CITY, value);
        return this;
    }

    public AddressSelection country(String... value) {
        addEquals(AddressColumns.COUNTRY, value);
        return this;
    }

    public AddressSelection countryNot(String... value) {
        addNotEquals(AddressColumns.COUNTRY, value);
        return this;
    }

    public AddressSelection countryLike(String... value) {
        addLike(AddressColumns.COUNTRY, value);
        return this;
    }

    public AddressSelection countryContains(String... value) {
        addContains(AddressColumns.COUNTRY, value);
        return this;
    }

    public AddressSelection countryStartsWith(String... value) {
        addStartsWith(AddressColumns.COUNTRY, value);
        return this;
    }

    public AddressSelection countryEndsWith(String... value) {
        addEndsWith(AddressColumns.COUNTRY, value);
        return this;
    }

    public AddressSelection state(String... value) {
        addEquals(AddressColumns.STATE, value);
        return this;
    }

    public AddressSelection stateNot(String... value) {
        addNotEquals(AddressColumns.STATE, value);
        return this;
    }

    public AddressSelection stateLike(String... value) {
        addLike(AddressColumns.STATE, value);
        return this;
    }

    public AddressSelection stateContains(String... value) {
        addContains(AddressColumns.STATE, value);
        return this;
    }

    public AddressSelection stateStartsWith(String... value) {
        addStartsWith(AddressColumns.STATE, value);
        return this;
    }

    public AddressSelection stateEndsWith(String... value) {
        addEndsWith(AddressColumns.STATE, value);
        return this;
    }

    public AddressSelection postalcode(String... value) {
        addEquals(AddressColumns.POSTALCODE, value);
        return this;
    }

    public AddressSelection postalcodeNot(String... value) {
        addNotEquals(AddressColumns.POSTALCODE, value);
        return this;
    }

    public AddressSelection postalcodeLike(String... value) {
        addLike(AddressColumns.POSTALCODE, value);
        return this;
    }

    public AddressSelection postalcodeContains(String... value) {
        addContains(AddressColumns.POSTALCODE, value);
        return this;
    }

    public AddressSelection postalcodeStartsWith(String... value) {
        addStartsWith(AddressColumns.POSTALCODE, value);
        return this;
    }

    public AddressSelection postalcodeEndsWith(String... value) {
        addEndsWith(AddressColumns.POSTALCODE, value);
        return this;
    }
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/base/AbstractContentValues.java
================================================
package com.example.project.database.provider.base;

import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;

public abstract class AbstractContentValues {
    protected final ContentValues mContentValues = new ContentValues();

    /**
     * Returns the {@code uri} argument to pass to the {@code ContentResolver} methods.
     */
    public abstract Uri uri();

    /**
     * Returns the {@code ContentValues} wrapped by this object.
     */
    public ContentValues values() {
        return mContentValues;
    }

    /**
     * Inserts a row into a table using the values stored by this object.
     * 
     * @param contentResolver The content resolver to use.
     */
    public Uri insert(ContentResolver contentResolver) {
        return contentResolver.insert(uri(), values());
    }
}

================================================
FILE: app/src/gen/java/com/example/project/database/provider/base/AbstractCursor.java
================================================
package com.example.project.database.provider.base;

import java.util.Date;
import java.util.HashMap;

import android.database.Cursor;
import android.database.CursorWrapper;
import android.provider.BaseColumns;

public abstract class AbstractCursor extends CursorWrapper {
    private final HashMap<String, Integer> mColumnIndexes;

    public AbstractCursor(Cursor cursor) {
        super(cursor);
        mColumnIndexes = new HashMap<String, Integer>(cursor.getColumnCount() * 4 / 3, .75f);
    }

    public abstract long getId();

    protected int getCachedColumnIndexOrThrow(String colName) {
        Integer index = mColumnIndexes.get(colName);
        if (index == null) {
            index = getColumnIndexOrThrow(colName);
            mColumnIndexes.put(colName, index);
        }
        return index;
    }

    public String getStringOrNull(String colName) {
        int index = getCachedColumnIndexOrThrow(colName);
        if (isNull(index)) return null;
        return getString(index);
    }

    public Integer getIntegerOrNull(String colName) {
        int index = getCachedColumnIndexOrThrow(colName);
        if (isNull(index)) return null;
        return getInt(index);
    }

    public Long getLongOrNull(String colName) {
        int index = getCachedColumnIndexOrThrow(colName);
        if (isNull(index)) return null;
        return getLong(index);
    }

    public Float getFloatOrNull(String colName) {
        int index = getCachedColumnIndexOrThrow(colName);
        if (isNull(index)) return null;
        return getFloat(index);
    }

    public Double getDoubleOrNull(String colName) {
        int index = getCachedColumnIndexOrThrow(colName);
        if (isNull(index)) return null;
        return getDouble(index);
    }

    public Boolean getBooleanOrNull(String colName) {
        int index = getCachedColumnIndexOrThrow(colName);
        if (isNull(index)) return null;
        return getInt(index) != 0;
    }

    public Date getDateOrNull(String colName) {
        int index = getCachedColumnIndexOrThrow(colName);
        if (isNull(index)) return null;
        return new Date(getLong(index));
    }

    public byte[] getBlobOrNull(String colName) {
        int index = getCachedColumnIndexOrThrow(colName);
        if (isNull(index)) return null;
        return getBlob(index);
    }
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/base/AbstractSelection.java
================================================
package com.example.project.database.provider.base;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.content.ContentResolver;
import android.net.Uri;

public abstract class AbstractSelection<T extends AbstractSelection<?>> {
    private static final String EQ = "=?";
    private static final String PAREN_OPEN = "(";
    private static final String PAREN_CLOSE = ")";
    private static final String AND = " AND ";
    private static final String OR = " OR ";
    private static final String IS_NULL = " IS NULL";
    private static final String IS_NOT_NULL = " IS NOT NULL";
    private static final String IN = " IN (";
    private static final String NOT_IN = " NOT IN (";
    private static final String COMMA = ",";
    private static final String GT = ">?";
    private static final String LT = "<?";
    private static final String GT_EQ = ">=?";
    private static final String LT_EQ = "<=?";
    private static final String NOT_EQ = "<>?";
    private static final String LIKE = " LIKE ?";
    private static final String CONTAINS = " LIKE '%' || ? || '%'";
    private static final String STARTS = " LIKE ? || '%'";
    private static final String ENDS = " LIKE '%' || ?";

    private final StringBuilder mSelection = new StringBuilder();
    private final List<String> mSelectionArgs = new ArrayList<String>(5);

    Boolean mNotify;
    String mGroupBy;
    String mHaving;
    Integer mLimit;

    protected void addEquals(String column, Object[] value) {
        mSelection.append(column);

        if (value == null) {
            // Single null value
            mSelection.append(IS_NULL);
        } else if (value.length > 1) {
            // Multiple values ('in' clause)
            mSelection.append(IN);
            for (int i = 0; i < value.length; i++) {
                mSelection.append("?");
                if (i < value.length - 1) {
                    mSelection.append(COMMA);
                }
                mSelectionArgs.add(valueOf(value[i]));
            }
            mSelection.append(PAREN_CLOSE);
        } else {
            // Single value
            if (value[0] == null) {
                // Single null value
                mSelection.append(IS_NULL);
            } else {
                // Single not null value
                mSelection.append(EQ);
                mSelectionArgs.add(valueOf(value[0]));
            }
        }
    }

    protected void addNotEquals(String column, Object[] value) {
        mSelection.append(column);

        if (value == null) {
            // Single null value
            mSelection.append(IS_NOT_NULL);
        } else if (value.length > 1) {
            // Multiple values ('in' clause)
            mSelection.append(NOT_IN);
            for (int i = 0; i < value.length; i++) {
                mSelection.append("?");
                if (i < value.length - 1) {
                    mSelection.append(COMMA);
                }
                mSelectionArgs.add(valueOf(value[i]));
            }
            mSelection.append(PAREN_CLOSE);
        } else {
            // Single value
            if (value[0] == null) {
                // Single null value
                mSelection.append(IS_NOT_NULL);
            } else {
                // Single not null value
                mSelection.append(NOT_EQ);
                mSelectionArgs.add(valueOf(value[0]));
            }
        }
    }

    protected void addLike(String column, String[] values) {
        mSelection.append(PAREN_OPEN);
        for (int i = 0; i < values.length; i++) {
            mSelection.append(column);
            mSelection.append(LIKE);
            mSelectionArgs.add(values[i]);
            if (i < values.length - 1) {
                mSelection.append(OR);
            }
        }
        mSelection.append(PAREN_CLOSE);
    }

    protected void addContains(String column, String[] values) {
        mSelection.append(PAREN_OPEN);
        for (int i = 0; i < values.length; i++) {
            mSelection.append(column);
            mSelection.append(CONTAINS);
            mSelectionArgs.add(values[i]);
            if (i < values.length - 1) {
                mSelection.append(OR);
            }
        }
        mSelection.append(PAREN_CLOSE);
    }

    protected void addStartsWith(String column, String[] values) {
        mSelection.append(PAREN_OPEN);
        for (int i = 0; i < values.length; i++) {
            mSelection.append(column);
            mSelection.append(STARTS);
            mSelectionArgs.add(values[i]);
            if (i < values.length - 1) {
                mSelection.append(OR);
            }
        }
        mSelection.append(PAREN_CLOSE);
    }

    protected void addEndsWith(String column, String[] values) {
        mSelection.append(PAREN_OPEN);
        for (int i = 0; i < values.length; i++) {
            mSelection.append(column);
            mSelection.append(ENDS);
            mSelectionArgs.add(values[i]);
            if (i < values.length - 1) {
                mSelection.append(OR);
            }
        }
        mSelection.append(PAREN_CLOSE);
    }

    protected void addGreaterThan(String column, Object value) {
        mSelection.append(column);
        mSelection.append(GT);
        mSelectionArgs.add(valueOf(value));
    }

    protected void addGreaterThanOrEquals(String column, Object value) {
        mSelection.append(column);
        mSelection.append(GT_EQ);
        mSelectionArgs.add(valueOf(value));
    }

    protected void addLessThan(String column, Object value) {
        mSelection.append(column);
        mSelection.append(LT);
        mSelectionArgs.add(valueOf(value));
    }

    protected void addLessThanOrEquals(String column, Object value) {
        mSelection.append(column);
        mSelection.append(LT_EQ);
        mSelectionArgs.add(valueOf(value));
    }

    public void addRaw(String raw, Object... args) {
        mSelection.append(" ");
        mSelection.append(raw);
        mSelection.append(" ");
        for (Object arg : args) {
            mSelectionArgs.add(valueOf(arg));
        }
    }

    private String valueOf(Object obj) {
        if (obj instanceof Date) {
            return String.valueOf(((Date) obj).getTime());
        } else if (obj instanceof Boolean) {
            return (Boolean) obj ? "1" : "0";
        } else if (obj instanceof Enum) {
            return String.valueOf(((Enum<?>) obj).ordinal());
        }
        return String.valueOf(obj);
    }

    @SuppressWarnings("unchecked")
    public T openParen() {
        mSelection.append(PAREN_OPEN);
        return (T) this;
    }

    @SuppressWarnings("unchecked")
    public T closeParen() {
        mSelection.append(PAREN_CLOSE);
        return (T) this;
    }

    @SuppressWarnings("unchecked")
    public T and() {
        mSelection.append(AND);
        return (T) this;
    }

    @SuppressWarnings("unchecked")
    public T or() {
        mSelection.append(OR);
        return (T) this;
    }


    protected Object[] toObjectArray(int... array) {
        Object[] res = new Object[array.length];
        for (int i = 0; i < array.length; i++) {
            res[i] = array[i];
        }
        return res;
    }

    protected Object[] toObjectArray(long... array) {
        Object[] res = new Object[array.length];
        for (int i = 0; i < array.length; i++) {
            res[i] = array[i];
        }
        return res;
    }

    protected Object[] toObjectArray(float... array) {
        Object[] res = new Object[array.length];
        for (int i = 0; i < array.length; i++) {
            res[i] = array[i];
        }
        return res;
    }

    protected Object[] toObjectArray(double... array) {
        Object[] res = new Object[array.length];
        for (int i = 0; i < array.length; i++) {
            res[i] = array[i];
        }
        return res;
    }

    protected Object[] toObjectArray(Boolean value) {
        return new Object[] { value };
    }


    /**
     * Returns the selection produced by this object.
     */
    public String sel() {
        return mSelection.toString();
    }

    /**
     * Returns the selection arguments produced by this object.
     */
    public String[] args() {
        int size = mSelectionArgs.size();
        if (size == 0) return null;
        return mSelectionArgs.toArray(new String[size]);
    }


    /**
     * Returns the {@code uri} argument to pass to the {@code ContentResolver} methods.
     */
    public Uri uri() {
        Uri uri = baseUri();
        if (mNotify != null) uri = BaseContentProvider.notify(uri, mNotify);
        if (mGroupBy != null) uri = BaseContentProvider.groupBy(uri, mGroupBy);
        if (mHaving != null) uri = BaseContentProvider.having(uri, mHaving);
        if (mLimit != null) uri = BaseContentProvider.limit(uri, String.valueOf(mLimit));
        return uri;
    }

    protected abstract Uri baseUri();

    /**
     * Deletes row(s) specified by this selection.
     *
     * @param contentResolver The content resolver to use.
     * @return The number of rows deleted.
     */
    public int delete(ContentResolver contentResolver) {
        return contentResolver.delete(uri(), sel(), args());
    }

    @SuppressWarnings("unchecked")
    public T notify(boolean notify) {
        mNotify = notify;
        return (T) this;
    }

    @SuppressWarnings("unchecked")
    public T groupBy(String groupBy) {
        mGroupBy = groupBy;
        return (T) this;
    }

    @SuppressWarnings("unchecked")
    public T having(String having) {
        mHaving = having;
        return (T) this;
    }

    @SuppressWarnings("unchecked")
    public T limit(int limit) {
        mLimit = limit;
        return (T) this;
    }
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/base/BaseContentProvider.java
================================================
package com.example.project.database.provider.base;

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashSet;

import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.OperationApplicationException;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.net.Uri;
import android.provider.BaseColumns;
import android.support.annotation.NonNull;
import android.util.Log;

public abstract class BaseContentProvider extends ContentProvider {
    public static final String QUERY_NOTIFY = "QUERY_NOTIFY";
    public static final String QUERY_GROUP_BY = "QUERY_GROUP_BY";
    public static final String QUERY_HAVING = "QUERY_HAVING";
    public static final String QUERY_LIMIT = "QUERY_LIMIT";

    public static class QueryParams {
        public String table;
        public String tablesWithJoins;
        public String idColumn;
        public String selection;
        public String orderBy;
    }


    protected abstract QueryParams getQueryParams(Uri uri, String selection, String[] projection);
    protected abstract boolean hasDebug();

    protected abstract SQLiteOpenHelper createSqLiteOpenHelper();

    protected SQLiteOpenHelper mSqLiteOpenHelper;

    @Override
    public final boolean onCreate() {
        if (hasDebug()) {
            // Enable logging of SQL statements as they are executed.
            try {
                Class<?> sqliteDebugClass = Class.forName("android.database.sqlite.SQLiteDebug");
                Field field = sqliteDebugClass.getDeclaredField("DEBUG_SQL_STATEMENTS");
                field.setAccessible(true);
                field.set(null, true);

                // Uncomment the following block if you also want logging of execution time (more verbose)
                // field = sqliteDebugClass.getDeclaredField("DEBUG_SQL_TIME");
                // field.setAccessible(true);
                // field.set(null, true);
            } catch (Throwable t) {
                if (hasDebug()) Log.w(getClass().getSimpleName(), "Could not enable SQLiteDebug logging", t);
            }
        }
        mSqLiteOpenHelper = createSqLiteOpenHelper();
        return false;
    }


    @Override
    public Uri insert(Uri uri, ContentValues values) {
        String table = uri.getLastPathSegment();
        long rowId = mSqLiteOpenHelper.getWritableDatabase().insertOrThrow(table, null, values);
        if (rowId == -1) return null;
        String notify;
        if (((notify = uri.getQueryParameter(QUERY_NOTIFY)) == null || "true".equals(notify))) {
            getContext().getContentResolver().notifyChange(uri, null);
        }
        return uri.buildUpon().appendEncodedPath(String.valueOf(rowId)).build();
    }

    @Override
    public int bulkInsert(Uri uri, ContentValues[] values) {
        String table = uri.getLastPathSegment();
        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
        int res = 0;
        db.beginTransaction();
        try {
            for (ContentValues v : values) {
                long id = db.insert(table, null, v);
                db.yieldIfContendedSafely();
                if (id != -1) {
                    res++;
                }
            }
            db.setTransactionSuccessful();
        } finally {
            db.endTransaction();
        }
        String notify;
        if (res != 0 && ((notify = uri.getQueryParameter(QUERY_NOTIFY)) == null || "true".equals(notify))) {
            getContext().getContentResolver().notifyChange(uri, null);
        }

        return res;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        QueryParams queryParams = getQueryParams(uri, selection, null);
        int res = mSqLiteOpenHelper.getWritableDatabase().update(queryParams.table, values, queryParams.selection, selectionArgs);
        String notify;
        if (res != 0 && ((notify = uri.getQueryParameter(QUERY_NOTIFY)) == null || "true".equals(notify))) {
            getContext().getContentResolver().notifyChange(uri, null);
        }
        return res;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        QueryParams queryParams = getQueryParams(uri, selection, null);
        int res = mSqLiteOpenHelper.getWritableDatabase().delete(queryParams.table, queryParams.selection, selectionArgs);
        String notify;
        if (res != 0 && ((notify = uri.getQueryParameter(QUERY_NOTIFY)) == null || "true".equals(notify))) {
            getContext().getContentResolver().notifyChange(uri, null);
        }
        return res;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        String groupBy = uri.getQueryParameter(QUERY_GROUP_BY);
        String having = uri.getQueryParameter(QUERY_HAVING);
        String limit = uri.getQueryParameter(QUERY_LIMIT);
        QueryParams queryParams = getQueryParams(uri, selection, projection);
        projection = ensureIdIsFullyQualified(projection, queryParams.table, queryParams.idColumn);
        Cursor res = mSqLiteOpenHelper.getReadableDatabase().query(queryParams.tablesWithJoins, projection, queryParams.selection, selectionArgs, groupBy,
                having, sortOrder == null ? queryParams.orderBy : sortOrder, limit);
        res.setNotificationUri(getContext().getContentResolver(), uri);
        return res;
    }

    private String[] ensureIdIsFullyQualified(String[] projection, String tableName, String idColumn) {
        if (projection == null) return null;
        String[] res = new String[projection.length];
        for (int i = 0; i < projection.length; i++) {
            if (projection[i].equals(idColumn)) {
                res[i] = tableName + "." + idColumn + " AS " + BaseColumns._ID;
            } else {
                res[i] = projection[i];
            }
        }
        return res;
    }

    @Override
    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations) throws OperationApplicationException {
        HashSet<Uri> urisToNotify = new HashSet<Uri>(operations.size());
        for (ContentProviderOperation operation : operations) {
            urisToNotify.add(operation.getUri());
        }
        SQLiteDatabase db = mSqLiteOpenHelper.getWritableDatabase();
        db.beginTransaction();
        try {
            int numOperations = operations.size();
            ContentProviderResult[] results = new ContentProviderResult[numOperations];
            int i = 0;
            for (ContentProviderOperation operation : operations) {
                results[i] = operation.apply(this, results, i);
                if (operation.isYieldAllowed()) {
                    db.yieldIfContendedSafely();
                }
                i++;
            }
            db.setTransactionSuccessful();
            for (Uri uri : urisToNotify) {
                getContext().getContentResolver().notifyChange(uri, null);
            }
            return results;
        } finally {
            db.endTransaction();
        }
    }


    public static Uri notify(Uri uri, boolean notify) {
        return uri.buildUpon().appendQueryParameter(QUERY_NOTIFY, String.valueOf(notify)).build();
    }

    public static Uri groupBy(Uri uri, String groupBy) {
        return uri.buildUpon().appendQueryParameter(QUERY_GROUP_BY, groupBy).build();
    }

    public static Uri having(Uri uri, String having) {
        return uri.buildUpon().appendQueryParameter(QUERY_HAVING, having).build();
    }

    public static Uri limit(Uri uri, String limit) {
        return uri.buildUpon().appendQueryParameter(QUERY_LIMIT, limit).build();
    }
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/base/BaseModel.java
================================================
package com.example.project.database.provider.base;

public interface BaseModel {
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/contact/ContactColumns.java
================================================
package com.example.project.database.provider.contact;

import android.net.Uri;
import android.provider.BaseColumns;

import com.example.project.database.provider.ExampleProvider;
import com.example.project.database.provider.address.AddressColumns;
import com.example.project.database.provider.contact.ContactColumns;

/**
 * Columns for the {@code contact} table.
 */
public class ContactColumns implements BaseColumns {
    public static final String TABLE_NAME = "contact";
    public static final Uri CONTENT_URI = Uri.parse(ExampleProvider.CONTENT_URI_BASE + "/" + TABLE_NAME);

    /**
     * Primary key.
     */
    public static final String _ID = BaseColumns._ID;

    public static final String UID = "uid";

    public static final String FIRST_NAME = "first_name";

    public static final String LAST_NAME = "last_name";

    public static final String BIRTHDATE = "birthdate";


    public static final String DEFAULT_ORDER = TABLE_NAME + "." +_ID;

    // @formatter:off
    public static final String[] ALL_COLUMNS = new String[] {
            _ID,
            UID,
            FIRST_NAME,
            LAST_NAME,
            BIRTHDATE
    };
    // @formatter:on

    public static boolean hasColumns(String[] projection) {
        if (projection == null) return true;
        for (String c : projection) {
            if (c.equals(UID) || c.contains("." + UID)) return true;
            if (c.equals(FIRST_NAME) || c.contains("." + FIRST_NAME)) return true;
            if (c.equals(LAST_NAME) || c.contains("." + LAST_NAME)) return true;
            if (c.equals(BIRTHDATE) || c.contains("." + BIRTHDATE)) return true;
        }
        return false;
    }

}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/contact/ContactContentValues.java
================================================
package com.example.project.database.provider.contact;

import java.util.Date;

import android.content.ContentResolver;
import android.net.Uri;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.example.project.database.provider.base.AbstractContentValues;

/**
 * Content values wrapper for the {@code contact} table.
 */
public class ContactContentValues extends AbstractContentValues {
    @Override
    public Uri uri() {
        return ContactColumns.CONTENT_URI;
    }

    /**
     * Update row(s) using the values stored by this object and the given selection.
     *
     * @param contentResolver The content resolver to use.
     * @param where The selection to use (can be {@code null}).
     */
    public int update(ContentResolver contentResolver, @Nullable ContactSelection where) {
        return contentResolver.update(uri(), values(), where == null ? null : where.sel(), where == null ? null : where.args());
    }

    public ContactContentValues putUid(@Nullable String value) {
        mContentValues.put(ContactColumns.UID, value);
        return this;
    }

    public ContactContentValues putUidNull() {
        mContentValues.putNull(ContactColumns.UID);
        return this;
    }

    public ContactContentValues putFirstName(@Nullable String value) {
        mContentValues.put(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public ContactContentValues putFirstNameNull() {
        mContentValues.putNull(ContactColumns.FIRST_NAME);
        return this;
    }

    public ContactContentValues putLastName(@Nullable String value) {
        mContentValues.put(ContactColumns.LAST_NAME, value);
        return this;
    }

    public ContactContentValues putLastNameNull() {
        mContentValues.putNull(ContactColumns.LAST_NAME);
        return this;
    }

    public ContactContentValues putBirthdate(@Nullable Date value) {
        mContentValues.put(ContactColumns.BIRTHDATE, value == null ? null : value.getTime());
        return this;
    }

    public ContactContentValues putBirthdateNull() {
        mContentValues.putNull(ContactColumns.BIRTHDATE);
        return this;
    }

    public ContactContentValues putBirthdate(@Nullable Long value) {
        mContentValues.put(ContactColumns.BIRTHDATE, value);
        return this;
    }
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/contact/ContactCursor.java
================================================
package com.example.project.database.provider.contact;

import java.util.Date;

import android.database.Cursor;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.example.project.database.provider.base.AbstractCursor;

/**
 * Cursor wrapper for the {@code contact} table.
 */
public class ContactCursor extends AbstractCursor implements ContactModel {
    public ContactCursor(Cursor cursor) {
        super(cursor);
    }

    /**
     * Primary key.
     */
    public long getId() {
        Long res = getLongOrNull(ContactColumns._ID);
        if (res == null)
            throw new NullPointerException("The value of '_id' in the database was null, which is not allowed according to the model definition");
        return res;
    }

    /**
     * Get the {@code uid} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getUid() {
        String res = getStringOrNull(ContactColumns.UID);
        return res;
    }

    /**
     * Get the {@code first_name} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getFirstName() {
        String res = getStringOrNull(ContactColumns.FIRST_NAME);
        return res;
    }

    /**
     * Get the {@code last_name} value.
     * Can be {@code null}.
     */
    @Nullable
    public String getLastName() {
        String res = getStringOrNull(ContactColumns.LAST_NAME);
        return res;
    }

    /**
     * Get the {@code birthdate} value.
     * Can be {@code null}.
     */
    @Nullable
    public Date getBirthdate() {
        Date res = getDateOrNull(ContactColumns.BIRTHDATE);
        return res;
    }
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/contact/ContactModel.java
================================================
package com.example.project.database.provider.contact;

import com.example.project.database.provider.base.BaseModel;

import java.util.Date;

import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

/**
 * Data model for the {@code contact} table.
 */
public interface ContactModel extends BaseModel {

    /**
     * Get the {@code uid} value.
     * Can be {@code null}.
     */
    @Nullable
    String getUid();

    /**
     * Get the {@code first_name} value.
     * Can be {@code null}.
     */
    @Nullable
    String getFirstName();

    /**
     * Get the {@code last_name} value.
     * Can be {@code null}.
     */
    @Nullable
    String getLastName();

    /**
     * Get the {@code birthdate} value.
     * Can be {@code null}.
     */
    @Nullable
    Date getBirthdate();
}


================================================
FILE: app/src/gen/java/com/example/project/database/provider/contact/ContactSelection.java
================================================
package com.example.project.database.provider.contact;

import java.util.Date;

import android.content.ContentResolver;
import android.database.Cursor;
import android.net.Uri;

import com.example.project.database.provider.base.AbstractSelection;

/**
 * Selection for the {@code contact} table.
 */
public class ContactSelection extends AbstractSelection<ContactSelection> {
    @Override
    protected Uri baseUri() {
        return ContactColumns.CONTENT_URI;
    }

    /**
     * Query the given content resolver using this selection.
     *
     * @param contentResolver The content resolver to query.
     * @param projection A list of which columns to return. Passing null will return all columns, which is inefficient.
     * @param sortOrder How to order the rows, formatted as an SQL ORDER BY clause (excluding the ORDER BY itself). Passing null will use the default sort
     *            order, which may be unordered.
     * @return A {@code ContactCursor} object, which is positioned before the first entry, or null.
     */
    public ContactCursor query(ContentResolver contentResolver, String[] projection, String sortOrder) {
        Cursor cursor = contentResolver.query(uri(), projection, sel(), args(), sortOrder);
        if (cursor == null) return null;
        return new ContactCursor(cursor);
    }

    /**
     * Equivalent of calling {@code query(contentResolver, projection, null)}.
     */
    public ContactCursor query(ContentResolver contentResolver, String[] projection) {
        return query(contentResolver, projection, null);
    }

    /**
     * Equivalent of calling {@code query(contentResolver, projection, null, null)}.
     */
    public ContactCursor query(ContentResolver contentResolver) {
        return query(contentResolver, null, null);
    }


    public ContactSelection id(long... value) {
        addEquals("contact." + ContactColumns._ID, toObjectArray(value));
        return this;
    }

    public ContactSelection uid(String... value) {
        addEquals(ContactColumns.UID, value);
        return this;
    }

    public ContactSelection uidNot(String... value) {
        addNotEquals(ContactColumns.UID, value);
        return this;
    }

    public ContactSelection uidLike(String... value) {
        addLike(ContactColumns.UID, value);
        return this;
    }

    public ContactSelection uidContains(String... value) {
        addContains(ContactColumns.UID, value);
        return this;
    }

    public ContactSelection uidStartsWith(String... value) {
        addStartsWith(ContactColumns.UID, value);
        return this;
    }

    public ContactSelection uidEndsWith(String... value) {
        addEndsWith(ContactColumns.UID, value);
        return this;
    }

    public ContactSelection firstName(String... value) {
        addEquals(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public ContactSelection firstNameNot(String... value) {
        addNotEquals(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public ContactSelection firstNameLike(String... value) {
        addLike(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public ContactSelection firstNameContains(String... value) {
        addContains(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public ContactSelection firstNameStartsWith(String... value) {
        addStartsWith(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public ContactSelection firstNameEndsWith(String... value) {
        addEndsWith(ContactColumns.FIRST_NAME, value);
        return this;
    }

    public ContactSelection lastName(String... value) {
        addEquals(ContactColumns.LAST_NAME, value);
        return this;
    }

    public ContactSelection lastNameNot(String... value) {
        addNotEquals(ContactColumns.LAST_NAME, value);
        return this;
    }

    public ContactSelection lastNameLike(String... value) {
        addLike(ContactColumns.LAST_NAME, value);
        return this;
    }

    public ContactSelection lastNameContains(String... value) {
        addContains(ContactColumns.LAST_NAME, value);
        return this;
    }

    public ContactSelection lastNameStartsWith(String... value) {
        addStartsWith(ContactColumns.LAST_NAME, value);
        return this;
    }

    public ContactSelection lastNameEndsWith(String... value) {
        addEndsWith(ContactColumns.LAST_NAME, value);
        return this;
    }

    public ContactSelection birthdate(Date... value) {
        addEquals(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public ContactSelection birthdateNot(Date... value) {
        addNotEquals(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public ContactSelection birthdate(Long... value) {
        addEquals(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public ContactSelection birthdateAfter(Date value) {
        addGreaterThan(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public ContactSelection birthdateAfterEq(Date value) {
        addGreaterThanOrEquals(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public ContactSelection birthdateBefore(Date value) {
        addLessThan(ContactColumns.BIRTHDATE, value);
        return this;
    }

    public ContactSelection birthdateBeforeEq(Date value) {
        addLessThanOrEquals(ContactColumns.BIRTHDATE, value);
        return this;
    }
}


================================================
FILE: app/src/gen/java/com/example/project/network/json/ContactJson.java
================================================

package com.example.project.network.json;

import java.util.HashMap;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;


/**
 * Simple single contact.
 * 
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "id",
    "firstName",
    "lastName",
    "birthDate"
})
public class ContactJson {

    @JsonProperty("id")
    private String id;
    @JsonProperty("firstName")
    private String firstName;
    @JsonProperty("lastName")
    private String lastName;
    @JsonProperty("birthDate")
    private String birthDate;
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     * @return
     *     The id
     */
    @JsonProperty("id")
    public String getId() {
        return id;
    }

    /**
     * 
     * @param id
     *     The id
     */
    @JsonProperty("id")
    public void setId(String id) {
        this.id = id;
    }

    /**
     * 
     * @return
     *     The firstName
     */
    @JsonProperty("firstName")
    public String getFirstName() {
        return firstName;
    }

    /**
     * 
     * @param firstName
     *     The firstName
     */
    @JsonProperty("firstName")
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    /**
     * 
     * @return
     *     The lastName
     */
    @JsonProperty("lastName")
    public String getLastName() {
        return lastName;
    }

    /**
     * 
     * @param lastName
     *     The lastName
     */
    @JsonProperty("lastName")
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    /**
     * 
     * @return
     *     The birthDate
     */
    @JsonProperty("birthDate")
    public String getBirthDate() {
        return birthDate;
    }

    /**
     * 
     * @param birthDate
     *     The birthDate
     */
    @JsonProperty("birthDate")
    public void setBirthDate(String birthDate) {
        this.birthDate = birthDate;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(id).append(firstName).append(lastName).append(birthDate).append(additionalProperties).toHashCode();
    }

    @Override
    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }
        if ((other instanceof ContactJson) == false) {
            return false;
        }
        ContactJson rhs = ((ContactJson) other);
        return new EqualsBuilder().append(id, rhs.id).append(firstName, rhs.firstName).append(lastName, rhs.lastName).append(birthDate, rhs.birthDate).append(additionalProperties, rhs.additionalProperties).isEquals();
    }

}


================================================
FILE: app/src/gen/java/com/example/project/network/json/ContactListJson.java
================================================

package com.example.project.network.json;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.annotation.Generated;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;


/**
 * Collection of contacts.
 * 
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
@Generated("org.jsonschema2pojo")
@JsonPropertyOrder({
    "contacts"
})
public class ContactListJson {

    @JsonProperty("contacts")
    private List<ContactJson> contacts = new ArrayList<ContactJson>();
    @JsonIgnore
    private Map<String, Object> additionalProperties = new HashMap<String, Object>();

    /**
     * 
     * @return
     *     The contacts
     */
    @JsonProperty("contacts")
    public List<ContactJson> getContacts() {
        return contacts;
    }

    /**
     * 
     * @param contacts
     *     The contacts
     */
    @JsonProperty("contacts")
    public void setContacts(List<ContactJson> contacts) {
        this.contacts = contacts;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this);
    }

    @JsonAnyGetter
    public Map<String, Object> getAdditionalProperties() {
        return this.additionalProperties;
    }

    @JsonAnySetter
    public void setAdditionalProperty(String name, Object value) {
        this.additionalProperties.put(name, value);
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder().append(contacts).append(additionalProperties).toHashCode();
    }

    @Override
    public boolean equals(Object other) {
        if (other == this) {
            return true;
        }
        if ((other instanceof ContactListJson) == false) {
            return false;
        }
        ContactListJson rhs = ((ContactListJson) other);
        return new EqualsBuilder().append(contacts, rhs.contacts).append(additionalProperties, rhs.additionalProperties).isEquals();
    }

}


================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.project">

    <uses-permission android:name="android.permission.INTERNET" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme">
        <activity
            android:name=".views.start.StartActivity_"
            android:finishOnTaskLaunch="true"
            android:label="@string/app_name"
            android:noHistory="true">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".views.contact_list.ContactListActivity_"
            android:label="List" />
        <activity
            android:name=".views.contact_details.DetailActivity_"
            android:label="Details">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".views.contact_list.ContactListActivity_" />
        </activity>
        <activity
            android:name=".views.contact_edit.EditActivity_"
            android:label="Create or Update">
            <meta-data
                android:name="android.support.PARENT_ACTIVITY"
                android:value=".views.contact_list.ContactListActivity_" />
        </activity>

        <provider
            android:name="com.example.project.database.ExampleDbProvider_"
            android:authorities="com.example.project"
            android:exported="false" />
    </application>

</manifest>


================================================
FILE: app/src/main/java/com/example/project/business/contact/CreateContactFunction.java
================================================
package com.example.project.business.contact;

import com.example.project.database.provider.contact.ContactContentValues;
import com.example.project.database.contact.ContactDb;

import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean;

import java.util.Date;

@EBean
public class CreateContactFunction {

    @Bean
    ContactDb contactDb;

    public void apply(String firstName, String lastName, Date birthDate) {
        apply("", firstName, lastName, birthDate);
    }

    public void apply(String uid, String firstName, String lastName, Date birthDate) {
        ContactContentValues contentValues = contactDb.insertDataContainer();
        contentValues.putUid(uid);
        contentValues.putFirstName(firstName);
        contentValues.putLastName(lastName);
        contentValues.putBirthdate(birthDate);
        contactDb.insert(contentValues);
    }
}


================================================
FILE: app/src/main/java/com/example/project/business/contact/DeleteContactFunction.java
================================================
package com.example.project.business.contact;

import org.androidannotations.annotations.EBean;

@EBean
public class DeleteContactFunction {
}


================================================
FILE: app/src/main/java/com/example/project/business/contact/QueryContactFunction.java
================================================
package com.example.project.business.contact;

import android.support.annotation.Nullable;

import com.example.project.database.contact.ContactDb;
import com.example.project.database.provider.contact.ContactCursor;
import com.example.project.database.provider.contact.ContactModel;

import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean;

import java.util.Date;

@EBean
public class QueryContactFunction {

    @Bean
    ContactDb contactDb;

    public ContactModel apply(long contactId) {
        ContactCursor contactCursor = contactDb.queryById(contactId);
        return createContactModel(contactCursor);
    }

    public ContactModel applyByUid(String contactUid) {
        ContactCursor contactCursor = contactDb.queryByUid(contactUid);
        return createContactModel(contactCursor);
    }

    private ContactModel createContactModel(ContactCursor contactCursor) {

        if(!contactCursor.moveToFirst()) {
            return null;
        }

        final String contactUid = contactCursor.getUid();
        final String firstName = contactCursor.getFirstName();
        final String lastName = contactCursor.getLastName();
        final Date birthDate = contactCursor.getBirthdate();
        contactCursor.close();

        return new ContactModel() {
            @Nullable
            @Override
            public String getUid() {
                return contactUid;
            }

            @Nullable
            @Override
            public String getFirstName() {
                return firstName;
            }

            @Nullable
            @Override
            public String getLastName() {
                return lastName;
            }

            @Nullable
            @Override
            public Date getBirthdate() {
                return birthDate;
            }
        };
    }
}


================================================
FILE: app/src/main/java/com/example/project/business/contact/QueryContactListFunction.java
================================================
package com.example.project.business.contact;

import com.example.project.database.provider.contact.ContactCursor;
import com.example.project.database.contact.ContactDb;

import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean;

@EBean
public class QueryContactListFunction {

    @Bean
    ContactDb contactDb;

    public ContactCursor apply() {
        return contactDb.queryAll();
    }
}


================================================
FILE: app/src/main/java/com/example/project/business/contact/UpdateContactFunction.java
================================================
package com.example.project.business.contact;

import org.androidannotations.annotations.EBean;

@EBean
public class UpdateContactFunction {
}


================================================
FILE: app/src/main/java/com/example/project/business/contact_sync/SyncContactsFunction.java
================================================
package com.example.project.business.contact_sync;

import com.example.project.business.contact.CreateContactFunction;
import com.example.project.business.contact.QueryContactFunction;
import com.example.project.database.provider.contact.ContactModel;
import com.example.project.network.contact.ContactRestClient;
import com.example.project.network.json.ContactJson;
import com.example.project.network.json.ContactListJson;

import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.rest.RestService;
import org.apache.http.conn.HttpHostConnectException;
import org.joda.time.DateTime;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.HttpClientErrorException;
import org.springframework.web.client.HttpServerErrorException;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestClientException;

import java.util.Date;

@EBean
public class SyncContactsFunction {

    @RestService
    ContactRestClient contactRestClient;

    @Bean
    QueryContactFunction queryContactFunction;

    @Bean
    CreateContactFunction createContactFunction;

    public static class Result {
        public boolean successful;

        public String errorReason;

        public Result(String errorReason) {
            this.errorReason = errorReason;
            successful = false;
        }

        public Result() {
            successful = true;
        }
    }

    public Result apply() {
        try {
            ResponseEntity<ContactListJson> contacts = contactRestClient.getContacts();
            if (contacts.getStatusCode() == HttpStatus.OK) {
                syncContactsToDatabase(contacts.getBody());
                return new Result();
            } else {
                return new Result("unknown");
            }
        } catch (RestClientException e) {
            return new Result(e.getMessage());
        }
    }

    private void syncContactsToDatabase(ContactListJson contacts) {
        for (ContactJson contact : contacts.getContacts()) {
            ContactModel contactModel = queryContactFunction.applyByUid(contact.getId());
            if (contactModel == null) {
                String uid = contact.getId();
                String firstName = contact.getFirstName();
                String lastName = contact.getLastName();
                Date birthDate = DateTime.parse(contact.getBirthDate()).toDate();
                createContactFunction.apply(uid, firstName, lastName, birthDate);
            }
        }
    }
}


================================================
FILE: app/src/main/java/com/example/project/database/ExampleDbProvider.java
================================================
package com.example.project.database;

import com.example.project.database.provider.ExampleProvider;

import org.androidannotations.annotations.EProvider;

@EProvider
public class ExampleDbProvider extends ExampleProvider {
}


================================================
FILE: app/src/main/java/com/example/project/database/ExampleSQLiteOpenHelperCallbacks.java
================================================
package com.example.project.database;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;

import android.util.Log;

import com.example.project.BuildConfig;

/**
 * Implement your custom database creation or upgrade code here.
 */
public class ExampleSQLiteOpenHelperCallbacks {
    private static final String TAG = ExampleSQLiteOpenHelperCallbacks.class.getSimpleName();

    public void onOpen(final Context context, final SQLiteDatabase db) {
        if (BuildConfig.DEBUG) Log.d(TAG, "onOpen");
        // Insert your db open code here.
    }

    public void onPreCreate(final Context context, final SQLiteDatabase db) {
        if (BuildConfig.DEBUG) Log.d(TAG, "onPreCreate");
        // Insert your db creation code here. This is called before your tables are created.
    }

    public void onPostCreate(final Context context, final SQLiteDatabase db) {
        if (BuildConfig.DEBUG) Log.d(TAG, "onPostCreate");
        // Insert your db creation code here. This is called after your tables are created.
    }

    public void onUpgrade(final Context context, final SQLiteDatabase db, final int oldVersion, final int newVersion) {
        if (BuildConfig.DEBUG) Log.d(TAG, "Upgrading database from version " + oldVersion + " to " + newVersion);
        // Insert your upgrading code here.
    }
}


================================================
FILE: app/src/main/java/com/example/project/database/contact/AddressDb.java
================================================
package com.example.project.database.contact;

import android.content.ContentUris;
import android.content.Context;
import android.net.Uri;

import com.example.project.database.provider.address.AddressColumns;
import com.example.project.database.provider.address.AddressContentValues;
import com.example.project.database.provider.address.AddressCursor;
import com.example.project.database.provider.address.AddressSelection;
import com.example.project.database.provider.contact.ContactColumns;

import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext;
import org.apache.commons.lang3.ArrayUtils;

@EBean
public class AddressDb {

    @RootContext
    Context context;

    // one join example
    private final String[] ALL_JOINED_COLUMNS = (String[]) ArrayUtils.addAll(AddressColumns.ALL_COLUMNS, ContactColumns.ALL_COLUMNS);

    public long insert(AddressContentValues contentValues) {
        Uri contentUri = contentValues.insert(context.getContentResolver());
        return ContentUris.parseId(contentUri);
    }

    public AddressCursor queryById(long addressId) {
        return new AddressSelection().id(addressId).query(context.getContentResolver(), ALL_JOINED_COLUMNS);
    }
}


================================================
FILE: app/src/main/java/com/example/project/database/contact/ContactDb.java
================================================
package com.example.project.database.contact;

import android.content.ContentUris;
import android.content.Context;
import android.net.Uri;

import com.example.project.database.provider.contact.ContactContentValues;
import com.example.project.database.provider.contact.ContactCursor;
import com.example.project.database.provider.contact.ContactSelection;

import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext;

@EBean
public class ContactDb {

    @RootContext
    Context context;

    public ContactContentValues insertDataContainer() {
        return new ContactContentValues();
    }

    public long insert(ContactContentValues contentValues) {
        Uri contentUri = contentValues.insert(context.getContentResolver());
        return ContentUris.parseId(contentUri);
    }

    public ContactCursor queryAll() {
        return new ContactSelection().query(context.getContentResolver());
    }

    public ContactCursor queryById(long contactId) {
        return new ContactSelection().id(contactId).query(context.getContentResolver());
    }

    public ContactCursor queryByUid(String contactUid) {
        return new ContactSelection().uid(contactUid).query(context.getContentResolver());
    }
}


================================================
FILE: app/src/main/java/com/example/project/network/contact/ContactRestClient.java
================================================
package com.example.project.network.contact;

import com.example.project.network.json.ContactListJson;

import org.androidannotations.annotations.rest.Delete;
import org.androidannotations.annotations.rest.Get;
import org.androidannotations.annotations.rest.Post;
import org.androidannotations.annotations.rest.Put;
import org.androidannotations.annotations.rest.Rest;
import org.springframework.http.ResponseEntity;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.client.RestClientException;

@Rest(converters = {MappingJackson2HttpMessageConverter.class}, interceptors = {RootUrlInterceptor.class})
public interface ContactRestClient {

    @Get("/contacts")
    ResponseEntity<ContactListJson> getContacts() throws RestClientException;

    @Post("/contacts")
    ResponseEntity<Void> createContact() throws RestClientException;

    @Put("/contacts/{id}")
    ResponseEntity<Void> updateContact(String id) throws RestClientException;

    @Delete("/contacts/{id}")
    ResponseEntity<Void> deleteContact(String id) throws RestClientException;
}


================================================
FILE: app/src/main/java/com/example/project/network/contact/RootUrlInterceptor.java
================================================
package com.example.project.network.contact;

import android.content.Context;

import com.example.project.R;

import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
import org.springframework.http.client.ClientHttpRequestExecution;
import org.springframework.http.client.ClientHttpRequestInterceptor;
import org.springframework.http.client.ClientHttpResponse;

import java.io.IOException;
import java.net.URI;

@EBean
public class RootUrlInterceptor implements ClientHttpRequestInterceptor {

    @RootContext
    Context context;

    @Override
    public ClientHttpResponse intercept(final HttpRequest originalRequest, byte[] body, ClientHttpRequestExecution execution) throws IOException {
        final URI uriWithRootUrl = prependRootUrl(originalRequest.getURI());
        return executeWithInterceptedUri(originalRequest, body, execution, uriWithRootUrl);
    }

    private ClientHttpResponse executeWithInterceptedUri(final HttpRequest originalRequest, byte[] body, ClientHttpRequestExecution execution, final URI uriWithRootUrl) throws IOException {
        HttpRequest interceptedRequest = new HttpRequest() {
            @Override
            public HttpHeaders getHeaders() {
                return originalRequest.getHeaders();
            }

            @Override
            public HttpMethod getMethod() {
                return originalRequest.getMethod();
            }

            @Override
            public URI getURI() {
                return uriWithRootUrl;
            }
        };
        return execution.execute(interceptedRequest, body);
    }

    private URI prependRootUrl(URI originalUri) {
        return URI.create("http://" + context.getResources().getString(R.string.const_wiremock_ip) + ":1337" + originalUri.toString());
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/common/AppIdlingResources.java
================================================
package com.example.project.views.common;

import android.support.test.espresso.contrib.CountingIdlingResource;

import org.androidannotations.annotations.EBean;

@EBean(scope = EBean.Scope.Singleton)
public class AppIdlingResources {

    CountingIdlingResource idlingResource = new CountingIdlingResource("AppIdlingResources");

    public CountingIdlingResource getIdlingResource() {
        return idlingResource;
    }

    public void increment() {
        idlingResource.increment();
    }

    public void decrement() {
        idlingResource.decrement();
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/common/cursorloader/CursorAdapterWithCursorLoader.java
================================================
package com.example.project.views.common.cursorloader;

import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.CursorAdapter;

import com.example.project.database.provider.contact.ContactCursor;
import com.example.project.views.common.mvp.BaseActivityPresenter;

import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext;

/**
 * Simplify handling for basic cursor loader + cursor adapter combination.
 * <p/>
 * Always listen for changes on the data source and reload new content.
 * <p/>
 * Implement this class, add the Adapter to a AdapterView and call {@link #start()}.
 */
@EBean
public abstract class CursorAdapterWithCursorLoader {

    /**
     * Expecting the adapter where the swap cursor method will be called.
     */
    public abstract CursorAdapter getCursorAdapter();

    /**
     * Provide an unique identifier for the cursor loader.
     */
    public abstract int getLoaderId();

    /**
     * Will be called on background when the cursor should loaded
     */
    public abstract Cursor loadCursor();

    @RootContext
    protected BaseActivityPresenter context;

    public void start() {
        LoaderManager loaderManager = context.getSupportLoaderManager();

        Loader<ContactCursor> loader = loaderManager.getLoader(getLoaderId());
        if (loader != null && !loader.isReset()) {
            loaderManager.restartLoader(getLoaderId(), null, createLoaderCallback());
        } else {
            loaderManager.initLoader(getLoaderId(), null, createLoaderCallback());
        }
    }

    private LoaderManager.LoaderCallbacks<Cursor> createLoaderCallback() {
        return new LoaderManager.LoaderCallbacks<Cursor>() {
            @Override
            public Loader<Cursor> onCreateLoader(int id, Bundle args) {
                return new CursorLoader(context) {

                    private ForceLoadContentObserver observer = new ForceLoadContentObserver();

                    @Override
                    public Cursor loadInBackground() {
                        Cursor cursor = loadCursor();
                        cursor.registerContentObserver(observer);
                        return cursor;
                    }
                };
            }

            @Override
            public void onLoadFinished(Loader<Cursor> loader, final Cursor data) {
                getCursorAdapter().swapCursor(data);
            }

            @Override
            public void onLoaderReset(Loader<Cursor> loader) {
                getCursorAdapter().swapCursor(null);
            }
        };
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/common/mvp/BaseActivityPresenter.java
================================================
package com.example.project.views.common.mvp;

import android.support.v7.app.AppCompatActivity;

import org.androidannotations.annotations.AfterViews;
import org.androidannotations.annotations.EActivity;

/**
 * Base presenter for activities.
 */
@EActivity
public abstract class BaseActivityPresenter extends AppCompatActivity implements BasePresenter {

    /** Guard to avoid multiple calls to {@link BasePresenter#onViewCreated} */
    private boolean firstTimeOnAfterViews = true;

    // wrapper for the life cycles

    @AfterViews
    protected void baseOnAfterViews() {
        if (firstTimeOnAfterViews) {
            firstTimeOnAfterViews = false;
            onViewCreated();
        }
    }

    @Override
    public void onResume() {
        super.onResume();
        onViewResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        onViewPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        onViewDestroy();
    }

    // don't force child classes to implement the life cycle methods

    @Override
    public void onViewCreated() {
    }

    @Override
    public void onViewResume() {
    }

    @Override
    public void onViewPause() {
    }

    @Override
    public void onViewDestroy() {
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/common/mvp/BaseFragmentPresenter.java
================================================
package com.example.project.views.common.mvp;

import android.os.Bundle;
import android.support.v4.app.Fragment;

import org.androidannotations.annotations.EFragment;

/**
 * Base presenter for fragments.
 */
@EFragment
public abstract class BaseFragmentPresenter extends Fragment implements BasePresenter {

    // wrapper for the life cycles

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        onViewCreated();
    }

    @Override
    public void onResume() {
        super.onResume();
        onViewResume();
    }

    @Override
    public void onPause() {
        super.onPause();
        onViewPause();
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        onViewDestroy();
    }

    // don't force child classes to implement the life cycle methods

    @Override
    public void onViewCreated() {
    }

    @Override
    public void onViewResume() {
    }

    @Override
    public void onViewPause() {
    }

    @Override
    public void onViewDestroy() {
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/common/mvp/BasePresenter.java
================================================
package com.example.project.views.common.mvp;

/**
 * Base presenter for activities and fragments.
 *
 * Equalize the lifecycle handling for easy switch between activity and fragment.
 * The wrapped life cycles avoid the necessary of super method calls and let you easy write unit tests.
 */
public interface BasePresenter {

    /**
     * Called after the view is full created and injected.
     *
     * At this time you should start to initialise the view content. This will only be called
     * once in the life of the view. This gets be called at very end of onCreate.
     */
    void onViewCreated();

    /**
     * Called if the view is shown and the user may interact with it.
     *
     * May be called multiple times but only in combination with {@link #onViewPause()}.
     */
    void onViewResume();

    /**
     * Called when the view is going into background and the user can't anymore interact with it.
     *
     * This is the place to save persistent content.
     *
     * This is the same like onPause. Take also note of {@link android.app.Activity#onPause()}.
     * May be called multiple times but only in combination with {@link #onViewResume()}.
     */
    void onViewPause();

    /**
     * Called if the view gets destroyed.
     *
     * Do final clean up by releasing/stopping not more necessary processes.
     */
    void onViewDestroy();
}


================================================
FILE: app/src/main/java/com/example/project/views/common/mvp/BaseView.java
================================================
package com.example.project.views.common.mvp;

public interface BaseView {
}


================================================
FILE: app/src/main/java/com/example/project/views/common/testwrapper/ViewFinisher.java
================================================
package com.example.project.views.common.testwrapper;

import android.app.Activity;

import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext;

@EBean
public class ViewFinisher {

    @RootContext
    Activity activity;

    public void finish() {
        activity.finish();
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_details/DetailActivity.java
================================================
package com.example.project.views.contact_details;

import com.example.project.R;
import com.example.project.views.common.mvp.BaseActivityPresenter;

import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.Extra;
import org.androidannotations.annotations.FragmentById;

@EActivity(R.layout.activity_detail)
public class DetailActivity extends BaseActivityPresenter {

    @FragmentById(R.id.fragment_detail)
    DetailFragment detailFragment;

    @Extra
    protected long contactId;

    @Override
    public void onViewCreated() {
        detailFragment.onShowContact(contactId);
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_details/DetailActivityIntent.java
================================================
package com.example.project.views.contact_details;

import android.content.Context;

import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext;

@EBean
public class DetailActivityIntent {

    @RootContext
    Context context;

    public void start(long contactId) {
        DetailActivity_.intent(context).contactId(contactId).start();
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_details/DetailFragment.java
================================================
package com.example.project.views.contact_details;

import com.example.project.R;
import com.example.project.views.common.mvp.BaseFragmentPresenter;

import org.androidannotations.annotations.EFragment;

@EFragment(R.layout.fragment_detail)
public class DetailFragment extends BaseFragmentPresenter {

    public void onShowContact(long contactId) {

    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_details/DetailView.java
================================================
package com.example.project.views.contact_details;

import com.example.project.views.common.mvp.BaseView;

public class DetailView implements BaseView {
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_edit/EditActivity.java
================================================
package com.example.project.views.contact_edit;

import com.example.project.R;
import com.example.project.views.common.mvp.BaseActivityPresenter;
import com.example.project.views.common.testwrapper.ViewFinisher;

import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.Extra;
import org.androidannotations.annotations.FragmentById;

@EActivity(R.layout.activity_edit)
public class EditActivity extends BaseActivityPresenter implements EditConfirmedListener {

    @FragmentById(R.id.fragment_edit)
    EditFragment editFragment;

    @Bean
    ViewFinisher viewFinisher;

    @Extra
    protected long contactId;

    @Override
    public void onViewCreated() {
        editFragment.setEditConfirmedListener(this);
        editFragment.onShowContact(contactId);
    }

    @Override
    public void onEditConfirmed() {
        viewFinisher.finish();
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_edit/EditActivityIntent.java
================================================
package com.example.project.views.contact_edit;

import android.content.Context;

import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext;

@EBean
public class EditActivityIntent {

    @RootContext
    Context context;

    public void start(long contactId) {
        EditActivity_.intent(context).contactId(contactId).start();
    }

    public void start() {
        EditActivity_.intent(context).start();
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_edit/EditConfirmedListener.java
================================================
package com.example.project.views.contact_edit;

public interface EditConfirmedListener {
    void onEditConfirmed();
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_edit/EditFragment.java
================================================
package com.example.project.views.contact_edit;

import com.example.project.R;
import com.example.project.business.contact.CreateContactFunction;
import com.example.project.business.contact.QueryContactFunction;
import com.example.project.database.provider.contact.ContactModel;
import com.example.project.views.common.mvp.BaseFragmentPresenter;

import org.androidannotations.annotations.Background;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.Click;
import org.androidannotations.annotations.EFragment;
import org.apache.commons.lang3.StringUtils;
import org.joda.time.DateTime;

import java.util.Date;

@EFragment(R.layout.fragment_edit)
public class EditFragment extends BaseFragmentPresenter {

    @Bean
    EditView editView;

    @Bean
    CreateContactFunction createContactFunction;

    @Bean
    QueryContactFunction queryContactFunction;

    private EditConfirmedListener editConfirmedListener;
    private long contactId;

    public void setEditConfirmedListener(EditConfirmedListener editConfirmedListener) {
        this.editConfirmedListener = editConfirmedListener;
    }

    public void onShowContact(long contactId) {
        this.contactId = contactId;
        if(contactId != 0) {
            loadAndShowContactDetails();
        }
    }

    private void loadAndShowContactDetails() {
        ContactModel contact = queryContactFunction.apply(contactId);
        editView.setFirstName(contact.getFirstName());
        editView.setLastName(contact.getLastName());
        editView.setBirthDate(dateString(contact.getBirthdate()));
    }

    @Click(R.id.confirm)
    public void onClickConfirm() {
        String firstName = editView.getFirstName();
        String lastName = editView.getLastName();
        String birthDate = editView.getBirthDate();

        createOrUpdateContact(firstName, lastName, date(birthDate));
        editConfirmedListener.onEditConfirmed();
    }

    @Background
    void createOrUpdateContact(String firstName, String lastName, Date birthDate) {
        createContactFunction.apply(firstName, lastName, birthDate);
    }

    private String dateString(Date date) {
        if (date == null) {
            return "";
        } else {
            return date.toString();
        }
    }

    private Date date(String dateString) {
        if(StringUtils.isNotEmpty(dateString)) {
            return DateTime.parse(dateString).toDate();
        } else {
            return null;
        }
    }

}


================================================
FILE: app/src/main/java/com/example/project/views/contact_edit/EditView.java
================================================
package com.example.project.views.contact_edit;

import android.widget.EditText;

import com.example.project.R;
import com.example.project.views.common.mvp.BaseView;

import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.ViewById;

@EBean
public class EditView implements BaseView {

    @ViewById(R.id.first_name)
    EditText firstName;

    @ViewById(R.id.last_name)
    EditText lastName;

    @ViewById(R.id.birth_date)
    EditText birthDate;

    public void setFirstName(String input) {
        firstName.setText(input);
    }

    public String getFirstName() {
        return firstName.getText().toString();
    }

    public void setLastName(String input) {
        lastName.setText(input);
    }

    public String getLastName() {
        return lastName.getText().toString();
    }

    public void setBirthDate(String input) {
        birthDate.setText(input);
    }

    public String getBirthDate() {
        return birthDate.getText().toString();
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_list/ContactAdapter.java
================================================
package com.example.project.views.contact_list;

import android.content.Context;
import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.example.project.database.provider.contact.ContactCursor;

import org.androidannotations.annotations.EBean;

@EBean
public class ContactAdapter extends CursorAdapter {

    public static final int AVOID_AUTO_QUERY_AND_CONTENT_OBSERVERS = 0;

    public ContactAdapter(Context context) {
        super(context, null, AVOID_AUTO_QUERY_AND_CONTENT_OBSERVERS);
    }

    @Override
    public View newView(Context context, Cursor cursor, ViewGroup parent) {
        return LayoutInflater.from(context).inflate(android.R.layout.simple_list_item_2, null);
    }

    @Override
    public void bindView(View view, Context context, Cursor cursor) {
        ContactCursor contacts = (ContactCursor) cursor;
        ((TextView) view.findViewById(android.R.id.text1)).setText(contacts.getFirstName() + " " + contacts.getLastName());
        if(contacts.getBirthdate() != null) {
            ((TextView) view.findViewById(android.R.id.text2)).setText(contacts.getBirthdate().toString());
        }
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_list/ContactAdapterLoader.java
================================================
package com.example.project.views.contact_list;

import android.database.Cursor;
import android.support.v4.widget.CursorAdapter;
import android.util.Log;

import com.example.project.business.contact.QueryContactListFunction;
import com.example.project.views.common.cursorloader.CursorAdapterWithCursorLoader;

import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EBean;

@EBean
public class ContactAdapterLoader extends CursorAdapterWithCursorLoader {

    @Bean
    ContactAdapter contactAdapter;

    @Bean
    QueryContactListFunction queryContactListFunction;

    @Override
    public CursorAdapter getCursorAdapter() {
        return contactAdapter;
    }

    @Override
    public int getLoaderId() {
        return 1;
    }

    @Override
    public Cursor loadCursor() {
        Log.e("sync", "sync load");
        return queryContactListFunction.apply();
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_list/ContactListActivity.java
================================================
package com.example.project.views.contact_list;

import android.util.Log;
import android.widget.Toast;

import com.example.project.R;
import com.example.project.business.contact_sync.SyncContactsFunction;
import com.example.project.views.common.AppIdlingResources;
import com.example.project.views.common.mvp.BaseActivityPresenter;
import com.example.project.views.contact_details.DetailActivityIntent;
import com.example.project.views.contact_details.DetailFragment;
import com.example.project.views.contact_edit.EditActivityIntent;

import org.androidannotations.annotations.Background;
import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.FragmentById;
import org.androidannotations.annotations.OptionsItem;
import org.androidannotations.annotations.OptionsMenu;
import org.androidannotations.annotations.UiThread;

@EActivity(R.layout.activity_main)
@OptionsMenu(R.menu.menu_main)
public class ContactListActivity extends BaseActivityPresenter implements ShowContactListener {

    @FragmentById(R.id.fragment_list)
    ContactListFragment contactListFragment;

    @FragmentById(R.id.fragment_detail)
    DetailFragment detailFragment;

    @Bean
    DetailActivityIntent detailActivityIntent;

    @Bean
    EditActivityIntent editActivityIntent;

    @Bean
    SyncContactsFunction syncContactsFunction;

    @Bean
    AppIdlingResources appIdlingResources;

    @Override
    public void onViewCreated() {
        contactListFragment.setShowContactListener(this);
    }

    @OptionsItem(R.id.action_add_contact)
    public void onCreateContact() {
        editActivityIntent.start();
    }

    @OptionsItem(R.id.action_sync_contacts)
    @Background
    void onSyncContacts() {
        Log.e("sync", "sync start");
        appIdlingResources.increment();
        SyncContactsFunction.Result result = syncContactsFunction.apply();
        showSyncResult(result);
        appIdlingResources.decrement();
        Log.e("sync", "sync finish");
    }

    @UiThread(propagation = UiThread.Propagation.REUSE)
    void showSyncResult(SyncContactsFunction.Result result) {
        if(result.successful) {
            Log.e("sync", "sync success");
            Toast.makeText(this, "Sync done", Toast.LENGTH_SHORT).show();
        } else {
            Log.e("sync", "sync failed");
            Toast.makeText(this, "Sync failed: " + result.errorReason, Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    public void onShowContact(long contactId) {
        if(detailFragment == null) {
            detailActivityIntent.start(contactId);
        } else {
            detailFragment.onShowContact(contactId);
        }
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_list/ContactListActivityIntent.java
================================================
package com.example.project.views.contact_list;

import android.content.Context;

import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.RootContext;

@EBean
public class ContactListActivityIntent {

    @RootContext
    Context context;

    public void start() {
        ContactListActivity_.intent(context).start();
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_list/ContactListFragment.java
================================================
package com.example.project.views.contact_list;

import com.example.project.R;
import com.example.project.database.provider.contact.ContactCursor;
import com.example.project.views.common.mvp.BaseFragmentPresenter;

import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EFragment;
import org.androidannotations.annotations.ItemClick;

@EFragment(R.layout.fragment_list)
public class ContactListFragment extends BaseFragmentPresenter {

    @Bean
    ContactListView view;

    @Bean
    ContactAdapterLoader contactsLoader;

    private ShowContactListener showContactListener;

    @Override
    public void onViewCreated() {
        view.showContacts(contactsLoader.getCursorAdapter());
        contactsLoader.start();
    }

    @ItemClick(R.id.listView)
    public void onContactClick(ContactCursor item) {
        showContactListener.onShowContact(item.getId());
    }

    public void setShowContactListener(ShowContactListener showContactListener) {
        this.showContactListener = showContactListener;
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_list/ContactListView.java
================================================
package com.example.project.views.contact_list;

import android.widget.ListAdapter;
import android.widget.ListView;

import com.example.project.R;
import com.example.project.views.common.mvp.BaseView;

import org.androidannotations.annotations.EBean;
import org.androidannotations.annotations.ViewById;

@EBean
public class ContactListView implements BaseView {

    @ViewById(R.id.listView)
    ListView contactList;

    public void showContacts(ListAdapter listAdapter) {
        contactList.setAdapter(listAdapter);
    }
}


================================================
FILE: app/src/main/java/com/example/project/views/contact_list/ShowContactListener.java
================================================
package com.example.project.views.contact_list;

public interface ShowContactListener {
    void onShowContact(long contact);
}


================================================
FILE: app/src/main/java/com/example/project/views/start/StartActivity.java
================================================
package com.example.project.views.start;

import com.example.project.views.common.mvp.BaseActivityPresenter;
import com.example.project.views.contact_list.ContactListActivityIntent;

import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;

@EActivity
public class StartActivity extends BaseActivityPresenter {

    @Bean
    ContactListActivityIntent contactListActivityIntent;

    @Override
    public void onViewResume() {
        contactListActivityIntent.start();
    }
}


================================================
FILE: app/src/main/json/database/schema/_config.json
================================================
{
  "syntaxVersion": 3,
  "projectPackageId": "com.example.project",
  "authority": "com.example.project",
  "providerJavaPackage": "com.example.project.database.provider",
  "providerClassName": "ExampleProvider",
  "sqliteOpenHelperClassName": "ExampleSQLiteOpenHelper",
  "sqliteOpenHelperCallbacksClassName": "ExampleSQLiteOpenHelperCallbacks",
  "databaseFileName": "example.db",
  "databaseVersion": 1,
  "enableForeignKeys": true,
  "useAnnotations": true
}

================================================
FILE: app/src/main/json/database/schema/address.json
================================================
{
  "fields": [
    {
      "name": "contact_id",
      "type": "Long",
      "nullable": false,
      "foreignKey": {
        "table": "contact",
        "onDelete": "CASCADE"
      }
    },
    {
      "name": "street",
      "type": "String",
      "nullable": true
    },
    {
      "name": "number",
      "type": "String",
      "nullable": true
    },
    {
      "name": "city",
      "type": "String",
      "nullable": true
    },
    {
      "name": "country",
      "type": "String",
      "nullable": true
    },
    {
      "name": "state",
      "type": "String",
      "nullable": true
    },
    {
      "name": "postalcode",
      "type": "String",
      "nullable": true
    }
  ]
}

================================================
FILE: app/src/main/json/database/schema/contact.json
================================================
{
  "fields": [
    {
      "name": "uid",
      "type": "String",
      "nullable": true
    },
    {
      "name": "first_name",
      "type": "String",
      "nullable": true
    },
    {
      "name": "last_name",
      "type": "String",
      "nullable": true
    },
    {
      "name": "birthdate",
      "type": "Date",
      "nullable": true
    }
  ],
  "constraints": [
    {
      "name": "first_or_last_name_must_be_given",
      "definition": "CHECK((first_name <> '' AND first_name IS NOT NULL) OR (last_name <> '' AND last_name IS NOT NULL)) ON CONFLICT FAIL"
    }
  ]
}

================================================
FILE: app/src/main/json/network/schema/contactJson.json
================================================
{
  "description": "Simple single contact.",
  "type": "object",
  "properties": {
    "id": { "type": "string" },
    "firstName": { "type": "string" },
    "lastName": { "type": "string" },
    "birthDate": { "type": "string" }
  }
}

================================================
FILE: app/src/main/json/network/schema/contactListJson.json
================================================
{
  "description": "Collection of contacts.",
  "type": "object",
  "properties": {
    "contacts" : {
      "type" : "array",
      "items" : {
        "$ref" : "contactJson.json"
      }
    }
  }
}

================================================
FILE: app/src/main/res/layout/activity_detail.xml
================================================
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_detail"
    android:name="com.example.project.views.contact_details.DetailFragment_"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:layout="@layout/fragment_detail" />


================================================
FILE: app/src/main/res/layout/activity_edit.xml
================================================
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_edit"
    android:name="com.example.project.views.contact_edit.EditFragment_"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:layout="@layout/fragment_edit" />


================================================
FILE: app/src/main/res/layout/activity_main.xml
================================================
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fragment_list"
    android:name="com.example.project.views.contact_list.ContactListFragment_"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:layout="@layout/fragment_list" />


================================================
FILE: app/src/main/res/layout/fragment_detail.xml
================================================
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivityFragment">

    <TextView
        android:id="@+id/first_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />
    <TextView
        android:id="@+id/last_name"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world" />

    <DatePicker
        android:id="@+id/birth_date"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />

    <Button
        android:id="@+id/confirm"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" />
</LinearLayout>


================================================
FILE: app/src/main/res/layout/fragment_edit.xml
================================================
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivityFragment">

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/first_name"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:hint="@string/first_name" />

    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/last_name"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:hint="@string/last_name" />

    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <EditText
            android:id="@+id/birth_date"
            android:layout_width="200dp"
            android:layout_height="wrap_content"
            android:inputType="date"
            android:hint="@string/birth_date" />

    </android.support.design.widget.TextInputLayout>

    <Button
        android:id="@+id/confirm"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/create_contact" />

</LinearLayout>


================================================
FILE: app/src/main/res/layout/fragment_list.xml
================================================
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivityFragment">

    <ListView
        android:id="@+id/listView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true" />

</RelativeLayout>


================================================
FILE: app/src/main/res/layout-land/activity_main.xml
================================================
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:baselineAligned="false"
    android:orientation="horizontal">

    <fragment
        android:id="@+id/fragment_list"
        android:name="com.example.project.views.contact_list.ContactListFragment_"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0.3"
        tools:layout="@layout/fragment_list" />

    <fragment
        android:id="@+id/fragment_detail"
        android:name="com.example.project.views.contact_details.DetailFragment_"
        android:layout_width="0dp"
        android:layout_height="match_parent"
        android:layout_weight="0.7"
        tools:layout="@layout/fragment_detail"
        tools:ignore="InconsistentLayout" />

</LinearLayout>

================================================
FILE: app/src/main/res/menu/menu_main.xml
================================================
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">

    <item
        android:id="@+id/action_add_contact"
        android:icon="@android:drawable/ic_input_add"
        android:orderInCategory="100"
        android:title="@string/action_add_contact"
        app:showAsAction="ifRoom" />

    <item
        android:id="@+id/action_sync_contacts"
        android:icon="@android:drawable/stat_notify_sync_noanim"
        android:orderInCategory="50"
        android:title="@string/action_sync_contacts"
        app:showAsAction="ifRoom" />
</menu>


================================================
FILE: app/src/main/res/values/dimens.xml
================================================
<resources>
    <!-- Default screen margins, per the Android Design guidelines. -->
    <dimen name="activity_horizontal_margin">16dp</dimen>
    <dimen name="activity_vertical_margin">16dp</dimen>
</resources>


================================================
FILE: app/src/main/res/values/string_api_url.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="const_wiremock_ip">#const_wiremock_ip#</string>
</resources>

================================================
FILE: app/src/main/res/values/strings.xml
================================================
<resources>
    <string name="app_name">InitialAndroidProject</string>
    <string name="hello_world">Hello world!</string>

    <string name="action_add_contact">Add Contact</string>
    <string name="action_sync_contacts">Sync Contacts</string>
</resources>


================================================
FILE: app/src/main/res/values/strings_details.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>


    <string name="first_name">First Name</string>
    <string name="last_name">Last Name</string>
    <string name="birth_date">Birth Date</string>
    <string name="create_contact">Add</string>
</resources>

================================================
FILE: app/src/main/res/values/styles.xml
================================================
<resources>

    <!-- Base application theme. -->
    <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
        <!-- Customize your theme here. -->
    </style>

</resources>


================================================
FILE: app/src/main/res/values-w820dp/dimens.xml
================================================
<resources>
    <!-- Example customization of dimensions originally defined in res/values/dimens.xml
         (such as screen margins) for screens with more than 820dp of available width. This
         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
    <dimen name="activity_horizontal_margin">64dp</dimen>
</resources>


================================================
FILE: app/src/test/java/com/example/project/RoboTestCase.java
================================================
package com.example.project;

import android.content.Context;

import com.example.project.database.provider.ExampleSQLiteOpenHelper;

import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricGradleTestRunner;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;

import java.lang.reflect.Field;

@RunWith(RobolectricGradleTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21)
public abstract class RoboTestCase {

    protected Context context;

    @Before
    public void roboSetup() {
        context = RuntimeEnvironment.application;
    }

    @After
    public void finishRobolectricTest() {
        resetSingleton(ExampleSQLiteOpenHelper.class, "sInstance");
    }

    private void resetSingleton(Class clazz, String fieldName) {
        Field instance;
        try {
            instance = clazz.getDeclaredField(fieldName);
            instance.setAccessible(true);
            instance.set(null, null);
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
}


================================================
FILE: app/src/test/java/com/example/project/business/contact/QueryContactListFunctionTest.java
================================================
package com.example.project.business.contact;

import com.example.project.database.provider.contact.ContactCursor;
import com.example.project.database.contact.ContactDb;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.mockito.BDDMockito.given;
import static org.assertj.core.api.Assertions.assertThat;

@RunWith(MockitoJUnitRunner.class)
public class QueryContactListFunctionTest {

    @InjectMocks
    QueryContactListFunction queryContactListFunction;

    @Mock
    ContactDb contactDb;

    @Mock
    ContactCursor allContactCursor;

    @Test
    public void shouldLoadAllContacts() {
        given(contactDb.queryAll()).willReturn(allContactCursor);
        ContactCursor result = queryContactListFunction.apply();
        assertThat(result).isSameAs(allContactCursor);
    }
}

================================================
FILE: app/src/test/java/com/example/project/database/contact/AddressDbInsertTest.java
================================================
package com.example.project.database.contact;

import android.database.sqlite.SQLiteException;

import com.example.project.RoboTestCase;
import com.example.project.database.provider.address.AddressContentValues;
import com.example.project.database.provider.contact.ContactContentValues;

import org.junit.Before;
import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class AddressDbInsertTest extends RoboTestCase {

    ContactDb contactDb;
    AddressDb addressDb;
    long contactId;
    long addressId;

    AddressContentValues addressContentValues = new AddressContentValues()
            .putStreet("My Street")
            .putNumber("42a")
            .putCity("Berlin")
            .putCountry("Berlin")
            .putState("Germany")
            .putPostalcode("12345");

    @Before
    public void setup() {
        addressDb = AddressDb_.getInstance_(context);
        contactDb = ContactDb_.getInstance_(context);
        givenContactReference();
    }

    @Test
    public void insert() {
        whenAddressIsInserted(addressContentValues);
        thenInsertWasSuccessful();
    }

    @Test(expected = SQLiteException.class)
    public void insert_contactId_isMandatory() {
        addressContentValues.putContactId(0);
        whenAddressIsInserted(addressContentValues);
    }

    @Test(expected = SQLiteException.class)
    public void insert_contactId_mustExist() {
        long notExistingContact = 42;
        assertThat(notExistingContact).isNotEqualTo(contactId);
        addressContentValues.putContactId(notExistingContact);
        whenAddressIsInserted(addressContentValues);
    }

    @Test
    public void insert_street_isNullable() {
        addressContentValues.putStreet(null);
        whenAddressIsInserted(addressContentValues);
        thenInsertWasSuccessful();
    }

    @Test
    public void insert_number_isNullable() {
        addressContentValues.putNumber(null);
        whenAddressIsInserted(addressContentValues);
        thenInsertWasSuccessful();
    }

    @Test
    public void insert_city_isNullable() {
        addressContentValues.putCity(null);
        whenAddressIsInserted(addressContentValues);
        thenInsertWasSuccessful();
    }

    @Test
    public void insert_country_isNullable() {
        addressContentValues.putCountry(null);
        whenAddressIsInserted(addressContentValues);
        thenInsertWasSuccessful();
    }

    @Test
    public void insert_state_isNullable() {
        addressContentValues.putState(null);
        whenAddressIsInserted(addressContentValues);
        thenInsertWasSuccessful();
    }

    @Test
    public void insert_postalcode_isNullable() {
        addressContentValues.putPostalcode(null);
        whenAddressIsInserted(addressContentValues);
        thenInsertWasSuccessful();
    }

    private void thenInsertWasSuccessful() {
        assertThat(addressId).isPositive();
    }

    private void givenContactReference() {
        contactId = contactDb.insert(new ContactContentValues().putFirstName("May"));
        addressContentValues.putContactId(contactId);
    }

    private void whenAddressIsInserted(AddressContentValues contentValues) {
        givenAddressAtDatabase(contentValues);
    }

    private void givenAddressAtDatabase(AddressContentValues contentValues) {
        addressId = addressDb.insert(contentValues);
    }
}

================================================
FILE: app/src/test/java/com/example/project/database/contact/AddressDbTest.java
================================================
package com.example.project.database.contact;

import com.example.project.RoboTestCase;
import com.example.project.database.provider.address.AddressContentValues;
import com.example.project.database.provider.address.AddressCursor;
import com.example.project.database.provider.contact.ContactContentValues;

import org.junit.Before;
import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class AddressDbTest extends RoboTestCase {

    ContactDb contactDb;
    AddressDb addressDb;
    long contactId;
    long addressId;

    AddressContentValues addressContentValues = new AddressContentValues()
            .putStreet("My Street")
            .putNumber("42a")
            .putCity("Berlin")
            .putCountry("Berlin")
            .putState("Germany")
            .putPostalcode("12345");

    @Before
    public void setup() {
        addressDb = AddressDb_.getInstance_(context);
        contactDb = ContactDb_.getInstance_(context);
        givenContactReference();
    }

    @Test
    public void queryById() {
        givenAddressAtDatabase(addressContentValues);
        AddressCursor addressCursor = addressDb.queryById(addressId);
        assertThat(addressCursor.getCount()).isEqualTo(1);
    }

    @Test
    public void queryById_correctIds() {
        givenContactReference();
        givenAddressAtDatabase(addressContentValues);
        assertThat(contactId).isNotEqualTo(1);
        assertThat(addressId).isNotEqualTo(contactId);

        AddressCursor addressCursor = addressDb.queryById(addressId);
        addressCursor.moveToFirst();

        assertThat(addressCursor.getId()).isEqualTo(addressId);
        assertThat(addressCursor.getContactId()).isEqualTo(contactId);
    }

    private void givenContactReference() {
        contactId = contactDb.insert(new ContactContentValues().putFirstName("May"));
        addressContentValues.putContactId(contactId);
    }

    private void givenAddressAtDatabase(AddressContentValues contentValues) {
        addressId = addressDb.insert(contentValues);
    }
}

================================================
FILE: app/src/test/java/com/example/project/database/contact/ContactDbInsertTest.java
================================================
package com.example.project.database.contact;


import android.database.sqlite.SQLiteException;

import com.example.project.RoboTestCase;
import com.example.project.database.provider.contact.ContactContentValues;

import org.junit.Before;
import org.junit.Test;

import java.util.Date;

import static org.assertj.core.api.Assertions.assertThat;

public class ContactDbInsertTest extends RoboTestCase {

    ContactDb contactDb;
    long contactId;

    ContactContentValues contactContentValues = new ContactContentValues()
            .putFirstName("Max")
            .putLastName("Max")
            .putBirthdate(new Date());

    @Before
    public void setup() {
        contactDb = ContactDb_.getInstance_(context);
    }

    @Test
    public void insert() {
        whenContactIsInserted(contactContentValues);
        thenInsertWasSuccessful();
    }

    @Test
    public void insert_firstname_isNullable() {
        contactContentValues.putFirstName(null);
        whenContactIsInserted(contactContentValues);
        thenInsertWasSuccessful();
    }

    @Test
    public void insert_lastname_isNullable() {
        contactContentValues.putLastName(null);
        whenContactIsInserted(contactContentValues);
        thenInsertWasSuccessful();
    }

    @Test(expected = SQLiteException.class)
    public void insert_firstOrLastname_isMandatory() {
        contactContentValues.putFirstName(null);
        contactContentValues.putLastName(null);
        whenContactIsInserted(contactContentValues);
    }

    @Test
    public void insert_birthdate_isNullable() {
        contactContentValues.putBirthdate(0l);
        whenContactIsInserted(contactContentValues);
        thenInsertWasSuccessful();
    }

    private void thenInsertWasSuccessful() {
        assertThat(contactId).isPositive();
    }

    private void whenContactIsInserted(ContactContentValues contentValues) {
        contactId = contactDb.insert(contentValues);
    }
}

================================================
FILE: app/src/test/java/com/example/project/database/contact/ContactDbTest.java
================================================
package com.example.project.database.contact;


import com.example.project.RoboTestCase;
import com.example.project.database.provider.contact.ContactContentValues;
import com.example.project.database.provider.contact.ContactCursor;

import org.junit.Before;
import org.junit.Test;

import java.util.Date;

import static org.assertj.android.api.Assertions.assertThat;

public class ContactDbTest extends RoboTestCase {

    ContactDb contactDb;
    long contactId;

    ContactContentValues contactContentValues = new ContactContentValues()
            .putFirstName("Max")
            .putLastName("Max")
            .putBirthdate(new Date());

    @Before
    public void setup() {
        contactDb = ContactDb_.getInstance_(context);
    }

    @Test
    public void queryAll() {
        givenContactAtDatabase(contactContentValues);
        givenContactAtDatabase(contactContentValues);
        ContactCursor contactCursor = contactDb.queryAll();
        assertThat(contactCursor).hasCount(2);
    }

    private void givenContactAtDatabase(ContactContentValues contentValues) {
        contactId = contactDb.insert(contentValues);
    }
}

================================================
FILE: app/src/test/java/com/example/project/views/contact_edit/EditActivityTest.java
================================================
package com.example.project.views.contact_edit;

import com.example.project.views.common.testwrapper.ViewFinisher;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class EditActivityTest {

    @InjectMocks
    EditActivity editActivity;

    @Mock
    EditFragment editFragment;

    @Mock
    ViewFinisher viewFinisher;

    long CONTACT_ID = 42;

    @Test
    public void testOnViewCreated_shouldInitDetailFragment() throws Exception {
        editActivity.contactId = CONTACT_ID;
        editActivity.onViewCreated();
        verify(editFragment).setEditConfirmedListener(editActivity);
        verify(editFragment).onShowContact(CONTACT_ID);
    }

    @Test
    public void testOnEditConfirmed_shouldFinishTheActivity() throws Exception {
        editActivity.onEditConfirmed();
        verify(viewFinisher).finish();
    }
}

================================================
FILE: app/src/test/java/com/example/project/views/contact_edit/EditFragmentTest.java
================================================
package com.example.project.views.contact_edit;

import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.junit.Assert.*;

@RunWith(MockitoJUnitRunner.class)
@Ignore
public class EditFragmentTest {

    @InjectMocks
    EditFragment editFragment;

    @Mock
    EditView editView;

    @Mock
    EditConfirmedListener editConfirmedListener;

    @Test
    public void testOnShowContact_shouldLoadContactDetails() throws Exception {
        editFragment.onShowContact(42);
    }

    @Test
    public void testOnClickConfirm_shouldSaveContact() throws Exception {

    }
}

================================================
FILE: app/src/test/java/com/example/project/views/contact_list/ContactListActivityTest.java
================================================
package com.example.project.views.contact_list;

import com.example.project.views.contact_details.DetailActivityIntent;
import com.example.project.views.contact_details.DetailFragment;
import com.example.project.views.contact_edit.EditActivityIntent;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class ContactListActivityTest {

    public static final int CONTACT_ID = 42;

    @Mock
    DetailActivityIntent detailActivityIntent;

    @Mock
    EditActivityIntent editActivityIntent;

    @Mock
    ContactListFragment contactListFragment;

    @Mock
    DetailFragment detailFragment;

    @InjectMocks
    ContactListActivity contactListActivity;

    @Test
    public void testOnCreateContact() throws Exception {
        whenClickCreateContact();
        thenEditActivityIsStartedInCreationMode();
    }

    @Test
    public void testOnShowContact_portrait() throws Exception {
        givenPortraitMode();
        contactListActivity.onShowContact(42);
        thenDetailAreShownInNewActivity(CONTACT_ID);
    }

    @Test
    public void testOnShowContact_landscape() throws Exception {
        givenLandscapeMode();
        contactListActivity.onShowContact(CONTACT_ID);
        thenDetailsAreShownInDetailFragment(CONTACT_ID);
    }

    @Test
    public void testOnViewCreated_shouldRegisterSelfAsShowContactListener() {
        contactListActivity.onViewCreated();
        verify(contactListFragment).setShowContactListener(contactListActivity);
    }

    private void thenDetailAreShownInNewActivity(long expectedContactId) {
        verify(detailActivityIntent).start(expectedContactId);
    }

    private void thenDetailsAreShownInDetailFragment(long expectedContactId) {
        verify(detailFragment).onShowContact(expectedContactId);
    }

    private void givenPortraitMode() {
        contactListActivity.detailFragment = null;
    }

    private void givenLandscapeMode() {
        assertThat(contactListActivity.detailFragment).isNotNull();
    }

    private void thenEditActivityIsStartedInCreationMode() {
        verify(editActivityIntent).start();
    }

    private void whenClickCreateContact() {
        contactListActivity.onCreateContact();
    }
}

================================================
FILE: app/src/test/java/com/example/project/views/contact_list/ContactListFragmentTest.java
================================================
package com.example.project.views.contact_list;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class ContactListFragmentTest {

    @Mock
    ContactListView view;

    @Mock
    ContactAdapterLoader contactAdapterLoader;

    @Mock
    ContactAdapter contactAdapter;

    @InjectMocks
    ContactListFragment contactListFragment;

    @Before
    public void setup() {
        given(contactAdapterLoader.getCursorAdapter()).willReturn(contactAdapter);
    }

    @Test
    public void testOnViewCreated_shouldStartLoadingContacts() throws Exception {
        contactListFragment.onViewCreated();
        verify(view).showContacts(contactAdapter);
        verify(contactAdapterLoader).start();
    }
}

================================================
FILE: app/src/test/java/com/example/project/views/start/StartActivityTest.java
================================================
package com.example.project.views.start;

import com.example.project.views.contact_list.ContactListActivityIntent;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import static org.mockito.Mockito.verify;

@RunWith(MockitoJUnitRunner.class)
public class StartActivityTest {

    @Mock
    ContactListActivityIntent contactListActivityIntent;

    @InjectMocks
    StartActivity startActivity;

    @Test
    public void viewIsStarted() throws Exception {
        startActivity.onViewResume();
        thenNextActivityShouldBeStarted();
    }

    private void thenNextActivityShouldBeStarted() {
        verify(contactListActivityIntent).start();
    }
}

================================================
FILE: appCt/build.gradle
================================================
buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        // support to get app module under test with robolectric in separated test module
        classpath "com.novoda:gradle-android-test-plugin:0.10.4"
    }
}

apply plugin: 'java'

// support code coverage for the component tests
// this must be before the plugin: 'android-test' declaration
apply plugin: "jacoco"

// support to get app module under test with robolectric in separated test module
apply plugin: 'android-test'

android {
    projectUnderTest ':app'
}

// support to get the separated test module work inside android studio
// this must be after the projectUnderTest declaration
apply from: 'build.novoda-android-studio.gradle'

// support code coverage for the component tests
// this must be after the projectUnderTest declaration
apply from: "build.jacoco-test-report.gradle"

// test support for android specific stuff like database and network
apply from: 'build.robolectric.gradle'

dependencies {

    // basic unit tests support + mocks + fluent assertions + android assertions
    testCompile 'junit:junit:4.12'
    testCompile 'org.mockito:mockito-all:2.0.2-beta'
    testCompile('com.squareup.assertj:assertj-android:1.1.0') {
        exclude module: "support-annotations"
    }

    // easy modify wiremock stubbing support
    // need standalone version to avoid conflicts with org.apache.http classes (not all tests will run anymore)
    testCompile ('com.github.tomakehurst:wiremock:1.42:standalone') { exclude module: "*" }
}


// force utf-8 is necessary for windows environments, without it test classes aren't interpreted in utf-8
tasks.withType(JavaCompile) {
    options.encoding = "utf-8"
}

// avoid release compile for tests for less build time
// avoid lint and tests in same process (TODO check if still necessary)
afterEvaluate {

    def isLintRun = false
    def isTestRun = false

    gradle.startParameter.taskNames.each {
        if (it.contains("lint")) {
            isLintRun = true
        }
        if (it.contains("test")) {
            isTestRun = true
        }
    }

    if (isLintRun && isTestRun) {
        println "WARNING: tests for release type are disabled for supporting jacoco"
        println "WARNING: run test and lint at same time is not supported"
        exit 1
    }

    if (isTestRun) {
        tasks.each {
            if (it.name.contains("Release")) {
                it.enabled = false
            }
        }
    }
}

================================================
FILE: appCt/build.jacoco-test-report.gradle
================================================
// apply plugin: "jacoco" must be before the plugin: 'android-test' declaration

jacoco {
    toolVersion = projectJacocoVersion
}

ext.coverageSourceDirs = [
        '../app/src/main/java',
        '../app/build/source/apt/debug',
        '../app/build/generated/source/db',
        '../app/build/generated/source/buildConfig/debug',
        '../app/build/generated/source/r/debug']

jacocoTestReport {
    reports {
        xml.enabled = false
        html.enabled = true
    }
    // class R is used, but usage will not be covered, so ignore this class from report
    classDirectories = fileTree(dir: '../App/build/intermediates/classes/debug',
            exclude: 'com/example/R*.class')
    additionalSourceDirs = files(coverageSourceDirs)
    executionData = files('build/jacoco/testDebug.exec')
}

// just clean up dashboard, following reports are not of interest
testRelease.reports.html.enabled = false
testRelease.reports.junitXml.enabled = false
testDebug.reports.junitXml.enabled = false

================================================
FILE: appCt/build.novoda-android-studio.gradle
================================================
// workaround force compile the test classes in android studio
tasks.testClasses.dependsOn(tasks.testDebugClasses)

// workaround to force recognize correct output dirs for android studio
task addTest {
    def file = file(project.name + ".iml")
    doLast {
        try {
            def parsedXml = (new XmlParser()).parse(file)
            def node = parsedXml.component[1]
            def outputNode = parsedXml.component[1].output[0]
            def outputTestNode = parsedXml.component[1].'output-test'[0]
            def rewrite = false

            new Node(node, 'sourceFolder', ['url': 'file://$MODULE_DIR$/' + "${it}", 'isTestSource': "true"])

            if (outputNode == null) {
                new Node(node, 'output', ['url': 'file://$MODULE_DIR$/build/resources/testDebug'])
                rewrite = true
            } else {
                if (outputNode.attributes['url'] != 'file://$MODULE_DIR$/build/resources/testDebug') {
                    outputNode.attributes = ['url': 'file://$MODULE_DIR$/build/resources/testDebug']
                    rewrite = true
                }
            }

            if (outputTestNode == null) {
                new Node(node, 'output-test', ['url': 'file://$MODULE_DIR$/build/test-classes/debug'])
                rewrite = true
            } else {
                if (outputTestNode.attributes['url'] != 'file://$MODULE_DIR$/build/test-classes/debug') {
                    outputTestNode.attributes = ['url': 'file://$MODULE_DIR$/build/test-classes/debug']
                    rewrite = true
                }
            }

            if (rewrite) {
                def writer = new StringWriter()
                new XmlNodePrinter(new PrintWriter(writer)).print(parsedXml)
                file.text = writer.toString()
            }
        } catch (FileNotFoundException e) {
            // iml not found, common on command line only builds
        }

    }
}
tasks.testClasses.dependsOn(tasks.addTest)

================================================
FILE: appCt/build.robolectric.gradle
================================================
dependencies {
    testCompile('org.robolectric:shadows-support-v4:3.0') {
        exclude module: "robolectric"
        exclude module: "support-v4"
        exclude module: "support-annotations"
    }

    testCompile('org.robolectric:robolectric:3.0') {
        exclude module: 'classworlds'
        exclude module: 'commons-logging'
        exclude module: 'httpclient'
        exclude module: 'maven-artifact'
        exclude module: 'maven-artifact-manager'
        exclude module: 'maven-error-diagnostics'
        exclude module: 'maven-model'
        exclude module: 'maven-project'
        exclude module: 'maven-settings'
        exclude module: 'plexus-container-default'
        exclude module: 'plexus-interpolation'
        exclude module: 'plexus-utils'
        exclude module: 'wagon-file'
        exclude module: 'wagon-http-lightweight'
        exclude module: 'wagon-provider-api'
    }
}

================================================
FILE: appCt/src/test/java/android/database/ShadowContentObservable.java
================================================
package android.database;

import android.net.Uri;

import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.annotation.RealObject;

import java.util.ArrayList;

@Implements(ContentObservable.class)
public class ShadowContentObservable {

    @RealObject
    ContentObservable realObject;

    /**
     * Through the synchronisation from foreground and background thread the mObservers access may throw ConcurrentModificationException
     * when the list gets modified after notify an observer.
     * <p/>
     * Example is a cursorLoader after insert data on background.
     * Then notify gets called and the loader does a reload where the loader add himself as observer.
     * This operation changes existing observers list.
     */
    @Implementation
    public void dispatchChange(boolean selfChange, Uri uri) {
        synchronized (realObject.mObservers) {
            @SuppressWarnings("unchecked")
            ArrayList<ContentObserver> currentObservers = (ArrayList<ContentObserver>) realObject.mObservers.clone();
            for (ContentObserver observer : currentObservers) {
                if (!selfChange || observer.deliverSelfNotifications()) {
                    observer.dispatchChange(selfChange, uri);
                }
            }
        }
    }
}


================================================
FILE: appCt/src/test/java/com/example/project/RobolectricTestCase.java
================================================
package com.example.project;

import android.content.Context;
import android.database.ShadowContentObservable;

import com.example.project.BuildConfig;
import com.example.project.database.provider.ExampleSQLiteOpenHelper;
import com.example.project.robolectric.CostomRobolectricTestRunner;
import com.example.project.robolectric.ShadowBackgroundExecutor;
import com.github.tomakehurst.wiremock.client.WireMock;

import org.junit.After;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;

import java.lang.reflect.Field;

@RunWith(CostomRobolectricTestRunner.class)
@Config(constants = BuildConfig.class, sdk = 21, shadows = {ShadowContentObservable.class, ShadowBackgroundExecutor.class})
public abstract class RobolectricTestCase {

    protected Context context;

    @Before
    public void roboSetup() {
        context = RuntimeEnvironment.application;
        WireMock.configureFor(context.getString(R.string.const_wiremock_ip), 1337);
        WireMock.resetToDefault();
    }

    @After
    public void finishRobolectricTest() {
        resetSingleton(ExampleSQLiteOpenHelper.class, "sInstance");
    }

    private void resetSingleton(Class clazz, String fieldName) {
        Field instance;
        try {
            instance = clazz.getDeclaredField(fieldName);
            instance.setAccessible(true);
            instance.set(null, null);
        } catch (Exception e) {
            throw new RuntimeException();
        }
    }
}

================================================
FILE: appCt/src/test/java/com/example/project/robolectric/CostomRobolectricTestRunner.java
================================================
package com.example.project.robolectric;

import com.example.project.BuildConfig;

import org.androidannotations.api.BackgroundExecutor;
import org.junit.runners.model.InitializationError;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.internal.SdkEnvironment;
import org.robolectric.internal.bytecode.InstrumentationConfiguration;

import java.io.File;

import static org.assertj.core.api.Assertions.assertThat;

/**
 * Adjust some path declarations to the module under test.
 * <p/>
 * Original robolectric would search at wrong locations when used inside separated test module.
 */
public class CostomRobolectricTestRunner extends RobolectricTestRunner {

    public CostomRobolectricTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass);

        // provide UncaughtExceptionHandler to avoid nullponter exception if error on thread occur
        Thread.setDefaultUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() {
            @Override
            public void uncaughtException(Thread t, Throwable e) {
                throw new RuntimeException(e);
            }
        });

        String buildVariant = (BuildConfig.FLAVOR.isEmpty() ? "" : BuildConfig.FLAVOR + "/") + BuildConfig.BUILD_TYPE;
        String intermediatesPath = BuildConfig.MODULE_PATH + "/build//intermediates";

        System.setProperty("android.package", BuildConfig.APPLICATION_ID);
        System.setProperty("android.manifest", intermediatesPath + "/manifests/full/" + buildVariant + "/AndroidManifest.xml");
        System.setProperty("android.resources", intermediatesPath + "/res/merged/" + buildVariant);
        System.setProperty("android.assets", intermediatesPath + "/assets/" + buildVariant);
        System.setProperty("java.io.tmpdir", intermediatesPath + "/test-data");
        mkdir(intermediatesPath + "/test-data");
    }

    private void mkdir(String path) {
        File file = new File(path);
        if (!file.exists()) {
            assertThat(file.mkdir()).isTrue();
        }
    }

    /**
     * Declare custom classes to be shadowed when shadow exist.
     */
    public InstrumentationConfiguration createClassLoaderConfig() {
        InstrumentationConfiguration.Builder builder = InstrumentationConfiguration.newBuilder();
        builder.addInstrumentedClass(BackgroundExecutor.class.getName());
        return builder.build();
    }
}


================================================
FILE: appCt/src/test/java/com/example/project/robolectric/RoboButton.java
================================================
package com.example.project.robolectric;

import android.app.Activity;
import android.widget.Button;

import static org.assertj.core.api.Assertions.assertThat;

public class RoboButton {

    Button button;

    public RoboButton(Activity activity, int resourceId) {
        button = (Button) activity.findViewById(resourceId);
    }

    public void click() {
        assertThat(button.performClick()).isTrue();
    }
}


================================================
FILE: appCt/src/test/java/com/example/project/robolectric/RoboListView.java
================================================
package com.example.project.robolectric;

import android.app.Activity;
import android.widget.ListView;

import org.robolectric.Shadows;

public class RoboListView {

    ListView listView;

    public RoboListView(Activity activity, int resourceId) {
        listView = (ListView) activity.findViewById(resourceId);
    }

    public int count() {
        Shadows.shadowOf(listView).populateItems();
        return listView.getCount();
    }

    public RoboListViewEntry entry(int pos) {
        Shadows.shadowOf(listView).populateItems();
        return new RoboListViewEntry(listView, listView.getChildAt(pos));
    }
}


================================================
FILE: appCt/src/test/java/com/example/project/robolectric/RoboListViewEntry.java
================================================
package com.example.project.robolectric;

import android.view.View;
import android.widget.ListView;

import static org.assertj.core.api.Assertions.assertThat;

public class RoboListViewEntry {

    private ListView listView;
    private View listViewEntry;

    public RoboListViewEntry(ListView listView, View listViewEntry) {
        this.listView = listView;
        this.listViewEntry = listViewEntry;
    }

    public void click() {
        assertThat(listView.performItemClick(null, listView.getPositionForView(listViewEntry), 0)).isTrue();
    }
}


================================================
FILE: appCt/src/test/java/com/example/project/robolectric/RoboTextEdit.java
================================================
package com.example.project.robolectric;

import android.app.Activity;
import android.widget.EditText;

public class RoboTextEdit {

    EditText editText;

    public RoboTextEdit(Activity activity, int resourceId) {
        editText = (EditText) activity.findViewById(resourceId);
    }

    public void insert(String text) {
        editText.setText(text);
    }
}


================================================
FILE: appCt/src/test/java/com/example/project/robolectric/ShadowBackgroundExecutor.java
================================================
package com.example.project.robolectric;

import org.androidannotations.api.BackgroundExecutor;
import org.assertj.core.util.Strings;
import org.robolectric.Robolectric;
import org.robolectric.annotation.Implementation;
import org.robolectric.annotation.Implements;
import org.robolectric.util.Scheduler;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;

/**
 * Ensure synchronous execution of android annotations background tasks.
 * <p/>
 * Robolectric is designed to execute all background tasks synced to avoid flaky tests. Current
 * it miss support for android annotations so this class will do the job.
 * <p/>
 * Additional the shadow tries to simulate the behaviour of android annotations cancelable tasks.
 * But real interrupt feature is not supported because there is no async with robolectric tests.
 */
@Implements(BackgroundExecutor.class)
public class ShadowBackgroundExecutor {

    static Map<String, Runnable> cancelableTasks = new HashMap<>();

    @Implementation
    public static synchronized void execute(final BackgroundExecutor.Task task) {
        String taskId = extractTaskId(task);

        if (Strings.isNullOrEmpty(taskId)) {
            Robolectric.getBackgroundThreadScheduler().post(task);
        } else {
            Runnable taskWrapper = wrapAsCancelableTask(task, taskId);
            Robolectric.getBackgroundThreadScheduler().post(taskWrapper);
        }
    }

    /**
     * Stop the run of queued background cancelableTasks.
     * <p/>
     * To use it you must stop automatic background task execution with
     * {@link }Robolectric#getBackgroundthreadScheduler()} and pause it {@link Scheduler#pause()}
     */
    public static synchronized void cancelAll(String id, boolean mayInterruptIfRunning) {
        Runnable runnable = cancelableTasks.remove(id);
        Robolectric.getBackgroundThreadScheduler().remove(runnable);
    }

    private static Runnable wrapAsCancelableTask(final BackgroundExecutor.Task task, String taskId) {
        final String fTaskId = taskId;
        Runnable taskWrapper = new Runnable() {
            @Override
            public void run() {
                task.run();
                cancelableTasks.remove(fTaskId);
            }
        };
        cancelableTasks.put(fTaskId, taskWrapper);
        return taskWrapper;
    }

    private static String extractTaskId(BackgroundExecutor.Task task) {
        try {
            Field privateStringField = BackgroundExecutor.Task.class.getDeclaredField("id");
            privateStringField.setAccessible(true);
            return (String) privateStringField.get(task);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

}

================================================
FILE: appCt/src/test/java/com/example/project/testdata/TestContactData.java
================================================
package com.example.project.testdata;

import com.example.project.database.provider.contact.ContactContentValues;
import com.example.project.database.contact.ContactDb;
import com.example.project.database.contact.ContactDb_;

import org.robolectric.RuntimeEnvironment;

import java.util.Date;

public class TestContactData {

    public static void createRandomeContacts(int count) {
        for (int i = 0; i < count; i++) {
            ContactContentValues contactContentValues = new ContactContentValues();
            contactContentValues.putFirstName("Max " + i);
            contactContentValues.putLastName("Muster");
            contactContentValues.putBirthdate(new Date());

            ContactDb contactDb = ContactDb_.getInstance_(RuntimeEnvironment.application);
            contactDb.insert(contactContentValues);
        }
    }
}


================================================
FILE: appCt/src/test/java/com/example/project/views/contac_list/ContactListSpec.java
================================================
package com.example.project.views.contac_list;

import android.content.Intent;

import com.example.project.RobolectricTestCase;
import com.example.project.business.contact.CreateContactFunction_;
import com.example.project.testdata.TestContactData;
import com.example.project.views.contact_details.DetailActivity_;
import com.example.project.views.contact_edit.EditActivity_;
import com.github.tomakehurst.wiremock.http.Fault;

import org.junit.Test;
import org.robolectric.shadows.ShadowToast;

import java.util.Date;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.stubFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static org.assertj.android.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThat;

public class ContactListSpec extends RobolectricTestCase {

    RoboContactListPage roboContactListPage = new RoboContactListPage();

    @Test
    public void showContactDetails() {
        givenPageHasContacts();
        whenClickListItem();
        thenDetailsAreShownInNewPage();
    }

    @Test
    public void openCreateContact() {
        givenPageWithoutContacts();
        whenClickCreateContact();
        thenCreateNewContactIsShownInNewPage();
    }

    @Test
    public void refreshContactListOnNewContact() {
        givenPageWithoutContacts();
        whenInsertNewContact();
        thenPageHasContacts();
    }

    @Test
    public void syncContacts() {
        givenPageWithoutContacts();
        whenClickSyncContact();
        thenPageHasContacts();
        thenToastWasShown("Sync done");
    }

    @Test
    public void syncContactsFail() {
        givenContactsRequestAnswerWithError(500);
        givenPageWithoutContacts();
        whenClickSyncContact();
        thenToastWasShown("Sync failed: 500 Internal Server Error");
    }

    @Test
    public void syncContactsWithConnectionLost() {
        givenContactsRequestAnswerWithFault(Fault.RANDOM_DATA_THEN_CLOSE);
        givenPageWithoutContacts();
        whenClickSyncContact();
        thenToastWasShown("Sync failed: Unknown status code [-1] null");
    }

    private void givenContactsRequestAnswerWithFault(Fault fault) {
        stubFor(get(urlEqualTo("/contacts")).willReturn(aResponse().withFault(fault)));
    }

    private void givenContactsRequestAnswerWithError(int statusCode) {
        stubFor(get(urlEqualTo("/contacts")).willReturn(aResponse().withStatus(statusCode)));
    }

    private void thenToastWasShown(String expectedMessage) {
        assertThat(ShadowToast.getTextOfLatestToast()).isEqualTo(expectedMessage);
    }

    private void whenClickSyncContact() {
        roboContactListPage.syncContacts().click();
    }

    private void thenPageHasContacts() {
        assertThat(roboContactListPage.list().count()).isPositive();
    }

    private void whenInsertNewContact() {
        CreateContactFunction_.getInstance_(context).apply("A", "B", new Date());
    }

    private void thenCreateNewContactIsShownInNewPage() {
        Intent intent = roboContactListPage.nextStartedActivity();
        assertThat(intent).hasComponent(context, EditActivity_.class);
        assertThat(intent.getLongExtra(EditActivity_.CONTACT_ID_EXTRA, 0)).isZero();
    }

    private void whenClickCreateContact() {
        roboContactListPage.createContact().click();
    }

    private void whenClickListItem() {
        roboContactListPage.list().entry(0).click();
    }

    private void thenDetailsAreShownInNewPage() {
        Intent intent = roboContactListPage.nextStartedActivity();
        assertThat(intent).hasComponent(context, DetailActivity_.class);
    }

    private void givenPageWithoutContacts() {
        roboContactListPage.startPage();
        assertThat(roboContactListPage.list().count()).isZero();
    }

    private void givenPageHasContacts() {
        TestContactData.createRandomeContacts(3);
        roboContactListPage.startPage();
        assertThat(roboContactListPage.list().count()).isPositive();
    }
}


================================================
FILE: appCt/src/test/java/com/example/project/views/contac_list/RoboContactListPage.java
================================================
package com.example.project.views.contac_list;

import android.content.Intent;

import com.example.project.R;
import com.example.project.robolectric.RoboListView;
import com.example.project.views.contact_list.ContactListActivity;
import com.example.project.views.contact_list.ContactListActivity_;

import org.robolectric.Robolectric;
import org.robolectric.Shadows;

import static org.assertj.core.api.Assertions.assertThat;

public class RoboContactListPage {

    ContactListActivity contactListActivity;

    public void startPage() {
        contactListActivity = Robolectric.setupActivity(ContactListActivity_.class);
    }

    public RoboListView list() {
        return new RoboListView(contactListActivity, R.id.listView);
    }

    public Menu createContact() {
        return new Menu(R.id.action_add_contact);
    }

    public Menu syncContacts() {
        return new Menu(R.id.action_sync_contacts);
    }

    public Intent nextStartedActivity() {
        return Shadows.shadowOf(contactListActivity).getNextStartedActivity();
    }

    public class Menu {
        private int resourceId;

        public Menu(int resourceId) {
            this.resourceId = resourceId;
        }

        public void click() {
            assertThat(Shadows.shadowOf(contactListActivity).clickMenuItem(resourceId)).isTrue();
        }
    }
}

================================================
FILE: appCt/src/test/java/com/example/project/views/contact_details/ContactDetailSpec.java
================================================
package com.example.project.views.contact_details;

import com.example.project.RobolectricTestCase;

import org.junit.Ignore;

@Ignore
public class ContactDetailSpec extends RobolectricTestCase {

}


================================================
FILE: appCt/src/test/java/com/example/project/views/contact_edit/ContactCreateSpec.java
================================================
package com.example.project.views.contact_edit;

import com.example.project.database.contact.ContactDb_;
import com.example.project.database.provider.contact.ContactCursor;
import com.example.project.RobolectricTestCase;

import org.junit.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.android.api.Assertions.assertThat;

public class ContactCreateSpec extends RobolectricTestCase {

    RoboContactEditPage contactEditPage = new RoboContactEditPage();

    @Test
    public void testShouldCreateContact() {
        givenDatabaseHasNoContacts();
        whenCreateContact();
        thenCreateContactViewIsClosed();
        thenDatabaseHasContacts(1);
    }

    private void thenDatabaseHasContacts(int expectedCount) {
        ContactCursor contactCursor = ContactDb_.getInstance_(context).queryAll();
        assertThat(contactCursor).hasCount(expectedCount);
    }

    private void thenCreateContactViewIsClosed() {
        assertThat(contactEditPage.editActivity.isFinishing()).isTrue();
    }

    private void whenCreateContact() {
        contactEditPage.startPage();
        contactEditPage.firstName().insert("My First Name");
        contactEditPage.lastName().insert("My Last Name");
        contactEditPage.birthDate().insert("1984-11-11");
        contactEditPage.confirm().click();
    }

    private void givenDatabaseHasNoContacts() {
        ContactCursor contactCursor = ContactDb_.getInstance_(context).queryAll();
        assertThat(contactCursor).hasCount(0);
    }
}


================================================
FILE: appCt/src/test/java/com/example/project/views/contact_edit/ContactEditSpec.java
================================================
package com.example.project.views.contact_edit;

import com.example.project.RobolectricTestCase;

import org.junit.Ignore;

@Ignore
public class ContactEditSpec extends RobolectricTestCase {

}


================================================
FILE: appCt/src/test/java/com/example/project/views/contact_edit/RoboContactEditPage.java
================================================
package com.example.project.views.contact_edit;

import com.example.project.R;
import com.example.project.robolectric.RoboButton;
import com.example.project.robolectric.RoboTextEdit;

import org.robolectric.Robolectric;

public class RoboContactEditPage {
    EditActivity editActivity;

    public void startPage() {
        editActivity = Robolectric.setupActivity(EditActivity_.class);
    }

    public RoboTextEdit firstName() {
        return new RoboTextEdit(editActivity, R.id.first_name);
    }

    public RoboTextEdit lastName() {
        return new RoboTextEdit(editActivity, R.id.last_name);
    }

    public RoboTextEdit birthDate() {
        return new RoboTextEdit(editActivity, R.id.birth_date);
    }

    public RoboButton confirm() {
        return new RoboButton(editActivity, R.id.confirm);
    }
}


================================================
FILE: appIt/build.gradle
================================================
apply plugin: 'com.android.test'

android {
    compileSdkVersion projectAndroidVersion
    buildToolsVersion projectAndroidBuildToolsVersion

    defaultConfig {
        // minimal should be same from app module
        minSdkVersion projectAndroidMinVersion
        testApplicationId 'com.example.project.test'
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }

    buildTypes {
        debug {
            // support code coverage for the integration tests
            testCoverageEnabled = true
        }
    }

    jacoco {
        //noinspection GroovyAssignabilityCheck
        version projectJacocoVersion
    }

    targetProjectPath ':app'
    targetVariant 'debug'
    
    dexOptions {
        if(isCi) {
            // CircleCi allow max 4G memory for all processes together and dex does exceed it
            // with his parallel execution. Shrink the javaMaxHeapSize does it only per dex process
            // but the combination exceed the max memory and to less value let it run for long time.
            // javaMaxHeapSize "1024M"

            // Speed up build for CI by ignoring extra build steps which should speed up build for developers.
            // Also reduce memory usage by avoiding multiple (pre) dex processes.
            incremental false
            preDexLibraries = false
        }
    }
}

dependencies {
    // force dependencies to use the same support-annotations version (must be same from app)
    compile "com.android.support:support-annotations:$projectAndroidSupportToolsVersion"

    // fluent assertion support and android specific assertions
    compile 'com.squareup.assertj:assertj-android:1.1.0'

    // espresso support
    compile 'com.android.support.test.espresso:espresso-core:2.2'
    compile 'com.android.support.test:runner:0.3'
}


================================================
FILE: appIt/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.project.test">

    <application
        android:allowBackup="true"
        android:icon="@android:drawable/sym_def_app_icon" />

    <!-- Specify runner and target application package -->
    <instrumentation
        android:name="android.support.test.runner.AndroidJUnitRunner"
        android:targetPackage="com.example.project" />

</manifest>


================================================
FILE: appIt/src/main/java/com/example/project/EspressoTestCase.java
================================================
package com.example.project;

import android.app.Activity;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.Espresso;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import android.view.WindowManager;

import com.example.project.database.provider.address.AddressSelection;
import com.example.project.database.provider.contact.ContactSelection;
import com.example.project.views.common.AppIdlingResources;
import com.example.project.views.common.AppIdlingResources_;

import org.junit.Before;
import org.junit.Rule;
import org.junit.runner.RunWith;

import java.lang.reflect.ParameterizedType;

@RunWith(AndroidJUnit4.class)
public abstract class EspressoTestCase<A extends Activity> {

    @Rule
    public ActivityTestRule<A> activityRule = new ActivityTestRule<>(getGenericActivityClass());

    @Before
    public void setupEspresso() {
        Espresso.registerIdlingResources(AppIdlingResources_.getInstance_(InstrumentationRegistry.getContext()).getIdlingResource());

        clearDatabase();
        avoidLockScreen();
    }

    private void clearDatabase() {
        new ContactSelection().delete(InstrumentationRegistry.getContext().getContentResolver());
        new AddressSelection().delete(InstrumentationRegistry.getContext().getContentResolver());
    }

    private void avoidLockScreen() {
        // sometimes tests failed on emulator, following approach should avoid it
        // http://stackoverflow.com/questions/22737476/false-positives-junit-framework-assertionfailederror-edittext-is-not-found
        // http://developer.android.com/reference/android/view/WindowManager.LayoutParams.html#FLAG_SHOW_WHEN_LOCKED
        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
            @Override
            public void run() {
                Activity activity = activityRule.getActivity();
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
                activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
            }
        });
    }

    private Class<A> getGenericActivityClass() {
        //noinspection unchecked
        return ((Class) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]);
    }
}


================================================
FILE: appIt/src/main/java/com/example/project/espresso/CurrentActivity.java
================================================
package com.example.project.espresso;

import android.app.Activity;
import android.support.test.InstrumentationRegistry;
import android.support.test.espresso.core.deps.guava.collect.Iterables;
import android.support.test.rule.ActivityTestRule;
import android.support.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
import android.support.test.runner.lifecycle.Stage;

public class CurrentActivity {

    @SuppressWarnings("unchecked")
    public static <A extends Activity> A get() {
        InstrumentationRegistry.getInstrumentation().waitForIdleSync();
        final Activity[] activity = new Activity[1];
        InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() {
            @Override
            public void run() {
                java.util.Collection<Activity> activities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED);
                activity[0] = Iterables.getOnlyElement(activities);
            }
        });
        return (A) activity[0];
    }
}


================================================
FILE: appIt/src/main/java/com/example/project/espresso/EspButton.java
================================================
package com.example.project.espresso;

import android.support.test.espresso.action.ViewActions;

import static android.support.test.esp
Download .txt
gitextract_0g2gn4nz/

├── .gitignore
├── app/
│   ├── build.generate-database.gradle
│   ├── build.generate-json-objects.gradle
│   ├── build.gradle
│   ├── build.jacoco-test-report.gradle
│   ├── build.robolectric.gradle
│   ├── build.wiremock-replace-ip.gradle
│   ├── lint.xml
│   ├── proguard-rules.pro
│   └── src/
│       ├── gen/
│       │   └── java/
│       │       └── com/
│       │           └── example/
│       │               └── project/
│       │                   ├── database/
│       │                   │   └── provider/
│       │                   │       ├── ExampleProvider.java
│       │                   │       ├── ExampleSQLiteOpenHelper.java
│       │                   │       ├── ExampleSQLiteOpenHelperCallbacks.java
│       │                   │       ├── address/
│       │                   │       │   ├── AddressColumns.java
│       │                   │       │   ├── AddressContentValues.java
│       │                   │       │   ├── AddressCursor.java
│       │                   │       │   ├── AddressModel.java
│       │                   │       │   └── AddressSelection.java
│       │                   │       ├── base/
│       │                   │       │   ├── AbstractContentValues.java
│       │                   │       │   ├── AbstractCursor.java
│       │                   │       │   ├── AbstractSelection.java
│       │                   │       │   ├── BaseContentProvider.java
│       │                   │       │   └── BaseModel.java
│       │                   │       └── contact/
│       │                   │           ├── ContactColumns.java
│       │                   │           ├── ContactContentValues.java
│       │                   │           ├── ContactCursor.java
│       │                   │           ├── ContactModel.java
│       │                   │           └── ContactSelection.java
│       │                   └── network/
│       │                       └── json/
│       │                           ├── ContactJson.java
│       │                           └── ContactListJson.java
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── java/
│       │   │   └── com/
│       │   │       └── example/
│       │   │           └── project/
│       │   │               ├── business/
│       │   │               │   ├── contact/
│       │   │               │   │   ├── CreateContactFunction.java
│       │   │               │   │   ├── DeleteContactFunction.java
│       │   │               │   │   ├── QueryContactFunction.java
│       │   │               │   │   ├── QueryContactListFunction.java
│       │   │               │   │   └── UpdateContactFunction.java
│       │   │               │   └── contact_sync/
│       │   │               │       └── SyncContactsFunction.java
│       │   │               ├── database/
│       │   │               │   ├── ExampleDbProvider.java
│       │   │               │   ├── ExampleSQLiteOpenHelperCallbacks.java
│       │   │               │   └── contact/
│       │   │               │       ├── AddressDb.java
│       │   │               │       └── ContactDb.java
│       │   │               ├── network/
│       │   │               │   └── contact/
│       │   │               │       ├── ContactRestClient.java
│       │   │               │       └── RootUrlInterceptor.java
│       │   │               └── views/
│       │   │                   ├── common/
│       │   │                   │   ├── AppIdlingResources.java
│       │   │                   │   ├── cursorloader/
│       │   │                   │   │   └── CursorAdapterWithCursorLoader.java
│       │   │                   │   ├── mvp/
│       │   │                   │   │   ├── BaseActivityPresenter.java
│       │   │                   │   │   ├── BaseFragmentPresenter.java
│       │   │                   │   │   ├── BasePresenter.java
│       │   │                   │   │   └── BaseView.java
│       │   │                   │   └── testwrapper/
│       │   │                   │       └── ViewFinisher.java
│       │   │                   ├── contact_details/
│       │   │                   │   ├── DetailActivity.java
│       │   │                   │   ├── DetailActivityIntent.java
│       │   │                   │   ├── DetailFragment.java
│       │   │                   │   └── DetailView.java
│       │   │                   ├── contact_edit/
│       │   │                   │   ├── EditActivity.java
│       │   │                   │   ├── EditActivityIntent.java
│       │   │                   │   ├── EditConfirmedListener.java
│       │   │                   │   ├── EditFragment.java
│       │   │                   │   └── EditView.java
│       │   │                   ├── contact_list/
│       │   │                   │   ├── ContactAdapter.java
│       │   │                   │   ├── ContactAdapterLoader.java
│       │   │                   │   ├── ContactListActivity.java
│       │   │                   │   ├── ContactListActivityIntent.java
│       │   │                   │   ├── ContactListFragment.java
│       │   │                   │   ├── ContactListView.java
│       │   │                   │   └── ShowContactListener.java
│       │   │                   └── start/
│       │   │                       └── StartActivity.java
│       │   ├── json/
│       │   │   ├── database/
│       │   │   │   └── schema/
│       │   │   │       ├── _config.json
│       │   │   │       ├── address.json
│       │   │   │       └── contact.json
│       │   │   └── network/
│       │   │       └── schema/
│       │   │           ├── contactJson.json
│       │   │           └── contactListJson.json
│       │   └── res/
│       │       ├── layout/
│       │       │   ├── activity_detail.xml
│       │       │   ├── activity_edit.xml
│       │       │   ├── activity_main.xml
│       │       │   ├── fragment_detail.xml
│       │       │   ├── fragment_edit.xml
│       │       │   └── fragment_list.xml
│       │       ├── layout-land/
│       │       │   └── activity_main.xml
│       │       ├── menu/
│       │       │   └── menu_main.xml
│       │       ├── values/
│       │       │   ├── dimens.xml
│       │       │   ├── string_api_url.xml
│       │       │   ├── strings.xml
│       │       │   ├── strings_details.xml
│       │       │   └── styles.xml
│       │       └── values-w820dp/
│       │           └── dimens.xml
│       └── test/
│           └── java/
│               └── com/
│                   └── example/
│                       └── project/
│                           ├── RoboTestCase.java
│                           ├── business/
│                           │   └── contact/
│                           │       └── QueryContactListFunctionTest.java
│                           ├── database/
│                           │   └── contact/
│                           │       ├── AddressDbInsertTest.java
│                           │       ├── AddressDbTest.java
│                           │       ├── ContactDbInsertTest.java
│                           │       └── ContactDbTest.java
│                           └── views/
│                               ├── contact_edit/
│                               │   ├── EditActivityTest.java
│                               │   └── EditFragmentTest.java
│                               ├── contact_list/
│                               │   ├── ContactListActivityTest.java
│                               │   └── ContactListFragmentTest.java
│                               └── start/
│                                   └── StartActivityTest.java
├── appCt/
│   ├── build.gradle
│   ├── build.jacoco-test-report.gradle
│   ├── build.novoda-android-studio.gradle
│   ├── build.robolectric.gradle
│   └── src/
│       └── test/
│           └── java/
│               ├── android/
│               │   └── database/
│               │       └── ShadowContentObservable.java
│               └── com/
│                   └── example/
│                       └── project/
│                           ├── RobolectricTestCase.java
│                           ├── robolectric/
│                           │   ├── CostomRobolectricTestRunner.java
│                           │   ├── RoboButton.java
│                           │   ├── RoboListView.java
│                           │   ├── RoboListViewEntry.java
│                           │   ├── RoboTextEdit.java
│                           │   └── ShadowBackgroundExecutor.java
│                           ├── testdata/
│                           │   └── TestContactData.java
│                           └── views/
│                               ├── contac_list/
│                               │   ├── ContactListSpec.java
│                               │   └── RoboContactListPage.java
│                               ├── contact_details/
│                               │   └── ContactDetailSpec.java
│                               └── contact_edit/
│                                   ├── ContactCreateSpec.java
│                                   ├── ContactEditSpec.java
│                                   └── RoboContactEditPage.java
├── appIt/
│   ├── build.gradle
│   └── src/
│       └── main/
│           ├── AndroidManifest.xml
│           └── java/
│               └── com/
│                   └── example/
│                       └── project/
│                           ├── EspressoTestCase.java
│                           ├── espresso/
│                           │   ├── CurrentActivity.java
│                           │   ├── EspButton.java
│                           │   ├── EspListView.java
│                           │   ├── EspMenuItem.java
│                           │   └── EspTextEdit.java
│                           ├── pages/
│                           │   ├── EspContactListPage.java
│                           │   └── EspEditContactPage.java
│                           └── test/
│                               ├── CreateContactTest.java
│                               └── SyncContactsTest.java
├── build.gradle
├── build.jacoco-test-report.gradle
├── circle.yml
├── docs/
│   ├── build.gradle
│   └── src/
│       └── main/
│           └── resources/
│               ├── adjust_project_to_your_needs.md
│               ├── concepts/
│               │   ├── function_class.md
│               │   ├── model_view_presenter.md
│               │   ├── package_structure.md
│               │   ├── project_structure.md
│               │   └── testing.md
│               ├── getting_started.md
│               ├── index.md
│               └── tools/
│                   ├── android_contentprovider_generator.md
│                   ├── androidannotations.md
│                   ├── circleci.md
│                   ├── coveralls.md
│                   ├── espresso.md
│                   ├── espresso_test_module.md
│                   ├── fest_assertions.md
│                   ├── jacoco.md
│                   ├── joda_timedate.md
│                   ├── jsonschema2pojo.md
│                   ├── robolectric.md
│                   ├── robolectric_test_module.md
│                   └── wiremock.md
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── readme.md
├── settings.gradle
├── tools/
│   ├── build.gradle
│   └── src/
│       └── main/
│           └── resources/
│               ├── rename-packages(in development).sh
│               ├── start-wiremock.sh
│               ├── test-all-with-coverage.bat
│               └── test-all-with-coverage.sh
└── wiremock/
    ├── build.gradle
    ├── src/
    │   └── main/
    │       └── resources/
    │           ├── __files/
    │           │   └── contacts-get.json
    │           └── mappings/
    │               ├── contcts-delete.json
    │               ├── contcts-get.json
    │               ├── contcts-post.json
    │               └── contcts-put.json
    └── wiremock-1.57-standalone.jar
Download .txt
SYMBOL INDEX (591 symbols across 92 files)

FILE: app/src/gen/java/com/example/project/database/provider/ExampleProvider.java
  class ExampleProvider (line 18) | public class ExampleProvider extends BaseContentProvider {
    method createSqLiteOpenHelper (line 46) | @Override
    method hasDebug (line 51) | @Override
    method getType (line 56) | @Override
    method insert (line 74) | @Override
    method bulkInsert (line 80) | @Override
    method update (line 86) | @Override
    method delete (line 92) | @Override
    method query (line 98) | @Override
    method getQueryParams (line 106) | @Override

FILE: app/src/gen/java/com/example/project/database/provider/ExampleSQLiteOpenHelper.java
  class ExampleSQLiteOpenHelper (line 16) | public class ExampleSQLiteOpenHelper extends SQLiteOpenHelper {
    method getInstance (line 51) | public static ExampleSQLiteOpenHelper getInstance(Context context) {
    method newInstance (line 61) | private static ExampleSQLiteOpenHelper newInstance(Context context) {
    method newInstancePreHoneycomb (line 72) | private static ExampleSQLiteOpenHelper newInstancePreHoneycomb(Context...
    method ExampleSQLiteOpenHelper (line 76) | private ExampleSQLiteOpenHelper(Context context) {
    method newInstancePostHoneycomb (line 86) | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    method ExampleSQLiteOpenHelper (line 91) | @TargetApi(Build.VERSION_CODES.HONEYCOMB)
    method onCreate (line 99) | @Override
    method onOpen (line 108) | @Override
    method setForeignKeyConstraintsEnabled (line 117) | private void setForeignKeyConstraintsEnabled(SQLiteDatabase db) {
    method setForeignKeyConstraintsEnabledPreJellyBean (line 125) | private void setForeignKeyConstraintsEnabledPreJellyBean(SQLiteDatabas...
    method setForeignKeyConstraintsEnabledPostJellyBean (line 129) | @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    method onUpgrade (line 134) | @Override

FILE: app/src/gen/java/com/example/project/database/provider/ExampleSQLiteOpenHelperCallbacks.java
  class ExampleSQLiteOpenHelperCallbacks (line 15) | public class ExampleSQLiteOpenHelperCallbacks {
    method onOpen (line 18) | public void onOpen(final Context context, final SQLiteDatabase db) {
    method onPreCreate (line 23) | public void onPreCreate(final Context context, final SQLiteDatabase db) {
    method onPostCreate (line 28) | public void onPostCreate(final Context context, final SQLiteDatabase d...
    method onUpgrade (line 33) | public void onUpgrade(final Context context, final SQLiteDatabase db, ...

FILE: app/src/gen/java/com/example/project/database/provider/address/AddressColumns.java
  class AddressColumns (line 13) | public class AddressColumns implements BaseColumns {
    method hasColumns (line 52) | public static boolean hasColumns(String[] projection) {

FILE: app/src/gen/java/com/example/project/database/provider/address/AddressContentValues.java
  class AddressContentValues (line 15) | public class AddressContentValues extends AbstractContentValues {
    method uri (line 16) | @Override
    method update (line 27) | public int update(ContentResolver contentResolver, @Nullable AddressSe...
    method putContactId (line 31) | public AddressContentValues putContactId(long value) {
    method putStreet (line 37) | public AddressContentValues putStreet(@Nullable String value) {
    method putStreetNull (line 42) | public AddressContentValues putStreetNull() {
    method putNumber (line 47) | public AddressContentValues putNumber(@Nullable String value) {
    method putNumberNull (line 52) | public AddressContentValues putNumberNull() {
    method putCity (line 57) | public AddressContentValues putCity(@Nullable String value) {
    method putCityNull (line 62) | public AddressContentValues putCityNull() {
    method putCountry (line 67) | public AddressContentValues putCountry(@Nullable String value) {
    method putCountryNull (line 72) | public AddressContentValues putCountryNull() {
    method putState (line 77) | public AddressContentValues putState(@Nullable String value) {
    method putStateNull (line 82) | public AddressContentValues putStateNull() {
    method putPostalcode (line 87) | public AddressContentValues putPostalcode(@Nullable String value) {
    method putPostalcodeNull (line 92) | public AddressContentValues putPostalcodeNull() {

FILE: app/src/gen/java/com/example/project/database/provider/address/AddressCursor.java
  class AddressCursor (line 15) | public class AddressCursor extends AbstractCursor implements AddressModel {
    method AddressCursor (line 16) | public AddressCursor(Cursor cursor) {
    method getId (line 23) | public long getId() {
    method getContactId (line 33) | public long getContactId() {
    method getContactUid (line 44) | @Nullable
    method getContactFirstName (line 54) | @Nullable
    method getContactLastName (line 64) | @Nullable
    method getContactBirthdate (line 74) | @Nullable
    method getStreet (line 84) | @Nullable
    method getNumber (line 94) | @Nullable
    method getCity (line 104) | @Nullable
    method getCountry (line 114) | @Nullable
    method getState (line 124) | @Nullable
    method getPostalcode (line 134) | @Nullable

FILE: app/src/gen/java/com/example/project/database/provider/address/AddressModel.java
  type AddressModel (line 13) | public interface AddressModel extends BaseModel {
    method getContactId (line 18) | long getContactId();
    method getStreet (line 24) | @Nullable
    method getNumber (line 31) | @Nullable
    method getCity (line 38) | @Nullable
    method getCountry (line 45) | @Nullable
    method getState (line 52) | @Nullable
    method getPostalcode (line 59) | @Nullable

FILE: app/src/gen/java/com/example/project/database/provider/address/AddressSelection.java
  class AddressSelection (line 15) | public class AddressSelection extends AbstractSelection<AddressSelection> {
    method baseUri (line 16) | @Override
    method query (line 30) | public AddressCursor query(ContentResolver contentResolver, String[] p...
    method query (line 39) | public AddressCursor query(ContentResolver contentResolver, String[] p...
    method query (line 46) | public AddressCursor query(ContentResolver contentResolver) {
    method id (line 51) | public AddressSelection id(long... value) {
    method contactId (line 56) | public AddressSelection contactId(long... value) {
    method contactIdNot (line 61) | public AddressSelection contactIdNot(long... value) {
    method contactIdGt (line 66) | public AddressSelection contactIdGt(long value) {
    method contactIdGtEq (line 71) | public AddressSelection contactIdGtEq(long value) {
    method contactIdLt (line 76) | public AddressSelection contactIdLt(long value) {
    method contactIdLtEq (line 81) | public AddressSelection contactIdLtEq(long value) {
    method contactUid (line 86) | public AddressSelection contactUid(String... value) {
    method contactUidNot (line 91) | public AddressSelection contactUidNot(String... value) {
    method contactUidLike (line 96) | public AddressSelection contactUidLike(String... value) {
    method contactUidContains (line 101) | public AddressSelection contactUidContains(String... value) {
    method contactUidStartsWith (line 106) | public AddressSelection contactUidStartsWith(String... value) {
    method contactUidEndsWith (line 111) | public AddressSelection contactUidEndsWith(String... value) {
    method contactFirstName (line 116) | public AddressSelection contactFirstName(String... value) {
    method contactFirstNameNot (line 121) | public AddressSelection contactFirstNameNot(String... value) {
    method contactFirstNameLike (line 126) | public AddressSelection contactFirstNameLike(String... value) {
    method contactFirstNameContains (line 131) | public AddressSelection contactFirstNameContains(String... value) {
    method contactFirstNameStartsWith (line 136) | public AddressSelection contactFirstNameStartsWith(String... value) {
    method contactFirstNameEndsWith (line 141) | public AddressSelection contactFirstNameEndsWith(String... value) {
    method contactLastName (line 146) | public AddressSelection contactLastName(String... value) {
    method contactLastNameNot (line 151) | public AddressSelection contactLastNameNot(String... value) {
    method contactLastNameLike (line 156) | public AddressSelection contactLastNameLike(String... value) {
    method contactLastNameContains (line 161) | public AddressSelection contactLastNameContains(String... value) {
    method contactLastNameStartsWith (line 166) | public AddressSelection contactLastNameStartsWith(String... value) {
    method contactLastNameEndsWith (line 171) | public AddressSelection contactLastNameEndsWith(String... value) {
    method contactBirthdate (line 176) | public AddressSelection contactBirthdate(Date... value) {
    method contactBirthdateNot (line 181) | public AddressSelection contactBirthdateNot(Date... value) {
    method contactBirthdate (line 186) | public AddressSelection contactBirthdate(Long... value) {
    method contactBirthdateAfter (line 191) | public AddressSelection contactBirthdateAfter(Date value) {
    method contactBirthdateAfterEq (line 196) | public AddressSelection contactBirthdateAfterEq(Date value) {
    method contactBirthdateBefore (line 201) | public AddressSelection contactBirthdateBefore(Date value) {
    method contactBirthdateBeforeEq (line 206) | public AddressSelection contactBirthdateBeforeEq(Date value) {
    method street (line 211) | public AddressSelection street(String... value) {
    method streetNot (line 216) | public AddressSelection streetNot(String... value) {
    method streetLike (line 221) | public AddressSelection streetLike(String... value) {
    method streetContains (line 226) | public AddressSelection streetContains(String... value) {
    method streetStartsWith (line 231) | public AddressSelection streetStartsWith(String... value) {
    method streetEndsWith (line 236) | public AddressSelection streetEndsWith(String... value) {
    method number (line 241) | public AddressSelection number(String... value) {
    method numberNot (line 246) | public AddressSelection numberNot(String... value) {
    method numberLike (line 251) | public AddressSelection numberLike(String... value) {
    method numberContains (line 256) | public AddressSelection numberContains(String... value) {
    method numberStartsWith (line 261) | public AddressSelection numberStartsWith(String... value) {
    method numberEndsWith (line 266) | public AddressSelection numberEndsWith(String... value) {
    method city (line 271) | public AddressSelection city(String... value) {
    method cityNot (line 276) | public AddressSelection cityNot(String... value) {
    method cityLike (line 281) | public AddressSelection cityLike(String... value) {
    method cityContains (line 286) | public AddressSelection cityContains(String... value) {
    method cityStartsWith (line 291) | public AddressSelection cityStartsWith(String... value) {
    method cityEndsWith (line 296) | public AddressSelection cityEndsWith(String... value) {
    method country (line 301) | public AddressSelection country(String... value) {
    method countryNot (line 306) | public AddressSelection countryNot(String... value) {
    method countryLike (line 311) | public AddressSelection countryLike(String... value) {
    method countryContains (line 316) | public AddressSelection countryContains(String... value) {
    method countryStartsWith (line 321) | public AddressSelection countryStartsWith(String... value) {
    method countryEndsWith (line 326) | public AddressSelection countryEndsWith(String... value) {
    method state (line 331) | public AddressSelection state(String... value) {
    method stateNot (line 336) | public AddressSelection stateNot(String... value) {
    method stateLike (line 341) | public AddressSelection stateLike(String... value) {
    method stateContains (line 346) | public AddressSelection stateContains(String... value) {
    method stateStartsWith (line 351) | public AddressSelection stateStartsWith(String... value) {
    method stateEndsWith (line 356) | public AddressSelection stateEndsWith(String... value) {
    method postalcode (line 361) | public AddressSelection postalcode(String... value) {
    method postalcodeNot (line 366) | public AddressSelection postalcodeNot(String... value) {
    method postalcodeLike (line 371) | public AddressSelection postalcodeLike(String... value) {
    method postalcodeContains (line 376) | public AddressSelection postalcodeContains(String... value) {
    method postalcodeStartsWith (line 381) | public AddressSelection postalcodeStartsWith(String... value) {
    method postalcodeEndsWith (line 386) | public AddressSelection postalcodeEndsWith(String... value) {

FILE: app/src/gen/java/com/example/project/database/provider/base/AbstractContentValues.java
  class AbstractContentValues (line 7) | public abstract class AbstractContentValues {
    method uri (line 13) | public abstract Uri uri();
    method values (line 18) | public ContentValues values() {
    method insert (line 27) | public Uri insert(ContentResolver contentResolver) {

FILE: app/src/gen/java/com/example/project/database/provider/base/AbstractCursor.java
  class AbstractCursor (line 10) | public abstract class AbstractCursor extends CursorWrapper {
    method AbstractCursor (line 13) | public AbstractCursor(Cursor cursor) {
    method getId (line 18) | public abstract long getId();
    method getCachedColumnIndexOrThrow (line 20) | protected int getCachedColumnIndexOrThrow(String colName) {
    method getStringOrNull (line 29) | public String getStringOrNull(String colName) {
    method getIntegerOrNull (line 35) | public Integer getIntegerOrNull(String colName) {
    method getLongOrNull (line 41) | public Long getLongOrNull(String colName) {
    method getFloatOrNull (line 47) | public Float getFloatOrNull(String colName) {
    method getDoubleOrNull (line 53) | public Double getDoubleOrNull(String colName) {
    method getBooleanOrNull (line 59) | public Boolean getBooleanOrNull(String colName) {
    method getDateOrNull (line 65) | public Date getDateOrNull(String colName) {
    method getBlobOrNull (line 71) | public byte[] getBlobOrNull(String colName) {

FILE: app/src/gen/java/com/example/project/database/provider/base/AbstractSelection.java
  class AbstractSelection (line 10) | public abstract class AbstractSelection<T extends AbstractSelection<?>> {
    method addEquals (line 39) | protected void addEquals(String column, Object[] value) {
    method addNotEquals (line 69) | protected void addNotEquals(String column, Object[] value) {
    method addLike (line 99) | protected void addLike(String column, String[] values) {
    method addContains (line 112) | protected void addContains(String column, String[] values) {
    method addStartsWith (line 125) | protected void addStartsWith(String column, String[] values) {
    method addEndsWith (line 138) | protected void addEndsWith(String column, String[] values) {
    method addGreaterThan (line 151) | protected void addGreaterThan(String column, Object value) {
    method addGreaterThanOrEquals (line 157) | protected void addGreaterThanOrEquals(String column, Object value) {
    method addLessThan (line 163) | protected void addLessThan(String column, Object value) {
    method addLessThanOrEquals (line 169) | protected void addLessThanOrEquals(String column, Object value) {
    method addRaw (line 175) | public void addRaw(String raw, Object... args) {
    method valueOf (line 184) | private String valueOf(Object obj) {
    method openParen (line 195) | @SuppressWarnings("unchecked")
    method closeParen (line 201) | @SuppressWarnings("unchecked")
    method and (line 207) | @SuppressWarnings("unchecked")
    method or (line 213) | @SuppressWarnings("unchecked")
    method toObjectArray (line 220) | protected Object[] toObjectArray(int... array) {
    method toObjectArray (line 228) | protected Object[] toObjectArray(long... array) {
    method toObjectArray (line 236) | protected Object[] toObjectArray(float... array) {
    method toObjectArray (line 244) | protected Object[] toObjectArray(double... array) {
    method toObjectArray (line 252) | protected Object[] toObjectArray(Boolean value) {
    method sel (line 260) | public String sel() {
    method args (line 267) | public String[] args() {
    method uri (line 277) | public Uri uri() {
    method baseUri (line 286) | protected abstract Uri baseUri();
    method delete (line 294) | public int delete(ContentResolver contentResolver) {
    method notify (line 298) | @SuppressWarnings("unchecked")
    method groupBy (line 304) | @SuppressWarnings("unchecked")
    method having (line 310) | @SuppressWarnings("unchecked")
    method limit (line 316) | @SuppressWarnings("unchecked")

FILE: app/src/gen/java/com/example/project/database/provider/base/BaseContentProvider.java
  class BaseContentProvider (line 20) | public abstract class BaseContentProvider extends ContentProvider {
    class QueryParams (line 26) | public static class QueryParams {
    method getQueryParams (line 35) | protected abstract QueryParams getQueryParams(Uri uri, String selectio...
    method hasDebug (line 36) | protected abstract boolean hasDebug();
    method createSqLiteOpenHelper (line 38) | protected abstract SQLiteOpenHelper createSqLiteOpenHelper();
    method onCreate (line 42) | @Override
    method insert (line 65) | @Override
    method bulkInsert (line 77) | @Override
    method update (line 103) | @Override
    method delete (line 114) | @Override
    method query (line 125) | @Override
    method ensureIdIsFullyQualified (line 138) | private String[] ensureIdIsFullyQualified(String[] projection, String ...
    method applyBatch (line 151) | @Override
    method notify (line 181) | public static Uri notify(Uri uri, boolean notify) {
    method groupBy (line 185) | public static Uri groupBy(Uri uri, String groupBy) {
    method having (line 189) | public static Uri having(Uri uri, String having) {
    method limit (line 193) | public static Uri limit(Uri uri, String limit) {

FILE: app/src/gen/java/com/example/project/database/provider/base/BaseModel.java
  type BaseModel (line 3) | public interface BaseModel {

FILE: app/src/gen/java/com/example/project/database/provider/contact/ContactColumns.java
  class ContactColumns (line 13) | public class ContactColumns implements BaseColumns {
    method hasColumns (line 43) | public static boolean hasColumns(String[] projection) {

FILE: app/src/gen/java/com/example/project/database/provider/contact/ContactContentValues.java
  class ContactContentValues (line 15) | public class ContactContentValues extends AbstractContentValues {
    method uri (line 16) | @Override
    method update (line 27) | public int update(ContentResolver contentResolver, @Nullable ContactSe...
    method putUid (line 31) | public ContactContentValues putUid(@Nullable String value) {
    method putUidNull (line 36) | public ContactContentValues putUidNull() {
    method putFirstName (line 41) | public ContactContentValues putFirstName(@Nullable String value) {
    method putFirstNameNull (line 46) | public ContactContentValues putFirstNameNull() {
    method putLastName (line 51) | public ContactContentValues putLastName(@Nullable String value) {
    method putLastNameNull (line 56) | public ContactContentValues putLastNameNull() {
    method putBirthdate (line 61) | public ContactContentValues putBirthdate(@Nullable Date value) {
    method putBirthdateNull (line 66) | public ContactContentValues putBirthdateNull() {
    method putBirthdate (line 71) | public ContactContentValues putBirthdate(@Nullable Long value) {

FILE: app/src/gen/java/com/example/project/database/provider/contact/ContactCursor.java
  class ContactCursor (line 14) | public class ContactCursor extends AbstractCursor implements ContactModel {
    method ContactCursor (line 15) | public ContactCursor(Cursor cursor) {
    method getId (line 22) | public long getId() {
    method getUid (line 33) | @Nullable
    method getFirstName (line 43) | @Nullable
    method getLastName (line 53) | @Nullable
    method getBirthdate (line 63) | @Nullable

FILE: app/src/gen/java/com/example/project/database/provider/contact/ContactModel.java
  type ContactModel (line 13) | public interface ContactModel extends BaseModel {
    method getUid (line 19) | @Nullable
    method getFirstName (line 26) | @Nullable
    method getLastName (line 33) | @Nullable
    method getBirthdate (line 40) | @Nullable

FILE: app/src/gen/java/com/example/project/database/provider/contact/ContactSelection.java
  class ContactSelection (line 14) | public class ContactSelection extends AbstractSelection<ContactSelection> {
    method baseUri (line 15) | @Override
    method query (line 29) | public ContactCursor query(ContentResolver contentResolver, String[] p...
    method query (line 38) | public ContactCursor query(ContentResolver contentResolver, String[] p...
    method query (line 45) | public ContactCursor query(ContentResolver contentResolver) {
    method id (line 50) | public ContactSelection id(long... value) {
    method uid (line 55) | public ContactSelection uid(String... value) {
    method uidNot (line 60) | public ContactSelection uidNot(String... value) {
    method uidLike (line 65) | public ContactSelection uidLike(String... value) {
    method uidContains (line 70) | public ContactSelection uidContains(String... value) {
    method uidStartsWith (line 75) | public ContactSelection uidStartsWith(String... value) {
    method uidEndsWith (line 80) | public ContactSelection uidEndsWith(String... value) {
    method firstName (line 85) | public ContactSelection firstName(String... value) {
    method firstNameNot (line 90) | public ContactSelection firstNameNot(String... value) {
    method firstNameLike (line 95) | public ContactSelection firstNameLike(String... value) {
    method firstNameContains (line 100) | public ContactSelection firstNameContains(String... value) {
    method firstNameStartsWith (line 105) | public ContactSelection firstNameStartsWith(String... value) {
    method firstNameEndsWith (line 110) | public ContactSelection firstNameEndsWith(String... value) {
    method lastName (line 115) | public ContactSelection lastName(String... value) {
    method lastNameNot (line 120) | public ContactSelection lastNameNot(String... value) {
    method lastNameLike (line 125) | public ContactSelection lastNameLike(String... value) {
    method lastNameContains (line 130) | public ContactSelection lastNameContains(String... value) {
    method lastNameStartsWith (line 135) | public ContactSelection lastNameStartsWith(String... value) {
    method lastNameEndsWith (line 140) | public ContactSelection lastNameEndsWith(String... value) {
    method birthdate (line 145) | public ContactSelection birthdate(Date... value) {
    method birthdateNot (line 150) | public ContactSelection birthdateNot(Date... value) {
    method birthdate (line 155) | public ContactSelection birthdate(Long... value) {
    method birthdateAfter (line 160) | public ContactSelection birthdateAfter(Date value) {
    method birthdateAfterEq (line 165) | public ContactSelection birthdateAfterEq(Date value) {
    method birthdateBefore (line 170) | public ContactSelection birthdateBefore(Date value) {
    method birthdateBeforeEq (line 175) | public ContactSelection birthdateBeforeEq(Date value) {

FILE: app/src/gen/java/com/example/project/network/json/ContactJson.java
  class ContactJson (line 22) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method getId (line 48) | @JsonProperty("id")
    method setId (line 58) | @JsonProperty("id")
    method getFirstName (line 68) | @JsonProperty("firstName")
    method setFirstName (line 78) | @JsonProperty("firstName")
    method getLastName (line 88) | @JsonProperty("lastName")
    method setLastName (line 98) | @JsonProperty("lastName")
    method getBirthDate (line 108) | @JsonProperty("birthDate")
    method setBirthDate (line 118) | @JsonProperty("birthDate")
    method toString (line 123) | @Override
    method getAdditionalProperties (line 128) | @JsonAnyGetter
    method setAdditionalProperty (line 133) | @JsonAnySetter
    method hashCode (line 138) | @Override
    method equals (line 143) | @Override

FILE: app/src/gen/java/com/example/project/network/json/ContactListJson.java
  class ContactListJson (line 24) | @JsonInclude(JsonInclude.Include.NON_NULL)
    method getContacts (line 41) | @JsonProperty("contacts")
    method setContacts (line 51) | @JsonProperty("contacts")
    method toString (line 56) | @Override
    method getAdditionalProperties (line 61) | @JsonAnyGetter
    method setAdditionalProperty (line 66) | @JsonAnySetter
    method hashCode (line 71) | @Override
    method equals (line 76) | @Override

FILE: app/src/main/java/com/example/project/business/contact/CreateContactFunction.java
  class CreateContactFunction (line 11) | @EBean
    method apply (line 17) | public void apply(String firstName, String lastName, Date birthDate) {
    method apply (line 21) | public void apply(String uid, String firstName, String lastName, Date ...

FILE: app/src/main/java/com/example/project/business/contact/DeleteContactFunction.java
  class DeleteContactFunction (line 5) | @EBean

FILE: app/src/main/java/com/example/project/business/contact/QueryContactFunction.java
  class QueryContactFunction (line 14) | @EBean
    method apply (line 20) | public ContactModel apply(long contactId) {
    method applyByUid (line 25) | public ContactModel applyByUid(String contactUid) {
    method createContactModel (line 30) | private ContactModel createContactModel(ContactCursor contactCursor) {

FILE: app/src/main/java/com/example/project/business/contact/QueryContactListFunction.java
  class QueryContactListFunction (line 9) | @EBean
    method apply (line 15) | public ContactCursor apply() {

FILE: app/src/main/java/com/example/project/business/contact/UpdateContactFunction.java
  class UpdateContactFunction (line 5) | @EBean

FILE: app/src/main/java/com/example/project/business/contact_sync/SyncContactsFunction.java
  class SyncContactsFunction (line 24) | @EBean
    class Result (line 36) | public static class Result {
      method Result (line 41) | public Result(String errorReason) {
      method Result (line 46) | public Result() {
    method apply (line 51) | public Result apply() {
    method syncContactsToDatabase (line 65) | private void syncContactsToDatabase(ContactListJson contacts) {

FILE: app/src/main/java/com/example/project/database/ExampleDbProvider.java
  class ExampleDbProvider (line 7) | @EProvider

FILE: app/src/main/java/com/example/project/database/ExampleSQLiteOpenHelperCallbacks.java
  class ExampleSQLiteOpenHelperCallbacks (line 13) | public class ExampleSQLiteOpenHelperCallbacks {
    method onOpen (line 16) | public void onOpen(final Context context, final SQLiteDatabase db) {
    method onPreCreate (line 21) | public void onPreCreate(final Context context, final SQLiteDatabase db) {
    method onPostCreate (line 26) | public void onPostCreate(final Context context, final SQLiteDatabase d...
    method onUpgrade (line 31) | public void onUpgrade(final Context context, final SQLiteDatabase db, ...

FILE: app/src/main/java/com/example/project/database/contact/AddressDb.java
  class AddressDb (line 17) | @EBean
    method insert (line 26) | public long insert(AddressContentValues contentValues) {
    method queryById (line 31) | public AddressCursor queryById(long addressId) {

FILE: app/src/main/java/com/example/project/database/contact/ContactDb.java
  class ContactDb (line 14) | @EBean
    method insertDataContainer (line 20) | public ContactContentValues insertDataContainer() {
    method insert (line 24) | public long insert(ContactContentValues contentValues) {
    method queryAll (line 29) | public ContactCursor queryAll() {
    method queryById (line 33) | public ContactCursor queryById(long contactId) {
    method queryByUid (line 37) | public ContactCursor queryByUid(String contactUid) {

FILE: app/src/main/java/com/example/project/network/contact/ContactRestClient.java
  type ContactRestClient (line 14) | @Rest(converters = {MappingJackson2HttpMessageConverter.class}, intercep...
    method getContacts (line 17) | @Get("/contacts")
    method createContact (line 20) | @Post("/contacts")
    method updateContact (line 23) | @Put("/contacts/{id}")
    method deleteContact (line 26) | @Delete("/contacts/{id}")

FILE: app/src/main/java/com/example/project/network/contact/RootUrlInterceptor.java
  class RootUrlInterceptor (line 19) | @EBean
    method intercept (line 25) | @Override
    method executeWithInterceptedUri (line 31) | private ClientHttpResponse executeWithInterceptedUri(final HttpRequest...
    method prependRootUrl (line 51) | private URI prependRootUrl(URI originalUri) {

FILE: app/src/main/java/com/example/project/views/common/AppIdlingResources.java
  class AppIdlingResources (line 7) | @EBean(scope = EBean.Scope.Singleton)
    method getIdlingResource (line 12) | public CountingIdlingResource getIdlingResource() {
    method increment (line 16) | public void increment() {
    method decrement (line 20) | public void decrement() {

FILE: app/src/main/java/com/example/project/views/common/cursorloader/CursorAdapterWithCursorLoader.java
  class CursorAdapterWithCursorLoader (line 23) | @EBean
    method getCursorAdapter (line 29) | public abstract CursorAdapter getCursorAdapter();
    method getLoaderId (line 34) | public abstract int getLoaderId();
    method loadCursor (line 39) | public abstract Cursor loadCursor();
    method start (line 44) | public void start() {
    method createLoaderCallback (line 55) | private LoaderManager.LoaderCallbacks<Cursor> createLoaderCallback() {

FILE: app/src/main/java/com/example/project/views/common/mvp/BaseActivityPresenter.java
  class BaseActivityPresenter (line 11) | @EActivity
    method baseOnAfterViews (line 19) | @AfterViews
    method onResume (line 27) | @Override
    method onPause (line 33) | @Override
    method onDestroy (line 39) | @Override
    method onViewCreated (line 47) | @Override
    method onViewResume (line 51) | @Override
    method onViewPause (line 55) | @Override
    method onViewDestroy (line 59) | @Override

FILE: app/src/main/java/com/example/project/views/common/mvp/BaseFragmentPresenter.java
  class BaseFragmentPresenter (line 11) | @EFragment
    method onActivityCreated (line 16) | @Override
    method onResume (line 22) | @Override
    method onPause (line 28) | @Override
    method onDestroy (line 34) | @Override
    method onViewCreated (line 42) | @Override
    method onViewResume (line 46) | @Override
    method onViewPause (line 50) | @Override
    method onViewDestroy (line 54) | @Override

FILE: app/src/main/java/com/example/project/views/common/mvp/BasePresenter.java
  type BasePresenter (line 9) | public interface BasePresenter {
    method onViewCreated (line 17) | void onViewCreated();
    method onViewResume (line 24) | void onViewResume();
    method onViewPause (line 34) | void onViewPause();
    method onViewDestroy (line 41) | void onViewDestroy();

FILE: app/src/main/java/com/example/project/views/common/mvp/BaseView.java
  type BaseView (line 3) | public interface BaseView {

FILE: app/src/main/java/com/example/project/views/common/testwrapper/ViewFinisher.java
  class ViewFinisher (line 8) | @EBean
    method finish (line 14) | public void finish() {

FILE: app/src/main/java/com/example/project/views/contact_details/DetailActivity.java
  class DetailActivity (line 10) | @EActivity(R.layout.activity_detail)
    method onViewCreated (line 19) | @Override

FILE: app/src/main/java/com/example/project/views/contact_details/DetailActivityIntent.java
  class DetailActivityIntent (line 8) | @EBean
    method start (line 14) | public void start(long contactId) {

FILE: app/src/main/java/com/example/project/views/contact_details/DetailFragment.java
  class DetailFragment (line 8) | @EFragment(R.layout.fragment_detail)
    method onShowContact (line 11) | public void onShowContact(long contactId) {

FILE: app/src/main/java/com/example/project/views/contact_details/DetailView.java
  class DetailView (line 5) | public class DetailView implements BaseView {

FILE: app/src/main/java/com/example/project/views/contact_edit/EditActivity.java
  class EditActivity (line 12) | @EActivity(R.layout.activity_edit)
    method onViewCreated (line 24) | @Override
    method onEditConfirmed (line 30) | @Override

FILE: app/src/main/java/com/example/project/views/contact_edit/EditActivityIntent.java
  class EditActivityIntent (line 8) | @EBean
    method start (line 14) | public void start(long contactId) {
    method start (line 18) | public void start() {

FILE: app/src/main/java/com/example/project/views/contact_edit/EditConfirmedListener.java
  type EditConfirmedListener (line 3) | public interface EditConfirmedListener {
    method onEditConfirmed (line 4) | void onEditConfirmed();

FILE: app/src/main/java/com/example/project/views/contact_edit/EditFragment.java
  class EditFragment (line 18) | @EFragment(R.layout.fragment_edit)
    method setEditConfirmedListener (line 33) | public void setEditConfirmedListener(EditConfirmedListener editConfirm...
    method onShowContact (line 37) | public void onShowContact(long contactId) {
    method loadAndShowContactDetails (line 44) | private void loadAndShowContactDetails() {
    method onClickConfirm (line 51) | @Click(R.id.confirm)
    method createOrUpdateContact (line 61) | @Background
    method dateString (line 66) | private String dateString(Date date) {
    method date (line 74) | private Date date(String dateString) {

FILE: app/src/main/java/com/example/project/views/contact_edit/EditView.java
  class EditView (line 11) | @EBean
    method setFirstName (line 23) | public void setFirstName(String input) {
    method getFirstName (line 27) | public String getFirstName() {
    method setLastName (line 31) | public void setLastName(String input) {
    method getLastName (line 35) | public String getLastName() {
    method setBirthDate (line 39) | public void setBirthDate(String input) {
    method getBirthDate (line 43) | public String getBirthDate() {

FILE: app/src/main/java/com/example/project/views/contact_list/ContactAdapter.java
  class ContactAdapter (line 15) | @EBean
    method ContactAdapter (line 20) | public ContactAdapter(Context context) {
    method newView (line 24) | @Override
    method bindView (line 29) | @Override

FILE: app/src/main/java/com/example/project/views/contact_list/ContactAdapterLoader.java
  class ContactAdapterLoader (line 13) | @EBean
    method getCursorAdapter (line 22) | @Override
    method getLoaderId (line 27) | @Override
    method loadCursor (line 32) | @Override

FILE: app/src/main/java/com/example/project/views/contact_list/ContactListActivity.java
  class ContactListActivity (line 22) | @EActivity(R.layout.activity_main)
    method onViewCreated (line 44) | @Override
    method onCreateContact (line 49) | @OptionsItem(R.id.action_add_contact)
    method onSyncContacts (line 54) | @OptionsItem(R.id.action_sync_contacts)
    method showSyncResult (line 65) | @UiThread(propagation = UiThread.Propagation.REUSE)
    method onShowContact (line 76) | @Override

FILE: app/src/main/java/com/example/project/views/contact_list/ContactListActivityIntent.java
  class ContactListActivityIntent (line 8) | @EBean
    method start (line 14) | public void start() {

FILE: app/src/main/java/com/example/project/views/contact_list/ContactListFragment.java
  class ContactListFragment (line 11) | @EFragment(R.layout.fragment_list)
    method onViewCreated (line 22) | @Override
    method onContactClick (line 28) | @ItemClick(R.id.listView)
    method setShowContactListener (line 33) | public void setShowContactListener(ShowContactListener showContactList...

FILE: app/src/main/java/com/example/project/views/contact_list/ContactListView.java
  class ContactListView (line 12) | @EBean
    method showContacts (line 18) | public void showContacts(ListAdapter listAdapter) {

FILE: app/src/main/java/com/example/project/views/contact_list/ShowContactListener.java
  type ShowContactListener (line 3) | public interface ShowContactListener {
    method onShowContact (line 4) | void onShowContact(long contact);

FILE: app/src/main/java/com/example/project/views/start/StartActivity.java
  class StartActivity (line 9) | @EActivity
    method onViewResume (line 15) | @Override

FILE: app/src/test/java/com/example/project/RoboTestCase.java
  class RoboTestCase (line 16) | @RunWith(RobolectricGradleTestRunner.class)
    method roboSetup (line 22) | @Before
    method finishRobolectricTest (line 27) | @After
    method resetSingleton (line 32) | private void resetSingleton(Class clazz, String fieldName) {

FILE: app/src/test/java/com/example/project/business/contact/QueryContactListFunctionTest.java
  class QueryContactListFunctionTest (line 15) | @RunWith(MockitoJUnitRunner.class)
    method shouldLoadAllContacts (line 27) | @Test

FILE: app/src/test/java/com/example/project/database/contact/AddressDbInsertTest.java
  class AddressDbInsertTest (line 14) | public class AddressDbInsertTest extends RoboTestCase {
    method setup (line 29) | @Before
    method insert (line 36) | @Test
    method insert_contactId_isMandatory (line 42) | @Test(expected = SQLiteException.class)
    method insert_contactId_mustExist (line 48) | @Test(expected = SQLiteException.class)
    method insert_street_isNullable (line 56) | @Test
    method insert_number_isNullable (line 63) | @Test
    method insert_city_isNullable (line 70) | @Test
    method insert_country_isNullable (line 77) | @Test
    method insert_state_isNullable (line 84) | @Test
    method insert_postalcode_isNullable (line 91) | @Test
    method thenInsertWasSuccessful (line 98) | private void thenInsertWasSuccessful() {
    method givenContactReference (line 102) | private void givenContactReference() {
    method whenAddressIsInserted (line 107) | private void whenAddressIsInserted(AddressContentValues contentValues) {
    method givenAddressAtDatabase (line 111) | private void givenAddressAtDatabase(AddressContentValues contentValues) {

FILE: app/src/test/java/com/example/project/database/contact/AddressDbTest.java
  class AddressDbTest (line 13) | public class AddressDbTest extends RoboTestCase {
    method setup (line 28) | @Before
    method queryById (line 35) | @Test
    method queryById_correctIds (line 42) | @Test
    method givenContactReference (line 56) | private void givenContactReference() {
    method givenAddressAtDatabase (line 61) | private void givenAddressAtDatabase(AddressContentValues contentValues) {

FILE: app/src/test/java/com/example/project/database/contact/ContactDbInsertTest.java
  class ContactDbInsertTest (line 16) | public class ContactDbInsertTest extends RoboTestCase {
    method setup (line 26) | @Before
    method insert (line 31) | @Test
    method insert_firstname_isNullable (line 37) | @Test
    method insert_lastname_isNullable (line 44) | @Test
    method insert_firstOrLastname_isMandatory (line 51) | @Test(expected = SQLiteException.class)
    method insert_birthdate_isNullable (line 58) | @Test
    method thenInsertWasSuccessful (line 65) | private void thenInsertWasSuccessful() {
    method whenContactIsInserted (line 69) | private void whenContactIsInserted(ContactContentValues contentValues) {

FILE: app/src/test/java/com/example/project/database/contact/ContactDbTest.java
  class ContactDbTest (line 15) | public class ContactDbTest extends RoboTestCase {
    method setup (line 25) | @Before
    method queryAll (line 30) | @Test
    method givenContactAtDatabase (line 38) | private void givenContactAtDatabase(ContactContentValues contentValues) {

FILE: app/src/test/java/com/example/project/views/contact_edit/EditActivityTest.java
  class EditActivityTest (line 13) | @RunWith(MockitoJUnitRunner.class)
    method testOnViewCreated_shouldInitDetailFragment (line 27) | @Test
    method testOnEditConfirmed_shouldFinishTheActivity (line 35) | @Test

FILE: app/src/test/java/com/example/project/views/contact_edit/EditFragmentTest.java
  class EditFragmentTest (line 12) | @RunWith(MockitoJUnitRunner.class)
    method testOnShowContact_shouldLoadContactDetails (line 25) | @Test
    method testOnClickConfirm_shouldSaveContact (line 30) | @Test

FILE: app/src/test/java/com/example/project/views/contact_list/ContactListActivityTest.java
  class ContactListActivityTest (line 16) | @RunWith(MockitoJUnitRunner.class)
    method testOnCreateContact (line 36) | @Test
    method testOnShowContact_portrait (line 42) | @Test
    method testOnShowContact_landscape (line 49) | @Test
    method testOnViewCreated_shouldRegisterSelfAsShowContactListener (line 56) | @Test
    method thenDetailAreShownInNewActivity (line 62) | private void thenDetailAreShownInNewActivity(long expectedContactId) {
    method thenDetailsAreShownInDetailFragment (line 66) | private void thenDetailsAreShownInDetailFragment(long expectedContactI...
    method givenPortraitMode (line 70) | private void givenPortraitMode() {
    method givenLandscapeMode (line 74) | private void givenLandscapeMode() {
    method thenEditActivityIsStartedInCreationMode (line 78) | private void thenEditActivityIsStartedInCreationMode() {
    method whenClickCreateContact (line 82) | private void whenClickCreateContact() {

FILE: app/src/test/java/com/example/project/views/contact_list/ContactListFragmentTest.java
  class ContactListFragmentTest (line 13) | @RunWith(MockitoJUnitRunner.class)
    method setup (line 28) | @Before
    method testOnViewCreated_shouldStartLoadingContacts (line 33) | @Test

FILE: app/src/test/java/com/example/project/views/start/StartActivityTest.java
  class StartActivityTest (line 13) | @RunWith(MockitoJUnitRunner.class)
    method viewIsStarted (line 22) | @Test
    method thenNextActivityShouldBeStarted (line 28) | private void thenNextActivityShouldBeStarted() {

FILE: appCt/src/test/java/android/database/ShadowContentObservable.java
  class ShadowContentObservable (line 11) | @Implements(ContentObservable.class)
    method dispatchChange (line 25) | @Implementation

FILE: appCt/src/test/java/com/example/project/RobolectricTestCase.java
  class RobolectricTestCase (line 20) | @RunWith(CostomRobolectricTestRunner.class)
    method roboSetup (line 26) | @Before
    method finishRobolectricTest (line 33) | @After
    method resetSingleton (line 38) | private void resetSingleton(Class clazz, String fieldName) {

FILE: appCt/src/test/java/com/example/project/robolectric/CostomRobolectricTestRunner.java
  class CostomRobolectricTestRunner (line 21) | public class CostomRobolectricTestRunner extends RobolectricTestRunner {
    method CostomRobolectricTestRunner (line 23) | public CostomRobolectricTestRunner(Class<?> testClass) throws Initiali...
    method mkdir (line 45) | private void mkdir(String path) {
    method createClassLoaderConfig (line 55) | public InstrumentationConfiguration createClassLoaderConfig() {

FILE: appCt/src/test/java/com/example/project/robolectric/RoboButton.java
  class RoboButton (line 8) | public class RoboButton {
    method RoboButton (line 12) | public RoboButton(Activity activity, int resourceId) {
    method click (line 16) | public void click() {

FILE: appCt/src/test/java/com/example/project/robolectric/RoboListView.java
  class RoboListView (line 8) | public class RoboListView {
    method RoboListView (line 12) | public RoboListView(Activity activity, int resourceId) {
    method count (line 16) | public int count() {
    method entry (line 21) | public RoboListViewEntry entry(int pos) {

FILE: appCt/src/test/java/com/example/project/robolectric/RoboListViewEntry.java
  class RoboListViewEntry (line 8) | public class RoboListViewEntry {
    method RoboListViewEntry (line 13) | public RoboListViewEntry(ListView listView, View listViewEntry) {
    method click (line 18) | public void click() {

FILE: appCt/src/test/java/com/example/project/robolectric/RoboTextEdit.java
  class RoboTextEdit (line 6) | public class RoboTextEdit {
    method RoboTextEdit (line 10) | public RoboTextEdit(Activity activity, int resourceId) {
    method insert (line 14) | public void insert(String text) {

FILE: appCt/src/test/java/com/example/project/robolectric/ShadowBackgroundExecutor.java
  class ShadowBackgroundExecutor (line 23) | @Implements(BackgroundExecutor.class)
    method execute (line 28) | @Implementation
    method cancelAll (line 46) | public static synchronized void cancelAll(String id, boolean mayInterr...
    method wrapAsCancelableTask (line 51) | private static Runnable wrapAsCancelableTask(final BackgroundExecutor....
    method extractTaskId (line 64) | private static String extractTaskId(BackgroundExecutor.Task task) {

FILE: appCt/src/test/java/com/example/project/testdata/TestContactData.java
  class TestContactData (line 11) | public class TestContactData {
    method createRandomeContacts (line 13) | public static void createRandomeContacts(int count) {

FILE: appCt/src/test/java/com/example/project/views/contac_list/ContactListSpec.java
  class ContactListSpec (line 24) | public class ContactListSpec extends RobolectricTestCase {
    method showContactDetails (line 28) | @Test
    method openCreateContact (line 35) | @Test
    method refreshContactListOnNewContact (line 42) | @Test
    method syncContacts (line 49) | @Test
    method syncContactsFail (line 57) | @Test
    method syncContactsWithConnectionLost (line 65) | @Test
    method givenContactsRequestAnswerWithFault (line 73) | private void givenContactsRequestAnswerWithFault(Fault fault) {
    method givenContactsRequestAnswerWithError (line 77) | private void givenContactsRequestAnswerWithError(int statusCode) {
    method thenToastWasShown (line 81) | private void thenToastWasShown(String expectedMessage) {
    method whenClickSyncContact (line 85) | private void whenClickSyncContact() {
    method thenPageHasContacts (line 89) | private void thenPageHasContacts() {
    method whenInsertNewContact (line 93) | private void whenInsertNewContact() {
    method thenCreateNewContactIsShownInNewPage (line 97) | private void thenCreateNewContactIsShownInNewPage() {
    method whenClickCreateContact (line 103) | private void whenClickCreateContact() {
    method whenClickListItem (line 107) | private void whenClickListItem() {
    method thenDetailsAreShownInNewPage (line 111) | private void thenDetailsAreShownInNewPage() {
    method givenPageWithoutContacts (line 116) | private void givenPageWithoutContacts() {
    method givenPageHasContacts (line 121) | private void givenPageHasContacts() {

FILE: appCt/src/test/java/com/example/project/views/contac_list/RoboContactListPage.java
  class RoboContactListPage (line 15) | public class RoboContactListPage {
    method startPage (line 19) | public void startPage() {
    method list (line 23) | public RoboListView list() {
    method createContact (line 27) | public Menu createContact() {
    method syncContacts (line 31) | public Menu syncContacts() {
    method nextStartedActivity (line 35) | public Intent nextStartedActivity() {
    class Menu (line 39) | public class Menu {
      method Menu (line 42) | public Menu(int resourceId) {
      method click (line 46) | public void click() {

FILE: appCt/src/test/java/com/example/project/views/contact_details/ContactDetailSpec.java
  class ContactDetailSpec (line 7) | @Ignore

FILE: appCt/src/test/java/com/example/project/views/contact_edit/ContactCreateSpec.java
  class ContactCreateSpec (line 12) | public class ContactCreateSpec extends RobolectricTestCase {
    method testShouldCreateContact (line 16) | @Test
    method thenDatabaseHasContacts (line 24) | private void thenDatabaseHasContacts(int expectedCount) {
    method thenCreateContactViewIsClosed (line 29) | private void thenCreateContactViewIsClosed() {
    method whenCreateContact (line 33) | private void whenCreateContact() {
    method givenDatabaseHasNoContacts (line 41) | private void givenDatabaseHasNoContacts() {

FILE: appCt/src/test/java/com/example/project/views/contact_edit/ContactEditSpec.java
  class ContactEditSpec (line 7) | @Ignore

FILE: appCt/src/test/java/com/example/project/views/contact_edit/RoboContactEditPage.java
  class RoboContactEditPage (line 9) | public class RoboContactEditPage {
    method startPage (line 12) | public void startPage() {
    method firstName (line 16) | public RoboTextEdit firstName() {
    method lastName (line 20) | public RoboTextEdit lastName() {
    method birthDate (line 24) | public RoboTextEdit birthDate() {
    method confirm (line 28) | public RoboButton confirm() {

FILE: appIt/src/main/java/com/example/project/EspressoTestCase.java
  class EspressoTestCase (line 21) | @RunWith(AndroidJUnit4.class)
    method setupEspresso (line 27) | @Before
    method clearDatabase (line 35) | private void clearDatabase() {
    method avoidLockScreen (line 40) | private void avoidLockScreen() {
    method getGenericActivityClass (line 56) | private Class<A> getGenericActivityClass() {

FILE: appIt/src/main/java/com/example/project/espresso/CurrentActivity.java
  class CurrentActivity (line 10) | public class CurrentActivity {
    method get (line 12) | @SuppressWarnings("unchecked")

FILE: appIt/src/main/java/com/example/project/espresso/EspButton.java
  class EspButton (line 8) | public class EspButton<P> {
    method EspButton (line 12) | public EspButton(int resourceId) {
    method click (line 16) | public P click() {

FILE: appIt/src/main/java/com/example/project/espresso/EspListView.java
  class EspListView (line 13) | public class EspListView {
    method EspListView (line 16) | public EspListView(int resourceId) {
    method count (line 20) | public int count() {

FILE: appIt/src/main/java/com/example/project/espresso/EspMenuItem.java
  class EspMenuItem (line 8) | public class EspMenuItem<P> {
    method EspMenuItem (line 12) | public EspMenuItem(int resourceId) {
    method click (line 16) | public P click() {

FILE: appIt/src/main/java/com/example/project/espresso/EspTextEdit.java
  class EspTextEdit (line 7) | public class EspTextEdit {
    method EspTextEdit (line 11) | public EspTextEdit(int resourceId) {
    method insert (line 15) | public void insert(String text) {

FILE: appIt/src/main/java/com/example/project/pages/EspContactListPage.java
  class EspContactListPage (line 7) | public class EspContactListPage {
    method createContact (line 9) | public EspMenuItem<EspEditContactPage> createContact() {
    method syncContacts (line 19) | public EspMenuItem<EspContactListPage> syncContacts() {
    method contactList (line 29) | public EspListView contactList() {

FILE: appIt/src/main/java/com/example/project/pages/EspEditContactPage.java
  class EspEditContactPage (line 7) | public class EspEditContactPage {
    method firstName (line 9) | public EspTextEdit firstName() {
    method lastName (line 13) | public EspTextEdit lastName() {
    method confirm (line 17) | public EspButton<EspContactListPage> confirm() {
    method birthDate (line 27) | public EspTextEdit birthDate() {

FILE: appIt/src/main/java/com/example/project/test/CreateContactTest.java
  class CreateContactTest (line 12) | public class CreateContactTest extends EspressoTestCase<ContactListActiv...
    method testCreateNewContact (line 16) | @Test
    method thenListHasContacts (line 23) | private void thenListHasContacts() {
    method whenAddContact (line 27) | private void whenAddContact() {
    method givenListHasNoContacts (line 35) | private void givenListHasNoContacts() {

FILE: appIt/src/main/java/com/example/project/test/SyncContactsTest.java
  class SyncContactsTest (line 20) | public class SyncContactsTest extends EspressoTestCase<ContactListActivi...
    method testSyncContacts (line 24) | @Test
    method thenListHasContacts (line 34) | private void thenListHasContacts() {
    method whenSyncContacts (line 38) | private void whenSyncContacts() {
    method givenListHasNoContacts (line 42) | private void givenListHasNoContacts() {
Condensed preview — 171 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (262K chars).
[
  {
    "path": ".gitignore",
    "chars": 87,
    "preview": ".DS_Store\n.idea\n.gradle\n*~\n*.iml\n**/build\nGenerateJsonRestModel/gen/*\nlocal.properties\n"
  },
  {
    "path": "app/build.generate-database.gradle",
    "chars": 951,
    "preview": "def dbSchemaPath = \"src/main/json/database/schema\"\ndef dbClassesPath = \"src/gen/java\"\nandroid.sourceSets.main.java.srcDi"
  },
  {
    "path": "app/build.generate-json-objects.gradle",
    "chars": 410,
    "preview": "apply plugin: 'jsonschema2pojo'\n\ndependencies {\n    compile 'com.fasterxml.jackson.core:jackson-databind:2.6.1'\n    comp"
  },
  {
    "path": "app/build.gradle",
    "chars": 4832,
    "preview": "buildscript {\n    repositories {\n        jcenter()\n    }\n    dependencies {\n        // code generation support for andro"
  },
  {
    "path": "app/build.jacoco-test-report.gradle",
    "chars": 1352,
    "preview": "apply plugin: \"jacoco\"\n\njacoco {\n    toolVersion = projectJacocoVersion\n}\n\ntask jacocoTestReport(type: JacocoReport /*, "
  },
  {
    "path": "app/build.robolectric.gradle",
    "chars": 764,
    "preview": "dependencies {\n    testCompile 'org.robolectric:shadows-support-v4:3.0'\n    testCompile 'org.robolectric:robolectric:3.0"
  },
  {
    "path": "app/build.wiremock-replace-ip.gradle",
    "chars": 2161,
    "preview": "// may be used to check if wiremock is running\nProcess p1 = Runtime.getRuntime().exec(\"curl \" + obtainCurrentIpAddress()"
  },
  {
    "path": "app/lint.xml",
    "chars": 130,
    "preview": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<lint>\n    <issue id=\"all\">\n        <ignore regexp=\"src/gen/java/*\" />\n    </issu"
  },
  {
    "path": "app/proguard-rules.pro",
    "chars": 714,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /U"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/ExampleProvider.java",
    "chars": 6097,
    "preview": "package com.example.project.database.provider;\n\nimport java.util.Arrays;\n\nimport android.content.ContentValues;\nimport a"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/ExampleSQLiteOpenHelper.java",
    "chars": 5390,
    "preview": "package com.example.project.database.provider;\n\nimport android.annotation.TargetApi;\nimport android.content.Context;\nimp"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/ExampleSQLiteOpenHelperCallbacks.java",
    "chars": 1431,
    "preview": "package com.example.project.database.provider;\n\nimport android.content.Context;\nimport android.database.sqlite.SQLiteDat"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/address/AddressColumns.java",
    "chars": 2207,
    "preview": "package com.example.project.database.provider.address;\n\nimport android.net.Uri;\nimport android.provider.BaseColumns;\n\nim"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/address/AddressContentValues.java",
    "chars": 2863,
    "preview": "package com.example.project.database.provider.address;\n\nimport java.util.Date;\n\nimport android.content.ContentResolver;\n"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/address/AddressCursor.java",
    "chars": 3398,
    "preview": "package com.example.project.database.provider.address;\n\nimport java.util.Date;\n\nimport android.database.Cursor;\nimport a"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/address/AddressModel.java",
    "chars": 1142,
    "preview": "package com.example.project.database.provider.address;\n\nimport com.example.project.database.provider.base.BaseModel;\n\nim"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/address/AddressSelection.java",
    "chars": 11569,
    "preview": "package com.example.project.database.provider.address;\n\nimport java.util.Date;\n\nimport android.content.ContentResolver;\n"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/base/AbstractContentValues.java",
    "chars": 843,
    "preview": "package com.example.project.database.provider.base;\n\nimport android.content.ContentResolver;\nimport android.content.Cont"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/base/AbstractCursor.java",
    "chars": 2335,
    "preview": "package com.example.project.database.provider.base;\n\nimport java.util.Date;\nimport java.util.HashMap;\n\nimport android.da"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/base/AbstractSelection.java",
    "chars": 9756,
    "preview": "package com.example.project.database.provider.base;\n\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/base/BaseContentProvider.java",
    "chars": 7947,
    "preview": "package com.example.project.database.provider.base;\n\nimport java.lang.reflect.Field;\nimport java.util.ArrayList;\nimport "
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/base/BaseModel.java",
    "chars": 84,
    "preview": "package com.example.project.database.provider.base;\n\npublic interface BaseModel {\n}\n"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/contact/ContactColumns.java",
    "chars": 1679,
    "preview": "package com.example.project.database.provider.contact;\n\nimport android.net.Uri;\nimport android.provider.BaseColumns;\n\nim"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/contact/ContactContentValues.java",
    "chars": 2344,
    "preview": "package com.example.project.database.provider.contact;\n\nimport java.util.Date;\n\nimport android.content.ContentResolver;\n"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/contact/ContactCursor.java",
    "chars": 1661,
    "preview": "package com.example.project.database.provider.contact;\n\nimport java.util.Date;\n\nimport android.database.Cursor;\nimport a"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/contact/ContactModel.java",
    "chars": 825,
    "preview": "package com.example.project.database.provider.contact;\n\nimport com.example.project.database.provider.base.BaseModel;\n\nim"
  },
  {
    "path": "app/src/gen/java/com/example/project/database/provider/contact/ContactSelection.java",
    "chars": 5464,
    "preview": "package com.example.project.database.provider.contact;\n\nimport java.util.Date;\n\nimport android.content.ContentResolver;\n"
  },
  {
    "path": "app/src/gen/java/com/example/project/network/json/ContactJson.java",
    "chars": 3592,
    "preview": "\npackage com.example.project.network.json;\n\nimport java.util.HashMap;\nimport java.util.Map;\nimport javax.annotation.Gene"
  },
  {
    "path": "app/src/gen/java/com/example/project/network/json/ContactListJson.java",
    "chars": 2379,
    "preview": "\npackage com.example.project.network.json;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "chars": 1766,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "app/src/main/java/com/example/project/business/contact/CreateContactFunction.java",
    "chars": 902,
    "preview": "package com.example.project.business.contact;\n\nimport com.example.project.database.provider.contact.ContactContentValues"
  },
  {
    "path": "app/src/main/java/com/example/project/business/contact/DeleteContactFunction.java",
    "chars": 143,
    "preview": "package com.example.project.business.contact;\n\nimport org.androidannotations.annotations.EBean;\n\n@EBean\npublic class Del"
  },
  {
    "path": "app/src/main/java/com/example/project/business/contact/QueryContactFunction.java",
    "chars": 1864,
    "preview": "package com.example.project.business.contact;\n\nimport android.support.annotation.Nullable;\n\nimport com.example.project.d"
  },
  {
    "path": "app/src/main/java/com/example/project/business/contact/QueryContactListFunction.java",
    "chars": 433,
    "preview": "package com.example.project.business.contact;\n\nimport com.example.project.database.provider.contact.ContactCursor;\nimpor"
  },
  {
    "path": "app/src/main/java/com/example/project/business/contact/UpdateContactFunction.java",
    "chars": 143,
    "preview": "package com.example.project.business.contact;\n\nimport org.androidannotations.annotations.EBean;\n\n@EBean\npublic class Upd"
  },
  {
    "path": "app/src/main/java/com/example/project/business/contact_sync/SyncContactsFunction.java",
    "chars": 2657,
    "preview": "package com.example.project.business.contact_sync;\n\nimport com.example.project.business.contact.CreateContactFunction;\ni"
  },
  {
    "path": "app/src/main/java/com/example/project/database/ExampleDbProvider.java",
    "chars": 226,
    "preview": "package com.example.project.database;\n\nimport com.example.project.database.provider.ExampleProvider;\n\nimport org.android"
  },
  {
    "path": "app/src/main/java/com/example/project/database/ExampleSQLiteOpenHelperCallbacks.java",
    "chars": 1336,
    "preview": "package com.example.project.database;\n\nimport android.content.Context;\nimport android.database.sqlite.SQLiteDatabase;\n\ni"
  },
  {
    "path": "app/src/main/java/com/example/project/database/contact/AddressDb.java",
    "chars": 1236,
    "preview": "package com.example.project.database.contact;\n\nimport android.content.ContentUris;\nimport android.content.Context;\nimpor"
  },
  {
    "path": "app/src/main/java/com/example/project/database/contact/ContactDb.java",
    "chars": 1256,
    "preview": "package com.example.project.database.contact;\n\nimport android.content.ContentUris;\nimport android.content.Context;\nimpor"
  },
  {
    "path": "app/src/main/java/com/example/project/network/contact/ContactRestClient.java",
    "chars": 1116,
    "preview": "package com.example.project.network.contact;\n\nimport com.example.project.network.json.ContactListJson;\n\nimport org.andro"
  },
  {
    "path": "app/src/main/java/com/example/project/network/contact/RootUrlInterceptor.java",
    "chars": 1953,
    "preview": "package com.example.project.network.contact;\n\nimport android.content.Context;\n\nimport com.example.project.R;\n\nimport org"
  },
  {
    "path": "app/src/main/java/com/example/project/views/common/AppIdlingResources.java",
    "chars": 572,
    "preview": "package com.example.project.views.common;\n\nimport android.support.test.espresso.contrib.CountingIdlingResource;\n\nimport "
  },
  {
    "path": "app/src/main/java/com/example/project/views/common/cursorloader/CursorAdapterWithCursorLoader.java",
    "chars": 2760,
    "preview": "package com.example.project.views.common.cursorloader;\n\nimport android.database.Cursor;\nimport android.os.Bundle;\nimport"
  },
  {
    "path": "app/src/main/java/com/example/project/views/common/mvp/BaseActivityPresenter.java",
    "chars": 1293,
    "preview": "package com.example.project.views.common.mvp;\n\nimport android.support.v7.app.AppCompatActivity;\n\nimport org.androidannot"
  },
  {
    "path": "app/src/main/java/com/example/project/views/common/mvp/BaseFragmentPresenter.java",
    "chars": 1095,
    "preview": "package com.example.project.views.common.mvp;\n\nimport android.os.Bundle;\nimport android.support.v4.app.Fragment;\n\nimport"
  },
  {
    "path": "app/src/main/java/com/example/project/views/common/mvp/BasePresenter.java",
    "chars": 1381,
    "preview": "package com.example.project.views.common.mvp;\n\n/**\n * Base presenter for activities and fragments.\n *\n * Equalize the li"
  },
  {
    "path": "app/src/main/java/com/example/project/views/common/mvp/BaseView.java",
    "chars": 77,
    "preview": "package com.example.project.views.common.mvp;\n\npublic interface BaseView {\n}\n"
  },
  {
    "path": "app/src/main/java/com/example/project/views/common/testwrapper/ViewFinisher.java",
    "chars": 329,
    "preview": "package com.example.project.views.common.testwrapper;\n\nimport android.app.Activity;\n\nimport org.androidannotations.annot"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_details/DetailActivity.java",
    "chars": 630,
    "preview": "package com.example.project.views.contact_details;\n\nimport com.example.project.R;\nimport com.example.project.views.commo"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_details/DetailActivityIntent.java",
    "chars": 391,
    "preview": "package com.example.project.views.contact_details;\n\nimport android.content.Context;\n\nimport org.androidannotations.annot"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_details/DetailFragment.java",
    "chars": 359,
    "preview": "package com.example.project.views.contact_details;\n\nimport com.example.project.R;\nimport com.example.project.views.commo"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_details/DetailView.java",
    "chars": 155,
    "preview": "package com.example.project.views.contact_details;\n\nimport com.example.project.views.common.mvp.BaseView;\n\npublic class "
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_edit/EditActivity.java",
    "chars": 945,
    "preview": "package com.example.project.views.contact_edit;\n\nimport com.example.project.R;\nimport com.example.project.views.common.m"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_edit/EditActivityIntent.java",
    "chars": 464,
    "preview": "package com.example.project.views.contact_edit;\n\nimport android.content.Context;\n\nimport org.androidannotations.annotati"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_edit/EditConfirmedListener.java",
    "chars": 120,
    "preview": "package com.example.project.views.contact_edit;\n\npublic interface EditConfirmedListener {\n    void onEditConfirmed();\n}\n"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_edit/EditFragment.java",
    "chars": 2498,
    "preview": "package com.example.project.views.contact_edit;\n\nimport com.example.project.R;\nimport com.example.project.business.conta"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_edit/EditView.java",
    "chars": 1009,
    "preview": "package com.example.project.views.contact_edit;\n\nimport android.widget.EditText;\n\nimport com.example.project.R;\nimport c"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_list/ContactAdapter.java",
    "chars": 1291,
    "preview": "package com.example.project.views.contact_list;\n\nimport android.content.Context;\nimport android.database.Cursor;\nimport "
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_list/ContactAdapterLoader.java",
    "chars": 910,
    "preview": "package com.example.project.views.contact_list;\n\nimport android.database.Cursor;\nimport android.support.v4.widget.Cursor"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_list/ContactListActivity.java",
    "chars": 2727,
    "preview": "package com.example.project.views.contact_list;\n\nimport android.util.Log;\nimport android.widget.Toast;\n\nimport com.examp"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_list/ContactListActivityIntent.java",
    "chars": 363,
    "preview": "package com.example.project.views.contact_list;\n\nimport android.content.Context;\n\nimport org.androidannotations.annotati"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_list/ContactListFragment.java",
    "chars": 1056,
    "preview": "package com.example.project.views.contact_list;\n\nimport com.example.project.R;\nimport com.example.project.database.provi"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_list/ContactListView.java",
    "chars": 528,
    "preview": "package com.example.project.views.contact_list;\n\nimport android.widget.ListAdapter;\nimport android.widget.ListView;\n\nimp"
  },
  {
    "path": "app/src/main/java/com/example/project/views/contact_list/ShowContactListener.java",
    "chars": 128,
    "preview": "package com.example.project.views.contact_list;\n\npublic interface ShowContactListener {\n    void onShowContact(long cont"
  },
  {
    "path": "app/src/main/java/com/example/project/views/start/StartActivity.java",
    "chars": 522,
    "preview": "package com.example.project.views.start;\n\nimport com.example.project.views.common.mvp.BaseActivityPresenter;\nimport com."
  },
  {
    "path": "app/src/main/json/database/schema/_config.json",
    "chars": 464,
    "preview": "{\n  \"syntaxVersion\": 3,\n  \"projectPackageId\": \"com.example.project\",\n  \"authority\": \"com.example.project\",\n  \"providerJa"
  },
  {
    "path": "app/src/main/json/database/schema/address.json",
    "chars": 702,
    "preview": "{\n  \"fields\": [\n    {\n      \"name\": \"contact_id\",\n      \"type\": \"Long\",\n      \"nullable\": false,\n      \"foreignKey\": {\n "
  },
  {
    "path": "app/src/main/json/database/schema/contact.json",
    "chars": 586,
    "preview": "{\n  \"fields\": [\n    {\n      \"name\": \"uid\",\n      \"type\": \"String\",\n      \"nullable\": true\n    },\n    {\n      \"name\": \"fi"
  },
  {
    "path": "app/src/main/json/network/schema/contactJson.json",
    "chars": 235,
    "preview": "{\n  \"description\": \"Simple single contact.\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"id\": { \"type\": \"string\" },\n    \""
  },
  {
    "path": "app/src/main/json/network/schema/contactListJson.json",
    "chars": 200,
    "preview": "{\n  \"description\": \"Collection of contacts.\",\n  \"type\": \"object\",\n  \"properties\": {\n    \"contacts\" : {\n      \"type\" : \"a"
  },
  {
    "path": "app/src/main/res/layout/activity_detail.xml",
    "chars": 362,
    "preview": "<fragment xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n"
  },
  {
    "path": "app/src/main/res/layout/activity_edit.xml",
    "chars": 353,
    "preview": "<fragment xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n"
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "chars": 360,
    "preview": "<fragment xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n"
  },
  {
    "path": "app/src/main/res/layout/fragment_detail.xml",
    "chars": 1194,
    "preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/too"
  },
  {
    "path": "app/src/main/res/layout/fragment_edit.xml",
    "chars": 1943,
    "preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/too"
  },
  {
    "path": "app/src/main/res/layout/fragment_list.xml",
    "chars": 787,
    "preview": "<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/t"
  },
  {
    "path": "app/src/main/res/layout-land/activity_main.xml",
    "chars": 943,
    "preview": "<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/too"
  },
  {
    "path": "app/src/main/res/menu/menu_main.xml",
    "chars": 701,
    "preview": "<menu xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\""
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "chars": 211,
    "preview": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal"
  },
  {
    "path": "app/src/main/res/values/string_api_url.xml",
    "chars": 129,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"const_wiremock_ip\">#const_wiremock_ip#</string>\n</r"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "chars": 260,
    "preview": "<resources>\n    <string name=\"app_name\">InitialAndroidProject</string>\n    <string name=\"hello_world\">Hello world!</stri"
  },
  {
    "path": "app/src/main/res/values/strings_details.xml",
    "chars": 260,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n\n    <string name=\"first_name\">First Name</string>\n    <string name="
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "chars": 194,
    "preview": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar"
  },
  {
    "path": "app/src/main/res/values-w820dp/dimens.xml",
    "chars": 358,
    "preview": "<resources>\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n         (such as s"
  },
  {
    "path": "app/src/test/java/com/example/project/RoboTestCase.java",
    "chars": 1110,
    "preview": "package com.example.project;\n\nimport android.content.Context;\n\nimport com.example.project.database.provider.ExampleSQLit"
  },
  {
    "path": "app/src/test/java/com/example/project/business/contact/QueryContactListFunctionTest.java",
    "chars": 916,
    "preview": "package com.example.project.business.contact;\n\nimport com.example.project.database.provider.contact.ContactCursor;\nimpor"
  },
  {
    "path": "app/src/test/java/com/example/project/database/contact/AddressDbInsertTest.java",
    "chars": 3389,
    "preview": "package com.example.project.database.contact;\n\nimport android.database.sqlite.SQLiteException;\n\nimport com.example.proje"
  },
  {
    "path": "app/src/test/java/com/example/project/database/contact/AddressDbTest.java",
    "chars": 2069,
    "preview": "package com.example.project.database.contact;\n\nimport com.example.project.RoboTestCase;\nimport com.example.project.datab"
  },
  {
    "path": "app/src/test/java/com/example/project/database/contact/ContactDbInsertTest.java",
    "chars": 1951,
    "preview": "package com.example.project.database.contact;\n\n\nimport android.database.sqlite.SQLiteException;\n\nimport com.example.proj"
  },
  {
    "path": "app/src/test/java/com/example/project/database/contact/ContactDbTest.java",
    "chars": 1143,
    "preview": "package com.example.project.database.contact;\n\n\nimport com.example.project.RoboTestCase;\nimport com.example.project.data"
  },
  {
    "path": "app/src/test/java/com/example/project/views/contact_edit/EditActivityTest.java",
    "chars": 1030,
    "preview": "package com.example.project.views.contact_edit;\n\nimport com.example.project.views.common.testwrapper.ViewFinisher;\n\nimpo"
  },
  {
    "path": "app/src/test/java/com/example/project/views/contact_edit/EditFragmentTest.java",
    "chars": 718,
    "preview": "package com.example.project.views.contact_edit;\n\nimport org.junit.Ignore;\nimport org.junit.Test;\nimport org.junit.runner"
  },
  {
    "path": "app/src/test/java/com/example/project/views/contact_list/ContactListActivityTest.java",
    "chars": 2444,
    "preview": "package com.example.project.views.contact_list;\n\nimport com.example.project.views.contact_details.DetailActivityIntent;\n"
  },
  {
    "path": "app/src/test/java/com/example/project/views/contact_list/ContactListFragmentTest.java",
    "chars": 970,
    "preview": "package com.example.project.views.contact_list;\n\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner"
  },
  {
    "path": "app/src/test/java/com/example/project/views/start/StartActivityTest.java",
    "chars": 768,
    "preview": "package com.example.project.views.start;\n\nimport com.example.project.views.contact_list.ContactListActivityIntent;\n\nimpo"
  },
  {
    "path": "appCt/build.gradle",
    "chars": 2477,
    "preview": "buildscript {\n    repositories {\n        jcenter()\n    }\n    dependencies {\n        // support to get app module under t"
  },
  {
    "path": "appCt/build.jacoco-test-report.gradle",
    "chars": 1001,
    "preview": "// apply plugin: \"jacoco\" must be before the plugin: 'android-test' declaration\n\njacoco {\n    toolVersion = projectJacoc"
  },
  {
    "path": "appCt/build.novoda-android-studio.gradle",
    "chars": 1974,
    "preview": "// workaround force compile the test classes in android studio\ntasks.testClasses.dependsOn(tasks.testDebugClasses)\n\n// w"
  },
  {
    "path": "appCt/build.robolectric.gradle",
    "chars": 907,
    "preview": "dependencies {\n    testCompile('org.robolectric:shadows-support-v4:3.0') {\n        exclude module: \"robolectric\"\n       "
  },
  {
    "path": "appCt/src/test/java/android/database/ShadowContentObservable.java",
    "chars": 1341,
    "preview": "package android.database;\n\nimport android.net.Uri;\n\nimport org.robolectric.annotation.Implementation;\nimport org.robolec"
  },
  {
    "path": "appCt/src/test/java/com/example/project/RobolectricTestCase.java",
    "chars": 1536,
    "preview": "package com.example.project;\n\nimport android.content.Context;\nimport android.database.ShadowContentObservable;\n\nimport c"
  },
  {
    "path": "appCt/src/test/java/com/example/project/robolectric/CostomRobolectricTestRunner.java",
    "chars": 2456,
    "preview": "package com.example.project.robolectric;\n\nimport com.example.project.BuildConfig;\n\nimport org.androidannotations.api.Bac"
  },
  {
    "path": "appCt/src/test/java/com/example/project/robolectric/RoboButton.java",
    "chars": 421,
    "preview": "package com.example.project.robolectric;\n\nimport android.app.Activity;\nimport android.widget.Button;\n\nimport static org."
  },
  {
    "path": "appCt/src/test/java/com/example/project/robolectric/RoboListView.java",
    "chars": 623,
    "preview": "package com.example.project.robolectric;\n\nimport android.app.Activity;\nimport android.widget.ListView;\n\nimport org.robol"
  },
  {
    "path": "appCt/src/test/java/com/example/project/robolectric/RoboListViewEntry.java",
    "chars": 556,
    "preview": "package com.example.project.robolectric;\n\nimport android.view.View;\nimport android.widget.ListView;\n\nimport static org.a"
  },
  {
    "path": "appCt/src/test/java/com/example/project/robolectric/RoboTextEdit.java",
    "chars": 368,
    "preview": "package com.example.project.robolectric;\n\nimport android.app.Activity;\nimport android.widget.EditText;\n\npublic class Rob"
  },
  {
    "path": "appCt/src/test/java/com/example/project/robolectric/ShadowBackgroundExecutor.java",
    "chars": 2727,
    "preview": "package com.example.project.robolectric;\n\nimport org.androidannotations.api.BackgroundExecutor;\nimport org.assertj.core."
  },
  {
    "path": "appCt/src/test/java/com/example/project/testdata/TestContactData.java",
    "chars": 846,
    "preview": "package com.example.project.testdata;\n\nimport com.example.project.database.provider.contact.ContactContentValues;\nimport"
  },
  {
    "path": "appCt/src/test/java/com/example/project/views/contac_list/ContactListSpec.java",
    "chars": 4162,
    "preview": "package com.example.project.views.contac_list;\n\nimport android.content.Intent;\n\nimport com.example.project.RobolectricTe"
  },
  {
    "path": "appCt/src/test/java/com/example/project/views/contac_list/RoboContactListPage.java",
    "chars": 1344,
    "preview": "package com.example.project.views.contac_list;\n\nimport android.content.Intent;\n\nimport com.example.project.R;\nimport com"
  },
  {
    "path": "appCt/src/test/java/com/example/project/views/contact_details/ContactDetailSpec.java",
    "chars": 199,
    "preview": "package com.example.project.views.contact_details;\n\nimport com.example.project.RobolectricTestCase;\n\nimport org.junit.Ig"
  },
  {
    "path": "appCt/src/test/java/com/example/project/views/contact_edit/ContactCreateSpec.java",
    "chars": 1535,
    "preview": "package com.example.project.views.contact_edit;\n\nimport com.example.project.database.contact.ContactDb_;\nimport com.exam"
  },
  {
    "path": "appCt/src/test/java/com/example/project/views/contact_edit/ContactEditSpec.java",
    "chars": 194,
    "preview": "package com.example.project.views.contact_edit;\n\nimport com.example.project.RobolectricTestCase;\n\nimport org.junit.Ignor"
  },
  {
    "path": "appCt/src/test/java/com/example/project/views/contact_edit/RoboContactEditPage.java",
    "chars": 822,
    "preview": "package com.example.project.views.contact_edit;\n\nimport com.example.project.R;\nimport com.example.project.robolectric.Ro"
  },
  {
    "path": "appIt/build.gradle",
    "chars": 1832,
    "preview": "apply plugin: 'com.android.test'\n\nandroid {\n    compileSdkVersion projectAndroidVersion\n    buildToolsVersion projectAnd"
  },
  {
    "path": "appIt/src/main/AndroidManifest.xml",
    "chars": 481,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package="
  },
  {
    "path": "appIt/src/main/java/com/example/project/EspressoTestCase.java",
    "chars": 2550,
    "preview": "package com.example.project;\n\nimport android.app.Activity;\nimport android.support.test.InstrumentationRegistry;\nimport a"
  },
  {
    "path": "appIt/src/main/java/com/example/project/espresso/CurrentActivity.java",
    "chars": 1033,
    "preview": "package com.example.project.espresso;\n\nimport android.app.Activity;\nimport android.support.test.InstrumentationRegistry;"
  },
  {
    "path": "appIt/src/main/java/com/example/project/espresso/EspButton.java",
    "chars": 491,
    "preview": "package com.example.project.espresso;\n\nimport android.support.test.espresso.action.ViewActions;\n\nimport static android.s"
  },
  {
    "path": "appIt/src/main/java/com/example/project/espresso/EspListView.java",
    "chars": 1036,
    "preview": "package com.example.project.espresso;\n\nimport android.view.View;\nimport android.widget.ListView;\n\nimport org.hamcrest.De"
  },
  {
    "path": "appIt/src/main/java/com/example/project/espresso/EspMenuItem.java",
    "chars": 487,
    "preview": "package com.example.project.espresso;\n\nimport android.support.test.espresso.action.ViewActions;\n\nimport static android.s"
  },
  {
    "path": "appIt/src/main/java/com/example/project/espresso/EspTextEdit.java",
    "chars": 488,
    "preview": "package com.example.project.espresso;\n\nimport static android.support.test.espresso.Espresso.onView;\nimport static androi"
  },
  {
    "path": "appIt/src/main/java/com/example/project/pages/EspContactListPage.java",
    "chars": 936,
    "preview": "package com.example.project.pages;\n\nimport com.example.project.R;\nimport com.example.project.espresso.EspListView;\nimpor"
  },
  {
    "path": "appIt/src/main/java/com/example/project/pages/EspEditContactPage.java",
    "chars": 776,
    "preview": "package com.example.project.pages;\n\nimport com.example.project.R;\nimport com.example.project.espresso.EspButton;\nimport "
  },
  {
    "path": "appIt/src/main/java/com/example/project/test/CreateContactTest.java",
    "chars": 1245,
    "preview": "package com.example.project.test;\n\nimport com.example.project.EspressoTestCase;\nimport com.example.project.pages.EspCont"
  },
  {
    "path": "appIt/src/main/java/com/example/project/test/SyncContactsTest.java",
    "chars": 1577,
    "preview": "package com.example.project.test;\n\nimport com.example.project.EspressoTestCase;\nimport com.example.project.pages.EspCont"
  },
  {
    "path": "build.gradle",
    "chars": 2015,
    "preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    r"
  },
  {
    "path": "build.jacoco-test-report.gradle",
    "chars": 2923,
    "preview": "apply plugin: \"jacoco\"\napply plugin: 'com.github.kt3k.coveralls'\n\njacoco {\n    toolVersion = projectJacocoVersion\n}\n\ntas"
  },
  {
    "path": "circle.yml",
    "chars": 2906,
    "preview": "machine:\n  java:\n    # latest wiremock version needs java 8\n    version: oraclejdk8\n  environment:\n    # auth for the co"
  },
  {
    "path": "docs/build.gradle",
    "chars": 20,
    "preview": "apply plugin: \"java\""
  },
  {
    "path": "docs/src/main/resources/adjust_project_to_your_needs.md",
    "chars": 1099,
    "preview": "[Back to Index](index.md)\n\n# Adjust the project to your needs\n\nStart by cloning the project `git clone https://github.co"
  },
  {
    "path": "docs/src/main/resources/concepts/function_class.md",
    "chars": 506,
    "preview": "[Back to Index](../index.md)\n\n# Function Class\n\nI don't know if this style has a name.\nI took this idea from some scala "
  },
  {
    "path": "docs/src/main/resources/concepts/model_view_presenter.md",
    "chars": 1885,
    "preview": "[Back to Index](../index.md)\n\n# Model View Presenter\n\n* [Wikipedia.org - Model View Presenter](https://en.wikipedia.org/"
  },
  {
    "path": "docs/src/main/resources/concepts/package_structure.md",
    "chars": 3941,
    "preview": "[Back to Index](../index.md)\n\n# Package structure\n\nThe project package structure follows mainly the package by feature a"
  },
  {
    "path": "docs/src/main/resources/concepts/project_structure.md",
    "chars": 650,
    "preview": "[Back to Index](../index.md)\n\n# Project structure\n\n### app - Application\n\ncontains the app with views, business logic, e"
  },
  {
    "path": "docs/src/main/resources/concepts/testing.md",
    "chars": 2000,
    "preview": "[Back to Index](../index.md)\n\n# Testing Strategies\n\n## Unit Tests\n\nCheck that your code work technically in isolation li"
  },
  {
    "path": "docs/src/main/resources/getting_started.md",
    "chars": 2496,
    "preview": "[Back to Index](index.md)\n\n# Getting Started\n\n## Start Wiremock\n\nWithout the example app sync process will fail.\n\nExecut"
  },
  {
    "path": "docs/src/main/resources/index.md",
    "chars": 1388,
    "preview": "[Back to Project](https://github.com/nenick/android-gradle-template)\n\n# Template explanation\n\n## Some basis information\n"
  },
  {
    "path": "docs/src/main/resources/tools/android_contentprovider_generator.md",
    "chars": 3427,
    "preview": "[Back to Index](../index.md)\n\n# Android ContentProvider Generator\n\nCreate tool for generating all necessary database fil"
  },
  {
    "path": "docs/src/main/resources/tools/androidannotations.md",
    "chars": 1744,
    "preview": "[Back to Index](../index.md)\n\n# AndroidAnnotations\n\nI decided me for androidannotations instead of dagger, butterknife a"
  },
  {
    "path": "docs/src/main/resources/tools/circleci.md",
    "chars": 870,
    "preview": "[Back to Index](../index.md)\n\n# Circle CI\n\nFor my continues integration I prefer Circle CI because of nice separation of"
  },
  {
    "path": "docs/src/main/resources/tools/coveralls.md",
    "chars": 176,
    "preview": "[Back to Index](../index.md)\n\n# Cloud Service to host code coverage reports\n\nclasspath 'org.kt3k.gradle.plugin:coveralls"
  },
  {
    "path": "docs/src/main/resources/tools/espresso.md",
    "chars": 519,
    "preview": "[Back to Index](../index.md)\n\nGetting startes wiki: https://code.google.com/p/android-test-kit/wiki/EspressoSetupInstruc"
  },
  {
    "path": "docs/src/main/resources/tools/espresso_test_module.md",
    "chars": 559,
    "preview": "[Back to Index](../index.md)\n\nmodule under test need to publish variants: publishNonDefault true\n\nInitial need dummy And"
  },
  {
    "path": "docs/src/main/resources/tools/fest_assertions.md",
    "chars": 775,
    "preview": "[Back to Index](../index.md)\n\n# Fluent Assertion with Android Support\n\nI prefer the fluent style because you must not th"
  },
  {
    "path": "docs/src/main/resources/tools/jacoco.md",
    "chars": 2403,
    "preview": "[Back to Index](../index.md)\n\n# Jacoco unit tests\n\nsimple unit tests in app module and robolectric supported\n\napply plug"
  },
  {
    "path": "docs/src/main/resources/tools/joda_timedate.md",
    "chars": 138,
    "preview": "[Back to Index](../index.md)\n\nhttp://stackoverflow.com/questions/5059663/android-java-joda-date-is-slow\n\n---\n\n[Back to I"
  },
  {
    "path": "docs/src/main/resources/tools/jsonschema2pojo.md",
    "chars": 924,
    "preview": "[Back to Index](../index.md)\n\nhttps://github.com/joelittlejohn/jsonschema2pojo\nhttps://github.com/joelittlejohn/jsonsche"
  },
  {
    "path": "docs/src/main/resources/tools/robolectric.md",
    "chars": 3344,
    "preview": "[Back to Index](../index.md)\n\n# Robolectric\n\nIs a create tool for testing your app inside jvm insdead to deploy it on a "
  },
  {
    "path": "docs/src/main/resources/tools/robolectric_test_module.md",
    "chars": 1114,
    "preview": "[Back to Index](../index.md)\n\n# gradle-android-test-plugin\n\nMove some of the robolectric supported tests into an own mod"
  },
  {
    "path": "docs/src/main/resources/tools/wiremock.md",
    "chars": 1347,
    "preview": "[Back to Index](../index.md)\n\n# Mocking REST Service\n\nhttp://wiremock.org/running-standalone.html\n\n### NoSuchMethodError"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "chars": 231,
    "preview": "#Sun Aug 16 11:19:08 CEST 2015\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER"
  },
  {
    "path": "gradle.properties",
    "chars": 855,
    "preview": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will o"
  },
  {
    "path": "gradlew",
    "chars": 5080,
    "preview": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start "
  },
  {
    "path": "gradlew.bat",
    "chars": 2404,
    "preview": "@if \"%DEBUG%\" == \"\" @echo off\r\n@rem ##########################################################################\r\n@rem\r\n@r"
  },
  {
    "path": "readme.md",
    "chars": 999,
    "preview": "# Android - Rapid Test Driven Development\n\n* Combine tools to generate most of the boilerplate code.\n* Examples how to t"
  },
  {
    "path": "settings.gradle",
    "chars": 68,
    "preview": "include 'app', 'appCt', 'appIt'\ninclude 'wiremock', 'docs', 'tools'\n"
  },
  {
    "path": "tools/build.gradle",
    "chars": 20,
    "preview": "apply plugin: \"java\""
  },
  {
    "path": "tools/src/main/resources/rename-packages(in development).sh",
    "chars": 602,
    "preview": "#!/bin/bash\n\n#\n# Change easy the base package to your needs\n#\n\nfunction printUsage {\n    echo \"\"\n    echo \"Failed: Start"
  },
  {
    "path": "tools/src/main/resources/start-wiremock.sh",
    "chars": 503,
    "preview": "#!/bin/bash\n\nfunction killCurrentWiremockInstance {\n\n\n    [ $(ps aux | grep -v grep | grep -c \"wiremock.*standalone\") -g"
  },
  {
    "path": "tools/src/main/resources/test-all-with-coverage.bat",
    "chars": 95,
    "preview": "gradlew.bat clean app:test appCt:test appIt:assembleDebug appIt:connectedCheck jacocoTestReport"
  },
  {
    "path": "tools/src/main/resources/test-all-with-coverage.sh",
    "chars": 93,
    "preview": "./gradlew clean app:test appCt:test appIt:assembleDebug appIt:connectedCheck jacocoTestReport"
  },
  {
    "path": "wiremock/build.gradle",
    "chars": 20,
    "preview": "apply plugin: \"java\""
  },
  {
    "path": "wiremock/src/main/resources/__files/contacts-get.json",
    "chars": 362,
    "preview": "{\n  \"contacts\": [\n    {\n      \"id\": \"k345lbhjt5er\",\n      \"firstName\": \"Max\",\n      \"lastName\": \"FromServer\",\n      \"bir"
  },
  {
    "path": "wiremock/src/main/resources/mappings/contcts-delete.json",
    "chars": 118,
    "preview": "{\n  \"request\": {\n    \"method\": \"DELETE\",\n    \"urlPattern\": \"/contacts/.*\"\n  },\n  \"response\": {\n    \"status\": 204\n  }\n}"
  },
  {
    "path": "wiremock/src/main/resources/mappings/contcts-get.json",
    "chars": 226,
    "preview": "{\n  \"request\": {\n    \"method\": \"GET\",\n    \"url\": \"/contacts\"\n  },\n  \"response\": {\n    \"status\": 200,\n    \"bodyFileName\":"
  },
  {
    "path": "wiremock/src/main/resources/mappings/contcts-post.json",
    "chars": 106,
    "preview": "{\n  \"request\": {\n    \"method\": \"POST\",\n    \"url\": \"/contacts\"\n  },\n  \"response\": {\n    \"status\": 201\n  }\n}"
  },
  {
    "path": "wiremock/src/main/resources/mappings/contcts-put.json",
    "chars": 115,
    "preview": "{\n  \"request\": {\n    \"method\": \"PUT\",\n    \"urlPattern\": \"/contacts/.*\"\n  },\n  \"response\": {\n    \"status\": 204\n  }\n}"
  }
]

// ... and 2 more files (download for full content)

About this extraction

This page contains the full source code of the nenick/android-gradle-template GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 171 files (231.7 KB), approximately 56.9k tokens, and a symbol index with 591 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!