[
  {
    "path": ".gitignore",
    "content": ".gradle\n*.iml\n.idea/\nout/\nbuild/\nlocal.properties\n"
  },
  {
    "path": ".travis.yml",
    "content": "# Use the Travis Container-Based Infrastructure\nsudo: false\nlanguage: android\n\njdk:\n  - oraclejdk8\n\nbefore_install:\n  # Install the rest of tools (e.g., avdmanager)\n  - yes | sdkmanager tools\n  # Install the system image\n  - yes | sdkmanager \"system-images;android-18;default;armeabi-v7a\"\n  # Create and start emulator for the script. Meant to race the install task.\n  - echo no | avdmanager create avd --force -n test -k \"system-images;android-18;default;armeabi-v7a\"\n  - $ANDROID_HOME/emulator/emulator -avd test -no-audio -no-window &\n\ninstall: ./gradlew clean assemble assembleAndroidTest --stacktrace\n\nbefore_script:\n  - android-wait-for-emulator\n  - adb shell input keyevent 82\n\nscript: ./gradlew check connectedCheck -x :tests:DaoTestPerformance:connectedCheck --stacktrace\n\nbefore_cache:\n  - rm -f  $HOME/.gradle/caches/modules-2/modules-2.lock\n  - rm -fr $HOME/.gradle/caches/*/plugin-resolution/\n\ncache:\n  directories:\n    - $HOME/.gradle/caches/\n    - $HOME/.gradle/wrapper/\n    - $HOME/.android/build-cache\n"
  },
  {
    "path": "CONTRIBUTING.md",
    "content": "Before you create an Issue...\n=============================\n\nThere are better Places for Support\n-----------------------------------\nWe want your question to be answered, so it is important that you ask at the right place. Be aware that an issue tracker is not the best place to ask for support. An issue tracker is used to track issues (bugs or feature requests).\nInstead, please use [stackoverflow.com](https://stackoverflow.com/questions/tagged/greendao?sort=frequent) and use the tag [greendao](https://stackoverflow.com/tags/greendao/info) for your question.\n\nExamples for support questions that are more likely to be answered on StackOverflow:\n\n* Asking how something works\n* Asking how to use greenDAO in a specific scenario\n* Your app crashes/misbehaves and you are not sure why\n\nThe perfect Issue Report\n------------------------\nA couple of simple steps can save time for everyone.\n\nCheck before reporting:\n\n* It's not a support inquiry\n* You have read the docs\n* You searched the web and stackoverflow\n* You searched existing issues to avoid duplicates\n\nReporting bugs:\n\n * Please investigate if is the bug is really caused by the library. Isolate the issue: what's the minimal code to reproduce the bug?\n * Bonus steps to gain extra karma points: once you isolated and identified the issue, you can prepare an push request. Submit an unit test causing the bug, and ideally a fix for the bug.\n\nRequesting features:\n\n * Ask yourself: is the feature useful for a majority users? One of our major goals is to keep the API simple and concise. We do not want to cover all possible use cases, but those that make 80% of users happy.\n\nThanks for reading!\n===================\nIt's your feedback that makes maintaining this library fun.\n"
  },
  {
    "path": "DaoCore/.gitignore",
    "content": "/gradle.properties\n"
  },
  {
    "path": "DaoCore/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "DaoCore/NOTICE",
    "content": "greenrobot greenDAO (c) Copyright 2011-2016 by Markus Junginger / greenrobot.org\nAll rights reserved\n\nThis product includes software developed at greenrobot.org"
  },
  {
    "path": "DaoCore/build.gradle",
    "content": "apply plugin: 'java'\n\ngroup = 'org.greenrobot'\narchivesBaseName = 'greendao'\nversion = rootProject.version\nsourceCompatibility = 1.7\ntargetCompatibility = 1.7\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    compile project(':greendao-api')\n    compileOnly 'com.google.android:android:4.1.1.4'\n    compileOnly 'com.google.android:android-test:4.1.1.4'\n    compileOnly 'com.google.android:annotations:4.1.1.4'\n    compileOnly 'com.google.android:support-v4:r7'\n\n    compileOnly 'io.reactivex:rxjava:1.1.8'\n\n    compileOnly files('libs/sqlcipher.jar')\n}\n\napply from: rootProject.file(\"gradle/publish.gradle\")\n\njavadoc {\n    failOnError = false\n    title = \" greenDAO ${version} API\"\n    options.bottom = 'Available under the Apache License, Version 2.0 - <i>Copyright &#169; 2011-2020 <a href=\"https://greenrobot.org/\">greenrobot.org</a>. All Rights Reserved.</i>'\n\n    excludes = ['org/greenrobot/dao/internal', 'org/greenrobot/dao/Internal*']\n    def srcApi = project(':greendao-api').file('src/main/java/')\n    if (!srcApi.directory) throw new GradleScriptException(\"Not a directory: ${srcApi}\", null)\n    source += srcApi\n    doLast {\n        copy {\n            from '../javadoc-style'\n            into \"build/docs/javadoc/\"\n        }\n    }\n}\n\ntask javadocJar(type: Jar, dependsOn: javadoc) {\n    classifier = 'javadoc'\n    from 'build/docs/javadoc'\n}\n\ntask sourcesJar(type: Jar) {\n    from sourceSets.main.allSource\n    classifier = 'sources'\n}\n\nartifacts {\n    // jar added by Java plugin.\n    archives javadocJar\n    archives sourcesJar\n}\n\nuploadArchives {\n    repositories {\n        mavenDeployer {\n            // Basic definitions are defined in root project\n            pom.project {\n                name 'greenDAO'\n                description 'greenDAO is a light and fast ORM for Android'\n\n                licenses {\n                    license {\n                        name 'The Apache Software License, Version 2.0'\n                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'\n                        distribution 'repo'\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/AbstractDao.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao;\n\nimport android.database.CrossProcessCursor;\nimport android.database.Cursor;\nimport android.database.CursorWindow;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.annotation.apihint.Experimental;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\nimport org.greenrobot.greendao.identityscope.IdentityScope;\nimport org.greenrobot.greendao.identityscope.IdentityScopeLong;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.internal.FastCursor;\nimport org.greenrobot.greendao.internal.TableStatements;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.rx.RxDao;\n\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Collection;\nimport java.util.List;\n\nimport rx.schedulers.Schedulers;\n\n/**\n * Base class for all DAOs: Implements entity operations like insert, load, delete, and query.\n * <p>\n * This class is thread-safe.\n *\n * @param <T> Entity type\n * @param <K> Primary key (PK) type; use Void if entity does not have exactly one PK\n * @author Markus\n */\n/*\n * When operating on TX, statements, or identity scope the following locking order must be met to avoid deadlocks:\n * \n * 1.) If not inside a TX already, begin a TX to acquire a DB connection (connection is to be handled like a lock)\n * \n * 2.) The DatabaseStatement\n * \n * 3.) identityScope\n */\npublic abstract class AbstractDao<T, K> {\n    protected final DaoConfig config;\n    protected final Database db;\n    protected final boolean isStandardSQLite;\n    protected final IdentityScope<K, T> identityScope;\n    protected final IdentityScopeLong<T> identityScopeLong;\n    protected final TableStatements statements;\n\n    protected final AbstractDaoSession session;\n    protected final int pkOrdinal;\n\n    private volatile RxDao<T, K> rxDao;\n    private volatile RxDao<T, K> rxDaoPlain;\n\n    public AbstractDao(DaoConfig config) {\n        this(config, null);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public AbstractDao(DaoConfig config, AbstractDaoSession daoSession) {\n        this.config = config;\n        this.session = daoSession;\n        db = config.db;\n        isStandardSQLite = db.getRawDatabase() instanceof SQLiteDatabase;\n        identityScope = (IdentityScope<K, T>) config.getIdentityScope();\n        if (identityScope instanceof IdentityScopeLong) {\n            identityScopeLong = (IdentityScopeLong<T>) identityScope;\n        } else {\n            identityScopeLong = null;\n        }\n        statements = config.statements;\n        pkOrdinal = config.pkProperty != null ? config.pkProperty.ordinal : -1;\n    }\n\n    public AbstractDaoSession getSession() {\n        return session;\n    }\n\n    TableStatements getStatements() {\n        return config.statements;\n    }\n\n    public String getTablename() {\n        return config.tablename;\n    }\n\n    public Property[] getProperties() {\n        return config.properties;\n    }\n\n    public Property getPkProperty() {\n        return config.pkProperty;\n    }\n\n    public String[] getAllColumns() {\n        return config.allColumns;\n    }\n\n    public String[] getPkColumns() {\n        return config.pkColumns;\n    }\n\n    public String[] getNonPkColumns() {\n        return config.nonPkColumns;\n    }\n\n    /**\n     * Loads the entity for the given PK.\n     *\n     * @param key a PK value or null\n     * @return The entity or null, if no entity matched the PK value\n     */\n    public T load(K key) {\n        assertSinglePk();\n        if (key == null) {\n            return null;\n        }\n        if (identityScope != null) {\n            T entity = identityScope.get(key);\n            if (entity != null) {\n                return entity;\n            }\n        }\n        String sql = statements.getSelectByKey();\n        String[] keyArray = new String[]{key.toString()};\n        Cursor cursor = db.rawQuery(sql, keyArray);\n        return loadUniqueAndCloseCursor(cursor);\n    }\n\n    public T loadByRowId(long rowId) {\n        String[] idArray = new String[]{Long.toString(rowId)};\n        Cursor cursor = db.rawQuery(statements.getSelectByRowId(), idArray);\n        return loadUniqueAndCloseCursor(cursor);\n    }\n\n    protected T loadUniqueAndCloseCursor(Cursor cursor) {\n        try {\n            return loadUnique(cursor);\n        } finally {\n            cursor.close();\n        }\n    }\n\n    protected T loadUnique(Cursor cursor) {\n        boolean available = cursor.moveToFirst();\n        if (!available) {\n            return null;\n        } else if (!cursor.isLast()) {\n            throw new DaoException(\"Expected unique result, but count was \" + cursor.getCount());\n        }\n        return loadCurrent(cursor, 0, true);\n    }\n\n    /** Loads all available entities from the database. */\n    public List<T> loadAll() {\n        Cursor cursor = db.rawQuery(statements.getSelectAll(), null);\n        return loadAllAndCloseCursor(cursor);\n    }\n\n    /** Detaches an entity from the identity scope (session). Subsequent query results won't return this object. */\n    public boolean detach(T entity) {\n        if (identityScope != null) {\n            K key = getKeyVerified(entity);\n            return identityScope.detach(key, entity);\n        } else {\n            return false;\n        }\n    }\n\n    /**\n     * Detaches all entities (of type T) from the identity scope (session). Subsequent query results won't return any\n     * previously loaded objects.\n     */\n    public void detachAll() {\n        if (identityScope != null) {\n            identityScope.clear();\n        }\n    }\n\n    protected List<T> loadAllAndCloseCursor(Cursor cursor) {\n        try {\n            return loadAllFromCursor(cursor);\n        } finally {\n            cursor.close();\n        }\n    }\n\n    /**\n     * Inserts the given entities in the database using a transaction.\n     *\n     * @param entities The entities to insert.\n     */\n    public void insertInTx(Iterable<T> entities) {\n        insertInTx(entities, isEntityUpdateable());\n    }\n\n    /**\n     * Inserts the given entities in the database using a transaction.\n     *\n     * @param entities The entities to insert.\n     */\n    public void insertInTx(T... entities) {\n        insertInTx(Arrays.asList(entities), isEntityUpdateable());\n    }\n\n    /**\n     * Inserts the given entities in the database using a transaction. The given entities will become tracked if the PK\n     * is set.\n     *\n     * @param entities      The entities to insert.\n     * @param setPrimaryKey if true, the PKs of the given will be set after the insert; pass false to improve\n     *                      performance.\n     */\n    public void insertInTx(Iterable<T> entities, boolean setPrimaryKey) {\n        DatabaseStatement stmt = statements.getInsertStatement();\n        executeInsertInTx(stmt, entities, setPrimaryKey);\n    }\n\n    /**\n     * Inserts or replaces the given entities in the database using a transaction. The given entities will become\n     * tracked if the PK is set.\n     *\n     * @param entities      The entities to insert.\n     * @param setPrimaryKey if true, the PKs of the given will be set after the insert; pass false to improve\n     *                      performance.\n     */\n    public void insertOrReplaceInTx(Iterable<T> entities, boolean setPrimaryKey) {\n        DatabaseStatement stmt = statements.getInsertOrReplaceStatement();\n        executeInsertInTx(stmt, entities, setPrimaryKey);\n    }\n\n    /**\n     * Inserts or replaces the given entities in the database using a transaction.\n     *\n     * @param entities The entities to insert.\n     */\n    public void insertOrReplaceInTx(Iterable<T> entities) {\n        insertOrReplaceInTx(entities, isEntityUpdateable());\n    }\n\n    /**\n     * Inserts or replaces the given entities in the database using a transaction.\n     *\n     * @param entities The entities to insert.\n     */\n    public void insertOrReplaceInTx(T... entities) {\n        insertOrReplaceInTx(Arrays.asList(entities), isEntityUpdateable());\n    }\n\n    private void executeInsertInTx(DatabaseStatement stmt, Iterable<T> entities, boolean setPrimaryKey) {\n        db.beginTransaction();\n        try {\n            synchronized (stmt) {\n                if (identityScope != null) {\n                    identityScope.lock();\n                }\n                try {\n                    if (isStandardSQLite) {\n                        SQLiteStatement rawStmt = (SQLiteStatement) stmt.getRawStatement();\n                        for (T entity : entities) {\n                            bindValues(rawStmt, entity);\n                            if (setPrimaryKey) {\n                                long rowId = rawStmt.executeInsert();\n                                updateKeyAfterInsertAndAttach(entity, rowId, false);\n                            } else {\n                                rawStmt.execute();\n                            }\n                        }\n                    } else {\n                        for (T entity : entities) {\n                            bindValues(stmt, entity);\n                            if (setPrimaryKey) {\n                                long rowId = stmt.executeInsert();\n                                updateKeyAfterInsertAndAttach(entity, rowId, false);\n                            } else {\n                                stmt.execute();\n                            }\n                        }\n                    }\n                } finally {\n                    if (identityScope != null) {\n                        identityScope.unlock();\n                    }\n                }\n            }\n            db.setTransactionSuccessful();\n        } finally {\n            db.endTransaction();\n        }\n    }\n\n    /**\n     * Insert an entity into the table associated with a concrete DAO.\n     *\n     * @return row ID of newly inserted entity\n     */\n    public long insert(T entity) {\n        return executeInsert(entity, statements.getInsertStatement(), true);\n    }\n\n    /**\n     * Insert an entity into the table associated with a concrete DAO <b>without</b> setting key property.\n     * <p>\n     * Warning: This may be faster, but the entity should not be used anymore. The entity also won't be attached to\n     * identity scope.\n     *\n     * @return row ID of newly inserted entity\n     */\n    public long insertWithoutSettingPk(T entity) {\n        return executeInsert(entity, statements.getInsertOrReplaceStatement(), false);\n    }\n\n    /**\n     * Insert an entity into the table associated with a concrete DAO.\n     *\n     * @return row ID of newly inserted entity\n     */\n    public long insertOrReplace(T entity) {\n        return executeInsert(entity, statements.getInsertOrReplaceStatement(), true);\n    }\n\n    private long executeInsert(T entity, DatabaseStatement stmt, boolean setKeyAndAttach) {\n        long rowId;\n        if (db.isDbLockedByCurrentThread()) {\n            rowId = insertInsideTx(entity, stmt);\n        } else {\n            // Do TX to acquire a connection before locking the stmt to avoid deadlocks\n            db.beginTransaction();\n            try {\n                rowId = insertInsideTx(entity, stmt);\n                db.setTransactionSuccessful();\n            } finally {\n                db.endTransaction();\n            }\n        }\n        if (setKeyAndAttach) {\n            updateKeyAfterInsertAndAttach(entity, rowId, true);\n        }\n        return rowId;\n    }\n\n    private long insertInsideTx(T entity, DatabaseStatement stmt) {\n        synchronized (stmt) {\n            if (isStandardSQLite) {\n                SQLiteStatement rawStmt = (SQLiteStatement) stmt.getRawStatement();\n                bindValues(rawStmt, entity);\n                return rawStmt.executeInsert();\n            } else {\n                bindValues(stmt, entity);\n                return stmt.executeInsert();\n            }\n        }\n    }\n\n    protected void updateKeyAfterInsertAndAttach(T entity, long rowId, boolean lock) {\n        if (rowId != -1) {\n            K key = updateKeyAfterInsert(entity, rowId);\n            attachEntity(key, entity, lock);\n        } else {\n            // TODO When does this actually happen? Should we throw instead?\n            DaoLog.w(\"Could not insert row (executeInsert returned -1)\");\n        }\n    }\n\n    /**\n     * \"Saves\" an entity to the database: depending on the existence of the key property, it will be inserted\n     * (key is null) or updated (key is not null).\n     * <p>\n     * This is similar to {@link #insertOrReplace(Object)}, but may be more efficient, because if a key is present,\n     * it does not have to query if that key already exists.\n     */\n    public void save(T entity) {\n        if (hasKey(entity)) {\n            update(entity);\n        } else {\n            insert(entity);\n        }\n    }\n\n    /**\n     * Saves (see {@link #save(Object)}) the given entities in the database using a transaction.\n     *\n     * @param entities The entities to save.\n     */\n    public void saveInTx(T... entities) {\n        saveInTx(Arrays.asList(entities));\n    }\n\n    /**\n     * Saves (see {@link #save(Object)}) the given entities in the database using a transaction.\n     *\n     * @param entities The entities to save.\n     */\n    public void saveInTx(Iterable<T> entities) {\n        int updateCount = 0;\n        int insertCount = 0;\n        for (T entity : entities) {\n            if (hasKey(entity)) {\n                updateCount++;\n            } else {\n                insertCount++;\n            }\n        }\n        if (updateCount > 0 && insertCount > 0) {\n            List<T> toUpdate = new ArrayList<>(updateCount);\n            List<T> toInsert = new ArrayList<>(insertCount);\n            for (T entity : entities) {\n                if (hasKey(entity)) {\n                    toUpdate.add(entity);\n                } else {\n                    toInsert.add(entity);\n                }\n            }\n\n            db.beginTransaction();\n            try {\n                updateInTx(toUpdate);\n                insertInTx(toInsert);\n                db.setTransactionSuccessful();\n            } finally {\n                db.endTransaction();\n            }\n        } else if (insertCount > 0) {\n            insertInTx(entities);\n        } else if (updateCount > 0) {\n            updateInTx(entities);\n        }\n    }\n\n    /** Reads all available rows from the given cursor and returns a list of entities. */\n    protected List<T> loadAllFromCursor(Cursor cursor) {\n        int count = cursor.getCount();\n        if (count == 0) {\n            return new ArrayList<T>();\n        }\n        List<T> list = new ArrayList<T>(count);\n        CursorWindow window = null;\n        boolean useFastCursor = false;\n        if (cursor instanceof CrossProcessCursor) {\n            window = ((CrossProcessCursor) cursor).getWindow();\n            if (window != null) { // E.g. Robolectric has no Window at this point\n                if (window.getNumRows() == count) {\n                    cursor = new FastCursor(window);\n                    useFastCursor = true;\n                } else {\n                    DaoLog.d(\"Window vs. result size: \" + window.getNumRows() + \"/\" + count);\n                }\n            }\n        }\n\n        if (cursor.moveToFirst()) {\n            if (identityScope != null) {\n                identityScope.lock();\n                identityScope.reserveRoom(count);\n            }\n\n            try {\n                if (!useFastCursor && window != null && identityScope != null) {\n                    loadAllUnlockOnWindowBounds(cursor, window, list);\n                } else {\n                    do {\n                        list.add(loadCurrent(cursor, 0, false));\n                    } while (cursor.moveToNext());\n                }\n            } finally {\n                if (identityScope != null) {\n                    identityScope.unlock();\n                }\n            }\n        }\n        return list;\n    }\n\n    private void loadAllUnlockOnWindowBounds(Cursor cursor, CursorWindow window, List<T> list) {\n        int windowEnd = window.getStartPosition() + window.getNumRows();\n        for (int row = 0; ; row++) {\n            list.add(loadCurrent(cursor, 0, false));\n            row++;\n            if (row >= windowEnd) {\n                window = moveToNextUnlocked(cursor);\n                if (window == null) {\n                    break;\n                }\n                windowEnd = window.getStartPosition() + window.getNumRows();\n            } else {\n                if (!cursor.moveToNext()) {\n                    break;\n                }\n            }\n        }\n    }\n\n    /**\n     * Unlock identityScope during cursor.moveToNext() when it is about to fill the window (needs a db connection):\n     * We should not hold the lock while trying to acquire a db connection to avoid deadlocks.\n     */\n    private CursorWindow moveToNextUnlocked(Cursor cursor) {\n        identityScope.unlock();\n        try {\n            if (cursor.moveToNext()) {\n                return ((CrossProcessCursor) cursor).getWindow();\n            } else {\n                return null;\n            }\n        } finally {\n            identityScope.lock();\n        }\n    }\n\n    /** Internal use only. Considers identity scope. */\n    final protected T loadCurrent(Cursor cursor, int offset, boolean lock) {\n        if (identityScopeLong != null) {\n            if (offset != 0) {\n                // Occurs with deep loads (left outer joins)\n                if (cursor.isNull(pkOrdinal + offset)) {\n                    return null;\n                }\n            }\n\n            long key = cursor.getLong(pkOrdinal + offset);\n            T entity = lock ? identityScopeLong.get2(key) : identityScopeLong.get2NoLock(key);\n            if (entity != null) {\n                return entity;\n            } else {\n                entity = readEntity(cursor, offset);\n                attachEntity(entity);\n                if (lock) {\n                    identityScopeLong.put2(key, entity);\n                } else {\n                    identityScopeLong.put2NoLock(key, entity);\n                }\n                return entity;\n            }\n        } else if (identityScope != null) {\n            K key = readKey(cursor, offset);\n            if (offset != 0 && key == null) {\n                // Occurs with deep loads (left outer joins)\n                return null;\n            }\n            T entity = lock ? identityScope.get(key) : identityScope.getNoLock(key);\n            if (entity != null) {\n                return entity;\n            } else {\n                entity = readEntity(cursor, offset);\n                attachEntity(key, entity, lock);\n                return entity;\n            }\n        } else {\n            // Check offset, assume a value !=0 indicating a potential outer join, so check PK\n            if (offset != 0) {\n                K key = readKey(cursor, offset);\n                if (key == null) {\n                    // Occurs with deep loads (left outer joins)\n                    return null;\n                }\n            }\n            T entity = readEntity(cursor, offset);\n            attachEntity(entity);\n            return entity;\n        }\n    }\n\n    /** Internal use only. Considers identity scope. */\n    final protected <O> O loadCurrentOther(AbstractDao<O, ?> dao, Cursor cursor, int offset) {\n        return dao.loadCurrent(cursor, offset, /* TODO check this */true);\n    }\n\n    /** A raw-style query where you can pass any WHERE clause and arguments. */\n    public List<T> queryRaw(String where, String... selectionArg) {\n        Cursor cursor = db.rawQuery(statements.getSelectAll() + where, selectionArg);\n        return loadAllAndCloseCursor(cursor);\n    }\n\n    /**\n     * Creates a repeatable {@link Query} object based on the given raw SQL where you can pass any WHERE clause and\n     * arguments.\n     */\n    public Query<T> queryRawCreate(String where, Object... selectionArg) {\n        List<Object> argList = Arrays.asList(selectionArg);\n        return queryRawCreateListArgs(where, argList);\n    }\n\n    /**\n     * Creates a repeatable {@link Query} object based on the given raw SQL where you can pass any WHERE clause and\n     * arguments.\n     */\n    public Query<T> queryRawCreateListArgs(String where, Collection<Object> selectionArg) {\n        return Query.internalCreate(this, statements.getSelectAll() + where, selectionArg.toArray());\n    }\n\n    public void deleteAll() {\n        // String sql = SqlUtils.createSqlDelete(config.tablename, null);\n        // db.execSQL(sql);\n\n        db.execSQL(\"DELETE FROM '\" + config.tablename + \"'\");\n        if (identityScope != null) {\n            identityScope.clear();\n        }\n    }\n\n    /** Deletes the given entity from the database. Currently, only single value PK entities are supported. */\n    public void delete(T entity) {\n        assertSinglePk();\n        K key = getKeyVerified(entity);\n        deleteByKey(key);\n    }\n\n    /** Deletes an entity with the given PK from the database. Currently, only single value PK entities are supported. */\n    public void deleteByKey(K key) {\n        assertSinglePk();\n        DatabaseStatement stmt = statements.getDeleteStatement();\n        if (db.isDbLockedByCurrentThread()) {\n            synchronized (stmt) {\n                deleteByKeyInsideSynchronized(key, stmt);\n            }\n        } else {\n            // Do TX to acquire a connection before locking the stmt to avoid deadlocks\n            db.beginTransaction();\n            try {\n                synchronized (stmt) {\n                    deleteByKeyInsideSynchronized(key, stmt);\n                }\n                db.setTransactionSuccessful();\n            } finally {\n                db.endTransaction();\n            }\n        }\n        if (identityScope != null) {\n            identityScope.remove(key);\n        }\n    }\n\n    private void deleteByKeyInsideSynchronized(K key, DatabaseStatement stmt) {\n        if (key instanceof Long) {\n            stmt.bindLong(1, (Long) key);\n        } else if (key == null) {\n            throw new DaoException(\"Cannot delete entity, key is null\");\n        } else {\n            stmt.bindString(1, key.toString());\n        }\n        stmt.execute();\n    }\n\n    private void deleteInTxInternal(Iterable<T> entities, Iterable<K> keys) {\n        assertSinglePk();\n        DatabaseStatement stmt = statements.getDeleteStatement();\n        List<K> keysToRemoveFromIdentityScope = null;\n        db.beginTransaction();\n        try {\n            synchronized (stmt) {\n                if (identityScope != null) {\n                    identityScope.lock();\n                    keysToRemoveFromIdentityScope = new ArrayList<K>();\n                }\n                try {\n                    if (entities != null) {\n                        for (T entity : entities) {\n                            K key = getKeyVerified(entity);\n                            deleteByKeyInsideSynchronized(key, stmt);\n                            if (keysToRemoveFromIdentityScope != null) {\n                                keysToRemoveFromIdentityScope.add(key);\n                            }\n                        }\n                    }\n                    if (keys != null) {\n                        for (K key : keys) {\n                            deleteByKeyInsideSynchronized(key, stmt);\n                            if (keysToRemoveFromIdentityScope != null) {\n                                keysToRemoveFromIdentityScope.add(key);\n                            }\n                        }\n                    }\n                } finally {\n                    if (identityScope != null) {\n                        identityScope.unlock();\n                    }\n                }\n            }\n            db.setTransactionSuccessful();\n            if (keysToRemoveFromIdentityScope != null && identityScope != null) {\n                identityScope.remove(keysToRemoveFromIdentityScope);\n            }\n        } finally {\n            db.endTransaction();\n        }\n    }\n\n    /**\n     * Deletes the given entities in the database using a transaction.\n     *\n     * @param entities The entities to delete.\n     */\n    public void deleteInTx(Iterable<T> entities) {\n        deleteInTxInternal(entities, null);\n    }\n\n    /**\n     * Deletes the given entities in the database using a transaction.\n     *\n     * @param entities The entities to delete.\n     */\n    public void deleteInTx(T... entities) {\n        deleteInTxInternal(Arrays.asList(entities), null);\n    }\n\n    /**\n     * Deletes all entities with the given keys in the database using a transaction.\n     *\n     * @param keys Keys of the entities to delete.\n     */\n    public void deleteByKeyInTx(Iterable<K> keys) {\n        deleteInTxInternal(null, keys);\n    }\n\n    /**\n     * Deletes all entities with the given keys in the database using a transaction.\n     *\n     * @param keys Keys of the entities to delete.\n     */\n    public void deleteByKeyInTx(K... keys) {\n        deleteInTxInternal(null, Arrays.asList(keys));\n    }\n\n    /** Resets all locally changed properties of the entity by reloading the values from the database. */\n    public void refresh(T entity) {\n        assertSinglePk();\n        K key = getKeyVerified(entity);\n        String sql = statements.getSelectByKey();\n        String[] keyArray = new String[]{key.toString()};\n        Cursor cursor = db.rawQuery(sql, keyArray);\n        try {\n            boolean available = cursor.moveToFirst();\n            if (!available) {\n                throw new DaoException(\"Entity does not exist in the database anymore: \" + entity.getClass()\n                        + \" with key \" + key);\n            } else if (!cursor.isLast()) {\n                throw new DaoException(\"Expected unique result, but count was \" + cursor.getCount());\n            }\n            readEntity(cursor, entity, 0);\n            attachEntity(key, entity, true);\n        } finally {\n            cursor.close();\n        }\n    }\n\n    public void update(T entity) {\n        assertSinglePk();\n        DatabaseStatement stmt = statements.getUpdateStatement();\n        if (db.isDbLockedByCurrentThread()) {\n            synchronized (stmt) {\n                if (isStandardSQLite) {\n                    updateInsideSynchronized(entity, (SQLiteStatement) stmt.getRawStatement(), true);\n                } else {\n                    updateInsideSynchronized(entity, stmt, true);\n                }\n            }\n        } else {\n            // Do TX to acquire a connection before locking the stmt to avoid deadlocks\n            db.beginTransaction();\n            try {\n                synchronized (stmt) {\n                    updateInsideSynchronized(entity, stmt, true);\n                }\n                db.setTransactionSuccessful();\n            } finally {\n                db.endTransaction();\n            }\n        }\n    }\n\n    public QueryBuilder<T> queryBuilder() {\n        return QueryBuilder.internalCreate(this);\n    }\n\n    protected void updateInsideSynchronized(T entity, DatabaseStatement stmt, boolean lock) {\n        // To do? Check if it's worth not to bind PKs here (performance).\n        bindValues(stmt, entity);\n        int index = config.allColumns.length + 1;\n        K key = getKey(entity);\n        if (key instanceof Long) {\n            stmt.bindLong(index, (Long) key);\n        } else if (key == null) {\n            throw new DaoException(\"Cannot update entity without key - was it inserted before?\");\n        } else {\n            stmt.bindString(index, key.toString());\n        }\n        stmt.execute();\n        attachEntity(key, entity, lock);\n    }\n\n    protected void updateInsideSynchronized(T entity, SQLiteStatement stmt, boolean lock) {\n        // To do? Check if it's worth not to bind PKs here (performance).\n        bindValues(stmt, entity);\n        int index = config.allColumns.length + 1;\n        K key = getKey(entity);\n        if (key instanceof Long) {\n            stmt.bindLong(index, (Long) key);\n        } else if (key == null) {\n            throw new DaoException(\"Cannot update entity without key - was it inserted before?\");\n        } else {\n            stmt.bindString(index, key.toString());\n        }\n        stmt.execute();\n        attachEntity(key, entity, lock);\n    }\n\n    /**\n     * Attaches the entity to the identity scope. Calls attachEntity(T entity).\n     *\n     * @param key    Needed only for identity scope, pass null if there's none.\n     * @param entity The entitiy to attach\n     */\n    protected final void attachEntity(K key, T entity, boolean lock) {\n        attachEntity(entity);\n        if (identityScope != null && key != null) {\n            if (lock) {\n                identityScope.put(key, entity);\n            } else {\n                identityScope.putNoLock(key, entity);\n            }\n        }\n    }\n\n    /**\n     * Sub classes with relations additionally set the DaoMaster here. Must be called before the entity is attached to\n     * the identity scope.\n     *\n     * @param entity The entitiy to attach\n     */\n    protected void attachEntity(T entity) {\n    }\n\n    /**\n     * Updates the given entities in the database using a transaction.\n     *\n     * @param entities The entities to insert.\n     */\n    public void updateInTx(Iterable<T> entities) {\n        DatabaseStatement stmt = statements.getUpdateStatement();\n        db.beginTransaction();\n        // txEx: just to preserve original exception in case another exceptions is thrown in endTransaction()\n        RuntimeException txEx = null;\n        try {\n            synchronized (stmt) {\n                if (identityScope != null) {\n                    identityScope.lock();\n                }\n                try {\n                    if (isStandardSQLite) {\n                        SQLiteStatement rawStmt = (SQLiteStatement) stmt.getRawStatement();\n                        for (T entity : entities) {\n                            updateInsideSynchronized(entity, rawStmt, false);\n                        }\n                    } else {\n                        for (T entity : entities) {\n                            updateInsideSynchronized(entity, stmt, false);\n                        }\n                    }\n                } finally {\n                    if (identityScope != null) {\n                        identityScope.unlock();\n                    }\n                }\n            }\n            db.setTransactionSuccessful();\n        } catch (RuntimeException e) {\n            txEx = e;\n        } finally {\n            try {\n                db.endTransaction();\n            } catch (RuntimeException e) {\n                if (txEx != null) {\n                    DaoLog.w(\"Could not end transaction (rethrowing initial exception)\", e);\n                    throw txEx;\n                } else {\n                    throw e;\n                }\n            }\n        }\n        if (txEx != null) {\n            throw txEx;\n        }\n    }\n\n    /**\n     * Updates the given entities in the database using a transaction.\n     *\n     * @param entities The entities to update.\n     */\n    public void updateInTx(T... entities) {\n        updateInTx(Arrays.asList(entities));\n    }\n\n    protected void assertSinglePk() {\n        if (config.pkColumns.length != 1) {\n            throw new DaoException(this + \" (\" + config.tablename + \") does not have a single-column primary key\");\n        }\n    }\n\n    public long count() {\n        return statements.getCountStatement().simpleQueryForLong();\n    }\n\n    /** See {@link #getKey(Object)}, but guarantees that the returned key is never null (throws if null). */\n    protected K getKeyVerified(T entity) {\n        K key = getKey(entity);\n        if (key == null) {\n            if (entity == null) {\n                throw new NullPointerException(\"Entity may not be null\");\n            } else {\n                throw new DaoException(\"Entity has no key\");\n            }\n        } else {\n            return key;\n        }\n    }\n\n    /**\n     * The returned RxDao is a special DAO that let's you interact with Rx Observables without any Scheduler set\n     * for subscribeOn.\n     *\n     * @see #rx()\n     */\n    @Experimental\n    public RxDao<T, K> rxPlain() {\n        if (rxDaoPlain == null) {\n            rxDaoPlain = new RxDao<>(this);\n        }\n        return rxDaoPlain;\n    }\n\n    /**\n     * The returned RxDao is a special DAO that let's you interact with Rx Observables using RX's IO scheduler for\n     * subscribeOn.\n     *\n     * @see #rxPlain()\n     */\n    @Experimental\n    public RxDao<T, K> rx() {\n        if (rxDao == null) {\n            rxDao = new RxDao<>(this, Schedulers.io());\n        }\n        return rxDao;\n    }\n\n    /** Gets the SQLiteDatabase for custom database access. Not needed for greenDAO entities. */\n    public Database getDatabase() {\n        return db;\n    }\n\n    /** Reads the values from the current position of the given cursor and returns a new entity. */\n    abstract protected T readEntity(Cursor cursor, int offset);\n\n\n    /** Reads the key from the current position of the given cursor, or returns null if there's no single-value key. */\n    abstract protected K readKey(Cursor cursor, int offset);\n\n    /** Reads the values from the current position of the given cursor into an existing entity. */\n    abstract protected void readEntity(Cursor cursor, T entity, int offset);\n\n    /** Binds the entity's values to the statement. Make sure to synchronize the statement outside of the method. */\n    abstract protected void bindValues(DatabaseStatement stmt, T entity);\n\n    /**\n     * Binds the entity's values to the statement. Make sure to synchronize the enclosing DatabaseStatement outside\n     * of the method.\n     */\n    protected abstract void bindValues(SQLiteStatement stmt, T entity);\n\n    /**\n     * Updates the entity's key if possible (only for Long PKs currently). This method must always return the entity's\n     * key regardless of whether the key existed before or not.\n     */\n    abstract protected K updateKeyAfterInsert(T entity, long rowId);\n\n    /**\n     * Returns the value of the primary key, if the entity has a single primary key, or, if not, null. Returns null if\n     * entity is null.\n     */\n    abstract protected K getKey(T entity);\n\n    /**\n     * Returns true if the entity is not null, and has a non-null key, which is also != 0.\n     * entity is null.\n     */\n    abstract protected boolean hasKey(T entity);\n\n    /** Returns true if the Entity class can be updated, e.g. for setting the PK after insert. */\n    abstract protected boolean isEntityUpdateable();\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/AbstractDaoMaster.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.identityscope.IdentityScopeType;\nimport org.greenrobot.greendao.internal.DaoConfig;\n\n/**\n * The master of dao will guide you: start dao sessions with the master.\n * \n * @author Markus\n */\npublic abstract class AbstractDaoMaster {\n    protected final Database db;\n    protected final int schemaVersion;\n    protected final Map<Class<? extends AbstractDao<?, ?>>, DaoConfig> daoConfigMap;\n\n    public AbstractDaoMaster(Database db, int schemaVersion) {\n        this.db = db;\n        this.schemaVersion = schemaVersion;\n\n        daoConfigMap = new HashMap<Class<? extends AbstractDao<?, ?>>, DaoConfig>();\n    }\n\n    protected void registerDaoClass(Class<? extends AbstractDao<?, ?>> daoClass) {\n        DaoConfig daoConfig = new DaoConfig(db, daoClass);\n        daoConfigMap.put(daoClass, daoConfig);\n    }\n\n    public int getSchemaVersion() {\n        return schemaVersion;\n    }\n\n    /** Gets the SQLiteDatabase for custom database access. Not needed for greenDAO entities. */\n    public Database getDatabase() {\n        return db;\n    }\n\n    public abstract AbstractDaoSession newSession();\n\n    public abstract AbstractDaoSession newSession(IdentityScopeType type);\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/AbstractDaoSession.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao;\n\nimport java.util.Collection;\nimport java.util.Collections;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.concurrent.Callable;\n\nimport org.greenrobot.greendao.annotation.apihint.Experimental;\nimport org.greenrobot.greendao.async.AsyncSession;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.rx.RxTransaction;\n\nimport rx.schedulers.Schedulers;\n\n/**\n * DaoSession gives you access to your DAOs, offers convenient persistence methods, and also serves as a session cache.<br>\n * <br>\n * To access the DAOs, call the get{entity}Dao methods by the generated DaoSession sub class.<br>\n * <br>\n * DaoSession offers many of the available persistence operations on entities as a convenience. Consider using DAOs\n * directly to access all available operations, especially if you call a lot of operations on a single entity type to\n * avoid the overhead imposed by DaoSession (the overhead is small, but it may add up).<br>\n * <br>\n * By default, the DaoSession has a session cache (IdentityScopeType.Session). The session cache is not just a plain\n * data cache to improve performance, but also manages object identities. For example, if you load the same entity twice\n * in a query, you will get a single Java object instead of two when using a session cache. This is particular useful\n * for relations pointing to a common set of entities.\n * \n * This class is thread-safe.\n * \n * @author Markus\n * \n */\npublic class AbstractDaoSession {\n    private final Database db;\n    private final Map<Class<?>, AbstractDao<?, ?>> entityToDao;\n\n    private volatile RxTransaction rxTxPlain;\n    private volatile RxTransaction rxTxIo;\n\n    public AbstractDaoSession(Database db) {\n        this.db = db;\n        this.entityToDao = new HashMap<Class<?>, AbstractDao<?, ?>>();\n    }\n\n    protected <T> void registerDao(Class<T> entityClass, AbstractDao<T, ?> dao) {\n        entityToDao.put(entityClass, dao);\n    }\n\n    /** Convenient call for {@link AbstractDao#insert(Object)}. */\n    public <T> long insert(T entity) {\n        @SuppressWarnings(\"unchecked\")\n        AbstractDao<T, ?> dao = (AbstractDao<T, ?>) getDao(entity.getClass());\n        return dao.insert(entity);\n    }\n\n    /** Convenient call for {@link AbstractDao#insertOrReplace(Object)}. */\n    public <T> long insertOrReplace(T entity) {\n        @SuppressWarnings(\"unchecked\")\n        AbstractDao<T, ?> dao = (AbstractDao<T, ?>) getDao(entity.getClass());\n        return dao.insertOrReplace(entity);\n    }\n\n    /** Convenient call for {@link AbstractDao#refresh(Object)}. */\n    public <T> void refresh(T entity) {\n        @SuppressWarnings(\"unchecked\")\n        AbstractDao<T, ?> dao = (AbstractDao<T, ?>) getDao(entity.getClass());\n        dao.refresh(entity);\n    }\n\n    /** Convenient call for {@link AbstractDao#update(Object)}. */\n    public <T> void update(T entity) {\n        @SuppressWarnings(\"unchecked\")\n        AbstractDao<T, ?> dao = (AbstractDao<T, ?>) getDao(entity.getClass());\n        dao.update(entity);\n    }\n\n    /** Convenient call for {@link AbstractDao#delete(Object)}. */\n    public <T> void delete(T entity) {\n        @SuppressWarnings(\"unchecked\")\n        AbstractDao<T, ?> dao = (AbstractDao<T, ?>) getDao(entity.getClass());\n        dao.delete(entity);\n    }\n\n    /** Convenient call for {@link AbstractDao#deleteAll()}. */\n    public <T> void deleteAll(Class<T> entityClass) {\n        @SuppressWarnings(\"unchecked\")\n        AbstractDao<T, ?> dao = (AbstractDao<T, ?>) getDao(entityClass);\n        dao.deleteAll();\n    }\n\n    /** Convenient call for {@link AbstractDao#load(Object)}. */\n    public <T, K> T load(Class<T> entityClass, K key) {\n        @SuppressWarnings(\"unchecked\")\n        AbstractDao<T, K> dao = (AbstractDao<T, K>) getDao(entityClass);\n        return dao.load(key);\n    }\n\n    /** Convenient call for {@link AbstractDao#loadAll()}. */\n    public <T, K> List<T> loadAll(Class<T> entityClass) {\n        @SuppressWarnings(\"unchecked\")\n        AbstractDao<T, K> dao = (AbstractDao<T, K>) getDao(entityClass);\n        return dao.loadAll();\n    }\n\n    /** Convenient call for {@link AbstractDao#queryRaw(String, String...)}. */\n    public <T, K> List<T> queryRaw(Class<T> entityClass, String where, String... selectionArgs) {\n        @SuppressWarnings(\"unchecked\")\n        AbstractDao<T, K> dao = (AbstractDao<T, K>) getDao(entityClass);\n        return dao.queryRaw(where, selectionArgs);\n    }\n\n    /** Convenient call for {@link AbstractDao#queryBuilder()}. */\n    public <T> QueryBuilder<T> queryBuilder(Class<T> entityClass) {\n        @SuppressWarnings(\"unchecked\")\n        AbstractDao<T, ?> dao = (AbstractDao<T, ?>) getDao(entityClass);\n        return dao.queryBuilder();\n    }\n\n    public AbstractDao<?, ?> getDao(Class<? extends Object> entityClass) {\n        AbstractDao<?, ?> dao = entityToDao.get(entityClass);\n        if (dao == null) {\n            throw new DaoException(\"No DAO registered for \" + entityClass);\n        }\n        return dao;\n    }\n\n    /**\n     * Run the given Runnable inside a database transaction. If you except a result, consider callInTx.\n     */\n    public void runInTx(Runnable runnable) {\n        db.beginTransaction();\n        try {\n            runnable.run();\n            db.setTransactionSuccessful();\n        } finally {\n            db.endTransaction();\n        }\n    }\n\n    /**\n     * Calls the given Callable inside a database transaction and returns the result of the Callable. If you don't\n     * except a result, consider runInTx.\n     */\n    public <V> V callInTx(Callable<V> callable) throws Exception {\n        db.beginTransaction();\n        try {\n            V result = callable.call();\n            db.setTransactionSuccessful();\n            return result;\n        } finally {\n            db.endTransaction();\n        }\n    }\n\n    /**\n     * Like {@link #callInTx(Callable)} but does not require Exception handling (rethrows an Exception as a runtime\n     * DaoException).\n     */\n    public <V> V callInTxNoException(Callable<V> callable) {\n        db.beginTransaction();\n        try {\n            V result;\n            try {\n                result = callable.call();\n            } catch (Exception e) {\n                throw new DaoException(\"Callable failed\", e);\n            }\n            db.setTransactionSuccessful();\n            return result;\n        } finally {\n            db.endTransaction();\n        }\n    }\n\n    /** Gets the Database for custom database access. Not needed for greenDAO entities. */\n    public Database getDatabase() {\n        return db;\n    }\n\n    /** Allows to inspect the meta model using DAOs (e.g. querying table names or properties). */\n    public Collection<AbstractDao<?, ?>> getAllDaos() {\n        return Collections.unmodifiableCollection(entityToDao.values());\n    }\n\n    /**\n     * Creates a new {@link AsyncSession} to issue asynchronous entity operations. See {@link AsyncSession} for details.\n     */\n    public AsyncSession startAsyncSession() {\n        return new AsyncSession(this);\n    }\n\n    /**\n     * The returned {@link RxTransaction} allows DB transactions using Rx Observables without any Scheduler set for\n     * subscribeOn.\n     *\n     * @see #rxTx()\n     */\n    @Experimental\n    public RxTransaction rxTxPlain() {\n        if (rxTxPlain == null) {\n            rxTxPlain = new RxTransaction(this);\n        }\n        return rxTxPlain;\n    }\n\n    /**\n     * The returned {@link RxTransaction} allows DB transactions using Rx Observables using RX's IO scheduler for\n     * subscribeOn.\n     *\n     * @see #rxTxPlain()\n     */\n    @Experimental\n    public RxTransaction rxTx() {\n        if (rxTxIo == null) {\n            rxTxIo = new RxTransaction(this, Schedulers.io());\n        }\n        return rxTxIo;\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/DaoException.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao;\n\nimport android.database.SQLException;\n\n/**\n * Exception thrown when something goes wrong in the DAO/ORM layer.\n * \n * @author Markus\n * \n */\npublic class DaoException extends SQLException {\n\n    private static final long serialVersionUID = -5877937327907457779L;\n\n    public DaoException() {\n    }\n\n    public DaoException(String error) {\n        super(error);\n    }\n\n    public DaoException(String error, Throwable cause) {\n        super(error);\n        safeInitCause(cause);\n    }\n\n    public DaoException(Throwable th) {\n        safeInitCause(th);\n    }\n\n    protected void safeInitCause(Throwable cause) {\n        try {\n            initCause(cause);\n        } catch (Throwable e) {\n            DaoLog.e(\"Could not set initial cause\", e);\n            DaoLog.e( \"Initial cause is:\", cause);\n        }\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/DaoLog.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao;\n\nimport android.util.Log;\n\n/**\n * Internal greenDAO logger class. A wrapper around the Android Log class providing a static Log Tag.\n * \n * @author markus\n * \n */\npublic class DaoLog {\n    private final static String TAG = \"greenDAO\";\n\n    public static final int VERBOSE = 2;\n    public static final int DEBUG = 3;\n    public static final int INFO = 4;\n    public static final int WARN = 5;\n    public static final int ERROR = 6;\n    public static final int ASSERT = 7;\n\n    public static boolean isLoggable(int level) {\n        return Log.isLoggable(TAG, level);\n    }\n\n    public static String getStackTraceString(Throwable th) {\n        return Log.getStackTraceString(th);\n    }\n\n    public static int println(int level, String msg) {\n        return Log.println(level, TAG, msg);\n    }\n\n    public static int v(String msg) {\n        return Log.v(TAG, msg);\n    }\n\n    public static int v(String msg, Throwable th) {\n        return Log.v(TAG, msg, th);\n    }\n\n    public static int d(String msg) {\n        return Log.d(TAG, msg);\n    }\n\n    public static int d(String msg, Throwable th) {\n        return Log.d(TAG, msg, th);\n    }\n\n    public static int i(String msg) {\n        return Log.i(TAG, msg);\n    }\n\n    public static int i(String msg, Throwable th) {\n        return Log.i(TAG, msg, th);\n    }\n\n    public static int w(String msg) {\n        return Log.w(TAG, msg);\n    }\n\n    public static int w(String msg, Throwable th) {\n        return Log.w(TAG, msg, th);\n    }\n\n    public static int w(Throwable th) {\n        return Log.w(TAG, th);\n    }\n\n    public static int e(String msg) {\n        return Log.w(TAG, msg);\n    }\n\n    public static int e(String msg, Throwable th) {\n        return Log.e(TAG, msg, th);\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/DbUtils.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\n\nimport android.content.Context;\nimport android.database.Cursor;\nimport android.database.DatabaseUtils;\nimport android.database.sqlite.SQLiteDatabase;\n\nimport org.greenrobot.greendao.database.Database;\n\n/** Database utils, for example to execute SQL scripts */\n// TODO add unit tests\npublic class DbUtils {\n\n    public static void vacuum(Database db) {\n        db.execSQL(\"VACUUM\");\n    }\n\n    /**\n     * Calls {@link #executeSqlScript(Context, Database, String, boolean)} with transactional set to true.\n     * \n     * @return number of statements executed.\n     */\n    public static int executeSqlScript(Context context, Database db, String assetFilename) throws IOException {\n        return executeSqlScript(context, db, assetFilename, true);\n    }\n\n    /**\n     * Executes the given SQL asset in the given database (SQL file should be UTF-8). The database file may contain\n     * multiple SQL statements. Statements are split using a simple regular expression (something like\n     * \"semicolon before a line break\"), not by analyzing the SQL syntax. This will work for many SQL files, but check\n     * yours.\n     * \n     * @return number of statements executed.\n     */\n    public static int executeSqlScript(Context context, Database db, String assetFilename, boolean transactional)\n            throws IOException {\n        byte[] bytes = readAsset(context, assetFilename);\n        String sql = new String(bytes, \"UTF-8\");\n        String[] lines = sql.split(\";(\\\\s)*[\\n\\r]\");\n        int count;\n        if (transactional) {\n            count = executeSqlStatementsInTx(db, lines);\n        } else {\n            count = executeSqlStatements(db, lines);\n        }\n        DaoLog.i(\"Executed \" + count + \" statements from SQL script '\" + assetFilename + \"'\");\n        return count;\n    }\n\n    public static int executeSqlStatementsInTx(Database db, String[] statements) {\n        db.beginTransaction();\n        try {\n            int count = executeSqlStatements(db, statements);\n            db.setTransactionSuccessful();\n            return count;\n        } finally {\n            db.endTransaction();\n        }\n    }\n\n    public static int executeSqlStatements(Database db, String[] statements) {\n        int count = 0;\n        for (String line : statements) {\n            line = line.trim();\n            if (line.length() > 0) {\n                db.execSQL(line);\n                count++;\n            }\n        }\n        return count;\n    }\n\n    /**\n     * Copies all available data from in to out without closing any stream.\n     * \n     * @return number of bytes copied\n     */\n    public static int copyAllBytes(InputStream in, OutputStream out) throws IOException {\n        int byteCount = 0;\n        byte[] buffer = new byte[4096];\n        while (true) {\n            int read = in.read(buffer);\n            if (read == -1) {\n                break;\n            }\n            out.write(buffer, 0, read);\n            byteCount += read;\n        }\n        return byteCount;\n    }\n\n    public static byte[] readAllBytes(InputStream in) throws IOException {\n        ByteArrayOutputStream out = new ByteArrayOutputStream();\n        copyAllBytes(in, out);\n        return out.toByteArray();\n    }\n\n    public static byte[] readAsset(Context context, String filename) throws IOException {\n        InputStream in = context.getResources().getAssets().open(filename);\n        try {\n            return readAllBytes(in);\n        } finally {\n            in.close();\n        }\n    }\n\n    public static void logTableDump(SQLiteDatabase db, String tablename) {\n        Cursor cursor = db.query(tablename, null, null, null, null, null, null);\n        try {\n            String dump = DatabaseUtils.dumpCursorToString(cursor);\n            DaoLog.d(dump);\n        } finally {\n            cursor.close();\n        }\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/InternalQueryDaoAccess.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao;\n\nimport java.util.List;\n\nimport android.database.Cursor;\nimport org.greenrobot.greendao.internal.TableStatements;\n\n/** For internal use by greenDAO only. */\npublic final class InternalQueryDaoAccess<T> {\n    private final AbstractDao<T, ?> dao;\n\n    public InternalQueryDaoAccess(AbstractDao<T, ?> abstractDao) {\n        dao = abstractDao;\n    }\n\n    public T loadCurrent(Cursor cursor, int offset, boolean lock) {\n        return dao.loadCurrent(cursor, offset, lock);\n    }\n\n    public List<T> loadAllAndCloseCursor(Cursor cursor) {\n        return dao.loadAllAndCloseCursor(cursor);\n    }\n\n    public T loadUniqueAndCloseCursor(Cursor cursor) {\n        return dao.loadUniqueAndCloseCursor(cursor);\n    }\n\n    public TableStatements getStatements() {\n        return dao.getStatements();\n    }\n\n    public static <T2> TableStatements getStatements(AbstractDao<T2, ?> dao) {\n        return dao.getStatements();\n    }\n\n}"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/InternalUnitTestDaoAccess.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao;\n\nimport android.database.Cursor;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.identityscope.IdentityScope;\nimport org.greenrobot.greendao.internal.DaoConfig;\n\nimport java.lang.reflect.Constructor;\n\n/** Reserved for internal unit tests that want to access some non-public methods. Don't use for anything else. */\npublic class InternalUnitTestDaoAccess<T, K> {\n    private final AbstractDao<T, K> dao;\n\n    public InternalUnitTestDaoAccess(Database db, Class<AbstractDao<T, K>> daoClass, IdentityScope<?, ?> identityScope)\n            throws Exception {\n        DaoConfig daoConfig = new DaoConfig(db, daoClass);\n        daoConfig.setIdentityScope(identityScope);\n        Constructor<AbstractDao<T, K>> constructor = daoClass.getConstructor(DaoConfig.class);\n        dao = constructor.newInstance(daoConfig);\n    }\n\n    public K getKey(T entity) {\n        return dao.getKey(entity);\n    }\n\n    public Property[] getProperties() {\n        return dao.getProperties();\n    }\n\n    public boolean isEntityUpdateable() {\n        return dao.isEntityUpdateable();\n    }\n\n    public T readEntity(Cursor cursor, int offset) {\n        return dao.readEntity(cursor, offset);\n    }\n\n    public K readKey(Cursor cursor, int offset) {\n        return dao.readKey(cursor, offset);\n    }\n\n    public AbstractDao<T, K> getDao() {\n        return dao;\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/Property.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao;\n\nimport java.util.Collection;\n\nimport org.greenrobot.greendao.internal.SqlUtils;\nimport org.greenrobot.greendao.query.WhereCondition;\nimport org.greenrobot.greendao.query.WhereCondition.PropertyCondition;\n\n/**\n * Meta data describing a property mapped to a database column; used to create WhereCondition object used by the query builder.\n * \n * @author Markus\n */\npublic class Property {\n    public final int ordinal;\n    public final Class<?> type;\n    public final String name;\n    public final boolean primaryKey;\n    public final String columnName;\n\n    public Property(int ordinal, Class<?> type, String name, boolean primaryKey, String columnName) {\n        this.ordinal = ordinal;\n        this.type = type;\n        this.name = name;\n        this.primaryKey = primaryKey;\n        this.columnName = columnName;\n    }\n\n    /** Creates an \"equal ('=')\" condition  for this property. */\n    public WhereCondition eq(Object value) {\n        return new PropertyCondition(this, \"=?\", value);\n    }\n\n    /** Creates an \"not equal ('&lt;&gt;')\" condition  for this property. */\n    public WhereCondition notEq(Object value) {\n        return new PropertyCondition(this, \"<>?\", value);\n    }\n\n    /** Creates an \"LIKE\" condition  for this property. */\n    public WhereCondition like(String value) {\n        return new PropertyCondition(this, \" LIKE ?\", value);\n    }\n\n    /** Creates an \"BETWEEN ... AND ...\" condition  for this property. */\n    public WhereCondition between(Object value1, Object value2) {\n        Object[] values = { value1, value2 };\n        return new PropertyCondition(this, \" BETWEEN ? AND ?\", values);\n    }\n\n    /** Creates an \"IN (..., ..., ...)\" condition  for this property. */\n    public WhereCondition in(Object... inValues) {\n        StringBuilder condition = new StringBuilder(\" IN (\");\n        SqlUtils.appendPlaceholders(condition, inValues.length).append(')');\n        return new PropertyCondition(this, condition.toString(), inValues);\n    }\n\n    /** Creates an \"IN (..., ..., ...)\" condition  for this property. */\n    public WhereCondition in(Collection<?> inValues) {\n        return in(inValues.toArray());\n    }\n\n    /** Creates an \"NOT IN (..., ..., ...)\" condition  for this property. */\n    public WhereCondition notIn(Object... notInValues) {\n        StringBuilder condition = new StringBuilder(\" NOT IN (\");\n        SqlUtils.appendPlaceholders(condition, notInValues.length).append(')');\n        return new PropertyCondition(this, condition.toString(), notInValues);\n    }\n\n    /** Creates an \"NOT IN (..., ..., ...)\" condition  for this property. */\n    public WhereCondition notIn(Collection<?> notInValues) {\n        return notIn(notInValues.toArray());\n    }\n\n    /** Creates an \"greater than ('&gt;')\" condition  for this property. */\n    public WhereCondition gt(Object value) {\n        return new PropertyCondition(this, \">?\", value);\n    }\n\n    /** Creates an \"less than ('&lt;')\" condition  for this property. */\n    public WhereCondition lt(Object value) {\n        return new PropertyCondition(this, \"<?\", value);\n    }\n\n    /** Creates an \"greater or equal ('&gt;=')\" condition  for this property. */\n    public WhereCondition ge(Object value) {\n        return new PropertyCondition(this, \">=?\", value);\n    }\n\n    /** Creates an \"less or equal ('&lt;=')\" condition  for this property. */\n    public WhereCondition le(Object value) {\n        return new PropertyCondition(this, \"<=?\", value);\n    }\n\n    /** Creates an \"IS NULL\" condition  for this property. */\n    public WhereCondition isNull() {\n        return new PropertyCondition(this, \" IS NULL\");\n    }\n\n    /** Creates an \"IS NOT NULL\" condition  for this property. */\n    public WhereCondition isNotNull() {\n        return new PropertyCondition(this, \" IS NOT NULL\");\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/async/AsyncDaoException.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.async;\n\nimport org.greenrobot.greendao.DaoException;\n\n/**\n * Used here: {@link AsyncOperation#getResult()}.\n * \n * @author Markus\n */\npublic class AsyncDaoException extends DaoException {\n\n    private static final long serialVersionUID = 5872157552005102382L;\n\n    private final AsyncOperation failedOperation;\n\n    public AsyncDaoException(AsyncOperation failedOperation, Throwable cause) {\n        super(cause);\n        this.failedOperation = failedOperation;\n    }\n\n    public AsyncOperation getFailedOperation() {\n        return failedOperation;\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/async/AsyncOperation.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.async;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.database.Database;\n\n/**\n * An operation that will be enqueued for asynchronous execution.\n *\n * @author Markus\n * @see AsyncSession\n */\n// TODO Implement Future<V>\npublic class AsyncOperation {\n    public enum OperationType {\n        Insert, InsertInTxIterable, InsertInTxArray, //\n        InsertOrReplace, InsertOrReplaceInTxIterable, InsertOrReplaceInTxArray, //\n        Update, UpdateInTxIterable, UpdateInTxArray, //\n        Delete, DeleteInTxIterable, DeleteInTxArray, //\n        DeleteByKey, DeleteAll, //\n        TransactionRunnable, TransactionCallable, //\n        QueryList, QueryUnique, //\n        Load, LoadAll, //\n        Count, Refresh\n    }\n\n    public static final int FLAG_MERGE_TX = 1;\n\n    /** TODO unused, just an idea */\n    public static final int FLAG_STOP_QUEUE_ON_EXCEPTION = 1 << 1;\n    public static final int FLAG_TRACK_CREATOR_STACKTRACE = 1 << 2;\n\n    final OperationType type;\n    final AbstractDao<Object, Object> dao;\n    private final Database database;\n    /** Entity, Iterable<Entity>, Entity[], or Runnable. */\n    final Object parameter;\n    final int flags;\n\n    volatile long timeStarted;\n    volatile long timeCompleted;\n    private volatile boolean completed;\n    volatile Throwable throwable;\n    final Exception creatorStacktrace;\n    volatile Object result;\n    volatile int mergedOperationsCount;\n\n    int sequenceNumber;\n\n    @SuppressWarnings(\"unchecked\")\n    /** Either supply dao or database (set other to null). */\n    AsyncOperation(OperationType type, AbstractDao<?, ?> dao, Database database, Object parameter, int flags) {\n        this.type = type;\n        this.flags = flags;\n        this.dao = (AbstractDao<Object, Object>) dao;\n        this.database = database;\n        this.parameter = parameter;\n        creatorStacktrace = (flags & FLAG_TRACK_CREATOR_STACKTRACE) != 0 ? new Exception(\"AsyncOperation was created here\") : null;\n    }\n\n    public Throwable getThrowable() {\n        return throwable;\n    }\n\n    public void setThrowable(Throwable throwable) {\n        this.throwable = throwable;\n    }\n\n    public OperationType getType() {\n        return type;\n    }\n\n    public Object getParameter() {\n        return parameter;\n    }\n\n    /**\n     * The operation's result after it has completed. Waits until a result is available.\n     *\n     * @return The operation's result or null if the operation type does not produce any result.\n     * @throws {@link AsyncDaoException} if the operation produced an exception\n     * @see #waitForCompletion()\n     */\n    public synchronized Object getResult() {\n        if (!completed) {\n            waitForCompletion();\n        }\n        if (throwable != null) {\n            throw new AsyncDaoException(this, throwable);\n        }\n        return result;\n    }\n\n    /** @return true if this operation may be merged with others into a single database transaction. */\n    public boolean isMergeTx() {\n        return (flags & FLAG_MERGE_TX) != 0;\n    }\n\n    Database getDatabase() {\n        return database != null ? database : dao.getDatabase();\n    }\n\n    /**\n     * @return true if this operation is mergeable with the given operation. Checks for null, {@link #FLAG_MERGE_TX},\n     * and if the database instances match.\n     */\n    boolean isMergeableWith(AsyncOperation other) {\n        return other != null && isMergeTx() && other.isMergeTx() && getDatabase() == other.getDatabase();\n    }\n\n    public long getTimeStarted() {\n        return timeStarted;\n    }\n\n    public long getTimeCompleted() {\n        return timeCompleted;\n    }\n\n    public long getDuration() {\n        if (timeCompleted == 0) {\n            throw new DaoException(\"This operation did not yet complete\");\n        } else {\n            return timeCompleted - timeStarted;\n        }\n    }\n\n    public boolean isFailed() {\n        return throwable != null;\n    }\n\n    public boolean isCompleted() {\n        return completed;\n    }\n\n    /**\n     * Waits until the operation is complete. If the thread gets interrupted, any {@link InterruptedException} will be\n     * rethrown as a {@link DaoException}.\n     *\n     * @return Result if any, see {@link #getResult()}\n     */\n    public synchronized Object waitForCompletion() {\n        while (!completed) {\n            try {\n                wait();\n            } catch (InterruptedException e) {\n                throw new DaoException(\"Interrupted while waiting for operation to complete\", e);\n            }\n        }\n        return result;\n    }\n\n    /**\n     * Waits until the operation is complete, but at most the given amount of milliseconds.If the thread gets\n     * interrupted, any {@link InterruptedException} will be rethrown as a {@link DaoException}.\n     *\n     * @return true if the operation completed in the given time frame.\n     */\n    public synchronized boolean waitForCompletion(int maxMillis) {\n        if (!completed) {\n            try {\n                wait(maxMillis);\n            } catch (InterruptedException e) {\n                throw new DaoException(\"Interrupted while waiting for operation to complete\", e);\n            }\n        }\n        return completed;\n    }\n\n    /** Called when the operation is done. Notifies any threads waiting for this operation's completion. */\n    synchronized void setCompleted() {\n        completed = true;\n        notifyAll();\n    }\n\n    public boolean isCompletedSucessfully() {\n        return completed && throwable == null;\n    }\n\n    /**\n     * If this operation was successfully merged with other operation into a single TX, this will give the count of\n     * merged operations. If the operation was not merged, it will be 0.\n     */\n    public int getMergedOperationsCount() {\n        return mergedOperationsCount;\n    }\n\n    /**\n     * Each operation get a unique sequence number when the operation is enqueued. Can be used for efficiently\n     * identifying/mapping operations.\n     */\n    public int getSequenceNumber() {\n        return sequenceNumber;\n    }\n\n    /** Reset to prepare another execution run. */\n    void reset() {\n        timeStarted = 0;\n        timeCompleted = 0;\n        completed = false;\n        throwable = null;\n        result = null;\n        mergedOperationsCount = 0;\n    }\n\n    /**\n     * The stacktrace is captured using an exception if {@link #FLAG_TRACK_CREATOR_STACKTRACE} was used (null\n     * otherwise).\n     */\n    public Exception getCreatorStacktrace() {\n        return creatorStacktrace;\n    }\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/async/AsyncOperationExecutor.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.async;\n\nimport android.os.Handler;\nimport android.os.Looper;\nimport android.os.Message;\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.query.Query;\n\nimport java.util.ArrayList;\nimport java.util.concurrent.BlockingQueue;\nimport java.util.concurrent.Callable;\nimport java.util.concurrent.ExecutorService;\nimport java.util.concurrent.Executors;\nimport java.util.concurrent.LinkedBlockingQueue;\nimport java.util.concurrent.TimeUnit;\n\nclass AsyncOperationExecutor implements Runnable, Handler.Callback {\n\n    private static ExecutorService executorService = Executors.newCachedThreadPool();\n\n    private final BlockingQueue<AsyncOperation> queue;\n    private volatile boolean executorRunning;\n    private volatile int maxOperationCountToMerge;\n    private volatile AsyncOperationListener listener;\n    private volatile AsyncOperationListener listenerMainThread;\n    private volatile int waitForMergeMillis;\n\n    private int countOperationsEnqueued;\n    private int countOperationsCompleted;\n\n    private Handler handlerMainThread;\n    private int lastSequenceNumber;\n\n    AsyncOperationExecutor() {\n        queue = new LinkedBlockingQueue<AsyncOperation>();\n        maxOperationCountToMerge = 50;\n        waitForMergeMillis = 50;\n    }\n\n    public void enqueue(AsyncOperation operation) {\n        synchronized (this) {\n            operation.sequenceNumber = ++lastSequenceNumber;\n            queue.add(operation);\n            countOperationsEnqueued++;\n            if (!executorRunning) {\n                executorRunning = true;\n                executorService.execute(this);\n            }\n        }\n    }\n\n    public int getMaxOperationCountToMerge() {\n        return maxOperationCountToMerge;\n    }\n\n    public void setMaxOperationCountToMerge(int maxOperationCountToMerge) {\n        this.maxOperationCountToMerge = maxOperationCountToMerge;\n    }\n\n    public int getWaitForMergeMillis() {\n        return waitForMergeMillis;\n    }\n\n    public void setWaitForMergeMillis(int waitForMergeMillis) {\n        this.waitForMergeMillis = waitForMergeMillis;\n    }\n\n    public AsyncOperationListener getListener() {\n        return listener;\n    }\n\n    public void setListener(AsyncOperationListener listener) {\n        this.listener = listener;\n    }\n\n    public AsyncOperationListener getListenerMainThread() {\n        return listenerMainThread;\n    }\n\n    public void setListenerMainThread(AsyncOperationListener listenerMainThread) {\n        this.listenerMainThread = listenerMainThread;\n    }\n\n    public synchronized boolean isCompleted() {\n        return countOperationsEnqueued == countOperationsCompleted;\n    }\n\n    /**\n     * Waits until all enqueued operations are complete. If the thread gets interrupted, any\n     * {@link InterruptedException} will be rethrown as a {@link DaoException}.\n     */\n    public synchronized void waitForCompletion() {\n        while (!isCompleted()) {\n            try {\n                wait();\n            } catch (InterruptedException e) {\n                throw new DaoException(\"Interrupted while waiting for all operations to complete\", e);\n            }\n        }\n    }\n\n    /**\n     * Waits until all enqueued operations are complete, but at most the given amount of milliseconds. If the thread\n     * gets interrupted, any {@link InterruptedException} will be rethrown as a {@link DaoException}.\n     *\n     * @return true if operations completed in the given time frame.\n     */\n    public synchronized boolean waitForCompletion(int maxMillis) {\n        if (!isCompleted()) {\n            try {\n                wait(maxMillis);\n            } catch (InterruptedException e) {\n                throw new DaoException(\"Interrupted while waiting for all operations to complete\", e);\n            }\n        }\n        return isCompleted();\n    }\n\n    @Override\n    public void run() {\n        try {\n            try {\n                while (true) {\n                    AsyncOperation operation = queue.poll(1, TimeUnit.SECONDS);\n                    if (operation == null) {\n                        synchronized (this) {\n                            // Check again, this time in synchronized to be in sync with enqueue(AsyncOperation)\n                            operation = queue.poll();\n                            if (operation == null) {\n                                // set flag while still inside synchronized\n                                executorRunning = false;\n                                return;\n                            }\n                        }\n                    }\n                    if (operation.isMergeTx()) {\n                        // Wait some ms for another operation to merge because a TX is expensive\n                        AsyncOperation operation2 = queue.poll(waitForMergeMillis, TimeUnit.MILLISECONDS);\n                        if (operation2 != null) {\n                            if (operation.isMergeableWith(operation2)) {\n                                mergeTxAndExecute(operation, operation2);\n                            } else {\n                                // Cannot merge, execute both\n                                executeOperationAndPostCompleted(operation);\n                                executeOperationAndPostCompleted(operation2);\n                            }\n                            continue;\n                        }\n                    }\n                    executeOperationAndPostCompleted(operation);\n                }\n            } catch (InterruptedException e) {\n                DaoLog.w(Thread.currentThread().getName() + \" was interruppted\", e);\n            }\n        } finally {\n            executorRunning = false;\n        }\n    }\n\n\n    /** Also checks for other operations in the queue that can be merged into the transaction. */\n    private void mergeTxAndExecute(AsyncOperation operation1, AsyncOperation operation2) {\n        ArrayList<AsyncOperation> mergedOps = new ArrayList<AsyncOperation>();\n        mergedOps.add(operation1);\n        mergedOps.add(operation2);\n\n        Database db = operation1.getDatabase();\n        db.beginTransaction();\n        boolean success = false;\n        try {\n            for (int i = 0; i < mergedOps.size(); i++) {\n                AsyncOperation operation = mergedOps.get(i);\n                executeOperation(operation);\n                if (operation.isFailed()) {\n                    // Operation may still have changed the DB, roll back everything\n                    break;\n                }\n                if (i == mergedOps.size() - 1) {\n                    AsyncOperation peekedOp = queue.peek();\n                    if (i < maxOperationCountToMerge && operation.isMergeableWith(peekedOp)) {\n                        AsyncOperation removedOp = queue.remove();\n                        if (removedOp != peekedOp) {\n                            // Paranoia check, should not occur unless threading is broken\n                            throw new DaoException(\"Internal error: peeked op did not match removed op\");\n                        }\n                        mergedOps.add(removedOp);\n                    } else {\n                        // No more ops in the queue to merge, finish it\n                        db.setTransactionSuccessful();\n                        success = true;\n                        break;\n                    }\n                }\n            }\n        } finally {\n            try {\n                db.endTransaction();\n            } catch (RuntimeException e) {\n                DaoLog.i(\"Async transaction could not be ended, success so far was: \" + success, e);\n                success = false;\n            }\n        }\n        if (success) {\n            int mergedCount = mergedOps.size();\n            for (AsyncOperation asyncOperation : mergedOps) {\n                asyncOperation.mergedOperationsCount = mergedCount;\n                handleOperationCompleted(asyncOperation);\n            }\n        } else {\n            DaoLog.i(\"Reverted merged transaction because one of the operations failed. Executing operations one by \" +\n                    \"one instead...\");\n            for (AsyncOperation asyncOperation : mergedOps) {\n                asyncOperation.reset();\n                executeOperationAndPostCompleted(asyncOperation);\n            }\n        }\n    }\n\n    private void handleOperationCompleted(AsyncOperation operation) {\n        operation.setCompleted();\n\n        AsyncOperationListener listenerToCall = listener;\n        if (listenerToCall != null) {\n            listenerToCall.onAsyncOperationCompleted(operation);\n        }\n        if (listenerMainThread != null) {\n            if (handlerMainThread == null) {\n                handlerMainThread = new Handler(Looper.getMainLooper(), this);\n            }\n            Message msg = handlerMainThread.obtainMessage(1, operation);\n            handlerMainThread.sendMessage(msg);\n        }\n        synchronized (this) {\n            countOperationsCompleted++;\n            if (countOperationsCompleted == countOperationsEnqueued) {\n                notifyAll();\n            }\n        }\n    }\n\n    private void executeOperationAndPostCompleted(AsyncOperation operation) {\n        executeOperation(operation);\n        handleOperationCompleted(operation);\n    }\n\n    @SuppressWarnings({\"unchecked\", \"rawtypes\"})\n    private void executeOperation(AsyncOperation operation) {\n        operation.timeStarted = System.currentTimeMillis();\n        try {\n            switch (operation.type) {\n                case Delete:\n                    operation.dao.delete(operation.parameter);\n                    break;\n                case DeleteInTxIterable:\n                    operation.dao.deleteInTx((Iterable<Object>) operation.parameter);\n                    break;\n                case DeleteInTxArray:\n                    operation.dao.deleteInTx((Object[]) operation.parameter);\n                    break;\n                case Insert:\n                    operation.dao.insert(operation.parameter);\n                    break;\n                case InsertInTxIterable:\n                    operation.dao.insertInTx((Iterable<Object>) operation.parameter);\n                    break;\n                case InsertInTxArray:\n                    operation.dao.insertInTx((Object[]) operation.parameter);\n                    break;\n                case InsertOrReplace:\n                    operation.dao.insertOrReplace(operation.parameter);\n                    break;\n                case InsertOrReplaceInTxIterable:\n                    operation.dao.insertOrReplaceInTx((Iterable<Object>) operation.parameter);\n                    break;\n                case InsertOrReplaceInTxArray:\n                    operation.dao.insertOrReplaceInTx((Object[]) operation.parameter);\n                    break;\n                case Update:\n                    operation.dao.update(operation.parameter);\n                    break;\n                case UpdateInTxIterable:\n                    operation.dao.updateInTx((Iterable<Object>) operation.parameter);\n                    break;\n                case UpdateInTxArray:\n                    operation.dao.updateInTx((Object[]) operation.parameter);\n                    break;\n                case TransactionRunnable:\n                    executeTransactionRunnable(operation);\n                    break;\n                case TransactionCallable:\n                    executeTransactionCallable(operation);\n                    break;\n                case QueryList:\n                    operation.result = ((Query) operation.parameter).forCurrentThread().list();\n                    break;\n                case QueryUnique:\n                    operation.result = ((Query) operation.parameter).forCurrentThread().unique();\n                    break;\n                case DeleteByKey:\n                    operation.dao.deleteByKey(operation.parameter);\n                    break;\n                case DeleteAll:\n                    operation.dao.deleteAll();\n                    break;\n                case Load:\n                    operation.result = operation.dao.load(operation.parameter);\n                    break;\n                case LoadAll:\n                    operation.result = operation.dao.loadAll();\n                    break;\n                case Count:\n                    operation.result = operation.dao.count();\n                    break;\n                case Refresh:\n                    operation.dao.refresh(operation.parameter);\n                    break;\n                default:\n                    throw new DaoException(\"Unsupported operation: \" + operation.type);\n            }\n        } catch (Throwable th) {\n            operation.throwable = th;\n        }\n        operation.timeCompleted = System.currentTimeMillis();\n        // Do not set it to completed here because it might be a merged TX\n    }\n\n    private void executeTransactionRunnable(AsyncOperation operation) {\n        Database db = operation.getDatabase();\n        db.beginTransaction();\n        try {\n            ((Runnable) operation.parameter).run();\n            db.setTransactionSuccessful();\n        } finally {\n            db.endTransaction();\n        }\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    private void executeTransactionCallable(AsyncOperation operation) throws Exception {\n        Database db = operation.getDatabase();\n        db.beginTransaction();\n        try {\n            operation.result = ((Callable<Object>) operation.parameter).call();\n            db.setTransactionSuccessful();\n        } finally {\n            db.endTransaction();\n        }\n    }\n\n    @Override\n    public boolean handleMessage(Message msg) {\n        AsyncOperationListener listenerToCall = listenerMainThread;\n        if (listenerToCall != null) {\n            listenerToCall.onAsyncOperationCompleted((AsyncOperation) msg.obj);\n        }\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/async/AsyncOperationListener.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.async;\n\n/** Listener being called after completion of {@link org.greenrobot.greendao.async.AsyncOperation}. */\npublic interface AsyncOperationListener {\n    /**\n     * Note, that the operation may not have been successful, check\n     * {@link AsyncOperation#isFailed()} and/or {@link AsyncOperation#getThrowable()} for error situations.\n     */\n    void onAsyncOperationCompleted(AsyncOperation operation);\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/async/AsyncSession.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.async;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.AbstractDaoSession;\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.async.AsyncOperation.OperationType;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.query.Query;\n\nimport java.util.concurrent.Callable;\n\n/**\n * Asynchronous interface to entity operations. All operations will enqueued a @link {@link AsyncOperation} and return\n * immediately (fine to call on the UI/main thread). The queue will be processed in a (single) background thread. The\n * processing order is the call order of the operations. It's possible to start multiple AsyncSessions that will\n * execute\n * concurrently.\n *\n * @author Markus\n * @see AbstractDaoSession#startAsyncSession()\n */\n// Facade to AsyncOperationExecutor: prepares operations and delegates work to AsyncOperationExecutor.\npublic class AsyncSession {\n    private final AbstractDaoSession daoSession;\n    private final AsyncOperationExecutor executor;\n    private int sessionFlags;\n\n    public AsyncSession(AbstractDaoSession daoSession) {\n        this.daoSession = daoSession;\n        this.executor = new AsyncOperationExecutor();\n    }\n\n    public int getMaxOperationCountToMerge() {\n        return executor.getMaxOperationCountToMerge();\n    }\n\n    public void setMaxOperationCountToMerge(int maxOperationCountToMerge) {\n        executor.setMaxOperationCountToMerge(maxOperationCountToMerge);\n    }\n\n    public int getWaitForMergeMillis() {\n        return executor.getWaitForMergeMillis();\n    }\n\n    public void setWaitForMergeMillis(int waitForMergeMillis) {\n        executor.setWaitForMergeMillis(waitForMergeMillis);\n    }\n\n    public AsyncOperationListener getListener() {\n        return executor.getListener();\n    }\n\n    public void setListener(AsyncOperationListener listener) {\n        executor.setListener(listener);\n    }\n\n    public AsyncOperationListener getListenerMainThread() {\n        return executor.getListenerMainThread();\n    }\n\n    public void setListenerMainThread(AsyncOperationListener listenerMainThread) {\n        executor.setListenerMainThread(listenerMainThread);\n    }\n\n    public boolean isCompleted() {\n        return executor.isCompleted();\n    }\n\n    /**\n     * Waits until all enqueued operations are complete. If the thread gets interrupted, any\n     * {@link InterruptedException} will be rethrown as a {@link DaoException}.\n     */\n    public void waitForCompletion() {\n        executor.waitForCompletion();\n    }\n\n    /**\n     * Waits until all enqueued operations are complete, but at most the given amount of milliseconds. If the thread\n     * gets interrupted, any {@link InterruptedException} will be rethrown as a {@link DaoException}.\n     *\n     * @return true if operations completed in the given time frame.\n     */\n    public boolean waitForCompletion(int maxMillis) {\n        return executor.waitForCompletion(maxMillis);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#insert(Object)}. */\n    public AsyncOperation insert(Object entity) {\n        return insert(entity, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#insert(Object)}. */\n    public AsyncOperation insert(Object entity, int flags) {\n        return enqueueEntityOperation(OperationType.Insert, entity, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#insertInTx(Object...)}. */\n    public <E> AsyncOperation insertInTx(Class<E> entityClass, E... entities) {\n        return insertInTx(entityClass, 0, entities);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#insertInTx(Object...)}. */\n    public <E> AsyncOperation insertInTx(Class<E> entityClass, int flags, E... entities) {\n        return enqueEntityOperation(OperationType.InsertInTxArray, entityClass, entities, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#insertInTx(Iterable)}. */\n    public <E> AsyncOperation insertInTx(Class<E> entityClass, Iterable<E> entities) {\n        return insertInTx(entityClass, entities, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#insertInTx(Iterable)}. */\n    public <E> AsyncOperation insertInTx(Class<E> entityClass, Iterable<E> entities, int flags) {\n        return enqueEntityOperation(OperationType.InsertInTxIterable, entityClass, entities, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#insertOrReplace(Object)}. */\n    public AsyncOperation insertOrReplace(Object entity) {\n        return insertOrReplace(entity, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#insertOrReplace(Object)}. */\n    public AsyncOperation insertOrReplace(Object entity, int flags) {\n        return enqueueEntityOperation(OperationType.InsertOrReplace, entity, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#insertOrReplaceInTx(Object...)}. */\n    public <E> AsyncOperation insertOrReplaceInTx(Class<E> entityClass, E... entities) {\n        return insertOrReplaceInTx(entityClass, 0, entities);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#insertOrReplaceInTx(Object...)}. */\n    public <E> AsyncOperation insertOrReplaceInTx(Class<E> entityClass, int flags, E... entities) {\n        return enqueEntityOperation(OperationType.InsertOrReplaceInTxArray, entityClass, entities, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#insertOrReplaceInTx(Iterable)}. */\n    public <E> AsyncOperation insertOrReplaceInTx(Class<E> entityClass, Iterable<E> entities) {\n        return insertOrReplaceInTx(entityClass, entities, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#insertOrReplaceInTx(Iterable)}. */\n    public <E> AsyncOperation insertOrReplaceInTx(Class<E> entityClass, Iterable<E> entities, int flags) {\n        return enqueEntityOperation(OperationType.InsertOrReplaceInTxIterable, entityClass, entities, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#update(Object)}. */\n    public AsyncOperation update(Object entity) {\n        return update(entity, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#update(Object)}. */\n    public AsyncOperation update(Object entity, int flags) {\n        return enqueueEntityOperation(OperationType.Update, entity, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#updateInTx(Object...)}. */\n    public <E> AsyncOperation updateInTx(Class<E> entityClass, E... entities) {\n        return updateInTx(entityClass, 0, entities);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#updateInTx(Object...)}. */\n    public <E> AsyncOperation updateInTx(Class<E> entityClass, int flags, E... entities) {\n        return enqueEntityOperation(OperationType.UpdateInTxArray, entityClass, entities, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#updateInTx(Iterable)}. */\n    public <E> AsyncOperation updateInTx(Class<E> entityClass, Iterable<E> entities) {\n        return updateInTx(entityClass, entities, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#updateInTx(Iterable)}. */\n    public <E> AsyncOperation updateInTx(Class<E> entityClass, Iterable<E> entities, int flags) {\n        return enqueEntityOperation(OperationType.UpdateInTxIterable, entityClass, entities, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#delete(Object)}. */\n    public AsyncOperation delete(Object entity) {\n        return delete(entity, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#delete(Object)}. */\n    public AsyncOperation delete(Object entity, int flags) {\n        return enqueueEntityOperation(OperationType.Delete, entity, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#deleteByKey(Object)}. */\n    public AsyncOperation deleteByKey(Object key) {\n        return deleteByKey(key, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#deleteByKey(Object)}. */\n    public AsyncOperation deleteByKey(Object key, int flags) {\n        return enqueueEntityOperation(OperationType.DeleteByKey, key, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#deleteInTx(Object...)}. */\n    public <E> AsyncOperation deleteInTx(Class<E> entityClass, E... entities) {\n        return deleteInTx(entityClass, 0, entities);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#deleteInTx(Object...)}. */\n    public <E> AsyncOperation deleteInTx(Class<E> entityClass, int flags, E... entities) {\n        return enqueEntityOperation(OperationType.DeleteInTxArray, entityClass, entities, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#deleteInTx(Iterable)}. */\n    public <E> AsyncOperation deleteInTx(Class<E> entityClass, Iterable<E> entities) {\n        return deleteInTx(entityClass, entities, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#deleteInTx(Iterable)}. */\n    public <E> AsyncOperation deleteInTx(Class<E> entityClass, Iterable<E> entities, int flags) {\n        return enqueEntityOperation(OperationType.DeleteInTxIterable, entityClass, entities, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#deleteAll()}. */\n    public <E> AsyncOperation deleteAll(Class<E> entityClass) {\n        return deleteAll(entityClass, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#deleteAll()}. */\n    public <E> AsyncOperation deleteAll(Class<E> entityClass, int flags) {\n        return enqueEntityOperation(OperationType.DeleteAll, entityClass, null, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDaoSession#runInTx(Runnable)}. */\n    public AsyncOperation runInTx(Runnable runnable) {\n        return runInTx(runnable, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDaoSession#runInTx(Runnable)}. */\n    public AsyncOperation runInTx(Runnable runnable, int flags) {\n        return enqueueDatabaseOperation(OperationType.TransactionRunnable, runnable, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDaoSession#callInTx(Callable)}. */\n    public AsyncOperation callInTx(Callable<?> callable) {\n        return callInTx(callable, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDaoSession#callInTx(Callable)}. */\n    public AsyncOperation callInTx(Callable<?> callable, int flags) {\n        return enqueueDatabaseOperation(OperationType.TransactionCallable, callable, flags);\n    }\n\n    /** Asynchronous version of {@link Query#list()}. */\n    public AsyncOperation queryList(Query<?> query) {\n        return queryList(query, 0);\n    }\n\n    /** Asynchronous version of {@link Query#list()}. */\n    public AsyncOperation queryList(Query<?> query, int flags) {\n        return enqueueDatabaseOperation(OperationType.QueryList, query, flags);\n    }\n\n    /** Asynchronous version of {@link Query#unique()}. */\n    public AsyncOperation queryUnique(Query<?> query) {\n        return queryUnique(query, 0);\n    }\n\n    /** Asynchronous version of {@link Query#unique()}. */\n    public AsyncOperation queryUnique(Query<?> query, int flags) {\n        return enqueueDatabaseOperation(OperationType.QueryUnique, query, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#load(Object)}. */\n    public AsyncOperation load(Class<?> entityClass, Object key) {\n        return load(entityClass, key, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#load(Object)}. */\n    public AsyncOperation load(Class<?> entityClass, Object key, int flags) {\n        return enqueEntityOperation(OperationType.Load, entityClass, key, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#loadAll()}. */\n    public AsyncOperation loadAll(Class<?> entityClass) {\n        return loadAll(entityClass, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#loadAll()}. */\n    public AsyncOperation loadAll(Class<?> entityClass, int flags) {\n        return enqueEntityOperation(OperationType.LoadAll, entityClass, null, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#count()}. */\n    public AsyncOperation count(Class<?> entityClass) {\n        return count(entityClass, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#count()}. */\n    public AsyncOperation count(Class<?> entityClass, int flags) {\n        return enqueEntityOperation(OperationType.Count, entityClass, null, flags);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#refresh(Object)}. */\n    public AsyncOperation refresh(Object entity) {\n        return refresh(entity, 0);\n    }\n\n    /** Asynchronous version of {@link AbstractDao#refresh(Object)}. */\n    public AsyncOperation refresh(Object entity, int flags) {\n        return enqueueEntityOperation(OperationType.Refresh, entity, flags);\n    }\n\n    private AsyncOperation enqueueDatabaseOperation(OperationType type, Object param, int flags) {\n        Database database = daoSession.getDatabase();\n        AsyncOperation operation = new AsyncOperation(type, null, database, param, flags | sessionFlags);\n        executor.enqueue(operation);\n        return operation;\n    }\n\n    private AsyncOperation enqueueEntityOperation(OperationType type, Object entity, int flags) {\n        return enqueEntityOperation(type, entity.getClass(), entity, flags);\n    }\n\n    private <E> AsyncOperation enqueEntityOperation(OperationType type, Class<E> entityClass, Object param, int flags) {\n        AbstractDao<?, ?> dao = daoSession.getDao(entityClass);\n        AsyncOperation operation = new AsyncOperation(type, dao, null, param, flags | sessionFlags);\n        executor.enqueue(operation);\n        return operation;\n    }\n\n    /** {@link org.greenrobot.greendao.async.AsyncOperation} flags set for all operations (will be ORed with call flags). */\n    public int getSessionFlags() {\n        return sessionFlags;\n    }\n\n    /** {@link org.greenrobot.greendao.async.AsyncOperation} flags set for all operations (will be ORed with call flags). */\n    public void setSessionFlags(int sessionFlags) {\n        this.sessionFlags = sessionFlags;\n    }\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/database/Database.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.database;\n\nimport android.database.Cursor;\nimport android.database.SQLException;\n\n/**\n * Database abstraction used internally by greenDAO.\n */\npublic interface Database {\n    Cursor rawQuery(String sql, String[] selectionArgs);\n\n    void execSQL(String sql) throws SQLException;\n\n    void beginTransaction();\n\n    void endTransaction();\n\n    boolean inTransaction();\n\n    void setTransactionSuccessful();\n\n    void execSQL(String sql, Object[] bindArgs) throws SQLException;\n\n    DatabaseStatement compileStatement(String sql);\n\n    boolean isDbLockedByCurrentThread();\n\n    boolean isOpen();\n\n    void close();\n\n    Object getRawDatabase();\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/database/DatabaseOpenHelper.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.database;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\nimport android.database.DatabaseErrorHandler;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.database.sqlite.SQLiteDatabase.CursorFactory;\nimport android.database.sqlite.SQLiteOpenHelper;\n\nimport org.greenrobot.greendao.DaoException;\n\nimport java.lang.reflect.Constructor;\n\n/**\n * SQLiteOpenHelper to allow working with greenDAO's {@link Database} abstraction to create and update database schemas.\n */\npublic abstract class DatabaseOpenHelper extends SQLiteOpenHelper {\n\n    private final Context context;\n    private final String name;\n    private final int version;\n\n    private EncryptedHelper encryptedHelper;\n    private boolean loadSQLCipherNativeLibs = true;\n\n    public DatabaseOpenHelper(Context context, String name, int version) {\n        this(context, name, null, version);\n    }\n\n    public DatabaseOpenHelper(Context context, String name, CursorFactory factory, int version) {\n        super(context, name, factory, version);\n        this.context = context;\n        this.name = name;\n        this.version = version;\n    }\n\n    @SuppressLint(\"NewApi\")\n    public DatabaseOpenHelper(Context context, String name, CursorFactory factory, int version, DatabaseErrorHandler errorHandler) {\n        super(context, name, factory, version, errorHandler);\n        this.context = context;\n        this.name = name;\n        this.version = version;\n    }\n\n    /**\n     * Flag to load SQLCipher native libs (default: true).\n     */\n    public void setLoadSQLCipherNativeLibs(boolean loadSQLCipherNativeLibs) {\n        this.loadSQLCipherNativeLibs = loadSQLCipherNativeLibs;\n    }\n\n    /**\n     * Like {@link #getWritableDatabase()}, but returns a greenDAO abstraction of the database.\n     * The backing DB is an standard {@link SQLiteDatabase}.\n     */\n    public Database getWritableDb() {\n        return wrap(getWritableDatabase());\n    }\n\n    /**\n     * Like {@link #getReadableDatabase()}, but returns a greenDAO abstraction of the database.\n     * The backing DB is an standard {@link SQLiteDatabase}.\n     */\n    public Database getReadableDb() {\n        return wrap(getReadableDatabase());\n    }\n\n    protected Database wrap(SQLiteDatabase sqLiteDatabase) {\n        return new StandardDatabase(sqLiteDatabase);\n    }\n\n    /**\n     * Delegates to {@link #onCreate(Database)}, which uses greenDAO's database abstraction.\n     */\n    @Override\n    public void onCreate(SQLiteDatabase db) {\n        onCreate(wrap(db));\n    }\n\n    /**\n     * Override this if you do not want to depend on {@link SQLiteDatabase}.\n     */\n    public void onCreate(Database db) {\n        // Do nothing by default\n    }\n\n    /**\n     * Delegates to {@link #onUpgrade(Database, int, int)}, which uses greenDAO's database abstraction.\n     */\n    @Override\n    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\n        onUpgrade(wrap(db), oldVersion, newVersion);\n    }\n\n    /**\n     * Override this if you do not want to depend on {@link SQLiteDatabase}.\n     */\n    public void onUpgrade(Database db, int oldVersion, int newVersion) {\n        // Do nothing by default\n    }\n\n    /**\n     * Delegates to {@link #onOpen(Database)}, which uses greenDAO's database abstraction.\n     */\n    @Override\n    public void onOpen(SQLiteDatabase db) {\n        onOpen(wrap(db));\n    }\n\n    /**\n     * Override this if you do not want to depend on {@link SQLiteDatabase}.\n     */\n    public void onOpen(Database db) {\n        // Do nothing by default\n    }\n\n    interface EncryptedHelper {\n        Database getEncryptedReadableDb(String password);\n        Database getEncryptedReadableDb(char[] password);\n        Database getEncryptedWritableDb(String password);\n        Database getEncryptedWritableDb(char[] password);\n    }\n\n    private EncryptedHelper checkEncryptedHelper() {\n        if (encryptedHelper == null) {\n            try {\n                Class.forName(\"net.sqlcipher.database.SQLiteOpenHelper\");\n            } catch (ClassNotFoundException e) {\n                throw new DaoException(\"Using an encrypted database requires SQLCipher, \" +\n                        \"make sure to add it to dependencies: \" +\n                        \"https://greenrobot.org/greendao/documentation/database-encryption/\");\n            }\n\n            // Avoid referencing SqlCipherEncryptedHelper to avoid\n            // \"Rejecting re-init on previously-failed class java.lang.NoClassDefFoundError\" logs\n            // if SQLCipher is not in classpath.\n            try {\n                Class<?> helperClass = Class.forName(\n                        \"org.greenrobot.greendao.database.SqlCipherEncryptedHelper\");\n                Constructor<?> constructor = helperClass.getConstructor(\n                        DatabaseOpenHelper.class, Context.class, String.class, int.class, boolean.class);\n                encryptedHelper = (EncryptedHelper) constructor.newInstance(\n                        this, context, name, version, loadSQLCipherNativeLibs);\n            } catch (Exception e) {\n                throw new DaoException(e);\n            }\n        }\n        return encryptedHelper;\n    }\n\n    /**\n     * Use this to initialize an encrypted SQLCipher database.\n     *\n     * @see #onCreate(Database)\n     * @see #onUpgrade(Database, int, int)\n     */\n    public Database getEncryptedWritableDb(String password) {\n        EncryptedHelper encryptedHelper = checkEncryptedHelper();\n        return encryptedHelper.getEncryptedWritableDb(password);\n    }\n\n    /**\n     * Use this to initialize an encrypted SQLCipher database.\n     *\n     * @see #onCreate(Database)\n     * @see #onUpgrade(Database, int, int)\n     */\n    public Database getEncryptedWritableDb(char[] password) {\n        EncryptedHelper encryptedHelper = checkEncryptedHelper();\n        return encryptedHelper.getEncryptedWritableDb(password);\n    }\n\n    /**\n     * Use this to initialize an encrypted SQLCipher database.\n     *\n     * @see #onCreate(Database)\n     * @see #onUpgrade(Database, int, int)\n     */\n    public Database getEncryptedReadableDb(String password) {\n        EncryptedHelper encryptedHelper = checkEncryptedHelper();\n        return encryptedHelper.getEncryptedReadableDb(password);\n    }\n\n    /**\n     * Use this to initialize an encrypted SQLCipher database.\n     *\n     * @see #onCreate(Database)\n     * @see #onUpgrade(Database, int, int)\n     */\n    public Database getEncryptedReadableDb(char[] password) {\n        EncryptedHelper encryptedHelper = checkEncryptedHelper();\n        return encryptedHelper.getEncryptedReadableDb(password);\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/database/DatabaseStatement.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.database;\n\npublic interface DatabaseStatement {\n    void execute();\n\n    long simpleQueryForLong();\n\n    void bindNull(int index);\n\n    long executeInsert();\n\n    void bindString(int index, String value);\n\n    void bindBlob(int index, byte[] value);\n\n    void bindLong(int index, long value);\n\n    void clearBindings();\n\n    void bindDouble(int index, double value);\n\n    void close();\n\n    Object getRawStatement();\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/database/EncryptedDatabase.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.database;\n\nimport android.database.Cursor;\nimport android.database.SQLException;\nimport net.sqlcipher.database.SQLiteDatabase;\n\npublic class EncryptedDatabase implements Database {\n    private final SQLiteDatabase delegate;\n\n    public EncryptedDatabase(SQLiteDatabase delegate) {\n        this.delegate = delegate;\n    }\n\n    @Override\n    public Cursor rawQuery(String sql, String[] selectionArgs) {\n        return delegate.rawQuery(sql, selectionArgs);\n    }\n\n    @Override\n    public void execSQL(String sql) throws SQLException {\n        delegate.execSQL(sql);\n    }\n\n    @Override\n    public void beginTransaction() {\n        delegate.beginTransaction();\n    }\n\n    @Override\n    public void endTransaction() {\n        delegate.endTransaction();\n    }\n\n    @Override\n    public boolean inTransaction() {\n        return delegate.inTransaction();\n    }\n\n    @Override\n    public void setTransactionSuccessful() {\n        delegate.setTransactionSuccessful();\n    }\n\n    @Override\n    public void execSQL(String sql, Object[] bindArgs) throws SQLException {\n        delegate.execSQL(sql, bindArgs);\n    }\n\n    @Override\n    public DatabaseStatement compileStatement(String sql) {\n        return new EncryptedDatabaseStatement(delegate.compileStatement(sql));\n    }\n\n    @Override\n    public boolean isDbLockedByCurrentThread() {\n        return delegate.isDbLockedByCurrentThread();\n    }\n\n    @Override\n    public boolean isOpen() {\n        return delegate.isOpen();\n    }\n\n    @Override\n    public void close() {\n        delegate.close();\n    }\n\n    @Override\n    public Object getRawDatabase() {\n        return delegate;\n    }\n\n    public SQLiteDatabase getSQLiteDatabase() {\n        return delegate;\n    }\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/database/EncryptedDatabaseStatement.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.database;\n\n\nimport net.sqlcipher.database.SQLiteStatement;\n\npublic class EncryptedDatabaseStatement implements DatabaseStatement {\n    private final SQLiteStatement delegate;\n\n    public EncryptedDatabaseStatement(SQLiteStatement delegate) {\n        this.delegate = delegate;\n    }\n\n    @Override\n    public void execute() {\n        delegate.execute();\n    }\n\n    @Override\n    public long simpleQueryForLong() {\n        return delegate.simpleQueryForLong();\n    }\n\n    @Override\n    public void bindNull(int index) {\n        delegate.bindNull(index);\n    }\n\n    @Override\n    public long executeInsert() {\n        return delegate.executeInsert();\n    }\n\n    @Override\n    public void bindString(int index, String value) {\n        delegate.bindString(index, value);\n    }\n\n    @Override\n    public void bindBlob(int index, byte[] value) {\n        delegate.bindBlob(index, value);\n    }\n\n    @Override\n    public void bindLong(int index, long value) {\n        delegate.bindLong(index, value);\n    }\n\n    @Override\n    public void clearBindings() {\n        delegate.clearBindings();\n    }\n\n    @Override\n    public void bindDouble(int index, double value) {\n        delegate.bindDouble(index, value);\n    }\n\n    @Override\n    public void close() {\n        delegate.close();\n    }\n\n    @Override\n    public Object getRawStatement() {\n        return delegate;\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/database/SqlCipherEncryptedHelper.java",
    "content": "package org.greenrobot.greendao.database;\n\nimport android.content.Context;\n\nimport net.sqlcipher.database.SQLiteDatabase;\nimport net.sqlcipher.database.SQLiteOpenHelper;\n\nclass SqlCipherEncryptedHelper extends SQLiteOpenHelper implements DatabaseOpenHelper.EncryptedHelper {\n\n    private final DatabaseOpenHelper delegate;\n\n    public SqlCipherEncryptedHelper(DatabaseOpenHelper delegate, Context context, String name, int version, boolean loadLibs) {\n        super(context, name, null, version);\n        this.delegate = delegate;\n        if (loadLibs) {\n            SQLiteDatabase.loadLibs(context);\n        }\n    }\n\n    private Database wrap(SQLiteDatabase sqLiteDatabase) {\n        return new EncryptedDatabase(sqLiteDatabase);\n    }\n\n    @Override\n    public void onCreate(SQLiteDatabase db) {\n        delegate.onCreate(wrap(db));\n    }\n\n    @Override\n    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\n        delegate.onUpgrade(wrap(db), oldVersion, newVersion);\n    }\n\n    @Override\n    public void onOpen(SQLiteDatabase db) {\n        delegate.onOpen(wrap(db));\n    }\n\n    @Override\n    public Database getEncryptedReadableDb(String password) {\n        return wrap(getReadableDatabase(password));\n    }\n\n    @Override\n    public Database getEncryptedReadableDb(char[] password) {\n        return wrap(getReadableDatabase(password));\n    }\n\n    @Override\n    public Database getEncryptedWritableDb(String password) {\n        return wrap(getWritableDatabase(password));\n    }\n\n    @Override\n    public Database getEncryptedWritableDb(char[] password) {\n        return wrap(getWritableDatabase(password));\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/database/StandardDatabase.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.database;\n\nimport android.database.Cursor;\nimport android.database.SQLException;\nimport android.database.sqlite.SQLiteDatabase;\n\npublic class StandardDatabase implements Database {\n    private final SQLiteDatabase delegate;\n\n    public StandardDatabase(SQLiteDatabase delegate) {\n        this.delegate = delegate;\n    }\n\n    @Override\n    public Cursor rawQuery(String sql, String[] selectionArgs) {\n        return delegate.rawQuery(sql, selectionArgs);\n    }\n\n    @Override\n    public void execSQL(String sql) throws SQLException {\n        delegate.execSQL(sql);\n    }\n\n    @Override\n    public void beginTransaction() {\n        delegate.beginTransaction();\n    }\n\n    @Override\n    public void endTransaction() {\n        delegate.endTransaction();\n    }\n\n    @Override\n    public boolean inTransaction() {\n        return delegate.inTransaction();\n    }\n\n    @Override\n    public void setTransactionSuccessful() {\n        delegate.setTransactionSuccessful();\n    }\n\n    @Override\n    public void execSQL(String sql, Object[] bindArgs) throws SQLException {\n        delegate.execSQL(sql, bindArgs);\n    }\n\n    @Override\n    public DatabaseStatement compileStatement(String sql) {\n        return new StandardDatabaseStatement(delegate.compileStatement(sql));\n    }\n\n    @Override\n    public boolean isDbLockedByCurrentThread() {\n        return delegate.isDbLockedByCurrentThread();\n    }\n\n    @Override\n    public boolean isOpen() {\n        return delegate.isOpen();\n    }\n\n    @Override\n    public void close() {\n        delegate.close();\n    }\n\n    @Override\n    public Object getRawDatabase() {\n        return delegate;\n    }\n\n    public SQLiteDatabase getSQLiteDatabase() {\n        return delegate;\n    }\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/database/StandardDatabaseStatement.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.database;\n\nimport android.database.sqlite.SQLiteStatement;\n\npublic class StandardDatabaseStatement implements DatabaseStatement {\n    private final SQLiteStatement delegate;\n\n    public StandardDatabaseStatement(SQLiteStatement delegate) {\n        this.delegate = delegate;\n    }\n\n    @Override\n    public void execute() {\n        delegate.execute();\n    }\n\n    @Override\n    public long simpleQueryForLong() {\n        return delegate.simpleQueryForLong();\n    }\n\n    @Override\n    public void bindNull(int index) {\n        delegate.bindNull(index);\n    }\n\n    @Override\n    public long executeInsert() {\n        return delegate.executeInsert();\n    }\n\n    @Override\n    public void bindString(int index, String value) {\n        delegate.bindString(index, value);\n    }\n\n    @Override\n    public void bindBlob(int index, byte[] value) {\n        delegate.bindBlob(index, value);\n    }\n\n    @Override\n    public void bindLong(int index, long value) {\n        delegate.bindLong(index, value);\n    }\n\n    @Override\n    public void clearBindings() {\n        delegate.clearBindings();\n    }\n\n    @Override\n    public void bindDouble(int index, double value) {\n        delegate.bindDouble(index, value);\n    }\n\n    @Override\n    public void close() {\n        delegate.close();\n    }\n\n    @Override\n    public Object getRawStatement() {\n        return delegate;\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/identityscope/IdentityScope.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.identityscope;\n\n/**\n * Common interface for a identity scopes needed internally by greenDAO. Identity scopes let greenDAO re-use Java\n * objects.\n * \n * @author Markus\n * \n * @param <K>\n *            Key\n * @param <T>\n *            Entity\n */\npublic interface IdentityScope<K, T> {\n\n    T get(K key);\n\n    void put(K key, T entity);\n\n    T getNoLock(K key);\n\n    void putNoLock(K key, T entity);\n\n    boolean detach(K key, T entity);\n\n    void remove(K key);\n\n    void remove(Iterable<K> key);\n\n    void clear();\n\n    void lock();\n\n    void unlock();\n\n    void reserveRoom(int count);\n\n}"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/identityscope/IdentityScopeLong.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.identityscope;\n\nimport java.lang.ref.Reference;\nimport java.lang.ref.WeakReference;\nimport java.util.concurrent.locks.ReentrantLock;\n\nimport org.greenrobot.greendao.internal.LongHashMap;\n\n/**\n * The context for entity identities. Provides the scope in which entities will be tracked and managed.\n * \n * @author Markus\n * @param <T>\n *            Entity\n */\npublic class IdentityScopeLong<T> implements IdentityScope<Long, T> {\n    private final LongHashMap<Reference<T>> map;\n    private final ReentrantLock lock;\n\n    public IdentityScopeLong() {\n        map = new LongHashMap<Reference<T>>();\n        lock = new ReentrantLock();\n    }\n\n    @Override\n    public T get(Long key) {\n        return get2(key);\n    }\n\n    @Override\n    public T getNoLock(Long key) {\n        return get2NoLock(key);\n    }\n\n    public T get2(long key) {\n        lock.lock();\n        Reference<T> ref;\n        try {\n            ref = map.get(key);\n        } finally {\n            lock.unlock();\n        }\n        if (ref != null) {\n            return ref.get();\n        } else {\n            return null;\n        }\n    }\n\n    public T get2NoLock(long key) {\n        Reference<T> ref = map.get(key);\n        if (ref != null) {\n            return ref.get();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public void put(Long key, T entity) {\n        put2(key, entity);\n    }\n\n    @Override\n    public void putNoLock(Long key, T entity) {\n        put2NoLock(key, entity);\n    }\n\n    public void put2(long key, T entity) {\n        lock.lock();\n        try {\n            map.put(key, new WeakReference<T>(entity));\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    public void put2NoLock(long key, T entity) {\n        map.put(key, new WeakReference<T>(entity));\n    }\n\n    @Override\n    public boolean detach(Long key, T entity) {\n        lock.lock();\n        try {\n            if (get(key) == entity && entity != null) {\n                remove(key);\n                return true;\n            } else {\n                return false;\n            }\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    @Override\n    public void remove(Long key) {\n        lock.lock();\n        try {\n            map.remove(key);\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    @Override\n    public void remove(Iterable<Long> keys) {\n        lock.lock();\n        try {\n            for (Long key : keys) {\n                map.remove(key);\n            }\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    @Override\n    public void clear() {\n        lock.lock();\n        try {\n            map.clear();\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    @Override\n    public void lock() {\n        lock.lock();\n    }\n\n    @Override\n    public void unlock() {\n        lock.unlock();\n    }\n\n    @Override\n    public void reserveRoom(int count) {\n        map.reserveRoom(count);\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/identityscope/IdentityScopeObject.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.identityscope;\n\nimport java.lang.ref.Reference;\nimport java.lang.ref.WeakReference;\nimport java.util.HashMap;\nimport java.util.concurrent.locks.ReentrantLock;\n\n/**\n * The context for entity identities. Provides the scope in which entities will be tracked and managed.\n * \n * @author Markus\n * @param <K>\n * @param <T>\n */\npublic class IdentityScopeObject<K, T> implements IdentityScope<K, T> {\n    private final HashMap<K, Reference<T>> map;\n    private final ReentrantLock lock;\n\n    public IdentityScopeObject() {\n        map = new HashMap<K, Reference<T>>();\n        lock = new ReentrantLock();\n    }\n\n    @Override\n    public T get(K key) {\n        Reference<T> ref;\n        lock.lock();\n        try {\n            ref = map.get(key);\n        } finally {\n            lock.unlock();\n        }\n        if (ref != null) {\n            return ref.get();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public T getNoLock(K key) {\n        Reference<T> ref = map.get(key);\n        if (ref != null) {\n            return ref.get();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public void put(K key, T entity) {\n        lock.lock();\n        try {\n            map.put(key, new WeakReference<T>(entity));\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    @Override\n    public void putNoLock(K key, T entity) {\n        map.put(key, new WeakReference<T>(entity));\n    }\n\n    @Override\n    public boolean detach(K key, T entity) {\n        lock.lock();\n        try {\n            if (get(key) == entity && entity != null) {\n                remove(key);\n                return true;\n            } else {\n                return false;\n            }\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    @Override\n    public void remove(K key) {\n        lock.lock();\n        try {\n            map.remove(key);\n        } finally {\n            lock.unlock();\n        }\n    }\n    \n    @Override\n    public void remove(Iterable< K> keys) {\n        lock.lock();\n        try {\n            for (K key : keys) {\n                map.remove(key);\n            }\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    @Override\n    public void clear() {\n        lock.lock();\n        try {\n            map.clear();\n        } finally {\n            lock.unlock();\n        }\n    }\n\n    @Override\n    public void lock() {\n        lock.lock();\n    }\n\n    @Override\n    public void unlock() {\n        lock.unlock();\n    }\n\n    @Override\n    public void reserveRoom(int count) {\n        // HashMap does not allow\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/identityscope/IdentityScopeType.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.identityscope;\n\npublic enum IdentityScopeType {\n    Session, None\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/internal/DaoConfig.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.internal;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Modifier;\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.identityscope.IdentityScope;\nimport org.greenrobot.greendao.identityscope.IdentityScopeLong;\nimport org.greenrobot.greendao.identityscope.IdentityScopeObject;\nimport org.greenrobot.greendao.identityscope.IdentityScopeType;\n\n/**\n * Internal class used by greenDAO. DaoConfig stores essential data for DAOs, and is hold by AbstractDaoMaster. This\n * class will retrieve the required information from the DAO classes.\n */\npublic final class DaoConfig implements Cloneable {\n\n    public final Database db;\n    public final String tablename;\n    public final Property[] properties;\n\n    public final String[] allColumns;\n    public final String[] pkColumns;\n    public final String[] nonPkColumns;\n\n    /** Single property PK or null if there's no PK or a multi property PK. */\n    public final Property pkProperty;\n    public final boolean keyIsNumeric;\n    public final TableStatements statements;\n\n    private IdentityScope<?, ?> identityScope;\n\n    public DaoConfig(Database db, Class<? extends AbstractDao<?, ?>> daoClass) {\n        this.db = db;\n        try {\n            this.tablename = (String) daoClass.getField(\"TABLENAME\").get(null);\n            Property[] properties = reflectProperties(daoClass);\n            this.properties = properties;\n\n            allColumns = new String[properties.length];\n\n            List<String> pkColumnList = new ArrayList<String>();\n            List<String> nonPkColumnList = new ArrayList<String>();\n            Property lastPkProperty = null;\n            for (int i = 0; i < properties.length; i++) {\n                Property property = properties[i];\n                String name = property.columnName;\n                allColumns[i] = name;\n                if (property.primaryKey) {\n                    pkColumnList.add(name);\n                    lastPkProperty = property;\n                } else {\n                    nonPkColumnList.add(name);\n                }\n            }\n            String[] nonPkColumnsArray = new String[nonPkColumnList.size()];\n            nonPkColumns = nonPkColumnList.toArray(nonPkColumnsArray);\n            String[] pkColumnsArray = new String[pkColumnList.size()];\n            pkColumns = pkColumnList.toArray(pkColumnsArray);\n\n            pkProperty = pkColumns.length == 1 ? lastPkProperty : null;\n            statements = new TableStatements(db, tablename, allColumns, pkColumns);\n\n            if (pkProperty != null) {\n                Class<?> type = pkProperty.type;\n                keyIsNumeric = type.equals(long.class) || type.equals(Long.class) || type.equals(int.class)\n                        || type.equals(Integer.class) || type.equals(short.class) || type.equals(Short.class)\n                        || type.equals(byte.class) || type.equals(Byte.class);\n            } else {\n                keyIsNumeric = false;\n            }\n\n        } catch (Exception e) {\n            throw new DaoException(\"Could not init DAOConfig\", e);\n        }\n    }\n\n    private static Property[] reflectProperties(Class<? extends AbstractDao<?, ?>> daoClass)\n            throws ClassNotFoundException, IllegalArgumentException, IllegalAccessException {\n        Class<?> propertiesClass = Class.forName(daoClass.getName() + \"$Properties\");\n        Field[] fields = propertiesClass.getDeclaredFields();\n\n        ArrayList<Property> propertyList = new ArrayList<Property>();\n        final int modifierMask = Modifier.STATIC | Modifier.PUBLIC;\n        for (Field field : fields) {\n            // There might be other fields introduced by some tools, just ignore them (see issue #28)\n            if ((field.getModifiers() & modifierMask) == modifierMask) {\n                Object fieldValue = field.get(null);\n                if (fieldValue instanceof Property) {\n                    propertyList.add((Property) fieldValue);\n                }\n            }\n        }\n\n        Property[] properties = new Property[propertyList.size()];\n        for (Property property : propertyList) {\n            if (properties[property.ordinal] != null) {\n                throw new DaoException(\"Duplicate property ordinals\");\n            }\n            properties[property.ordinal] = property;\n        }\n        return properties;\n    }\n\n    /** Does not copy identity scope. */\n    public DaoConfig(DaoConfig source) {\n        db = source.db;\n        tablename = source.tablename;\n        properties = source.properties;\n        allColumns = source.allColumns;\n        pkColumns = source.pkColumns;\n        nonPkColumns = source.nonPkColumns;\n        pkProperty = source.pkProperty;\n        statements = source.statements;\n        keyIsNumeric = source.keyIsNumeric;\n    }\n\n    /** Does not copy identity scope. */\n    @Override\n    public DaoConfig clone() {\n        return new DaoConfig(this);\n    }\n\n    public IdentityScope<?, ?> getIdentityScope() {\n        return identityScope;\n    }\n\n    /**\n     * Clears the identify scope if it exists.\n     */\n    public void clearIdentityScope() {\n        IdentityScope<?, ?> identityScope = this.identityScope;\n        if(identityScope != null) {\n            identityScope.clear();\n        }\n    }\n\n    public void setIdentityScope(IdentityScope<?, ?> identityScope) {\n        this.identityScope = identityScope;\n    }\n\n    @SuppressWarnings(\"rawtypes\")\n    public void initIdentityScope(IdentityScopeType type) {\n        if (type == IdentityScopeType.None) {\n            identityScope = null;\n        } else if (type == IdentityScopeType.Session) {\n            if (keyIsNumeric) {\n                identityScope = new IdentityScopeLong();\n            } else {\n                identityScope = new IdentityScopeObject();\n            }\n        } else {\n            throw new IllegalArgumentException(\"Unsupported type: \" + type);\n        }\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/internal/FastCursor.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.internal;\n\nimport android.content.ContentResolver;\nimport android.database.CharArrayBuffer;\nimport android.database.ContentObserver;\nimport android.database.Cursor;\nimport android.database.CursorWindow;\nimport android.database.DataSetObserver;\nimport android.net.Uri;\nimport android.os.Bundle;\n\n/** Internal class used by greenDAO. */\nfinal public class FastCursor implements Cursor {\n\n    private final CursorWindow window;\n    private int position;\n    private final int count;\n\n    public FastCursor(CursorWindow window) {\n        this.window = window;\n        count = window.getNumRows();\n    }\n\n    @Override\n    public int getCount() {\n        return window.getNumRows();\n    }\n\n    @Override\n    public int getPosition() {\n        return position;\n    }\n\n    @Override\n    public boolean move(int offset) {\n        return moveToPosition(position + offset);\n    }\n\n    @Override\n    public boolean moveToPosition(int position) {\n        if (position >= 0 && position < count) {\n            this.position = position;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    @Override\n    public boolean moveToFirst() {\n        position = 0;\n        return count > 0;\n    }\n\n    @Override\n    public boolean moveToLast() {\n        if (count > 0) {\n            position = count - 1;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    @Override\n    public boolean moveToNext() {\n        if (position < count - 1) {\n            position++;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    @Override\n    public boolean moveToPrevious() {\n        if (position > 0) {\n            position--;\n            return true;\n        } else {\n            return false;\n        }\n    }\n\n    @Override\n    public boolean isFirst() {\n        return position == 0;\n    }\n\n    @Override\n    public boolean isLast() {\n        return position == count - 1;\n    }\n\n    @Override\n    public boolean isBeforeFirst() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public boolean isAfterLast() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public int getColumnIndex(String columnName) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public int getColumnIndexOrThrow(String columnName) throws IllegalArgumentException {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public String getColumnName(int columnIndex) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public String[] getColumnNames() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public int getColumnCount() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public byte[] getBlob(int columnIndex) {\n        return window.getBlob(position, columnIndex);\n    }\n\n    @Override\n    public String getString(int columnIndex) {\n        return window.getString(position, columnIndex);\n    }\n\n    @Override\n    public void copyStringToBuffer(int columnIndex, CharArrayBuffer buffer) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public short getShort(int columnIndex) {\n        return window.getShort(position, columnIndex);\n    }\n\n    @Override\n    public int getInt(int columnIndex) {\n        return window.getInt(position, columnIndex);\n    }\n\n    @Override\n    public long getLong(int columnIndex) {\n        return window.getLong(position, columnIndex);\n    }\n\n    @Override\n    public float getFloat(int columnIndex) {\n        return window.getFloat(position, columnIndex);\n    }\n\n    @Override\n    public double getDouble(int columnIndex) {\n        return window.getDouble(position, columnIndex);\n    }\n\n    @SuppressWarnings(\"deprecation\")\n    @Override\n    public boolean isNull(int columnIndex) {\n        return window.isNull(position, columnIndex);\n    }\n\n    @Override\n    public void deactivate() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public boolean requery() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public void close() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public boolean isClosed() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public void registerContentObserver(ContentObserver observer) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public void unregisterContentObserver(ContentObserver observer) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public void registerDataSetObserver(DataSetObserver observer) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public void unregisterDataSetObserver(DataSetObserver observer) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public void setNotificationUri(ContentResolver cr, Uri uri) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public boolean getWantsAllOnMoveCalls() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public Bundle getExtras() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public Bundle respond(Bundle extras) {\n        throw new UnsupportedOperationException();\n    }\n\n    /** Since API level 11 */\n    public int getType(int columnIndex) {\n        throw new UnsupportedOperationException();\n    }\n\n    /** Since API level 19 */\n    public Uri getNotificationUri() {\n        return null;\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/internal/LongHashMap.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.internal;\n\nimport java.util.Arrays;\n\nimport org.greenrobot.greendao.DaoLog;\n\n/**\n * An minimalistic hash map optimized for long keys.\n * \n * @author Markus\n * \n * @param <T>\n *            The class to store.\n */\npublic final class LongHashMap<T> {\n    final static class Entry<T> {\n        final long key;\n        T value;\n        Entry<T> next;\n\n        Entry(long key, T value, Entry<T> next) {\n            this.key = key;\n            this.value = value;\n            this.next = next;\n        }\n    }\n\n    private Entry<T>[] table;\n    private int capacity;\n    private int threshold;\n    private int size;\n\n    public LongHashMap() {\n        this(16);\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public LongHashMap(int capacity) {\n        this.capacity = capacity;\n        this.threshold = capacity * 4 / 3;\n        this.table = new Entry[capacity];\n    }\n\n    public boolean containsKey(long key) {\n        final int index = ((((int) (key >>> 32)) ^ ((int) (key))) & 0x7fffffff) % capacity;\n\n        for (Entry<T> entry = table[index]; entry != null; entry = entry.next) {\n            if (entry.key == key) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    public T get(long key) {\n        final int index = ((((int) (key >>> 32)) ^ ((int) (key))) & 0x7fffffff) % capacity;\n        for (Entry<T> entry = table[index]; entry != null; entry = entry.next) {\n            if (entry.key == key) {\n                return entry.value;\n            }\n        }\n        return null;\n    }\n\n    public T put(long key, T value) {\n        final int index = ((((int) (key >>> 32)) ^ ((int) (key))) & 0x7fffffff) % capacity;\n        final Entry<T> entryOriginal = table[index];\n        for (Entry<T> entry = entryOriginal; entry != null; entry = entry.next) {\n            if (entry.key == key) {\n                T oldValue = entry.value;\n                entry.value = value;\n                return oldValue;\n            }\n        }\n        table[index] = new Entry<T>(key, value, entryOriginal);\n        size++;\n        if (size > threshold) {\n            setCapacity(2 * capacity);\n        }\n        return null;\n    }\n\n    public T remove(long key) {\n        int index = ((((int) (key >>> 32)) ^ ((int) (key))) & 0x7fffffff) % capacity;\n        Entry<T> previous = null;\n        Entry<T> entry = table[index];\n        while (entry != null) {\n            Entry<T> next = entry.next;\n            if (entry.key == key) {\n                if (previous == null) {\n                    table[index] = next;\n                } else {\n                    previous.next = next;\n                }\n                size--;\n                return entry.value;\n            }\n            previous = entry;\n            entry = next;\n        }\n        return null;\n    }\n\n    public void clear() {\n        size = 0;\n        Arrays.fill(table, null);\n    }\n\n    public int size() {\n        return size;\n    }\n\n    public void setCapacity(int newCapacity) {\n        @SuppressWarnings(\"unchecked\")\n        Entry<T>[] newTable = new Entry[newCapacity];\n        int length = table.length;\n        for (int i = 0; i < length; i++) {\n            Entry<T> entry = table[i];\n            while (entry != null) {\n                long key = entry.key;\n                int index = ((((int) (key >>> 32)) ^ ((int) (key))) & 0x7fffffff) % newCapacity;\n\n                Entry<T> originalNext = entry.next;\n                entry.next = newTable[index];\n                newTable[index] = entry;\n                entry = originalNext;\n            }\n        }\n        table = newTable;\n        capacity = newCapacity;\n        threshold = newCapacity * 4 / 3;\n    }\n\n    /** Target load: 0,6 */\n    public void reserveRoom(int entryCount) {\n        setCapacity(entryCount * 5 / 3);\n    }\n\n    public void logStats() {\n        int collisions = 0;\n        for (Entry<T> entry : table) {\n            while (entry != null && entry.next != null) {\n                collisions++;\n                entry = entry.next;\n            }\n        }\n        DaoLog.d(\"load: \" + ((float) size) / capacity + \", size: \" + size + \", capa: \" + capacity + \", collisions: \"\n                + collisions + \", collision ratio: \" + ((float) collisions) / size);\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/internal/SqlUtils.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.internal;\n\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.Property;\n\n/** Helper class to create SQL statements as used by greenDAO internally. */\npublic class SqlUtils {\n    private final static char[] HEX_ARRAY = \"0123456789ABCDEF\".toCharArray();\n\n    public static StringBuilder appendProperty(StringBuilder builder, String tablePrefix, Property property) {\n        if (tablePrefix != null) {\n            builder.append(tablePrefix).append('.');\n        }\n        builder.append('\"').append(property.columnName).append('\"');\n        return builder;\n    }\n\n    public static StringBuilder appendColumn(StringBuilder builder, String column) {\n        builder.append('\"').append(column).append('\"');\n        return builder;\n    }\n\n    public static StringBuilder appendColumn(StringBuilder builder, String tableAlias, String column) {\n        builder.append(tableAlias).append(\".\\\"\").append(column).append('\"');\n        return builder;\n    }\n\n    public static StringBuilder appendColumns(StringBuilder builder, String tableAlias, String[] columns) {\n        int length = columns.length;\n        for (int i = 0; i < length; i++) {\n            appendColumn(builder, tableAlias, columns[i]);\n            if (i < length - 1) {\n                builder.append(',');\n            }\n        }\n        return builder;\n    }\n\n    public static StringBuilder appendColumns(StringBuilder builder, String[] columns) {\n        int length = columns.length;\n        for (int i = 0; i < length; i++) {\n            builder.append('\"').append(columns[i]).append('\"');\n            if (i < length - 1) {\n                builder.append(',');\n            }\n        }\n        return builder;\n    }\n\n    public static StringBuilder appendPlaceholders(StringBuilder builder, int count) {\n        for (int i = 0; i < count; i++) {\n            if (i < count - 1) {\n                builder.append(\"?,\");\n            } else {\n                builder.append('?');\n            }\n        }\n        return builder;\n    }\n\n    public static StringBuilder appendColumnsEqualPlaceholders(StringBuilder builder, String[] columns) {\n        for (int i = 0; i < columns.length; i++) {\n            appendColumn(builder, columns[i]).append(\"=?\");\n            if (i < columns.length - 1) {\n                builder.append(',');\n            }\n        }\n        return builder;\n    }\n\n    public static StringBuilder appendColumnsEqValue(StringBuilder builder, String tableAlias, String[] columns) {\n        for (int i = 0; i < columns.length; i++) {\n            appendColumn(builder, tableAlias, columns[i]).append(\"=?\");\n            if (i < columns.length - 1) {\n                builder.append(',');\n            }\n        }\n        return builder;\n    }\n\n    public static String createSqlInsert(String insertInto, String tablename, String[] columns) {\n        StringBuilder builder = new StringBuilder(insertInto);\n        builder.append('\"').append(tablename).append('\"').append(\" (\");\n        appendColumns(builder, columns);\n        builder.append(\") VALUES (\");\n        appendPlaceholders(builder, columns.length);\n        builder.append(')');\n        return builder.toString();\n    }\n\n    /** Creates an select for given columns with a trailing space */\n    public static String createSqlSelect(String tablename, String tableAlias, String[] columns, boolean distinct) {\n        if (tableAlias == null || tableAlias.length() < 0) {\n            throw new DaoException(\"Table alias required\");\n        }\n\n        StringBuilder builder = new StringBuilder(distinct ? \"SELECT DISTINCT \" : \"SELECT \");\n        SqlUtils.appendColumns(builder, tableAlias, columns).append(\" FROM \");\n        builder.append('\"').append(tablename).append('\"').append(' ').append(tableAlias).append(' ');\n        return builder.toString();\n    }\n\n    /** Creates SELECT COUNT(*) with a trailing space. */\n    public static String createSqlSelectCountStar(String tablename, String tableAliasOrNull) {\n        StringBuilder builder = new StringBuilder(\"SELECT COUNT(*) FROM \");\n        builder.append('\"').append(tablename).append('\"').append(' ');\n        if (tableAliasOrNull != null) {\n            builder.append(tableAliasOrNull).append(' ');\n        }\n        return builder.toString();\n    }\n\n    /** Remember: SQLite does not support joins nor table alias for DELETE. */\n    public static String createSqlDelete(String tablename, String[] columns) {\n        String quotedTablename = '\"' + tablename + '\"';\n        StringBuilder builder = new StringBuilder(\"DELETE FROM \");\n        builder.append(quotedTablename);\n        if (columns != null && columns.length > 0) {\n            builder.append(\" WHERE \");\n            appendColumnsEqValue(builder, quotedTablename, columns);\n        }\n        return builder.toString();\n    }\n\n    public static String createSqlUpdate(String tablename, String[] updateColumns, String[] whereColumns) {\n        String quotedTablename = '\"' + tablename + '\"';\n        StringBuilder builder = new StringBuilder(\"UPDATE \");\n        builder.append(quotedTablename).append(\" SET \");\n        appendColumnsEqualPlaceholders(builder, updateColumns);\n        builder.append(\" WHERE \");\n        appendColumnsEqValue(builder, quotedTablename, whereColumns);\n        return builder.toString();\n    }\n\n    public static String createSqlCount(String tablename) {\n        return \"SELECT COUNT(*) FROM \\\"\" + tablename +'\"';\n    }\n    \n    public static String escapeBlobArgument(byte[] bytes) {\n        return \"X'\" + toHex(bytes) + '\\'';\n    }\n\n    public static String toHex(byte[] bytes) {\n        char[] hexChars = new char[bytes.length * 2];\n        for (int i = 0; i < bytes.length; i++) {\n            int byteValue = bytes[i] & 0xFF;\n            hexChars[i * 2] = HEX_ARRAY[byteValue >>> 4];\n            hexChars[i * 2 + 1] = HEX_ARRAY[byteValue & 0x0F];\n        }\n        return new String(hexChars);\n    }\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/internal/TableStatements.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.internal;\n\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n/** Helper class to create SQL statements for specific tables (used by greenDAO internally). */\n// Note: avoid locking while compiling any statement (accessing the db) to avoid deadlocks on lock-savvy DBs like\n// SQLCipher.\npublic class TableStatements {\n    private final Database db;\n    private final String tablename;\n    private final String[] allColumns;\n    private final String[] pkColumns;\n\n    private DatabaseStatement insertStatement;\n    private DatabaseStatement insertOrReplaceStatement;\n    private DatabaseStatement updateStatement;\n    private DatabaseStatement deleteStatement;\n    private DatabaseStatement countStatement;\n\n    private volatile String selectAll;\n    private volatile String selectByKey;\n    private volatile String selectByRowId;\n    private volatile String selectKeys;\n\n    public TableStatements(Database db, String tablename, String[] allColumns, String[] pkColumns) {\n        this.db = db;\n        this.tablename = tablename;\n        this.allColumns = allColumns;\n        this.pkColumns = pkColumns;\n    }\n\n    public DatabaseStatement getInsertStatement() {\n        if (insertStatement == null) {\n            String sql = SqlUtils.createSqlInsert(\"INSERT INTO \", tablename, allColumns);\n            DatabaseStatement newInsertStatement = db.compileStatement(sql);\n            synchronized (this) {\n                if (insertStatement == null) {\n                    insertStatement = newInsertStatement;\n                }\n            }\n            if (insertStatement != newInsertStatement) {\n                newInsertStatement.close();\n            }\n        }\n        return insertStatement;\n    }\n\n    public DatabaseStatement getInsertOrReplaceStatement() {\n        if (insertOrReplaceStatement == null) {\n            String sql = SqlUtils.createSqlInsert(\"INSERT OR REPLACE INTO \", tablename, allColumns);\n            DatabaseStatement newInsertOrReplaceStatement = db.compileStatement(sql);\n            synchronized (this) {\n                if (insertOrReplaceStatement == null) {\n                    insertOrReplaceStatement = newInsertOrReplaceStatement;\n                }\n            }\n            if (insertOrReplaceStatement != newInsertOrReplaceStatement) {\n                newInsertOrReplaceStatement.close();\n            }\n        }\n        return insertOrReplaceStatement;\n    }\n\n    public DatabaseStatement getDeleteStatement() {\n        if (deleteStatement == null) {\n            String sql = SqlUtils.createSqlDelete(tablename, pkColumns);\n            DatabaseStatement newDeleteStatement = db.compileStatement(sql);\n            synchronized (this) {\n                if (deleteStatement == null) {\n                    deleteStatement = newDeleteStatement;\n                }\n            }\n            if (deleteStatement != newDeleteStatement) {\n                newDeleteStatement.close();\n            }\n        }\n        return deleteStatement;\n    }\n\n    public DatabaseStatement getUpdateStatement() {\n        if (updateStatement == null) {\n            String sql = SqlUtils.createSqlUpdate(tablename, allColumns, pkColumns);\n            DatabaseStatement newUpdateStatement = db.compileStatement(sql);\n            synchronized (this) {\n                if (updateStatement == null) {\n                    updateStatement = newUpdateStatement;\n                }\n            }\n            if (updateStatement != newUpdateStatement) {\n                newUpdateStatement.close();\n            }\n        }\n        return updateStatement;\n    }\n\n    public DatabaseStatement getCountStatement() {\n        if (countStatement == null) {\n            String sql = SqlUtils.createSqlCount(tablename);\n            countStatement = db.compileStatement(sql);\n        }\n        return countStatement;\n    }\n\n    /** ends with an space to simplify appending to this string. */\n    public String getSelectAll() {\n        if (selectAll == null) {\n            selectAll = SqlUtils.createSqlSelect(tablename, \"T\", allColumns, false);\n        }\n        return selectAll;\n    }\n\n    /** ends with an space to simplify appending to this string. */\n    public String getSelectKeys() {\n        if (selectKeys == null) {\n            selectKeys = SqlUtils.createSqlSelect(tablename, \"T\", pkColumns, false);\n        }\n        return selectKeys;\n    }\n\n    // TODO precompile\n    public String getSelectByKey() {\n        if (selectByKey == null) {\n            StringBuilder builder = new StringBuilder(getSelectAll());\n            builder.append(\"WHERE \");\n            SqlUtils.appendColumnsEqValue(builder, \"T\", pkColumns);\n            selectByKey = builder.toString();\n        }\n        return selectByKey;\n    }\n\n    public String getSelectByRowId() {\n        if (selectByRowId == null) {\n            selectByRowId = getSelectAll() + \"WHERE ROWID=?\";\n        }\n        return selectByRowId;\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/AbstractQuery.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.query;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.InternalQueryDaoAccess;\n\nimport java.util.Date;\n\n/**\n * A repeatable query returning entities.\n * \n * @author Markus\n * \n * @param <T>\n *            The entity class the query will return results for.\n */\n// TODO support long, double and other types, not just Strings, for parameters\n// TODO Make parameters setable by Property (if unique in parameters)\n// TODO Make query compilable\nabstract class AbstractQuery<T> {\n    protected final AbstractDao<T, ?> dao;\n    protected final InternalQueryDaoAccess<T> daoAccess;\n    protected final String sql;\n    protected final String[] parameters;\n    protected final Thread ownerThread;\n\n    protected static String[] toStringArray(Object[] values) {\n        int length = values.length;\n        String[] strings = new String[length];\n        for (int i = 0; i < length; i++) {\n            Object object = values[i];\n            if (object != null) {\n                strings[i] = object.toString();\n            } else {\n                strings[i] = null;\n            }\n        }\n        return strings;\n    }\n\n    protected AbstractQuery(AbstractDao<T, ?> dao, String sql, String[] parameters) {\n        this.dao = dao;\n        this.daoAccess = new InternalQueryDaoAccess<T>(dao);\n        this.sql = sql;\n        this.parameters = parameters;\n        ownerThread = Thread.currentThread();\n    }\n\n    // public void compile() {\n    // // TODO implement compile\n    // }\n\n    /**\n     * Sets the parameter (0 based) using the position in which it was added during building the query.\n     */\n    public AbstractQuery<T> setParameter(int index, Object parameter) {\n        checkThread();\n        if (parameter != null) {\n            parameters[index] = parameter.toString();\n        } else {\n            parameters[index] = null;\n        }\n        return this;\n    }\n\n    /**\n     * @see #setParameter(int, Object)\n     */\n    public AbstractQuery<T> setParameter(int index, Date parameter) {\n        Long converted = parameter != null ? parameter.getTime() : null;\n        return setParameter(index, converted);\n    }\n\n    /**\n     * @see #setParameter(int, Object)\n     */\n    public AbstractQuery<T> setParameter(int index, Boolean parameter) {\n        Integer converted = parameter != null ? (parameter ? 1 : 0) : null;\n        return setParameter(index, converted);\n    }\n\n    protected void checkThread() {\n        if (Thread.currentThread() != ownerThread) {\n            throw new DaoException(\n                    \"Method may be called only in owner thread, use forCurrentThread to get an instance for this thread\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/AbstractQueryData.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.query;\n\nimport org.greenrobot.greendao.AbstractDao;\n\nimport java.lang.ref.WeakReference;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport java.util.Map;\nimport java.util.Map.Entry;\n\nabstract class AbstractQueryData<T, Q extends AbstractQuery<T>> {\n    final String sql;\n    final AbstractDao<T, ?> dao;\n    final String[] initialValues;\n    final Map<Long, WeakReference<Q>> queriesForThreads;\n\n    AbstractQueryData(AbstractDao<T, ?> dao, String sql, String[] initialValues) {\n        this.dao = dao;\n        this.sql = sql;\n        this.initialValues = initialValues;\n        queriesForThreads = new HashMap<>();\n    }\n\n    /**\n     * Just an optimized version, which performs faster if the current thread is already the query's owner thread.\n     * Note: all parameters are reset to their initial values specified in {@link QueryBuilder}.\n     */\n    Q forCurrentThread(Q query) {\n        if (Thread.currentThread() == query.ownerThread) {\n            System.arraycopy(initialValues, 0, query.parameters, 0, initialValues.length);\n            return query;\n        } else {\n            return forCurrentThread();\n        }\n    }\n\n    /**\n     * Note: all parameters are reset to their initial values specified in {@link QueryBuilder}.\n     */\n    Q forCurrentThread() {\n        // Process.myTid() seems to have issues on some devices (see Github #376) and Robolectric (#171):\n        // We use currentThread().getId() instead (unfortunately return a long, can not use SparseArray).\n        // PS.: thread ID may be reused, which should be fine because old thread will be gone anyway.\n        long threadId = Thread.currentThread().getId();\n        synchronized (queriesForThreads) {\n            WeakReference<Q> queryRef = queriesForThreads.get(threadId);\n            Q query = queryRef != null ? queryRef.get() : null;\n            if (query == null) {\n                gc();\n                query = createQuery();\n                queriesForThreads.put(threadId, new WeakReference<Q>(query));\n            } else {\n                System.arraycopy(initialValues, 0, query.parameters, 0, initialValues.length);\n            }\n            return query;\n        }\n    }\n\n    abstract protected Q createQuery();\n\n    void gc() {\n        synchronized (queriesForThreads) {\n            Iterator<Entry<Long, WeakReference<Q>>> iterator = queriesForThreads.entrySet().iterator();\n            while (iterator.hasNext()) {\n                Entry<Long, WeakReference<Q>> entry = iterator.next();\n                if (entry.getValue().get() == null) {\n                    iterator.remove();\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/AbstractQueryWithLimit.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.query;\n\nimport org.greenrobot.greendao.AbstractDao;\n\n/**\n * Base class for queries returning data (entities or cursor).\n *\n * @param <T> The entity class the query will return results for.\n * @author Markus\n */\n// TODO Query for PKs/ROW IDs\nabstract class AbstractQueryWithLimit<T> extends AbstractQuery<T> {\n    protected final int limitPosition;\n    protected final int offsetPosition;\n\n    protected AbstractQueryWithLimit(AbstractDao<T, ?> dao, String sql, String[] initialValues, int limitPosition,\n                                     int offsetPosition) {\n        super(dao, sql, initialValues);\n        this.limitPosition = limitPosition;\n        this.offsetPosition = offsetPosition;\n    }\n\n    /**\n     * Sets the parameter (0 based) using the position in which it was added during building the query. Note: all\n     * standard WHERE parameters come first. After that come the WHERE parameters of joins (if any).\n     */\n    public AbstractQueryWithLimit<T> setParameter(int index, Object parameter) {\n        if (index >= 0 && (index == limitPosition || index == offsetPosition)) {\n            throw new IllegalArgumentException(\"Illegal parameter index: \" + index);\n        }\n        return (AbstractQueryWithLimit<T>) super.setParameter(index, parameter);\n    }\n\n    /**\n     * Sets the limit of the maximum number of results returned by this Query. {@link\n     * org.greenrobot.greendao.query.QueryBuilder#limit(int)} must\n     * have been called on the QueryBuilder that created this Query object.\n     */\n    public void setLimit(int limit) {\n        checkThread();\n        if (limitPosition == -1) {\n            throw new IllegalStateException(\"Limit must be set with QueryBuilder before it can be used here\");\n        }\n        parameters[limitPosition] = Integer.toString(limit);\n    }\n\n    /**\n     * Sets the offset for results returned by this Query. {@link org.greenrobot.greendao.query.QueryBuilder#offset(int)} must\n     * have been called on\n     * the QueryBuilder that created this Query object.\n     */\n    public void setOffset(int offset) {\n        checkThread();\n        if (offsetPosition == -1) {\n            throw new IllegalStateException(\"Offset must be set with QueryBuilder before it can be used here\");\n        }\n        parameters[offsetPosition] = Integer.toString(offset);\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/CloseableListIterator.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.query;\n\nimport java.io.Closeable;\nimport java.util.ListIterator;\n\n/**\n * A list iterator that needs to be closed (or the associated list) to free underlying resources like a database cursor.\n * Typically used with LazyList.\n * \n * @author Markus\n * \n * @param <T>\n */\npublic interface CloseableListIterator<T> extends ListIterator<T>, Closeable {\n\n}"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/CountQuery.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.query;\n\nimport android.database.Cursor;\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.DaoException;\n\nimport java.util.Date;\n\npublic class CountQuery<T> extends AbstractQuery<T> {\n\n    private final static class QueryData<T2> extends AbstractQueryData<T2, CountQuery<T2>> {\n\n        private QueryData(AbstractDao<T2, ?> dao, String sql, String[] initialValues) {\n            super(dao, sql, initialValues);\n        }\n\n        @Override\n        protected CountQuery<T2> createQuery() {\n            return new CountQuery<T2>(this, dao, sql, initialValues.clone());\n        }\n    }\n\n    static <T2> CountQuery<T2> create(AbstractDao<T2, ?> dao, String sql, Object[] initialValues) {\n        QueryData<T2> queryData = new QueryData<T2>(dao, sql, toStringArray(initialValues));\n        return queryData.forCurrentThread();\n    }\n\n    private final QueryData<T> queryData;\n\n    private CountQuery(QueryData<T> queryData, AbstractDao<T, ?> dao, String sql, String[] initialValues) {\n        super(dao, sql, initialValues);\n        this.queryData = queryData;\n    }\n\n    public CountQuery<T> forCurrentThread() {\n        return queryData.forCurrentThread(this);\n    }\n\n    /** Returns the count (number of results matching the query). Uses SELECT COUNT (*) sematics. */\n    public long count() {\n        checkThread();\n        Cursor cursor = dao.getDatabase().rawQuery(sql, parameters);\n        try {\n            if (!cursor.moveToNext()) {\n                throw new DaoException(\"No result for count\");\n            } else if (!cursor.isLast()) {\n                throw new DaoException(\"Unexpected row count: \" + cursor.getCount());\n            } else if (cursor.getColumnCount() != 1) {\n                throw new DaoException(\"Unexpected column count: \" + cursor.getColumnCount());\n            }\n            return cursor.getLong(0);\n        } finally {\n            cursor.close();\n        }\n    }\n\n    // copy setParameter methods to allow easy chaining\n    @Override\n    public CountQuery<T> setParameter(int index, Object parameter) {\n        return (CountQuery<T>) super.setParameter(index, parameter);\n    }\n\n    @Override\n    public CountQuery<T> setParameter(int index, Date parameter) {\n        return (CountQuery<T>) super.setParameter(index, parameter);\n    }\n\n    @Override\n    public CountQuery<T> setParameter(int index, Boolean parameter) {\n        return (CountQuery<T>) super.setParameter(index, parameter);\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/CursorQuery.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.query;\n\nimport android.database.Cursor;\nimport org.greenrobot.greendao.AbstractDao;\n\nimport java.util.Date;\n\n/**\n * A repeatable query returning a raw android.database.Cursor. Note, that using cursors is usually a hassle and\n * greenDAO provides a higher level abstraction using entities (see {@link org.greenrobot.greendao.query.Query}). This class\n * can nevertheless be useful to work with legacy code that is based on Cursors or CursorLoaders.\n *\n * @param <T> The entity class the query will return results for.\n * @author Markus\n */\npublic class CursorQuery<T> extends AbstractQueryWithLimit<T> {\n    private final static class QueryData<T2> extends AbstractQueryData<T2, CursorQuery<T2>> {\n        private final int limitPosition;\n        private final int offsetPosition;\n\n        QueryData(AbstractDao dao, String sql, String[] initialValues, int limitPosition, int offsetPosition) {\n            super(dao, sql, initialValues);\n            this.limitPosition = limitPosition;\n            this.offsetPosition = offsetPosition;\n        }\n\n        @Override\n        protected CursorQuery<T2> createQuery() {\n            return new CursorQuery<T2>(this, dao, sql, initialValues.clone(), limitPosition, offsetPosition);\n        }\n\n    }\n\n    /** For internal use by greenDAO only. */\n    public static <T2> CursorQuery<T2> internalCreate(AbstractDao<T2, ?> dao, String sql, Object[] initialValues) {\n        return create(dao, sql, initialValues, -1, -1);\n    }\n\n    static <T2> CursorQuery<T2> create(AbstractDao<T2, ?> dao, String sql, Object[] initialValues, int limitPosition,\n                                       int offsetPosition) {\n        QueryData<T2> queryData = new QueryData<T2>(dao, sql, toStringArray(initialValues), limitPosition,\n                offsetPosition);\n        return queryData.forCurrentThread();\n    }\n\n    private final QueryData<T> queryData;\n\n    private CursorQuery(QueryData<T> queryData, AbstractDao<T, ?> dao, String sql, String[] initialValues, int limitPosition,\n                        int offsetPosition) {\n        super(dao, sql, initialValues, limitPosition, offsetPosition);\n        this.queryData = queryData;\n    }\n\n    public CursorQuery forCurrentThread() {\n        return queryData.forCurrentThread(this);\n    }\n\n    /** Executes the query and returns a raw android.database.Cursor. Don't forget to close it. */\n    public Cursor query() {\n        checkThread();\n        return dao.getDatabase().rawQuery(sql, parameters);\n    }\n\n    // copy setParameter methods to allow easy chaining\n    @Override\n    public CursorQuery<T> setParameter(int index, Object parameter) {\n        return (CursorQuery<T>) super.setParameter(index, parameter);\n    }\n\n    @Override\n    public CursorQuery<T> setParameter(int index, Date parameter) {\n        return (CursorQuery<T>) super.setParameter(index, parameter);\n    }\n\n    @Override\n    public CursorQuery<T> setParameter(int index, Boolean parameter) {\n        return (CursorQuery<T>) super.setParameter(index, parameter);\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/DeleteQuery.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.query;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.database.Database;\n\nimport java.util.Date;\n\n/**\n * A repeatable query for deleting entities.<br/>\n * New API note: this is more likely to change.\n *\n * @param <T> The entity class the query will delete from.\n * @author Markus\n */\npublic class DeleteQuery<T> extends AbstractQuery<T> {\n    private final static class QueryData<T2> extends AbstractQueryData<T2, DeleteQuery<T2>> {\n\n        private QueryData(AbstractDao<T2, ?> dao, String sql, String[] initialValues) {\n            super(dao, sql, initialValues);\n        }\n\n        @Override\n        protected DeleteQuery<T2> createQuery() {\n            return new DeleteQuery<T2>(this, dao, sql, initialValues.clone());\n        }\n    }\n\n    static <T2> DeleteQuery<T2> create(AbstractDao<T2, ?> dao, String sql, Object[] initialValues) {\n        QueryData<T2> queryData = new QueryData<T2>(dao, sql, toStringArray(initialValues));\n        return queryData.forCurrentThread();\n    }\n\n    private final QueryData<T> queryData;\n\n    private DeleteQuery(QueryData<T> queryData, AbstractDao<T, ?> dao, String sql, String[] initialValues) {\n        super(dao, sql, initialValues);\n        this.queryData = queryData;\n    }\n\n    public DeleteQuery<T> forCurrentThread() {\n        return queryData.forCurrentThread(this);\n    }\n\n    /**\n     * Deletes all matching entities without detaching them from the identity scope (aka session/cache). Note that this\n     * method may lead to stale entity objects in the session cache. Stale entities may be returned when loaded by\n     * their\n     * primary key, but not using queries.\n     */\n    public void executeDeleteWithoutDetachingEntities() {\n        checkThread();\n        Database db = dao.getDatabase();\n        if (db.isDbLockedByCurrentThread()) {\n            dao.getDatabase().execSQL(sql, parameters);\n        } else {\n            // Do TX to acquire a connection before locking this to avoid deadlocks\n            // Locking order as described in AbstractDao\n            db.beginTransaction();\n            try {\n                dao.getDatabase().execSQL(sql, parameters);\n                db.setTransactionSuccessful();\n            } finally {\n                db.endTransaction();\n            }\n        }\n    }\n\n    // copy setParameter methods to allow easy chaining\n    @Override\n    public DeleteQuery<T> setParameter(int index, Object parameter) {\n        return (DeleteQuery<T>) super.setParameter(index, parameter);\n    }\n\n    @Override\n    public DeleteQuery<T> setParameter(int index, Date parameter) {\n        return (DeleteQuery<T>) super.setParameter(index, parameter);\n    }\n\n    @Override\n    public DeleteQuery<T> setParameter(int index, Boolean parameter) {\n        return (DeleteQuery<T>) super.setParameter(index, parameter);\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/Join.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.query;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\n\n/**\n * A Join lets you relate to other entity types for queries, and allows using WHERE statements on the joined entity\n * type.\n */\npublic class Join<SRC, DST> {\n\n    final String sourceTablePrefix;\n    final AbstractDao<DST, ?> daoDestination;\n\n    final Property joinPropertySource;\n    final Property joinPropertyDestination;\n    final String tablePrefix;\n    final WhereCollector<DST> whereCollector;\n\n    public Join(String sourceTablePrefix, Property sourceJoinProperty,\n                AbstractDao<DST, ?> daoDestination, Property destinationJoinProperty,\n                String joinTablePrefix) {\n        this.sourceTablePrefix = sourceTablePrefix;\n        this.joinPropertySource = sourceJoinProperty;\n        this.daoDestination = daoDestination;\n        this.joinPropertyDestination = destinationJoinProperty;\n        tablePrefix = joinTablePrefix;\n        whereCollector = new WhereCollector<DST>(daoDestination, joinTablePrefix);\n    }\n\n\n    /**\n     * Adds the given conditions to the where clause using an logical AND. To create new conditions, use the properties\n     * given in the generated dao classes.\n     */\n    public Join<SRC, DST> where(WhereCondition cond, WhereCondition... condMore) {\n        whereCollector.add(cond, condMore);\n        return this;\n    }\n\n    /**\n     * Adds the given conditions to the where clause using an logical OR. To create new conditions, use the properties\n     * given in the generated dao classes.\n     */\n    public Join<SRC, DST> whereOr(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore) {\n        whereCollector.add(or(cond1, cond2, condMore));\n        return this;\n    }\n\n    /**\n     * Creates a WhereCondition by combining the given conditions using OR. The returned WhereCondition must be used\n     * inside {@link #where(WhereCondition, WhereCondition...)} or\n     * {@link #whereOr(WhereCondition, WhereCondition, WhereCondition...)}.\n     */\n    public WhereCondition or(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore) {\n        return whereCollector.combineWhereConditions(\" OR \", cond1, cond2, condMore);\n    }\n\n    /**\n     * Creates a WhereCondition by combining the given conditions using AND. The returned WhereCondition must be used\n     * inside {@link #where(WhereCondition, WhereCondition...)} or\n     * {@link #whereOr(WhereCondition, WhereCondition, WhereCondition...)}.\n     */\n    public WhereCondition and(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore) {\n        return whereCollector.combineWhereConditions(\" AND \", cond1, cond2, condMore);\n    }\n\n    /**\n     * Usually you don't need this value; just in case you are mixing custom\n     * {@link org.greenrobot.greendao.query.WhereCondition.StringCondition} into the query, this value allows to reference\n     * the joined (target) table.\n     */\n    public String getTablePrefix() {\n        return tablePrefix;\n    }\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/LazyList.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.query;\n\nimport java.io.Closeable;\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.Iterator;\nimport java.util.List;\nimport java.util.ListIterator;\nimport java.util.NoSuchElementException;\nimport java.util.concurrent.locks.ReentrantLock;\n\nimport android.database.Cursor;\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.InternalQueryDaoAccess;\n\n/**\n * A thread-safe, unmodifiable list that reads entities once they are accessed from an underlying database cursor. Make\n * sure to close the list once you are done with it. The lazy list can be cached or not. Cached lazy lists store the\n * entities in memory to avoid loading entities more than once. Some features of the list are limited to cached lists\n * (e.g. features that require the entire list). Cached lists close the cursor automatically once you queried all\n * entities. However, to avoid leaked cursors, you should not rely on this behavior: if an exception occurs before the\n * entire list is read, you should close the lazy list (and thus the underlying cursor) on your own to be on the safe\n * side.\n * \n * @author Markus\n * \n * @param <E>\n *            Entity type.\n */\npublic class LazyList<E> implements List<E>, Closeable {\n    protected class LazyIterator implements CloseableListIterator<E> {\n        private int index;\n        private final boolean closeWhenDone;\n\n        public LazyIterator(int startLocation, boolean closeWhenDone) {\n            index = startLocation;\n            this.closeWhenDone = closeWhenDone;\n        }\n\n        @Override\n        public void add(E object) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        /** FIXME: before hasPrevious(), next() must be called. */\n        public boolean hasPrevious() {\n            return index > 0;\n        }\n\n        @Override\n        public int nextIndex() {\n            return index;\n        }\n\n        @Override\n        /** FIXME: before previous(), next() must be called. */\n        public E previous() {\n            if (index <= 0) {\n                throw new NoSuchElementException();\n            }\n            index--;\n            E entity = get(index);\n            // if (index == size && closeWhenDone) {\n            // close();\n            // }\n            return entity;\n        }\n\n        @Override\n        public int previousIndex() {\n            return index - 1;\n        }\n\n        @Override\n        public void set(E object) {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public boolean hasNext() {\n            return index < size;\n        }\n\n        @Override\n        public E next() {\n            if (index >= size) {\n                throw new NoSuchElementException();\n            }\n            E entity = get(index);\n            index++;\n            if (index == size && closeWhenDone) {\n                close();\n            }\n            return entity;\n        }\n\n        @Override\n        public void remove() {\n            throw new UnsupportedOperationException();\n        }\n\n        @Override\n        public void close() {\n            LazyList.this.close();\n        }\n\n    }\n\n    private final InternalQueryDaoAccess<E> daoAccess;\n    private final Cursor cursor;\n    private final List<E> entities;\n    private final int size;\n    private final ReentrantLock lock;\n    private volatile int loadedCount;\n\n    LazyList(InternalQueryDaoAccess<E> daoAccess, Cursor cursor, boolean cacheEntities) {\n        this.cursor = cursor;\n        this.daoAccess = daoAccess;\n        size = cursor.getCount();\n        if (cacheEntities) {\n            entities = new ArrayList<E>(size);\n            for (int i = 0; i < size; i++) {\n                entities.add(null);\n            }\n        } else {\n            entities = null;\n        }\n        if (size == 0) {\n            cursor.close();\n        }\n\n        lock = new ReentrantLock();\n    }\n\n    /** Loads the remaining entities (if any) that were not loaded before. Applies to cached lazy lists only. */\n    public void loadRemaining() {\n        checkCached();\n        int size = entities.size();\n        for (int i = 0; i < size; i++) {\n            get(i);\n        }\n    }\n\n    protected void checkCached() {\n        if (entities == null) {\n            throw new DaoException(\"This operation only works with cached lazy lists\");\n        }\n    }\n\n    /** Like get but does not load the entity if it was not loaded before. */\n    public E peek(int location) {\n        if (entities != null) {\n            return entities.get(location);\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    /** Closes the underlying cursor: do not try to get entities not loaded (using get) before. */\n    public void close() {\n        cursor.close();\n    }\n\n    public boolean isClosed() {\n        return cursor.isClosed();\n    }\n\n    public int getLoadedCount() {\n        return loadedCount;\n    }\n\n    public boolean isLoadedCompletely() {\n        return loadedCount == size;\n    }\n\n    @Override\n    public boolean add(E object) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public void add(int location, E object) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public boolean addAll(Collection<? extends E> arg0) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public boolean addAll(int arg0, Collection<? extends E> arg1) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public void clear() {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public boolean contains(Object object) {\n        loadRemaining();\n        return entities.contains(object);\n    }\n\n    @Override\n    public boolean containsAll(Collection<?> collection) {\n        loadRemaining();\n        return entities.containsAll(collection);\n    }\n\n    @Override\n    public E get(int location) {\n        if (entities != null) {\n            E entity = entities.get(location);\n            if (entity == null) {\n                lock.lock();\n                try {\n                    entity = entities.get(location);\n                    if (entity == null) {\n                        entity = loadEntity(location);\n                        entities.set(location, entity);\n                        // Ignore FindBugs: increment of volatile is fine here because we use a lock\n                        loadedCount++;\n                        if (loadedCount == size) {\n                            cursor.close();\n                        }\n                    }\n                } finally {\n                    lock.unlock();\n                }\n            }\n            return entity;\n        } else {\n            lock.lock();\n            try {\n                return loadEntity(location);\n            } finally {\n                lock.unlock();\n            }\n        }\n    }\n\n    /** Lock must be locked when entering this method. */\n    protected E loadEntity(int location) {\n        boolean ok = cursor.moveToPosition(location);\n        if(!ok) {\n            throw new DaoException(\"Could not move to cursor location \" + location);\n        }\n        E entity = daoAccess.loadCurrent(cursor, 0, true);\n        if (entity == null) {\n            throw new DaoException(\"Loading of entity failed (null) at position \" + location);\n        }\n        return entity;\n    }\n\n    @Override\n    public int indexOf(Object object) {\n        loadRemaining();\n        return entities.indexOf(object);\n    }\n\n    @Override\n    public boolean isEmpty() {\n        return size == 0;\n    }\n\n    @Override\n    public Iterator<E> iterator() {\n        return new LazyIterator(0, false);\n    }\n\n    @Override\n    public int lastIndexOf(Object object) {\n        loadRemaining();\n        return entities.lastIndexOf(object);\n    }\n\n    @Override\n    public CloseableListIterator<E> listIterator() {\n        return new LazyIterator(0, false);\n    }\n\n    /** Closes this list's cursor once the iterator is fully iterated through. */\n    public CloseableListIterator<E> listIteratorAutoClose() {\n        return new LazyIterator(0, true);\n    }\n\n    @Override\n    public ListIterator<E> listIterator(int location) {\n        return new LazyIterator(location, false);\n    }\n\n    @Override\n    public E remove(int location) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public boolean remove(Object object) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public boolean removeAll(Collection<?> arg0) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public boolean retainAll(Collection<?> arg0) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public E set(int location, E object) {\n        throw new UnsupportedOperationException();\n    }\n\n    @Override\n    public int size() {\n        return size;\n    }\n\n    @Override\n    public List<E> subList(int start, int end) {\n        checkCached();\n        for (int i = start; i < end; i++) {\n            get(i);\n        }\n        return entities.subList(start, end);\n    }\n\n    @Override\n    public Object[] toArray() {\n        loadRemaining();\n        return entities.toArray();\n    }\n\n    @Override\n    public <T> T[] toArray(T[] array) {\n        loadRemaining();\n        return entities.toArray(array);\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/Query.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.query;\n\nimport android.database.Cursor;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.annotation.apihint.Internal;\nimport org.greenrobot.greendao.rx.RxQuery;\nimport org.greenrobot.greendao.rx.RxTransaction;\n\nimport java.util.Date;\nimport java.util.List;\n\nimport rx.schedulers.Schedulers;\n\n/**\n * A repeatable query returning entities.\n *\n * @param <T> The entity class the query will return results for.\n * @author Markus\n */\npublic class Query<T> extends AbstractQueryWithLimit<T> {\n    private final static class QueryData<T2> extends AbstractQueryData<T2, Query<T2>> {\n        private final int limitPosition;\n        private final int offsetPosition;\n\n        QueryData(AbstractDao<T2, ?> dao, String sql, String[] initialValues, int limitPosition, int offsetPosition) {\n            super(dao, sql, initialValues);\n            this.limitPosition = limitPosition;\n            this.offsetPosition = offsetPosition;\n        }\n\n        @Override\n        protected Query<T2> createQuery() {\n            return new Query<T2>(this, dao, sql, initialValues.clone(), limitPosition, offsetPosition);\n        }\n\n    }\n\n    /** For internal use by greenDAO only. */\n    public static <T2> Query<T2> internalCreate(AbstractDao<T2, ?> dao, String sql, Object[] initialValues) {\n        return create(dao, sql, initialValues, -1, -1);\n    }\n\n    static <T2> Query<T2> create(AbstractDao<T2, ?> dao, String sql, Object[] initialValues, int limitPosition,\n                                 int offsetPosition) {\n        QueryData<T2> queryData = new QueryData<T2>(dao, sql, toStringArray(initialValues), limitPosition,\n                offsetPosition);\n        return queryData.forCurrentThread();\n    }\n\n    private final QueryData<T> queryData;\n\n    private volatile RxQuery rxTxPlain;\n    private volatile RxQuery rxTxIo;\n\n    private Query(QueryData<T> queryData, AbstractDao<T, ?> dao, String sql, String[] initialValues, int limitPosition,\n                  int offsetPosition) {\n        super(dao, sql, initialValues, limitPosition, offsetPosition);\n        this.queryData = queryData;\n    }\n\n    /**\n     * Note: all parameters are reset to their initial values specified in {@link QueryBuilder}.\n     */\n    public Query<T> forCurrentThread() {\n        return queryData.forCurrentThread(this);\n    }\n\n    /** Executes the query and returns the result as a list containing all entities loaded into memory. */\n    public List<T> list() {\n        checkThread();\n        Cursor cursor = dao.getDatabase().rawQuery(sql, parameters);\n        return daoAccess.loadAllAndCloseCursor(cursor);\n    }\n\n    /**\n     * Executes the query and returns the result as a list that lazy loads the entities on first access. Entities are\n     * cached, so accessing the same entity more than once will not result in loading an entity from the underlying\n     * cursor again.Make sure to close it to close the underlying cursor.\n     */\n    public LazyList<T> listLazy() {\n        checkThread();\n        Cursor cursor = dao.getDatabase().rawQuery(sql, parameters);\n        return new LazyList<T>(daoAccess, cursor, true);\n    }\n\n    /**\n     * Executes the query and returns the result as a list that lazy loads the entities on every access (uncached).\n     * Make sure to close the list to close the underlying cursor.\n     */\n    public LazyList<T> listLazyUncached() {\n        checkThread();\n        Cursor cursor = dao.getDatabase().rawQuery(sql, parameters);\n        return new LazyList<T>(daoAccess, cursor, false);\n    }\n\n    /**\n     * Executes the query and returns the result as a list iterator; make sure to close it to close the underlying\n     * cursor. The cursor is closed once the iterator is fully iterated through.\n     */\n    public CloseableListIterator<T> listIterator() {\n        return listLazyUncached().listIteratorAutoClose();\n    }\n\n    /**\n     * Executes the query and returns the unique result or null.\n     *\n     * @return Entity or null if no matching entity was found\n     * @throws DaoException if the result is not unique\n     */\n    public T unique() {\n        checkThread();\n        Cursor cursor = dao.getDatabase().rawQuery(sql, parameters);\n        return daoAccess.loadUniqueAndCloseCursor(cursor);\n    }\n\n    /**\n     * Executes the query and returns the unique result (never null).\n     *\n     * @return Entity\n     * @throws DaoException if the result is not unique or no entity was found\n     */\n    public T uniqueOrThrow() {\n        T entity = unique();\n        if (entity == null) {\n            throw new DaoException(\"No entity found for query\");\n        }\n        return entity;\n    }\n\n    @Override\n    public Query<T> setParameter(int index, Object parameter) {\n        return (Query<T>) super.setParameter(index, parameter);\n    }\n\n    @Override\n    public Query<T> setParameter(int index, Date parameter) {\n        return (Query<T>) super.setParameter(index, parameter);\n    }\n\n    @Override\n    public Query<T> setParameter(int index, Boolean parameter) {\n        return (Query<T>) super.setParameter(index, parameter);\n    }\n\n    /**\n     * DO NOT USE.\n     * The returned {@link RxTransaction} allows getting query results using Rx Observables without any Scheduler set\n     * for subscribeOn.\n     *\n     * @see #__InternalRx()\n     */\n    @Internal\n    public RxQuery __internalRxPlain() {\n        if (rxTxPlain == null) {\n            rxTxPlain = new RxQuery(this);\n        }\n        return rxTxPlain;\n    }\n\n    /**\n     * DO NOT USE.\n     * The returned {@link RxTransaction} allows getting query results using Rx Observables using RX's IO scheduler for\n     * subscribeOn.\n     *\n     * @see #__internalRxPlain()\n     */\n    @Internal\n    public RxQuery __InternalRx() {\n        if (rxTxIo == null) {\n            rxTxIo = new RxQuery(this, Schedulers.io());\n        }\n        return rxTxIo;\n    }\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/QueryBuilder.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.query;\n\nimport android.database.sqlite.SQLiteDatabase;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.AbstractDaoSession;\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.annotation.apihint.Experimental;\nimport org.greenrobot.greendao.internal.SqlUtils;\nimport org.greenrobot.greendao.rx.RxQuery;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Builds custom entity queries using constraints and parameters and without SQL (QueryBuilder creates SQL for you). To\n * acquire an QueryBuilder, use {@link AbstractDao#queryBuilder()} or {@link AbstractDaoSession#queryBuilder(Class)}.\n * Entity properties are referenced by Fields in the \"Properties\" inner class of the generated DAOs. This approach\n * allows compile time checks and prevents typo errors occuring at build time.<br/>\n * <br/>\n * Example: Query for all users with the first name \"Joe\" ordered by their last name. (The class Properties is an inner\n * class of UserDao and should be imported before.)<br/>\n * <code>\n * List<User> joes = dao.queryBuilder().where(Properties.FirstName.eq(\"Joe\")).orderAsc(Properties.LastName).list();\n * </code>\n *\n * @param <T> Entity class to create an query for.\n * @author Markus\n */\npublic class QueryBuilder<T> {\n\n    /** Set to true to debug the SQL. */\n    public static boolean LOG_SQL;\n\n    /** Set to see the given values. */\n    public static boolean LOG_VALUES;\n    private final WhereCollector<T> whereCollector;\n\n    private StringBuilder orderBuilder;\n\n    private final List<Object> values;\n    private final List<Join<T, ?>> joins;\n    private final AbstractDao<T, ?> dao;\n    private final String tablePrefix;\n\n    private Integer limit;\n    private Integer offset;\n    private boolean distinct;\n\n    /** stored with a leading space */\n    private String stringOrderCollation;\n\n    /** For internal use by greenDAO only. */\n    public static <T2> QueryBuilder<T2> internalCreate(AbstractDao<T2, ?> dao) {\n        return new QueryBuilder<T2>(dao);\n    }\n\n    protected QueryBuilder(AbstractDao<T, ?> dao) {\n        this(dao, \"T\");\n    }\n\n    protected QueryBuilder(AbstractDao<T, ?> dao, String tablePrefix) {\n        this.dao = dao;\n        this.tablePrefix = tablePrefix;\n        values = new ArrayList<Object>();\n        joins = new ArrayList<Join<T, ?>>();\n        whereCollector = new WhereCollector<T>(dao, tablePrefix);\n        stringOrderCollation = \" COLLATE NOCASE\";\n    }\n\n    private void checkOrderBuilder() {\n        if (orderBuilder == null) {\n            orderBuilder = new StringBuilder();\n        } else if (orderBuilder.length() > 0) {\n            orderBuilder.append(\",\");\n        }\n    }\n\n    /** Use a SELECT DISTINCT to avoid duplicate entities returned, e.g. when doing joins. */\n    public QueryBuilder<T> distinct() {\n        distinct = true;\n        return this;\n    }\n\n    /**\n     * If using Android's embedded SQLite, this enables localized ordering of strings\n     * (see {@link #orderAsc(Property...)} and {@link #orderDesc(Property...)}). This uses \"COLLATE LOCALIZED\", which\n     * is unavailable in SQLCipher (in that case, the ordering is unchanged).\n     *\n     * @see #stringOrderCollation\n     */\n    public QueryBuilder<T> preferLocalizedStringOrder() {\n        // SQLCipher 3.5.0+ does not understand \"COLLATE LOCALIZED\"\n        if (dao.getDatabase().getRawDatabase() instanceof SQLiteDatabase) {\n            stringOrderCollation = \" COLLATE LOCALIZED\";\n        }\n        return this;\n    }\n\n    /**\n     * Customizes the ordering of strings used by {@link #orderAsc(Property...)} and {@link #orderDesc(Property...)}.\n     * Default is \"COLLATE NOCASE\".\n     *\n     * @see #preferLocalizedStringOrder\n     */\n    public QueryBuilder<T> stringOrderCollation(String stringOrderCollation) {\n        this.stringOrderCollation = stringOrderCollation == null || stringOrderCollation.startsWith(\" \") ?\n                stringOrderCollation : \" \" + stringOrderCollation;\n        return this;\n    }\n\n    /**\n     * Adds the given conditions to the where clause using an logical AND. To create new conditions, use the properties\n     * given in the generated dao classes.\n     */\n    public QueryBuilder<T> where(WhereCondition cond, WhereCondition... condMore) {\n        whereCollector.add(cond, condMore);\n        return this;\n    }\n\n    /**\n     * Adds the given conditions to the where clause using an logical OR. To create new conditions, use the properties\n     * given in the generated dao classes.\n     */\n    public QueryBuilder<T> whereOr(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore) {\n        whereCollector.add(or(cond1, cond2, condMore));\n        return this;\n    }\n\n    /**\n     * Creates a WhereCondition by combining the given conditions using OR. The returned WhereCondition must be used\n     * inside {@link #where(WhereCondition, WhereCondition...)} or\n     * {@link #whereOr(WhereCondition, WhereCondition, WhereCondition...)}.\n     */\n    public WhereCondition or(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore) {\n        return whereCollector.combineWhereConditions(\" OR \", cond1, cond2, condMore);\n    }\n\n    /**\n     * Creates a WhereCondition by combining the given conditions using AND. The returned WhereCondition must be used\n     * inside {@link #where(WhereCondition, WhereCondition...)} or\n     * {@link #whereOr(WhereCondition, WhereCondition, WhereCondition...)}.\n     */\n    public WhereCondition and(WhereCondition cond1, WhereCondition cond2, WhereCondition... condMore) {\n        return whereCollector.combineWhereConditions(\" AND \", cond1, cond2, condMore);\n    }\n\n    /**\n     * Expands the query to another entity type by using a JOIN. The primary key property of the primary entity for\n     * this QueryBuilder is used to match the given destinationProperty.\n     */\n    public <J> Join<T, J> join(Class<J> destinationEntityClass, Property destinationProperty) {\n        return join(dao.getPkProperty(), destinationEntityClass, destinationProperty);\n    }\n\n    /**\n     * Expands the query to another entity type by using a JOIN. The given sourceProperty is used to match the primary\n     * key property of the given destinationEntity.\n     */\n    public <J> Join<T, J> join(Property sourceProperty, Class<J> destinationEntityClass) {\n        AbstractDao<J, ?> destinationDao = (AbstractDao<J, ?>) dao.getSession().getDao(destinationEntityClass);\n        Property destinationProperty = destinationDao.getPkProperty();\n        return addJoin(tablePrefix, sourceProperty, destinationDao, destinationProperty);\n    }\n\n    /**\n     * Expands the query to another entity type by using a JOIN. The given sourceProperty is used to match the given\n     * destinationProperty of the given destinationEntity.\n     */\n    public <J> Join<T, J> join(Property sourceProperty, Class<J> destinationEntityClass, Property destinationProperty) {\n        AbstractDao<J, ?> destinationDao = (AbstractDao<J, ?>) dao.getSession().getDao(destinationEntityClass);\n        return addJoin(tablePrefix, sourceProperty, destinationDao, destinationProperty);\n    }\n\n    /**\n     * Expands the query to another entity type by using a JOIN. The given sourceJoin's property is used to match the\n     * given destinationProperty of the given destinationEntity. Note that destination entity of the given join is used\n     * as the source for the new join to add. In this way, it is possible to compose complex \"join of joins\" across\n     * several entities if required.\n     */\n    public <J> Join<T, J> join(Join<?, T> sourceJoin, Property sourceProperty, Class<J> destinationEntityClass,\n                               Property destinationProperty) {\n        AbstractDao<J, ?> destinationDao = (AbstractDao<J, ?>) dao.getSession().getDao(destinationEntityClass);\n        return addJoin(sourceJoin.tablePrefix, sourceProperty, destinationDao, destinationProperty);\n    }\n\n    private <J> Join<T, J> addJoin(String sourceTablePrefix, Property sourceProperty, AbstractDao<J, ?> destinationDao,\n                                   Property destinationProperty) {\n        String joinTablePrefix = \"J\" + (joins.size() + 1);\n        Join<T, J> join = new Join<T, J>(sourceTablePrefix, sourceProperty, destinationDao, destinationProperty,\n                joinTablePrefix);\n        joins.add(join);\n        return join;\n    }\n\n    /** Adds the given properties to the ORDER BY section using ascending order. */\n    public QueryBuilder<T> orderAsc(Property... properties) {\n        orderAscOrDesc(\" ASC\", properties);\n        return this;\n    }\n\n    /** Adds the given properties to the ORDER BY section using descending order. */\n    public QueryBuilder<T> orderDesc(Property... properties) {\n        orderAscOrDesc(\" DESC\", properties);\n        return this;\n    }\n\n    private void orderAscOrDesc(String ascOrDescWithLeadingSpace, Property... properties) {\n        for (Property property : properties) {\n            checkOrderBuilder();\n            append(orderBuilder, property);\n            if (String.class.equals(property.type) && stringOrderCollation != null) {\n                orderBuilder.append(stringOrderCollation);\n            }\n            orderBuilder.append(ascOrDescWithLeadingSpace);\n        }\n    }\n\n    /** Adds the given properties to the ORDER BY section using the given custom order. */\n    public QueryBuilder<T> orderCustom(Property property, String customOrderForProperty) {\n        checkOrderBuilder();\n        append(orderBuilder, property).append(' ');\n        orderBuilder.append(customOrderForProperty);\n        return this;\n    }\n\n    /**\n     * Adds the given raw SQL string to the ORDER BY section. Do not use this for standard properties: orderAsc and\n     * orderDesc are preferred.\n     */\n    public QueryBuilder<T> orderRaw(String rawOrder) {\n        checkOrderBuilder();\n        orderBuilder.append(rawOrder);\n        return this;\n    }\n\n    protected StringBuilder append(StringBuilder builder, Property property) {\n        whereCollector.checkProperty(property);\n        builder.append(tablePrefix).append('.').append('\\'').append(property.columnName).append('\\'');\n        return builder;\n    }\n\n\n    /** Limits the number of results returned by queries. */\n    public QueryBuilder<T> limit(int limit) {\n        this.limit = limit;\n        return this;\n    }\n\n    /**\n     * Sets the offset for query results in combination with {@link #limit(int)}. The first {@code offset} results are\n     * skipped and the total number of results will be limited by {@code limit}. You cannot use offset without limit.\n     */\n    public QueryBuilder<T> offset(int offset) {\n        this.offset = offset;\n        return this;\n    }\n\n    /**\n     * Builds a reusable query object (Query objects can be executed more efficiently than creating a QueryBuilder for\n     * each execution.\n     */\n    public Query<T> build() {\n        StringBuilder builder = createSelectBuilder();\n        int limitPosition = checkAddLimit(builder);\n        int offsetPosition = checkAddOffset(builder);\n\n        String sql = builder.toString();\n        checkLog(sql);\n\n        return Query.create(dao, sql, values.toArray(), limitPosition, offsetPosition);\n    }\n\n    /**\n     * Builds a reusable query object for low level android.database.Cursor access.\n     * (Query objects can be executed more efficiently than creating a QueryBuilder for each execution.\n     */\n    public CursorQuery buildCursor() {\n        StringBuilder builder = createSelectBuilder();\n        int limitPosition = checkAddLimit(builder);\n        int offsetPosition = checkAddOffset(builder);\n\n        String sql = builder.toString();\n        checkLog(sql);\n\n        return CursorQuery.create(dao, sql, values.toArray(), limitPosition, offsetPosition);\n    }\n\n    private StringBuilder createSelectBuilder() {\n        String select = SqlUtils.createSqlSelect(dao.getTablename(), tablePrefix, dao.getAllColumns(), distinct);\n        StringBuilder builder = new StringBuilder(select);\n\n        appendJoinsAndWheres(builder, tablePrefix);\n\n        if (orderBuilder != null && orderBuilder.length() > 0) {\n            builder.append(\" ORDER BY \").append(orderBuilder);\n        }\n        return builder;\n    }\n\n    private int checkAddLimit(StringBuilder builder) {\n        int limitPosition = -1;\n        if (limit != null) {\n            builder.append(\" LIMIT ?\");\n            values.add(limit);\n            limitPosition = values.size() - 1;\n        }\n        return limitPosition;\n    }\n\n    private int checkAddOffset(StringBuilder builder) {\n        int offsetPosition = -1;\n        if (offset != null) {\n            if (limit == null) {\n                throw new IllegalStateException(\"Offset cannot be set without limit\");\n            }\n            builder.append(\" OFFSET ?\");\n            values.add(offset);\n            offsetPosition = values.size() - 1;\n        }\n        return offsetPosition;\n    }\n\n    /**\n     * Builds a reusable query object for deletion (Query objects can be executed more efficiently than creating a\n     * QueryBuilder for each execution.\n     */\n    public DeleteQuery<T> buildDelete() {\n        if (!joins.isEmpty()) {\n            throw new DaoException(\"JOINs are not supported for DELETE queries\");\n        }\n        String tablename = dao.getTablename();\n        String baseSql = SqlUtils.createSqlDelete(tablename, null);\n        StringBuilder builder = new StringBuilder(baseSql);\n\n        // tablePrefix gets replaced by table name below. Don't use tableName here because it causes trouble when\n        // table name ends with tablePrefix.\n        appendJoinsAndWheres(builder, tablePrefix);\n\n        String sql = builder.toString();\n        // Remove table aliases, not supported for DELETE queries.\n        // TODO(?): don't create table aliases in the first place.\n        sql = sql.replace(tablePrefix + \".\\\"\", '\"' + tablename + \"\\\".\\\"\");\n        checkLog(sql);\n\n        return DeleteQuery.create(dao, sql, values.toArray());\n    }\n\n    /**\n     * Builds a reusable query object for counting rows (Query objects can be executed more efficiently than creating a\n     * QueryBuilder for each execution.\n     */\n    public CountQuery<T> buildCount() {\n        String tablename = dao.getTablename();\n        String baseSql = SqlUtils.createSqlSelectCountStar(tablename, tablePrefix);\n        StringBuilder builder = new StringBuilder(baseSql);\n        appendJoinsAndWheres(builder, tablePrefix);\n\n        String sql = builder.toString();\n        checkLog(sql);\n\n        return CountQuery.create(dao, sql, values.toArray());\n    }\n\n    private void checkLog(String sql) {\n        if (LOG_SQL) {\n            DaoLog.d(\"Built SQL for query: \" + sql);\n        }\n        if (LOG_VALUES) {\n            DaoLog.d(\"Values for query: \" + values);\n        }\n    }\n\n    private void appendJoinsAndWheres(StringBuilder builder, String tablePrefixOrNull) {\n        values.clear();\n        for (Join<T, ?> join : joins) {\n            builder.append(\" JOIN \");\n            builder.append('\"').append(join.daoDestination.getTablename()).append('\"').append(' ');\n            builder.append(join.tablePrefix).append(\" ON \");\n            SqlUtils.appendProperty(builder, join.sourceTablePrefix, join.joinPropertySource).append('=');\n            SqlUtils.appendProperty(builder, join.tablePrefix, join.joinPropertyDestination);\n        }\n        boolean whereAppended = !whereCollector.isEmpty();\n        if (whereAppended) {\n            builder.append(\" WHERE \");\n            whereCollector.appendWhereClause(builder, tablePrefixOrNull, values);\n        }\n        for (Join<T, ?> join : joins) {\n            if (!join.whereCollector.isEmpty()) {\n                if (!whereAppended) {\n                    builder.append(\" WHERE \");\n                    whereAppended = true;\n                } else {\n                    builder.append(\" AND \");\n                }\n                join.whereCollector.appendWhereClause(builder, join.tablePrefix, values);\n            }\n        }\n    }\n\n    /**\n     * Shorthand for {@link QueryBuilder#build() build()}.{@link Query#list() list()}; see {@link Query#list()} for\n     * details. To execute a query more than once, you should build the query and keep the {@link Query} object for\n     * efficiency reasons.\n     */\n    public List<T> list() {\n        return build().list();\n    }\n\n    /**\n     * Shorthand for {@link QueryBuilder#build() build()}.{@link Query#__InternalRx()}.\n     */\n    @Experimental\n    public RxQuery<T> rx() {\n        return build().__InternalRx();\n    }\n\n    /**\n     * Shorthand for {@link QueryBuilder#build() build()}.{@link Query#__internalRxPlain()}.\n     */\n    @Experimental\n    public RxQuery<T> rxPlain() {\n        return build().__internalRxPlain();\n    }\n\n    /**\n     * Shorthand for {@link QueryBuilder#build() build()}.{@link Query#listLazy() listLazy()}; see\n     * {@link Query#listLazy()} for details. To execute a query more than once, you should build the query and keep the\n     * {@link Query} object for efficiency reasons.\n     */\n    public LazyList<T> listLazy() {\n        return build().listLazy();\n    }\n\n    /**\n     * Shorthand for {@link QueryBuilder#build() build()}.{@link Query#listLazyUncached() listLazyUncached()}; see\n     * {@link Query#listLazyUncached()} for details. To execute a query more than once, you should build the query and\n     * keep the {@link Query} object for efficiency reasons.\n     */\n    public LazyList<T> listLazyUncached() {\n        return build().listLazyUncached();\n    }\n\n    /**\n     * Shorthand for {@link QueryBuilder#build() build()}.{@link Query#listIterator() listIterator()}; see\n     * {@link Query#listIterator()} for details. To execute a query more than once, you should build the query and keep\n     * the {@link Query} object for efficiency reasons.\n     */\n    public CloseableListIterator<T> listIterator() {\n        return build().listIterator();\n    }\n\n    /**\n     * Shorthand for {@link QueryBuilder#build() build()}.{@link Query#unique() unique()}; see {@link Query#unique()}\n     * for details. To execute a query more than once, you should build the query and keep the {@link Query} object for\n     * efficiency reasons.\n     */\n    public T unique() {\n        return build().unique();\n    }\n\n    /**\n     * Shorthand for {@link QueryBuilder#build() build()}.{@link Query#uniqueOrThrow() uniqueOrThrow()}; see\n     * {@link Query#uniqueOrThrow()} for details. To execute a query more than once, you should build the query and\n     * keep\n     * the {@link Query} object for efficiency reasons.\n     */\n    public T uniqueOrThrow() {\n        return build().uniqueOrThrow();\n    }\n\n    /**\n     * Shorthand for {@link QueryBuilder#buildCount() buildCount()}.{@link CountQuery#count() count()}; see\n     * {@link CountQuery#count()} for details. To execute a query more than once, you should build the query and keep\n     * the {@link CountQuery} object for efficiency reasons.\n     */\n    public long count() {\n        return buildCount().count();\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/WhereCollector.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.query;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.Property;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.ListIterator;\n\n/** Internal class to collect WHERE conditions. */\nclass WhereCollector<T> {\n\n    private final AbstractDao<T, ?> dao;\n    private final List<WhereCondition> whereConditions;\n    private final String tablePrefix;\n\n    WhereCollector(AbstractDao<T, ?> dao, String tablePrefix) {\n        this.dao = dao;\n        this.tablePrefix = tablePrefix;\n        whereConditions = new ArrayList<WhereCondition>();\n    }\n\n    void add(WhereCondition cond, WhereCondition... condMore) {\n        checkCondition(cond);\n        whereConditions.add(cond);\n        for (WhereCondition whereCondition : condMore) {\n            checkCondition(whereCondition);\n            whereConditions.add(whereCondition);\n        }\n    }\n\n    WhereCondition combineWhereConditions(String combineOp, WhereCondition cond1, WhereCondition cond2,\n                                          WhereCondition... condMore) {\n        StringBuilder builder = new StringBuilder(\"(\");\n        List<Object> combinedValues = new ArrayList<Object>();\n\n        addCondition(builder, combinedValues, cond1);\n        builder.append(combineOp);\n        addCondition(builder, combinedValues, cond2);\n\n        for (WhereCondition cond : condMore) {\n            builder.append(combineOp);\n            addCondition(builder, combinedValues, cond);\n        }\n        builder.append(')');\n        return new WhereCondition.StringCondition(builder.toString(), combinedValues.toArray());\n    }\n\n    void addCondition(StringBuilder builder, List<Object> values, WhereCondition condition) {\n        checkCondition(condition);\n        condition.appendTo(builder, tablePrefix);\n        condition.appendValuesTo(values);\n    }\n\n    void checkCondition(WhereCondition whereCondition) {\n        if (whereCondition instanceof WhereCondition.PropertyCondition) {\n            checkProperty(((WhereCondition.PropertyCondition) whereCondition).property);\n        }\n    }\n\n    void checkProperty(Property property) {\n        if (dao != null) {\n            Property[] properties = dao.getProperties();\n            boolean found = false;\n            for (Property property2 : properties) {\n                if (property == property2) {\n                    found = true;\n                    break;\n                }\n            }\n            if (!found) {\n                throw new DaoException(\"Property '\" + property.name + \"' is not part of \" + dao);\n            }\n        }\n    }\n\n    void appendWhereClause(StringBuilder builder, String tablePrefixOrNull, List<Object> values) {\n        ListIterator<WhereCondition> iter = whereConditions.listIterator();\n        while (iter.hasNext()) {\n            if (iter.hasPrevious()) {\n                builder.append(\" AND \");\n            }\n            WhereCondition condition = iter.next();\n            condition.appendTo(builder, tablePrefixOrNull);\n            condition.appendValuesTo(values);\n        }\n    }\n\n    boolean isEmpty() {\n        return whereConditions.isEmpty();\n    }\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/query/WhereCondition.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.query;\n\nimport java.util.Date;\nimport java.util.List;\n\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.SqlUtils;\n\n/**\n * Internal interface to model WHERE conditions used in queries. Use the {@link Property} objects in the DAO classes to\n * create new conditions.\n */\npublic interface WhereCondition {\n\n    void appendTo(StringBuilder builder, String tableAlias);\n\n    void appendValuesTo(List<Object> values);\n\n    abstract class AbstractCondition implements WhereCondition {\n\n        protected final boolean hasSingleValue;\n        protected final Object value;\n        protected final Object[] values;\n\n        public AbstractCondition() {\n            hasSingleValue = false;\n            value = null;\n            values = null;\n        }\n\n        public AbstractCondition(Object value) {\n            this.value = value;\n            hasSingleValue = true;\n            values = null;\n        }\n\n        public AbstractCondition(Object[] values) {\n            this.value = null;\n            hasSingleValue = false;\n            this.values = values;\n        }\n\n        @Override\n        public void appendValuesTo(List<Object> valuesTarget) {\n            if (hasSingleValue) {\n                valuesTarget.add(value);\n            } else if (values != null) {\n                for (Object value : values) {\n                    valuesTarget.add(value);\n                }\n            }\n        }\n    }\n\n    class PropertyCondition extends AbstractCondition {\n\n        private static Object checkValueForType(Property property, Object value) {\n            if (value != null && value.getClass().isArray()) {\n                throw new DaoException(\"Illegal value: found array, but simple object required\");\n            }\n            Class<?> type = property.type;\n            if (type == Date.class) {\n                if (value instanceof Date) {\n                    return ((Date) value).getTime();\n                } else if (value instanceof Long) {\n                    return value;\n                } else {\n                    throw new DaoException(\"Illegal date value: expected java.util.Date or Long for value \" + value);\n                }\n            } else if (property.type == boolean.class || property.type == Boolean.class) {\n                if (value instanceof Boolean) {\n                    return ((Boolean) value) ? 1 : 0;\n                } else if (value instanceof Number) {\n                    int intValue = ((Number) value).intValue();\n                    if (intValue != 0 && intValue != 1) {\n                        throw new DaoException(\"Illegal boolean value: numbers must be 0 or 1, but was \" + value);\n                    }\n                } else if (value instanceof String) {\n                    String stringValue = ((String) value);\n                    if (\"TRUE\".equalsIgnoreCase(stringValue)) {\n                        return 1;\n                    } else if (\"FALSE\".equalsIgnoreCase(stringValue)) {\n                        return 0;\n                    } else {\n                        throw new DaoException(\n                                \"Illegal boolean value: Strings must be \\\"TRUE\\\" or \\\"FALSE\\\" (case insensitive), but was \"\n                                        + value);\n                    }\n                }\n            }\n            return value;\n        }\n\n        private static Object[] checkValuesForType(Property property, Object[] values) {\n            for (int i = 0; i < values.length; i++) {\n                values[i] = checkValueForType(property, values[i]);\n            }\n            return values;\n        }\n\n        public final Property property;\n        public final String op;\n\n        public PropertyCondition(Property property, String op) {\n            this.property = property;\n            this.op = op;\n        }\n\n        public PropertyCondition(Property property, String op, Object value) {\n            super(checkValueForType(property, value));\n            this.property = property;\n            this.op = op;\n        }\n\n        public PropertyCondition(Property property, String op, Object[] values) {\n            super(checkValuesForType(property, values));\n            this.property = property;\n            this.op = op;\n        }\n\n        @Override\n        public void appendTo(StringBuilder builder, String tableAlias) {\n            SqlUtils.appendProperty(builder, tableAlias, property).append(op);\n        }\n    }\n\n    class StringCondition extends AbstractCondition {\n\n        protected final String string;\n\n        public StringCondition(String string) {\n            this.string = string;\n        }\n\n        public StringCondition(String string, Object value) {\n            super(value);\n            this.string = string;\n        }\n\n        public StringCondition(String string, Object... values) {\n            super(values);\n            this.string = string;\n        }\n\n        @Override\n        public void appendTo(StringBuilder builder, String tableAlias) {\n            builder.append(string);\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/rx/RxBase.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.rx;\n\nimport org.greenrobot.greendao.annotation.apihint.Experimental;\nimport org.greenrobot.greendao.annotation.apihint.Internal;\n\nimport java.util.concurrent.Callable;\n\nimport rx.Observable;\nimport rx.Scheduler;\n\n/**\n * Base functionality for Rx, e.g. default scheduler.\n */\n@Internal\nclass RxBase {\n\n    protected final Scheduler scheduler;\n\n    /**\n     * No default scheduler.\n     */\n    RxBase() {\n        scheduler = null;\n    }\n\n    /**\n     * Sets the default scheduler, which is used to configure returned observables with\n     * {@link Observable#subscribeOn(Scheduler)}.\n     */\n    @Experimental\n    RxBase(Scheduler scheduler) {\n        this.scheduler = scheduler;\n    }\n\n    /**\n     * The default scheduler (or null) used for wrapping.\n     */\n    @Experimental\n    public Scheduler getScheduler() {\n        return scheduler;\n    }\n\n    protected <R> Observable<R> wrap(Callable<R> callable) {\n        return wrap(RxUtils.fromCallable(callable));\n    }\n\n    protected <R> Observable<R> wrap(Observable<R> observable) {\n        if (scheduler != null) {\n            return observable.subscribeOn(scheduler);\n        } else {\n            return observable;\n        }\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/rx/RxDao.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.rx;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.annotation.apihint.Experimental;\n\nimport java.util.List;\nimport java.util.concurrent.Callable;\n\nimport rx.Observable;\nimport rx.Scheduler;\n\n/**\n * Like {@link AbstractDao} but with Rx support. Most methods from AbstractDao are present here, but will return an\n * {@link Observable}. Modifying operations return the given entities, so they can be further processed in Rx.\n * <p>\n * Instances of RxDao may have an default {@link rx.Scheduler}, which is used to configure returned observables with\n * {@link Observable#subscribeOn(Scheduler)} (see {@link AbstractDao#rxPlain()}, which uses the IO scheduler).\n *\n * Note: DO NOT call more than one data modification operation when you can use a transaction instead (see\n * {@link RxTransaction}. Individual calls use a transaction each and are much slower.\n *\n * @param <T> Entity type\n * @param <K> Primary key (PK) type; use Void if entity does not have exactly one PK\n * @see AbstractDao#rxPlain()\n */\n@Experimental\npublic class RxDao<T, K> extends RxBase {\n\n    private final AbstractDao<T, K> dao;\n\n    /**\n     * Creates a new RxDao without a default scheduler.\n     */\n    @Experimental\n    public RxDao(AbstractDao<T, K> dao) {\n        this(dao, null);\n    }\n\n    /**\n     * Creates a new RxDao with a default scheduler, which is used to configure returned observables with\n     * {@link Observable#subscribeOn(Scheduler)}.\n     */\n    @Experimental\n    public RxDao(AbstractDao<T, K> dao, Scheduler scheduler) {\n        super(scheduler);\n        this.dao = dao;\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#loadAll()} returning an Observable.\n     */\n    @Experimental\n    public Observable<List<T>> loadAll() {\n        return wrap(new Callable<List<T>>() {\n            @Override\n            public List<T> call() throws Exception {\n                return dao.loadAll();\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#loadAll()} returning an Observable.\n     */\n    @Experimental\n    public Observable<T> load(final K key) {\n        return wrap(new Callable<T>() {\n            @Override\n            public T call() throws Exception {\n                return dao.load(key);\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#refresh(Object)} returning an Observable.\n     * Note that the Observable will emit the given entity back to its subscribers.\n     */\n    @Experimental\n    public Observable<T> refresh(final T entity) {\n        return wrap(new Callable<T>() {\n            @Override\n            public T call() throws Exception {\n                dao.refresh(entity);\n                return entity;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#insert(Object)} returning an Observable.\n     * Note that the Observable will emit the given entity back to its subscribers.\n     */\n    @Experimental\n    public Observable<T> insert(final T entity) {\n        return wrap(new Callable<T>() {\n            @Override\n            public T call() throws Exception {\n                dao.insert(entity);\n                return entity;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#insertInTx(Iterable)} returning an Observable.\n     * Note that the Observable will emit the given entities back to its subscribers.\n     */\n    @Experimental\n    public Observable<Iterable<T>> insertInTx(final Iterable<T> entities) {\n        return wrap(new Callable<Iterable<T>>() {\n            @Override\n            public Iterable<T> call() throws Exception {\n                dao.insertInTx(entities);\n                return entities;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#insertInTx(Object[])} returning an Observable.\n     * Note that the Observable will emit the given entities back to its subscribers.\n     */\n    @Experimental\n    public Observable<Object[]> insertInTx(final T... entities) {\n        return wrap(new Callable<Object[]>() {\n            @Override\n            public Object[] call() throws Exception {\n                dao.insertInTx(entities);\n                return entities;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#insertOrReplace(Object)} returning an Observable.\n     * Note that the Observable will emit the given entity back to its subscribers.\n     */\n    @Experimental\n    public Observable<T> insertOrReplace(final T entity) {\n        return wrap(new Callable<T>() {\n            @Override\n            public T call() throws Exception {\n                dao.insertOrReplace(entity);\n                return entity;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#insertOrReplaceInTx(Iterable)} returning an Observable.\n     * Note that the Observable will emit the given entities back to its subscribers.\n     */\n    @Experimental\n    public Observable<Iterable<T>> insertOrReplaceInTx(final Iterable<T> entities) {\n        return wrap(new Callable<Iterable<T>>() {\n            @Override\n            public Iterable<T> call() throws Exception {\n                dao.insertOrReplaceInTx(entities);\n                return entities;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#insertOrReplaceInTx(Object[])} returning an Observable.\n     * Note that the Observable will emit the given entities back to its subscribers.\n     */\n    @Experimental\n    public Observable<Object[]> insertOrReplaceInTx(final T... entities) {\n        return wrap(new Callable<Object[]>() {\n            @Override\n            public Object[] call() throws Exception {\n                dao.insertOrReplaceInTx(entities);\n                return entities;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#save(Object)} returning an Observable.\n     * Note that the Observable will emit the given entity back to its subscribers.\n     */\n    @Experimental\n    public Observable<T> save(final T entity) {\n        return wrap(new Callable<T>() {\n            @Override\n            public T call() throws Exception {\n                dao.save(entity);\n                return entity;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#saveInTx(Iterable)} returning an Observable.\n     * Note that the Observable will emit the given entities back to its subscribers.\n     */\n    @Experimental\n    public Observable<Iterable<T>> saveInTx(final Iterable<T> entities) {\n        return wrap(new Callable<Iterable<T>>() {\n            @Override\n            public Iterable<T> call() throws Exception {\n                dao.saveInTx(entities);\n                return entities;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#saveInTx(Object[])} returning an Observable.\n     * Note that the Observable will emit the given entities back to its subscribers.\n     */\n    @Experimental\n    public Observable<Object[]> saveInTx(final T... entities) {\n        return wrap(new Callable<Object[]>() {\n            @Override\n            public Object[] call() throws Exception {\n                dao.saveInTx(entities);\n                return entities;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#update(Object)} returning an Observable.\n     * Note that the Observable will emit the given entity back to its subscribers.\n     */\n    @Experimental\n    public Observable<T> update(final T entity) {\n        return wrap(new Callable<T>() {\n            @Override\n            public T call() throws Exception {\n                dao.update(entity);\n                return entity;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#updateInTx(Iterable)} returning an Observable.\n     * Note that the Observable will emit the given entities back to its subscribers.\n     */\n    @Experimental\n    public Observable<Iterable<T>> updateInTx(final Iterable<T> entities) {\n        return wrap(new Callable<Iterable<T>>() {\n            @Override\n            public Iterable<T> call() throws Exception {\n                dao.updateInTx(entities);\n                return entities;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#updateInTx(Object[])} returning an Observable.\n     * Note that the Observable will emit the given entities back to its subscribers.\n     */\n    @Experimental\n    public Observable<Object[]> updateInTx(final T... entities) {\n        return wrap(new Callable<Object[]>() {\n            @Override\n            public Object[] call() throws Exception {\n                dao.updateInTx(entities);\n                return entities;\n            }\n        });\n    }\n\n\n    /**\n     * Rx version of {@link AbstractDao#delete(Object)} returning an Observable.\n     */\n    @Experimental\n    public Observable<Void> delete(final T entity) {\n        return wrap(new Callable<Void>() {\n            @Override\n            public Void call() throws Exception {\n                dao.delete(entity);\n                return null;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#deleteByKey(Object)} returning an Observable.\n     */\n    @Experimental\n    public Observable<Void> deleteByKey(final K key) {\n        return wrap(new Callable<Void>() {\n            @Override\n            public Void call() throws Exception {\n                dao.deleteByKey(key);\n                return null;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#deleteAll()} returning an Observable.\n     */\n    @Experimental\n    public Observable<Void> deleteAll() {\n        return wrap(new Callable<Void>() {\n            @Override\n            public Void call() throws Exception {\n                dao.deleteAll();\n                return null;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#deleteInTx(Iterable)} returning an Observable.\n     */\n    @Experimental\n    public Observable<Void> deleteInTx(final Iterable<T> entities) {\n        return wrap(new Callable<Void>() {\n            @Override\n            public Void call() throws Exception {\n                dao.deleteInTx(entities);\n                return null;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#deleteInTx(Object[])} returning an Observable.\n     */\n    @Experimental\n    public Observable<Void> deleteInTx(final T... entities) {\n        return wrap(new Callable<Void>() {\n            @Override\n            public Void call() throws Exception {\n                dao.deleteInTx(entities);\n                return null;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#deleteByKeyInTx(Iterable)} returning an Observable.\n     */\n    @Experimental\n    public Observable<Void> deleteByKeyInTx(final Iterable<K> keys) {\n        return wrap(new Callable<Void>() {\n            @Override\n            public Void call() throws Exception {\n                dao.deleteByKeyInTx(keys);\n                return null;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#deleteByKeyInTx(Object[])} returning an Observable.\n     */\n    @Experimental\n    public Observable<Void> deleteByKeyInTx(final K... keys) {\n        return wrap(new Callable<Void>() {\n            @Override\n            public Void call() throws Exception {\n                dao.deleteByKeyInTx(keys);\n                return null;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDao#count()} returning an Observable.\n     */\n    @Experimental\n    public Observable<Long> count() {\n        return wrap(new Callable<Long>() {\n            @Override\n            public Long call() throws Exception {\n                return dao.count();\n            }\n        });\n    }\n\n    /**\n     * The plain DAO.\n     */\n    @Experimental\n    public AbstractDao<T, K> getDao() {\n        return dao;\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/rx/RxQuery.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.rx;\n\nimport org.greenrobot.greendao.annotation.apihint.Experimental;\nimport org.greenrobot.greendao.query.LazyList;\nimport org.greenrobot.greendao.query.Query;\n\nimport java.util.List;\nimport java.util.concurrent.Callable;\n\nimport rx.Observable;\nimport rx.Observable.OnSubscribe;\nimport rx.Scheduler;\nimport rx.Subscriber;\nimport rx.exceptions.Exceptions;\n\n/**\n * Gets {@link org.greenrobot.greendao.query.Query} results in Rx fashion.\n */\n@Experimental\n// TODO Pass parameters: currently, parameters are always set to their initial values because of forCurrentThread()\npublic class RxQuery<T> extends RxBase {\n    private final Query<T> query;\n\n    public RxQuery(Query<T> query) {\n        this.query = query;\n    }\n\n    public RxQuery(Query<T> query, Scheduler scheduler) {\n        super(scheduler);\n        this.query = query;\n    }\n\n    /**\n     * Rx version of {@link Query#list()} returning an Observable.\n     */\n    @Experimental\n    public Observable<List<T>> list() {\n        return wrap(new Callable<List<T>>() {\n            @Override\n            public List<T> call() throws Exception {\n                return query.forCurrentThread().list();\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link Query#unique()} returning an Observable.\n     */\n    @Experimental\n    public Observable<T> unique() {\n        return wrap(new Callable<T>() {\n            @Override\n            public T call() throws Exception {\n                return query.forCurrentThread().unique();\n            }\n        });\n    }\n\n    /**\n     * Emits the resulting entities one by one, producing them on the fly (\"streaming\" entities).\n     * Unlike {@link #list()}, it does not wait for the query to gather all results. Thus, the first entities are\n     * immediately available as soon the underlying database cursor has data. This approach may be more memory\n     * efficient for large number of entities (or large entities) at the cost of additional overhead caused by a\n     * per-entity delivery through Rx.\n     */\n    public Observable<T> oneByOne() {\n        Observable<T> observable = Observable.create(new OnSubscribe<T>() {\n            @Override\n            public void call(Subscriber<? super T> subscriber) {\n                try {\n                    LazyList<T> lazyList = query.forCurrentThread().listLazyUncached();\n                    try {\n                        for (T entity : lazyList) {\n                            if (subscriber.isUnsubscribed()) {\n                                break;\n                            }\n                            subscriber.onNext(entity);\n                        }\n                    } finally {\n                        lazyList.close();\n                    }\n                    if (!subscriber.isUnsubscribed()) {\n                        subscriber.onCompleted();\n                    }\n                } catch (Throwable e) {\n                    Exceptions.throwIfFatal(e);\n                    subscriber.onError(e);\n                }\n            }\n        });\n        return wrap(observable);\n    }\n\n//    @Experimental\n//    public Query<T> getQuery() {\n//        return query;\n//    }\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/rx/RxTransaction.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.rx;\n\nimport org.greenrobot.greendao.AbstractDaoSession;\nimport org.greenrobot.greendao.annotation.apihint.Experimental;\n\nimport java.util.concurrent.Callable;\n\nimport rx.Observable;\nimport rx.Scheduler;\n\n/**\n * Allows to do transactions using Rx Observable.\n */\n@Experimental\npublic class RxTransaction extends RxBase {\n    private final AbstractDaoSession daoSession;\n\n    public RxTransaction(AbstractDaoSession daoSession) {\n        this.daoSession = daoSession;\n    }\n\n    public RxTransaction(AbstractDaoSession daoSession, Scheduler scheduler) {\n        super(scheduler);\n        this.daoSession = daoSession;\n    }\n\n    /**\n     * Rx version of {@link AbstractDaoSession#runInTx(Runnable)} returning an Observable.\n     */\n    @Experimental\n    public Observable<Void> run(final Runnable runnable) {\n        return wrap(new Callable<Void>() {\n            @Override\n            public Void call() throws Exception {\n                daoSession.runInTx(runnable);\n                return null;\n            }\n        });\n    }\n\n    /**\n     * Rx version of {@link AbstractDaoSession#callInTx(Callable)} returning an Observable.\n     */\n    @Experimental\n    public <T> Observable<T> call(final Callable<T> callable) {\n        return wrap(new Callable<T>() {\n            @Override\n            public T call() throws Exception {\n                return daoSession.callInTx(callable);\n            }\n        });\n    }\n\n    // Note: wrapping callInTxNoException does not make sense, because the Exception is handled by Rx anyway.\n\n\n    @Experimental\n    public AbstractDaoSession getDaoSession() {\n        return daoSession;\n    }\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/rx/RxUtils.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.rx;\n\nimport org.greenrobot.greendao.annotation.apihint.Internal;\n\nimport java.util.concurrent.Callable;\n\nimport rx.Observable;\nimport rx.functions.Func0;\n\n@Internal\nclass RxUtils {\n    /** As of RxJava 1.1.7, Observable.fromCallable is still @Beta, so just in case... */\n    @Internal\n    static <T> Observable<T> fromCallable(final Callable<T> callable) {\n        return Observable.defer(new Func0<Observable<T>>() {\n\n            @Override\n            public Observable<T> call() {\n                T result;\n                try {\n                    result = callable.call();\n                } catch (Exception e) {\n                    return Observable.error(e);\n                }\n                return Observable.just(result);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/test/AbstractDaoSessionTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.test;\n\nimport java.lang.reflect.Constructor;\nimport java.lang.reflect.Method;\n\nimport android.database.sqlite.SQLiteDatabase;\nimport org.greenrobot.greendao.AbstractDaoMaster;\nimport org.greenrobot.greendao.AbstractDaoSession;\nimport org.greenrobot.greendao.database.Database;\n\n/**\n * Base class for DAO (master) related testing.\n * \n * @author Markus\n * \n * @param <T>\n *            Type of a concrete DAO master\n */\npublic abstract class AbstractDaoSessionTest<T extends AbstractDaoMaster, S extends AbstractDaoSession>\n        extends DbTest {\n\n    private final Class<T> daoMasterClass;\n    protected T daoMaster;\n    protected S daoSession;\n\n    public AbstractDaoSessionTest(Class<T> daoMasterClass) {\n        this(daoMasterClass, true);\n    }\n\n    public AbstractDaoSessionTest(Class<T> daoMasterClass, boolean inMemory) {\n        super(inMemory);\n        this.daoMasterClass = daoMasterClass;\n    }\n\n\t@SuppressWarnings(\"unchecked\")\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        try {\n            Constructor<T> constructor = daoMasterClass.getConstructor(Database.class);\n            daoMaster = constructor.newInstance(db);\n\n            Method createTableMethod = daoMasterClass.getMethod(\"createAllTables\", Database.class, boolean.class);\n            createTableMethod.invoke(null, db, false);\n        } catch (Exception e) {\n            throw new RuntimeException(\"Could not prepare DAO session test\", e);\n        }\n        daoSession = (S) daoMaster.newSession();\n    }\n\n}"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/test/AbstractDaoTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.test;\n\nimport java.lang.reflect.Method;\n\nimport android.database.sqlite.SQLiteDatabase;\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.InternalUnitTestDaoAccess;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.identityscope.IdentityScope;\n\n/**\n * Base class for DAO related testing without any tests. Prepares an in-memory DB and DAO.\n * \n * @author Markus\n * \n * @param <D>\n *            DAO class\n * @param <T>\n *            Entity type of the DAO\n * @param <K>\n *            Key type of the DAO\n */\npublic abstract class AbstractDaoTest<D extends AbstractDao<T, K>, T, K> extends DbTest {\n\n    protected final Class<D> daoClass;\n    protected D dao;\n    protected InternalUnitTestDaoAccess<T, K> daoAccess;\n    protected Property pkColumn;\n    protected IdentityScope<K, T> identityScopeForDao;\n\n    public AbstractDaoTest(Class<D> daoClass) {\n        this(daoClass, true);\n    }\n\n    public AbstractDaoTest(Class<D> daoClass, boolean inMemory) {\n        super(inMemory);\n        this.daoClass = daoClass;\n    }\n\n    public void setIdentityScopeBeforeSetUp(IdentityScope<K, T> identityScope) {\n        this.identityScopeForDao = identityScope;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        try {\n            setUpTableForDao();\n            daoAccess = new InternalUnitTestDaoAccess<T, K>(db, (Class<AbstractDao<T, K>>) daoClass, identityScopeForDao);\n            dao = (D) daoAccess.getDao();\n        } catch (Exception e) {\n            throw new RuntimeException(\"Could not prepare DAO Test\", e);\n        }\n    }\n\n    protected void setUpTableForDao() throws Exception {\n        try {\n            Method createTableMethod = daoClass.getMethod(\"createTable\", Database.class, boolean.class);\n            createTableMethod.invoke(null, db, false);\n        } catch (NoSuchMethodException e) {\n            DaoLog.i(\"No createTable method\");\n        }\n    }\n\n    protected void clearIdentityScopeIfAny() {\n        if (identityScopeForDao != null) {\n            identityScopeForDao.clear();\n            DaoLog.d(\"Identity scope cleared\");\n        } else {\n            DaoLog.d(\"No identity scope to clear\");\n        }\n    }\n\n    protected void logTableDump() {\n        logTableDump(dao.getTablename());\n    }\n}"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/test/AbstractDaoTestLongPk.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.test;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.DaoLog;\n\n/**\n * Base class for DAOs having a long/Long as a PK, which is quite common.\n *\n * @param <D> DAO class\n * @param <T> Entity type of the DAO\n * @author Markus\n */\npublic abstract class AbstractDaoTestLongPk<D extends AbstractDao<T, Long>, T> extends AbstractDaoTestSinglePk<D, T, Long> {\n\n    public AbstractDaoTestLongPk(Class<D> daoClass) {\n        super(daoClass);\n    }\n\n    /** {@inheritDoc} */\n    protected Long createRandomPk() {\n        return random.nextLong();\n    }\n\n    public void testAssignPk() {\n        if (daoAccess.isEntityUpdateable()) {\n            T entity1 = createEntity(null);\n            if (entity1 != null) {\n                T entity2 = createEntity(null);\n\n                dao.insert(entity1);\n                dao.insert(entity2);\n\n                Long pk1 = daoAccess.getKey(entity1);\n                assertNotNull(pk1);\n                Long pk2 = daoAccess.getKey(entity2);\n                assertNotNull(pk2);\n\n                assertFalse(pk1.equals(pk2));\n\n                assertNotNull(dao.load(pk1));\n                assertNotNull(dao.load(pk2));\n            } else {\n                DaoLog.d(\"Skipping testAssignPk for \" + daoClass + \" (createEntity returned null for null key)\");\n            }\n        } else {\n            DaoLog.d(\"Skipping testAssignPk for not updateable \" + daoClass);\n        }\n    }\n\n}"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/test/AbstractDaoTestSinglePk.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.test;\n\nimport android.database.Cursor;\nimport android.database.DatabaseUtils;\nimport android.database.SQLException;\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.SqlUtils;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\n\n/**\n * Default tests for single-PK entities.\n *\n * @param <D> DAO class\n * @param <T> Entity type of the DAO\n * @param <K> Key type of the DAO\n * @author Markus\n */\npublic abstract class AbstractDaoTestSinglePk<D extends AbstractDao<T, K>, T, K> extends AbstractDaoTest<D, T, K> {\n\n    protected Set<K> usedPks;\n    private Property pkColumn;\n\n    public AbstractDaoTestSinglePk(Class<D> daoClass) {\n        super(daoClass);\n        usedPks = new HashSet<K>();\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        Property[] columns = daoAccess.getProperties();\n        for (Property column : columns) {\n            if (column.primaryKey) {\n                if (pkColumn != null) {\n                    throw new RuntimeException(\"Test does not work with multiple PK columns\");\n                }\n                pkColumn = column;\n            }\n        }\n        if (pkColumn == null) {\n            throw new RuntimeException(\"Test does not work without a PK column\");\n        }\n    }\n\n    public void testInsertAndLoad() {\n        K pk = nextPk();\n        T entity = createEntity(pk);\n        dao.insert(entity);\n        assertEquals(pk, daoAccess.getKey(entity));\n        T entity2 = dao.load(pk);\n        assertNotNull(entity2);\n        assertEquals(daoAccess.getKey(entity), daoAccess.getKey(entity2));\n    }\n\n    public void testInsertInTx() {\n        dao.deleteAll();\n        List<T> list = new ArrayList<T>();\n        for (int i = 0; i < 20; i++) {\n            list.add(createEntityWithRandomPk());\n        }\n        dao.insertInTx(list);\n        assertEquals(list.size(), dao.count());\n    }\n\n    public void testCount() {\n        dao.deleteAll();\n        assertEquals(0, dao.count());\n        dao.insert(createEntityWithRandomPk());\n        assertEquals(1, dao.count());\n        dao.insert(createEntityWithRandomPk());\n        assertEquals(2, dao.count());\n    }\n\n    public void testInsertTwice() {\n        K pk = nextPk();\n        T entity = createEntity(pk);\n        dao.insert(entity);\n        try {\n            dao.insert(entity);\n            fail(\"Inserting twice should not work\");\n        } catch (SQLException expected) {\n            // OK\n        }\n    }\n\n    public void testInsertOrReplaceTwice() {\n        T entity = createEntityWithRandomPk();\n        long rowId1 = dao.insert(entity);\n        long rowId2 = dao.insertOrReplace(entity);\n        if (dao.getPkProperty().type == Long.class) {\n            assertEquals(rowId1, rowId2);\n        }\n    }\n\n    public void testInsertOrReplaceInTx() {\n        dao.deleteAll();\n        List<T> listPartial = new ArrayList<T>();\n        List<T> listAll = new ArrayList<T>();\n        for (int i = 0; i < 20; i++) {\n            T entity = createEntityWithRandomPk();\n            if (i % 2 == 0) {\n                listPartial.add(entity);\n            }\n            listAll.add(entity);\n        }\n        dao.insertOrReplaceInTx(listPartial);\n        dao.insertOrReplaceInTx(listAll);\n        assertEquals(listAll.size(), dao.count());\n    }\n\n    public void testDelete() {\n        K pk = nextPk();\n        dao.deleteByKey(pk);\n        T entity = createEntity(pk);\n        dao.insert(entity);\n        assertNotNull(dao.load(pk));\n        dao.deleteByKey(pk);\n        assertNull(dao.load(pk));\n    }\n\n    public void testDeleteAll() {\n        List<T> entityList = new ArrayList<T>();\n        for (int i = 0; i < 10; i++) {\n            T entity = createEntityWithRandomPk();\n            entityList.add(entity);\n        }\n        dao.insertInTx(entityList);\n        dao.deleteAll();\n        assertEquals(0, dao.count());\n        for (T entity : entityList) {\n            K key = daoAccess.getKey(entity);\n            assertNotNull(key);\n            assertNull(dao.load(key));\n        }\n    }\n\n    public void testDeleteInTx() {\n        List<T> entityList = new ArrayList<T>();\n        for (int i = 0; i < 10; i++) {\n            T entity = createEntityWithRandomPk();\n            entityList.add(entity);\n        }\n        dao.insertInTx(entityList);\n        List<T> entitiesToDelete = new ArrayList<T>();\n        entitiesToDelete.add(entityList.get(0));\n        entitiesToDelete.add(entityList.get(3));\n        entitiesToDelete.add(entityList.get(4));\n        entitiesToDelete.add(entityList.get(8));\n        dao.deleteInTx(entitiesToDelete);\n        assertEquals(entityList.size() - entitiesToDelete.size(), dao.count());\n        for (T deletedEntity : entitiesToDelete) {\n            K key = daoAccess.getKey(deletedEntity);\n            assertNotNull(key);\n            assertNull(dao.load(key));\n        }\n    }\n\n    public void testDeleteByKeyInTx() {\n        List<T> entityList = new ArrayList<T>();\n        for (int i = 0; i < 10; i++) {\n            T entity = createEntityWithRandomPk();\n            entityList.add(entity);\n        }\n        dao.insertInTx(entityList);\n        List<K> keysToDelete = new ArrayList<K>();\n        keysToDelete.add(daoAccess.getKey(entityList.get(0)));\n        keysToDelete.add(daoAccess.getKey(entityList.get(3)));\n        keysToDelete.add(daoAccess.getKey(entityList.get(4)));\n        keysToDelete.add(daoAccess.getKey(entityList.get(8)));\n        dao.deleteByKeyInTx(keysToDelete);\n        assertEquals(entityList.size() - keysToDelete.size(), dao.count());\n        for (K key : keysToDelete) {\n            assertNotNull(key);\n            assertNull(dao.load(key));\n        }\n    }\n\n    public void testRowId() {\n        T entity1 = createEntityWithRandomPk();\n        T entity2 = createEntityWithRandomPk();\n        long rowId1 = dao.insert(entity1);\n        long rowId2 = dao.insert(entity2);\n        assertTrue(rowId1 != rowId2);\n    }\n\n    public void testLoadAll() {\n        dao.deleteAll();\n        List<T> list = new ArrayList<T>();\n        for (int i = 0; i < 15; i++) {\n            T entity = createEntity(nextPk());\n            list.add(entity);\n        }\n        dao.insertInTx(list);\n        List<T> loaded = dao.loadAll();\n        assertEquals(list.size(), loaded.size());\n    }\n\n    public void testQuery() {\n        dao.insert(createEntityWithRandomPk());\n        K pkForQuery = nextPk();\n        dao.insert(createEntity(pkForQuery));\n        dao.insert(createEntityWithRandomPk());\n\n        String where = \"WHERE \" + dao.getPkColumns()[0] + \"=?\";\n        List<T> list = dao.queryRaw(where, pkForQuery.toString());\n        assertEquals(1, list.size());\n        assertEquals(pkForQuery, daoAccess.getKey(list.get(0)));\n    }\n\n    public void testUpdate() {\n        dao.deleteAll();\n        T entity = createEntityWithRandomPk();\n        dao.insert(entity);\n        dao.update(entity);\n        assertEquals(1, dao.count());\n    }\n\n    public void testReadWithOffset() {\n        K pk = nextPk();\n        T entity = createEntity(pk);\n        dao.insert(entity);\n\n        Cursor cursor = queryWithDummyColumnsInFront(5, \"42\", pk);\n        try {\n            T entity2 = daoAccess.readEntity(cursor, 5);\n            assertEquals(pk, daoAccess.getKey(entity2));\n        } finally {\n            cursor.close();\n        }\n    }\n\n    public void testLoadPkWithOffset() {\n        runLoadPkTest(10);\n    }\n\n    public void testLoadPk() {\n        runLoadPkTest(0);\n    }\n\n    public void testSave() {\n        if(!checkKeyIsNullable()) {\n            return;\n        }\n        dao.deleteAll();\n        T entity = createEntity(null);\n        if (entity != null) {\n            dao.save(entity);\n            dao.save(entity);\n            assertEquals(1, dao.count());\n        }\n    }\n\n    public void testSaveInTx() {\n        if(!checkKeyIsNullable()) {\n            return;\n        }\n        dao.deleteAll();\n        List<T> listPartial = new ArrayList<T>();\n        List<T> listAll = new ArrayList<T>();\n        for (int i = 0; i < 20; i++) {\n            T entity = createEntity(null);\n            if (i % 2 == 0) {\n                listPartial.add(entity);\n            }\n            listAll.add(entity);\n        }\n        dao.saveInTx(listPartial);\n        dao.saveInTx(listAll);\n        assertEquals(listAll.size(), dao.count());\n    }\n\n    protected void runLoadPkTest(int offset) {\n        K pk = nextPk();\n        T entity = createEntity(pk);\n        dao.insert(entity);\n\n        Cursor cursor = queryWithDummyColumnsInFront(offset, \"42\", pk);\n        try {\n            K pk2 = daoAccess.readKey(cursor, offset);\n            assertEquals(pk, pk2);\n        } finally {\n            cursor.close();\n        }\n    }\n\n    protected Cursor queryWithDummyColumnsInFront(int dummyCount, String valueForColumn, K pk) {\n        StringBuilder builder = new StringBuilder(\"SELECT \");\n        for (int i = 0; i < dummyCount; i++) {\n            builder.append(valueForColumn).append(\",\");\n        }\n        SqlUtils.appendColumns(builder, \"T\", dao.getAllColumns()).append(\" FROM \");\n        builder.append('\"').append(dao.getTablename()).append('\"').append(\" T\");\n        if (pk != null) {\n            builder.append(\" WHERE \");\n\n            assertEquals(1, dao.getPkColumns().length);\n            builder.append(dao.getPkColumns()[0]).append(\"=\");\n            DatabaseUtils.appendValueToSql(builder, pk);\n        }\n\n        String select = builder.toString();\n        Cursor cursor = db.rawQuery(select, null);\n        assertTrue(cursor.moveToFirst());\n        try {\n            for (int i = 0; i < dummyCount; i++) {\n                assertEquals(valueForColumn, cursor.getString(i));\n            }\n            if (pk != null) {\n                assertEquals(1, cursor.getCount());\n            }\n        } catch (RuntimeException ex) {\n            cursor.close();\n            throw ex;\n        }\n        return cursor;\n    }\n\n    protected boolean checkKeyIsNullable() {\n        if (createEntity(null) == null) {\n            DaoLog.d(\"Test is not available for entities with non-null keys\");\n            return false;\n        }\n        return true;\n    }\n\n    /** Provides a collision free PK () not returned before in the current test. */\n    protected K nextPk() {\n        for (int i = 0; i < 100000; i++) {\n            K pk = createRandomPk();\n            if (usedPks.add(pk)) {\n                return pk;\n            }\n        }\n        throw new IllegalStateException(\"Could not find a new PK\");\n    }\n\n    protected T createEntityWithRandomPk() {\n        return createEntity(nextPk());\n    }\n\n    /** K does not have to be collision free, check nextPk for collision free PKs. */\n    protected abstract K createRandomPk();\n\n    /**\n     * Creates an insertable entity. If the given key is null, but the entity's PK is not null the method must return\n     * null.\n     */\n    protected abstract T createEntity(K key);\n\n}"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/test/AbstractDaoTestStringPk.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.test;\n\nimport org.greenrobot.greendao.AbstractDao;\n\n/**\n * Base class for DAOs having a String as a PK.\n * \n * @author Markus\n * \n * @param <D>\n *            DAO class\n * @param <T>\n *            Entity type of the DAO\n */\npublic abstract class AbstractDaoTestStringPk<D extends AbstractDao<T, String>, T> extends\n        AbstractDaoTestSinglePk<D, T, String> {\n\n    public AbstractDaoTestStringPk(Class<D> daoClass) {\n        super(daoClass);\n    }\n\n    @Override\n    protected String createRandomPk() {\n        int len = 1 + random.nextInt(30);\n        StringBuilder builder = new StringBuilder();\n        for (int i = 0; i < len; i++) {\n            char c = (char) ('a' + random.nextInt('z' - 'a'));\n            builder.append(c);\n        }\n        return builder.toString();\n    }\n\n}\n"
  },
  {
    "path": "DaoCore/src/main/java/org/greenrobot/greendao/test/DbTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.test;\n\nimport android.app.Application;\nimport android.app.Instrumentation;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.test.AndroidTestCase;\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.DbUtils;\nimport org.greenrobot.greendao.database.StandardDatabase;\nimport org.greenrobot.greendao.database.Database;\n\nimport java.util.Random;\n\n/**\n * Base class for database related testing, which prepares an in-memory or an file-based DB (using the test {@link\n * android.content.Context}). Also, offers some convenience methods to create new {@link Application} objects similar\n * to {@link android.test.ApplicationTestCase}.\n * <p/>\n * Unlike ApplicationTestCase, this class should behave more correctly when you call {@link #createApplication(Class)}\n * during {@link #setUp()}: {@link android.test.ApplicationTestCase#testApplicationTestCaseSetUpProperly()} leaves\n * Application objects un-terminated.\n *\n * @author Markus\n */\npublic abstract class DbTest extends AndroidTestCase {\n\n    public static final String DB_NAME = \"greendao-unittest-db.temp\";\n\n    protected final Random random;\n    protected final boolean inMemory;\n    protected Database db;\n\n    private Application application;\n\n    public DbTest() {\n        this(true);\n    }\n\n    public DbTest(boolean inMemory) {\n        this.inMemory = inMemory;\n        random = new Random();\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        db = createDatabase();\n    }\n\n    /** Returns a prepared application with the onCreate method already called. */\n    public <T extends Application> T createApplication(Class<T> appClass) {\n        assertNull(\"Application already created\", application);\n        T app;\n        try {\n            app = (T) Instrumentation.newApplication(appClass, getContext());\n        } catch (Exception e) {\n            throw new RuntimeException(\"Could not create application \" + appClass, e);\n        }\n        app.onCreate();\n        application = app;\n        return app;\n    }\n\n    /** Terminates a previously created application. Also called by {@link #tearDown()} if needed. */\n    public void terminateApplication() {\n        assertNotNull(\"Application not yet created\", application);\n        application.onTerminate();\n        application = null;\n    }\n\n    /** Gets the previously created application. */\n    public <T extends Application> T getApplication() {\n        assertNotNull(\"Application not yet created\", application);\n        return (T) application;\n    }\n\n    /** May be overriden by sub classes to set up a different db. */\n    protected Database createDatabase() {\n        SQLiteDatabase sqLiteDatabase;\n        if (inMemory) {\n            sqLiteDatabase = SQLiteDatabase.create(null);\n\n        } else {\n            getContext().deleteDatabase(DB_NAME);\n            sqLiteDatabase = getContext().openOrCreateDatabase(DB_NAME, 0, null);\n        }\n        return new StandardDatabase(sqLiteDatabase);\n    }\n\n    @Override\n    /** Closes the db, and terminates an application, if one was created before. */\n    protected void tearDown() throws Exception {\n        if (application != null) {\n            terminateApplication();\n        }\n        db.close();\n        if (!inMemory) {\n            getContext().deleteDatabase(DB_NAME);\n        }\n        super.tearDown();\n    }\n\n    protected void logTableDump(String tablename) {\n        if (db instanceof StandardDatabase) {\n            DbUtils.logTableDump(((StandardDatabase) db).getSQLiteDatabase(), tablename);\n        } else {\n            DaoLog.w(\"Table dump unsupported for \" + db);\n        }\n    }\n\n}"
  },
  {
    "path": "DaoGenerator/.freemarker-ide.xml",
    "content": "<config>\n\t<context-values>\n\t\t<resource path=\"src-template/dao-master.ftl\">\n\t\t\t<value key=\"schema\" object-class=\"org.greenrobot.greendao.generator.Schema\"/>\n\t\t</resource>\n\t\t<resource path=\"src-template/content-provider.ftl\">\n\t\t\t<value key=\"entity\" object-class=\"org.greenrobot.greendao.generator.Entity\"/>\n\t\t\t<value key=\"contentProvider\" object-class=\"org.greenrobot.greendao.generator.ContentProvider\"/>\n\t\t\t<value key=\"schema\" object-class=\"org.greenrobot.greendao.generator.Schema\"/>\n\t\t</resource>\n\t\t<resource path=\"src-template/dao.ftl\">\n\t\t\t<value key=\"entity\" object-class=\"org.greenrobot.greendao.generator.Entity\"/>\n\t\t\t<value key=\"schema\" object-class=\"org.greenrobot.greendao.generator.Schema\"/>\n\t\t</resource>\n\t\t<resource path=\"src-template/dao-deep.ftl\">\n\t\t\t<value key=\"entity\" object-class=\"org.greenrobot.greendao.generator.Entity\"/>\n\t\t\t<value key=\"schema\" object-class=\"org.greenrobot.greendao.generator.Schema\"/>\n\t\t</resource>\n\t\t<resource path=\"src-template/entity.ftl\">\n\t\t\t<value key=\"entity\" object-class=\"org.greenrobot.greendao.generator.Entity\"/>\n\t\t\t<value key=\"schema\" object-class=\"org.greenrobot.greendao.generator.Schema\"/>\n\t\t</resource>\n\t\t<resource path=\"src-template/dao-unit-test.ftl\">\n\t\t\t<value key=\"schema\" object-class=\"org.greenrobot.greendao.generator.Schema\"/>\n\t\t\t<value key=\"entity\" object-class=\"org.greenrobot.greendao.generator.Entity\"/>\n\t\t</resource>\n\t\t<resource path=\"template/dao.ftl\">\n\t\t\t<value key=\"table\" object-class=\"org.greenrobot.greendao.generator.Entity\"/>\n\t\t</resource>\n\t</context-values>\n\t<macro-library>\n\t</macro-library>\n</config>"
  },
  {
    "path": "DaoGenerator/.gitignore",
    "content": "/gradle.properties\n"
  },
  {
    "path": "DaoGenerator/build.gradle",
    "content": "apply plugin: 'java'\n\ngroup = 'org.greenrobot'\narchivesBaseName = 'greendao-generator'\nversion = rootProject.version\nsourceCompatibility = 1.7\n\nrepositories {\n    mavenCentral()\n}\n\ndependencies {\n    compile 'org.freemarker:freemarker:2.3.29'\n    testImplementation 'junit:junit:4.12'\n}\n\nsourceSets {\n    main {\n        java {\n            srcDir 'src'\n        }\n        resources {\n            srcDir 'src-template'\n        }\n    }\n    test {\n        java {\n            srcDir 'src-test'\n        }\n    }\n}\n\ntest {\n    doFirst {\n        mkdir 'test-out'\n    }\n    doLast {\n        delete 'test-out'\n    }\n}\n\napply from: rootProject.file(\"gradle/publish.gradle\")\n\njavadoc {\n    failOnError = false\n    title = \"greenDAO Generator ${version} API\"\n    // Unfinished APIs:\n    excludes = ['org/greenrobot/daogenerator/Query*']\n    options.bottom = 'Available under the GPLv3 - <i>Copyright &#169; 2011-2020 <a href=\"https://greenrobot.org/\">greenrobot.org</a>. All Rights Reserved.</i>'\n    doLast {\n        copy {\n            from '../javadoc-style/'\n            into \"build/docs/javadoc/\"\n        }\n    }\n}\n\ntask javadocJar(type: Jar, dependsOn: javadoc) {\n    classifier = 'javadoc'\n    from 'build/docs/javadoc'\n}\n\ntask sourcesJar(type: Jar) {\n    from sourceSets.main.allSource\n    classifier = 'sources'\n}\n\nartifacts {\n    // jar added by Java plugin.\n    archives javadocJar\n    archives sourcesJar\n}\n\nuploadArchives {\n    repositories {\n        mavenDeployer {\n            // Basic definitions are defined in root project\n            pom.project {\n                name 'greenDAO Generator'\n                description 'Code generator for greenDAO, the light and fast ORM for Android'\n\n                licenses {\n                    license {\n                        name 'GNU General Public License, Version 3'\n                        url 'http://www.gnu.org/licenses/gpl.txt'\n                        distribution 'repo'\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/ContentProvider.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\nimport java.util.List;\n\n@SuppressWarnings(\"unused\")\npublic class ContentProvider {\n    private final List<Entity> entities;\n    private String authority;\n    private String basePath;\n    private String className;\n    private String javaPackage;\n    private boolean readOnly;\n    private Schema schema;\n\n    public ContentProvider(Schema schema, List<Entity> entities) {\n        this.schema = schema;\n        this.entities = entities;\n    }\n\n    public String getAuthority() {\n        return authority;\n    }\n\n    public void setAuthority(String authority) {\n        this.authority = authority;\n    }\n\n    public String getBasePath() {\n        return basePath;\n    }\n\n    public void setBasePath(String basePath) {\n        this.basePath = basePath;\n    }\n\n    public String getClassName() {\n        return className;\n    }\n\n    public void setClassName(String className) {\n        this.className = className;\n    }\n\n    public String getJavaPackage() {\n        return javaPackage;\n    }\n\n    public void setJavaPackage(String javaPackage) {\n        this.javaPackage = javaPackage;\n    }\n\n    public boolean isReadOnly() {\n        return readOnly;\n    }\n\n    public void readOnly() {\n        this.readOnly = true;\n    }\n\n    public List<Entity> getEntities() {\n        return entities;\n    }\n\n    public void init2ndPass() {\n        if (authority == null) {\n            authority = schema.getDefaultJavaPackage() + \".provider\";\n        }\n        if (basePath == null) {\n            basePath = \"\";\n        }\n        if (className == null) {\n            className = entities.get(0).getClassName() + \"ContentProvider\";\n        }\n        if (javaPackage == null) {\n            javaPackage = schema.getDefaultJavaPackage();\n        }\n\n    }\n\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/DaoGenerator.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\nimport java.io.File;\nimport java.io.FileWriter;\nimport java.io.IOException;\nimport java.io.Writer;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\nimport freemarker.template.Configuration;\nimport freemarker.template.Template;\nimport freemarker.template.TemplateNotFoundException;\n\n/**\n * Once you have your model created, use this class to generate entities and DAOs.\n *\n * @author Markus\n */\npublic class DaoGenerator {\n\n    private Pattern patternKeepIncludes;\n    private Pattern patternKeepFields;\n    private Pattern patternKeepMethods;\n\n    private Template templateDao;\n    private Template templateDaoMaster;\n    private Template templateDaoSession;\n    private Template templateEntity;\n    private Template templateDaoUnitTest;\n    private Template templateContentProvider;\n\n    public DaoGenerator() throws IOException {\n        System.out.println(\"greenDAO Generator\");\n        System.out.println(\"Copyright 2011-2016 Markus Junginger, greenrobot.de. Licensed under GPL V3.\");\n        System.out.println(\"This program comes with ABSOLUTELY NO WARRANTY\");\n\n        patternKeepIncludes = compilePattern(\"INCLUDES\");\n        patternKeepFields = compilePattern(\"FIELDS\");\n        patternKeepMethods = compilePattern(\"METHODS\");\n\n        Configuration config = getConfiguration(\"dao.ftl\");\n        templateDao = config.getTemplate(\"dao.ftl\");\n        templateDaoMaster = config.getTemplate(\"dao-master.ftl\");\n        templateDaoSession = config.getTemplate(\"dao-session.ftl\");\n        templateEntity = config.getTemplate(\"entity.ftl\");\n        templateDaoUnitTest = config.getTemplate(\"dao-unit-test.ftl\");\n        templateContentProvider = config.getTemplate(\"content-provider.ftl\");\n    }\n\n    private Configuration getConfiguration(String probingTemplate) throws IOException {\n        Configuration config = new Configuration(Configuration.VERSION_2_3_29);\n        config.setClassForTemplateLoading(getClass(), \"/\");\n\n        try {\n            config.getTemplate(probingTemplate);\n        } catch (TemplateNotFoundException e) {\n            // When running from an IDE like IntelliJ, class loading resources may fail for some reason (Gradle is OK)\n\n            // Working dir is module dir\n            File dir = new File(\"src/main/resources/\");\n            if (!dir.exists()) {\n                // Working dir is base module dir\n                dir = new File(\"DaoGenerator/src/main/resources/\");\n            }\n            if (dir.exists() && new File(dir, probingTemplate).exists()) {\n                config.setDirectoryForTemplateLoading(dir);\n                config.getTemplate(probingTemplate);\n            } else {\n                throw e;\n            }\n        }\n        return config;\n    }\n\n    private Pattern compilePattern(String sectionName) {\n        int flags = Pattern.DOTALL | Pattern.MULTILINE;\n        return Pattern.compile(\".*^\\\\s*?//\\\\s*?KEEP \" + sectionName + \".*?\\n(.*?)^\\\\s*// KEEP \" + sectionName\n                + \" END.*?\\n\", flags);\n    }\n\n    /** Generates all entities and DAOs for the given schema. */\n    public void generateAll(Schema schema, String outDir) throws Exception {\n        generateAll(schema, outDir, null, null);\n    }\n\n    /** Generates all entities and DAOs for the given schema. */\n    public void generateAll(Schema schema, String outDir, String outDirEntity, String outDirTest) throws Exception {\n        long start = System.currentTimeMillis();\n\n        File outDirFile = toFileForceExists(outDir);\n        File outDirEntityFile = outDirEntity != null ? toFileForceExists(outDirEntity) : outDirFile;\n        File outDirTestFile = outDirTest != null ? toFileForceExists(outDirTest) : null;\n\n        schema.init2ndPass();\n        schema.init3rdPass();\n\n        System.out.println(\"Processing schema version \" + schema.getVersion() + \"...\");\n\n        List<Entity> entities = schema.getEntities();\n        for (Entity entity : entities) {\n            generate(templateDao, outDirFile, entity.getJavaPackageDao(), entity.getClassNameDao(), schema, entity);\n            if (!entity.isProtobuf() && !entity.isSkipGeneration()) {\n                generate(templateEntity, outDirEntityFile, entity.getJavaPackage(), entity.getClassName(), schema, entity);\n            }\n            if (outDirTestFile != null && !entity.isSkipGenerationTest()) {\n                String javaPackageTest = entity.getJavaPackageTest();\n                String classNameTest = entity.getClassNameTest();\n                File javaFilename = toJavaFilename(outDirTestFile, javaPackageTest, classNameTest);\n                if (!javaFilename.exists()) {\n                    generate(templateDaoUnitTest, outDirTestFile, javaPackageTest, classNameTest, schema, entity);\n                } else {\n                    System.out.println(\"Skipped \" + javaFilename.getCanonicalPath());\n                }\n            }\n            for (ContentProvider contentProvider : entity.getContentProviders()) {\n                Map<String, Object> additionalObjectsForTemplate = new HashMap<>();\n                additionalObjectsForTemplate.put(\"contentProvider\", contentProvider);\n                generate(templateContentProvider, outDirFile, entity.getJavaPackage(), entity.getClassName()\n                        + \"ContentProvider\", schema, entity, additionalObjectsForTemplate);\n            }\n        }\n        generate(templateDaoMaster, outDirFile, schema.getDefaultJavaPackageDao(),\n                schema.getPrefix() + \"DaoMaster\", schema, null);\n        generate(templateDaoSession, outDirFile, schema.getDefaultJavaPackageDao(),\n                schema.getPrefix() + \"DaoSession\", schema, null);\n\n        long time = System.currentTimeMillis() - start;\n        System.out.println(\"Processed \" + entities.size() + \" entities in \" + time + \"ms\");\n    }\n\n    protected File toFileForceExists(String filename) throws IOException {\n        File file = new File(filename);\n        if (!file.exists()) {\n            throw new IOException(filename\n                    + \" does not exist. This check is to prevent accidental file generation into a wrong path.\");\n        }\n        return file;\n    }\n\n    private void generate(Template template, File outDirFile, String javaPackage, String javaClassName, Schema schema,\n                          Entity entity) throws Exception {\n        generate(template, outDirFile, javaPackage, javaClassName, schema, entity, null);\n    }\n\n    private void generate(Template template, File outDirFile, String javaPackage, String javaClassName, Schema schema,\n                          Entity entity, Map<String, Object> additionalObjectsForTemplate) throws Exception {\n        Map<String, Object> root = new HashMap<>();\n        root.put(\"schema\", schema);\n        root.put(\"entity\", entity);\n        if (additionalObjectsForTemplate != null) {\n            root.putAll(additionalObjectsForTemplate);\n        }\n        try {\n            File file = toJavaFilename(outDirFile, javaPackage, javaClassName);\n            //noinspection ResultOfMethodCallIgnored\n            file.getParentFile().mkdirs();\n\n            if (entity != null && entity.getHasKeepSections()) {\n                checkKeepSections(file, root);\n            }\n\n            Writer writer = new FileWriter(file);\n            try {\n                template.process(root, writer);\n                writer.flush();\n                System.out.println(\"Written \" + file.getCanonicalPath());\n            } finally {\n                writer.close();\n            }\n        } catch (Exception ex) {\n            System.err.println(\"Data map for template: \" + root);\n            System.err.println(\"Error while generating \" + javaPackage + \".\" + javaClassName + \" (\"\n                    + outDirFile.getCanonicalPath() + \")\");\n            throw ex;\n        }\n    }\n\n    private void checkKeepSections(File file, Map<String, Object> root) {\n        if (file.exists()) {\n            try {\n                String contents = new String(DaoUtil.readAllBytes(file));\n\n                Matcher matcher;\n\n                matcher = patternKeepIncludes.matcher(contents);\n                if (matcher.matches()) {\n                    root.put(\"keepIncludes\", matcher.group(1));\n                }\n\n                matcher = patternKeepFields.matcher(contents);\n                if (matcher.matches()) {\n                    root.put(\"keepFields\", matcher.group(1));\n                }\n\n                matcher = patternKeepMethods.matcher(contents);\n                if (matcher.matches()) {\n                    root.put(\"keepMethods\", matcher.group(1));\n                }\n            } catch (IOException e) {\n                e.printStackTrace();\n            }\n        }\n    }\n\n    protected File toJavaFilename(File outDirFile, String javaPackage, String javaClassName) {\n        String packageSubPath = javaPackage.replace('.', '/');\n        File packagePath = new File(outDirFile, packageSubPath);\n        return new File(packagePath, javaClassName + \".java\");\n    }\n\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/DaoUtil.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\n\n/** Internal API */\npublic class DaoUtil {\n    public static String dbName(String javaName) {\n        StringBuilder builder = new StringBuilder(javaName);\n        for (int i = 1; i < builder.length(); i++) {\n            boolean lastWasUpper = Character.isUpperCase(builder.charAt(i - 1));\n            boolean isUpper = Character.isUpperCase(builder.charAt(i));\n            if (isUpper && !lastWasUpper) {\n                builder.insert(i, '_');\n                i++;\n            }\n        }\n        return builder.toString().toUpperCase();\n    }\n\n    public static String getClassnameFromFullyQualified(String clazz) {\n        int index = clazz.lastIndexOf('.');\n        if (index != -1) {\n            return clazz.substring(index + 1);\n        } else {\n            return clazz;\n        }\n    }\n\n    public static String capFirst(String string) {\n        return Character.toUpperCase(string.charAt(0)) + (string.length() > 1 ? string.substring(1) : \"\");\n    }\n\n    public static String getPackageFromFullyQualified(String clazz) {\n        int index = clazz.lastIndexOf('.');\n        if (index != -1) {\n            return clazz.substring(0, index);\n        } else {\n            return null;\n        }\n    }\n\n    public static byte[] readAllBytes(InputStream in) throws IOException {\n        ByteArrayOutputStream out = new ByteArrayOutputStream();\n        copyAllBytes(in, out);\n        return out.toByteArray();\n    }\n\n    public static byte[] readAllBytes(File file) throws IOException {\n        FileInputStream is = new FileInputStream(file);\n        try {\n            return DaoUtil.readAllBytes(is);\n        } finally {\n            is.close();\n        }\n    }\n\n    public static byte[] readAllBytes(String filename) throws IOException {\n        FileInputStream is = new FileInputStream(filename);\n        try {\n            return DaoUtil.readAllBytes(is);\n        } finally {\n            is.close();\n        }\n    }\n\n    /**\n     * Copies all available data from in to out without closing any stream.\n     *\n     * @return number of bytes copied\n     */\n    public static int copyAllBytes(InputStream in, OutputStream out) throws IOException {\n        int byteCount = 0;\n        byte[] buffer = new byte[4096];\n        while (true) {\n            int read = in.read(buffer);\n            if (read == -1) {\n                break;\n            }\n            out.write(buffer, 0, read);\n            byteCount += read;\n        }\n        return byteCount;\n    }\n\n    public static String checkConvertToJavaDoc(String javaDoc, String indent) {\n        if (javaDoc != null && !javaDoc.trim().startsWith(\"/**\")) {\n            javaDoc = javaDoc.replace(\"\\n\", \"\\n\" + indent + \" * \");\n            javaDoc = indent + \"/**\\n\" + indent + \" * \" + javaDoc + \"\\n\" + indent + \" */\";\n        }\n        return javaDoc;\n    }\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/Entity.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\nimport org.greenrobot.greendao.generator.Property.PropertyBuilder;\n\nimport java.util.ArrayList;\nimport java.util.Collection;\nimport java.util.HashSet;\nimport java.util.List;\nimport java.util.Set;\nimport java.util.TreeSet;\n\n/**\n * Model class for an entity: a Java data object mapped to a data base table. A new entity is added to a {@link Schema}\n * by the method {@link Schema#addEntity(String)} (there is no public constructor for {@link Entity} itself). <br/>\n * <br/> Use the various addXXX methods to add entity properties, indexes, and relations to other entities (addToOne,\n * addToMany).<br/> <br/> There are further configuration possibilities: <ul> <li>{@link\n * Entity#implementsInterface(String...)} and {@link #implementsSerializable()} to specify interfaces the entity will\n * implement</li> <li>{@link #setSuperclass(String)} to specify a class of which the entity will extend from</li>\n * <li>Various setXXX methods</li> </ul>\n *\n * @see <a href=\"http://greendao-orm.com/documentation/modelling-entities/\">Modelling Entities (Documentation page)</a>\n * @see <a href=\"http://greendao-orm.com/documentation/relations/\">Relations (Documentation page)</a>\n */\n@SuppressWarnings(\"unused\")\npublic class Entity {\n    private final Schema schema;\n    private final String className;\n    private final List<Property> properties;\n    private List<Property> propertiesColumns;\n    private final List<Property> propertiesPk;\n    private final List<Property> propertiesNonPk;\n    private final Set<String> propertyNames;\n    private final List<Index> indexes;\n    private final List<Index> multiIndexes;\n    private final List<ToOne> toOneRelations;\n    private final List<ToManyBase> toManyRelations;\n    private final List<ToManyBase> incomingToManyRelations;\n    private final Collection<String> additionalImportsEntity;\n    private final Collection<String> additionalImportsDao;\n    private final List<String> interfacesToImplement;\n    private final List<ContentProvider> contentProviders;\n\n    private String dbName;\n    private boolean nonDefaultDbName;\n    private String classNameDao;\n    private String classNameTest;\n    private String javaPackage;\n    private String javaPackageDao;\n    private String javaPackageTest;\n    private Property pkProperty;\n    private String pkType;\n    private String superclass;\n    private String javaDoc;\n    private String codeBeforeClass;\n\n    private boolean protobuf;\n    private boolean constructors;\n    private boolean skipGeneration;\n    private boolean skipGenerationTest;\n    private boolean skipCreationInDb;\n    private Boolean active;\n    private Boolean hasKeepSections;\n\n    Entity(Schema schema, String className) {\n        this.schema = schema;\n        this.className = className;\n        properties = new ArrayList<>();\n        propertiesPk = new ArrayList<>();\n        propertiesNonPk = new ArrayList<>();\n        propertyNames = new HashSet<>();\n        indexes = new ArrayList<>();\n        multiIndexes = new ArrayList<>();\n        toOneRelations = new ArrayList<>();\n        toManyRelations = new ArrayList<>();\n        incomingToManyRelations = new ArrayList<>();\n        additionalImportsEntity = new TreeSet<>();\n        additionalImportsDao = new TreeSet<>();\n        interfacesToImplement = new ArrayList<>();\n        contentProviders = new ArrayList<>();\n        constructors = true;\n    }\n\n    public PropertyBuilder addBooleanProperty(String propertyName) {\n        return addProperty(PropertyType.Boolean, propertyName);\n    }\n\n    public PropertyBuilder addByteProperty(String propertyName) {\n        return addProperty(PropertyType.Byte, propertyName);\n    }\n\n    public PropertyBuilder addShortProperty(String propertyName) {\n        return addProperty(PropertyType.Short, propertyName);\n    }\n\n    public PropertyBuilder addIntProperty(String propertyName) {\n        return addProperty(PropertyType.Int, propertyName);\n    }\n\n    public PropertyBuilder addLongProperty(String propertyName) {\n        return addProperty(PropertyType.Long, propertyName);\n    }\n\n    public PropertyBuilder addFloatProperty(String propertyName) {\n        return addProperty(PropertyType.Float, propertyName);\n    }\n\n    public PropertyBuilder addDoubleProperty(String propertyName) {\n        return addProperty(PropertyType.Double, propertyName);\n    }\n\n    public PropertyBuilder addByteArrayProperty(String propertyName) {\n        return addProperty(PropertyType.ByteArray, propertyName);\n    }\n\n    public PropertyBuilder addStringProperty(String propertyName) {\n        return addProperty(PropertyType.String, propertyName);\n    }\n\n    public PropertyBuilder addDateProperty(String propertyName) {\n        return addProperty(PropertyType.Date, propertyName);\n    }\n\n    public PropertyBuilder addProperty(PropertyType propertyType, String propertyName) {\n        if (!propertyNames.add(propertyName)) {\n            throw new RuntimeException(\"Property already defined: \" + propertyName);\n        }\n        PropertyBuilder builder = new PropertyBuilder(schema, this, propertyType, propertyName);\n        properties.add(builder.getProperty());\n        return builder;\n    }\n\n    /** Adds a standard _id column required by standard Android classes, e.g. list adapters. */\n    public PropertyBuilder addIdProperty() {\n        PropertyBuilder builder = addLongProperty(\"id\");\n        builder.dbName(\"_id\").primaryKey();\n        return builder;\n    }\n\n    /** Adds a to-many relationship; the target entity is joined to the PK property of this entity (typically the ID). */\n    public ToMany addToMany(Entity target, Property targetProperty) {\n        Property[] targetProperties = {targetProperty};\n        return addToMany(null, target, targetProperties);\n    }\n\n    /**\n     * Convenience method for {@link Entity#addToMany(Entity, Property)} with a subsequent call to {@link\n     * ToMany#setName(String)}.\n     */\n    public ToMany addToMany(Entity target, Property targetProperty, String name) {\n        ToMany toMany = addToMany(target, targetProperty);\n        toMany.setName(name);\n        return toMany;\n    }\n\n    /**\n     * Add a to-many relationship; the target entity is joined using the given target property (of the target entity)\n     * and given source property (of this entity).\n     */\n    public ToMany addToMany(Property sourceProperty, Entity target, Property targetProperty) {\n        Property[] sourceProperties = {sourceProperty};\n        Property[] targetProperties = {targetProperty};\n        return addToMany(sourceProperties, target, targetProperties);\n    }\n\n    public ToMany addToMany(Property[] sourceProperties, Entity target, Property[] targetProperties) {\n        if (protobuf) {\n            throw new IllegalStateException(\"Protobuf entities do not support relations, currently\");\n        }\n\n        ToMany toMany = new ToMany(schema, this, sourceProperties, target, targetProperties);\n        toManyRelations.add(toMany);\n        target.incomingToManyRelations.add(toMany);\n        return toMany;\n    }\n\n    public ToManyWithJoinEntity addToMany(Entity target, Entity joinEntity, Property id1, Property id2) {\n        ToManyWithJoinEntity toMany = new ToManyWithJoinEntity(schema, this, target, joinEntity, id1, id2);\n        toManyRelations.add(toMany);\n        target.incomingToManyRelations.add(toMany);\n        return toMany;\n    }\n\n    /**\n     * Adds a to-one relationship to the given target entity using the given given foreign key property (which belongs\n     * to this entity).\n     */\n    public ToOne addToOne(Entity target, Property fkProperty) {\n        if (protobuf) {\n            throw new IllegalStateException(\"Protobuf entities do not support realtions, currently\");\n        }\n\n        Property[] fkProperties = {fkProperty};\n        ToOne toOne = new ToOne(schema, this, target, fkProperties, true);\n        toOneRelations.add(toOne);\n        return toOne;\n    }\n\n    /** Convenience for {@link #addToOne(Entity, Property)} with a subsequent call to {@link ToOne#setName(String)}. */\n    public ToOne addToOne(Entity target, Property fkProperty, String name) {\n        ToOne toOne = addToOne(target, fkProperty);\n        toOne.setName(name);\n        return toOne;\n    }\n\n    public ToOne addToOneWithoutProperty(String name, Entity target, String fkColumnName) {\n        return addToOneWithoutProperty(name, target, fkColumnName, false, false);\n    }\n\n    public ToOne addToOneWithoutProperty(String name, Entity target, String fkColumnName, boolean notNull,\n                                         boolean unique) {\n        PropertyBuilder propertyBuilder = new PropertyBuilder(schema, this, null, name);\n        if (notNull) {\n            propertyBuilder.notNull();\n        }\n        if (unique) {\n            propertyBuilder.unique();\n        }\n        propertyBuilder.dbName(fkColumnName);\n        Property column = propertyBuilder.getProperty();\n        Property[] fkColumns = {column};\n        ToOne toOne = new ToOne(schema, this, target, fkColumns, false);\n        toOne.setName(name);\n        toOneRelations.add(toOne);\n        return toOne;\n    }\n\n    protected void addIncomingToMany(ToMany toMany) {\n        incomingToManyRelations.add(toMany);\n    }\n\n    public ContentProvider addContentProvider() {\n        List<Entity> entities = new ArrayList<>();\n        entities.add(this);\n        ContentProvider contentProvider = new ContentProvider(schema, entities);\n        contentProviders.add(contentProvider);\n        return contentProvider;\n    }\n\n    /** Adds a new index to the entity. */\n    public Entity addIndex(Index index) {\n        indexes.add(index);\n        return this;\n    }\n\n    public Entity addImport(String additionalImport) {\n        additionalImportsEntity.add(additionalImport);\n        return this;\n    }\n\n    /** The entity is represented by a protocol buffers object. Requires some special actions like using builders. */\n    Entity useProtobuf() {\n        protobuf = true;\n        return this;\n    }\n\n    public boolean isProtobuf() {\n        return protobuf;\n    }\n\n    public Schema getSchema() {\n        return schema;\n    }\n\n    public String getDbName() {\n        return dbName;\n    }\n\n    @Deprecated\n    /**\n     * @deprecated Use setDbName\n     */\n    public void setTableName(String tableName) {\n        setDbName(tableName);\n    }\n\n    public void setDbName(String dbName) {\n        this.dbName = dbName;\n        this.nonDefaultDbName = dbName != null;\n    }\n\n    public String getClassName() {\n        return className;\n    }\n\n    public List<Property> getProperties() {\n        return properties;\n    }\n\n    public List<Property> getPropertiesColumns() {\n        return propertiesColumns;\n    }\n\n    public String getJavaPackage() {\n        return javaPackage;\n    }\n\n    public void setJavaPackage(String javaPackage) {\n        this.javaPackage = javaPackage;\n    }\n\n    public String getJavaPackageDao() {\n        return javaPackageDao;\n    }\n\n    public void setJavaPackageDao(String javaPackageDao) {\n        this.javaPackageDao = javaPackageDao;\n    }\n\n    public String getClassNameDao() {\n        return classNameDao;\n    }\n\n    public void setClassNameDao(String classNameDao) {\n        this.classNameDao = classNameDao;\n    }\n\n    public String getClassNameTest() {\n        return classNameTest;\n    }\n\n    public void setClassNameTest(String classNameTest) {\n        this.classNameTest = classNameTest;\n    }\n\n    public String getJavaPackageTest() {\n        return javaPackageTest;\n    }\n\n    public void setJavaPackageTest(String javaPackageTest) {\n        this.javaPackageTest = javaPackageTest;\n    }\n\n    /** Internal property used by templates, don't use during entity definition. */\n    public List<Property> getPropertiesPk() {\n        return propertiesPk;\n    }\n\n    /** Internal property used by templates, don't use during entity definition. */\n    public List<Property> getPropertiesNonPk() {\n        return propertiesNonPk;\n    }\n\n    /** Internal property used by templates, don't use during entity definition. */\n    public Property getPkProperty() {\n        return pkProperty;\n    }\n\n    public List<Index> getIndexes() {\n        return indexes;\n    }\n\n    /** Internal property used by templates, don't use during entity definition. */\n    public String getPkType() {\n        return pkType;\n    }\n\n    public boolean isConstructors() {\n        return constructors;\n    }\n\n    /** Flag to define if constructors should be generated. */\n    public void setConstructors(boolean constructors) {\n        this.constructors = constructors;\n    }\n\n    public boolean isSkipGeneration() {\n        return skipGeneration;\n    }\n\n    /**\n     * Flag if the entity's code generation should be skipped. E.g. if you need to change the class after initial\n     * generation.\n     */\n    public void setSkipGeneration(boolean skipGeneration) {\n        this.skipGeneration = skipGeneration;\n    }\n\n    @Deprecated\n    /**\n     * @deprecated Use setSkipCreationInDb\n     */\n    public void setSkipTableCreation(boolean skipTableCreation) {\n        setSkipCreationInDb(skipTableCreation);\n    }\n\n    /** Flag if CREATE and DROP TABLE scripts should be skipped in Dao. */\n    public void setSkipCreationInDb(boolean skipCreationInDb) {\n        this.skipCreationInDb = skipCreationInDb;\n    }\n\n    public boolean isSkipCreationInDb() {\n        return skipCreationInDb;\n    }\n\n    public boolean isSkipGenerationTest() {\n        return skipGenerationTest;\n    }\n\n    public void setSkipGenerationTest(boolean skipGenerationTest) {\n        this.skipGenerationTest = skipGenerationTest;\n    }\n\n    public List<ToOne> getToOneRelations() {\n        return toOneRelations;\n    }\n\n    public List<ToManyBase> getToManyRelations() {\n        return toManyRelations;\n    }\n\n    public List<ToManyBase> getIncomingToManyRelations() {\n        return incomingToManyRelations;\n    }\n\n    /**\n     * Entities with relations are active, but this method allows to make the entities active even if it does not have\n     * relations.\n     */\n    public void setActive(Boolean active) {\n        this.active = active;\n    }\n\n    public Boolean getActive() {\n        return active;\n    }\n\n    public Boolean getHasKeepSections() {\n        return hasKeepSections;\n    }\n\n    public Collection<String> getAdditionalImportsEntity() {\n        return additionalImportsEntity;\n    }\n\n    public Collection<String> getAdditionalImportsDao() {\n        return additionalImportsDao;\n    }\n\n    public void setHasKeepSections(Boolean hasKeepSections) {\n        this.hasKeepSections = hasKeepSections;\n    }\n\n    public List<String> getInterfacesToImplement() {\n        return interfacesToImplement;\n    }\n\n    public List<ContentProvider> getContentProviders() {\n        return contentProviders;\n    }\n\n    public void implementsInterface(String... interfaces) {\n        for (String interfaceToImplement : interfaces) {\n            if (interfacesToImplement.contains(interfaceToImplement)) {\n                throw new RuntimeException(\"Interface defined more than once: \" + interfaceToImplement);\n            }\n            interfacesToImplement.add(interfaceToImplement);\n        }\n    }\n\n    public void implementsSerializable() {\n        interfacesToImplement.add(\"java.io.Serializable\");\n    }\n\n    public String getSuperclass() {\n        return superclass;\n    }\n\n    public void setSuperclass(String classToExtend) {\n        this.superclass = classToExtend;\n    }\n\n    public String getJavaDoc() {\n        return javaDoc;\n    }\n\n    public void setJavaDoc(String javaDoc) {\n        this.javaDoc = DaoUtil.checkConvertToJavaDoc(javaDoc, \"\");\n    }\n\n    public String getCodeBeforeClass() {\n        return codeBeforeClass;\n    }\n\n    public void setCodeBeforeClass(String codeBeforeClass) {\n        this.codeBeforeClass = codeBeforeClass;\n    }\n\n    void init2ndPass() {\n        init2ndPassNamesWithDefaults();\n\n        for (int i = 0; i < properties.size(); i++) {\n            Property property = properties.get(i);\n            property.setOrdinal(i);\n            property.init2ndPass();\n            if (property.isPrimaryKey()) {\n                propertiesPk.add(property);\n            } else {\n                propertiesNonPk.add(property);\n            }\n        }\n\n        for (int i = 0; i < indexes.size(); i++) {\n            final Index index = indexes.get(i);\n            final int propertiesSize = index.getProperties().size();\n            if (propertiesSize == 1) {\n                final Property property = index.getProperties().get(0);\n                property.setIndex(index);\n            } else if (propertiesSize > 1) {\n                multiIndexes.add(index);\n            }\n        }\n\n        if (propertiesPk.size() == 1) {\n            pkProperty = propertiesPk.get(0);\n            pkType = schema.mapToJavaTypeNullable(pkProperty.getPropertyType());\n        } else {\n            pkType = \"Void\";\n        }\n\n        propertiesColumns = new ArrayList<>(properties);\n        for (ToOne toOne : toOneRelations) {\n            toOne.init2ndPass();\n            Property[] fkProperties = toOne.getFkProperties();\n            for (Property fkProperty : fkProperties) {\n                if (!propertiesColumns.contains(fkProperty)) {\n                    propertiesColumns.add(fkProperty);\n                }\n            }\n        }\n\n        for (ToManyBase toMany : toManyRelations) {\n            toMany.init2ndPass();\n            // Source Properties may not be virtual, so we do not need the following code:\n            // for (Property sourceProperty : toMany.getSourceProperties()) {\n            // if (!propertiesColumns.contains(sourceProperty)) {\n            // propertiesColumns.add(sourceProperty);\n            // }\n            // }\n        }\n\n        if (active == null) {\n            active = schema.isUseActiveEntitiesByDefault();\n        }\n        active |= !toOneRelations.isEmpty() || !toManyRelations.isEmpty();\n\n        if (hasKeepSections == null) {\n            hasKeepSections = schema.isHasKeepSectionsByDefault();\n        }\n\n        init2ndPassIndexNamesWithDefaults();\n\n        for (ContentProvider contentProvider : contentProviders) {\n            contentProvider.init2ndPass();\n        }\n    }\n\n    protected void init2ndPassNamesWithDefaults() {\n        if (dbName == null) {\n            dbName = DaoUtil.dbName(className);\n            nonDefaultDbName = false;\n        }\n\n        if (classNameDao == null) {\n            classNameDao = className + \"Dao\";\n        }\n        if (classNameTest == null) {\n            classNameTest = className + \"Test\";\n        }\n\n        if (javaPackage == null) {\n            javaPackage = schema.getDefaultJavaPackage();\n        }\n\n        if (javaPackageDao == null) {\n            javaPackageDao = schema.getDefaultJavaPackageDao();\n            if (javaPackageDao == null) {\n                javaPackageDao = javaPackage;\n            }\n        }\n        if (javaPackageTest == null) {\n            javaPackageTest = schema.getDefaultJavaPackageTest();\n            if (javaPackageTest == null) {\n                javaPackageTest = javaPackage;\n            }\n        }\n    }\n\n    protected void init2ndPassIndexNamesWithDefaults() {\n        for (int i = 0; i < indexes.size(); i++) {\n            Index index = indexes.get(i);\n            if (index.getName() == null) {\n                String indexName = \"IDX_\" + getDbName();\n                List<Property> properties = index.getProperties();\n                for (int j = 0; j < properties.size(); j++) {\n                    Property property = properties.get(j);\n                    indexName += \"_\" + property.getDbName();\n                    if (\"DESC\".equalsIgnoreCase(index.getPropertiesOrder().get(j))) {\n                        indexName += \"_DESC\";\n                    }\n                }\n                // TODO can this get too long? how to shorten reliably without depending on the order (i)\n                index.setDefaultName(indexName);\n            }\n        }\n    }\n\n    void init3rdPass() {\n        for (Property property : properties) {\n            property.init3ndPass();\n        }\n\n        init3rdPassRelations();\n        init3rdPassAdditionalImports();\n    }\n\n    private void init3rdPassRelations() {\n        Set<String> toOneNames = new HashSet<>();\n        for (ToOne toOne : toOneRelations) {\n            toOne.init3ndPass();\n            if (!toOneNames.add(toOne.getName().toLowerCase())) {\n                throw new RuntimeException(\"Duplicate name for \" + toOne);\n            }\n        }\n\n        Set<String> toManyNames = new HashSet<>();\n        for (ToManyBase toMany : toManyRelations) {\n            toMany.init3rdPass();\n            if (toMany instanceof ToMany) {\n                Entity targetEntity = toMany.getTargetEntity();\n                for (Property targetProperty : ((ToMany) toMany).getTargetProperties()) {\n                    if (!targetEntity.propertiesColumns.contains(targetProperty)) {\n                        targetEntity.propertiesColumns.add(targetProperty);\n                    }\n                }\n            }\n            if (!toManyNames.add(toMany.getName().toLowerCase())) {\n                throw new RuntimeException(\"Duplicate name for \" + toMany);\n            }\n        }\n    }\n\n    private void init3rdPassAdditionalImports() {\n        if (active && !javaPackage.equals(javaPackageDao)) {\n            additionalImportsEntity.add(javaPackageDao + \".\" + classNameDao);\n        }\n\n        for (ToOne toOne : toOneRelations) {\n            Entity targetEntity = toOne.getTargetEntity();\n            checkAdditionalImportsEntityTargetEntity(targetEntity);\n            // For deep loading\n            checkAdditionalImportsDaoTargetEntity(targetEntity);\n        }\n\n        for (ToManyBase toMany : toManyRelations) {\n            Entity targetEntity = toMany.getTargetEntity();\n            checkAdditionalImportsEntityTargetEntity(targetEntity);\n        }\n\n        for (ToManyBase incomingToMany : incomingToManyRelations) {\n            if (incomingToMany instanceof ToManyWithJoinEntity) {\n                final ToManyWithJoinEntity toManyWithJoinEntity = (ToManyWithJoinEntity) incomingToMany;\n                final Entity joinEntity = toManyWithJoinEntity.getJoinEntity();\n                checkAdditionalImportsDaoTargetEntity(joinEntity);\n            }\n        }\n\n        for (Property property : properties) {\n            String customType = property.getCustomType();\n            if (customType != null) {\n                String pack = DaoUtil.getPackageFromFullyQualified(customType);\n                if (pack != null && !pack.equals(javaPackage)) {\n                    additionalImportsEntity.add(customType);\n                }\n                if (pack != null && !pack.equals(javaPackageDao)) {\n                    additionalImportsDao.add(customType);\n                }\n            }\n\n            String converter = property.getConverter();\n            if (converter != null) {\n                String pack = DaoUtil.getPackageFromFullyQualified(converter);\n                if (pack != null && !pack.equals(javaPackageDao)) {\n                    additionalImportsDao.add(converter);\n                }\n            }\n\n        }\n    }\n\n    private void checkAdditionalImportsEntityTargetEntity(Entity targetEntity) {\n        if (!targetEntity.getJavaPackage().equals(javaPackage)) {\n            additionalImportsEntity.add(targetEntity.getJavaPackage() + \".\" + targetEntity.getClassName());\n        }\n        if (!targetEntity.getJavaPackageDao().equals(javaPackage)) {\n            additionalImportsEntity.add(targetEntity.getJavaPackageDao() + \".\" + targetEntity.getClassNameDao());\n        }\n    }\n\n    private void checkAdditionalImportsDaoTargetEntity(Entity targetEntity) {\n        if (!targetEntity.getJavaPackage().equals(javaPackageDao)) {\n            additionalImportsDao.add(targetEntity.getJavaPackage() + \".\" + targetEntity.getClassName());\n        }\n    }\n\n    public void validatePropertyExists(Property property) {\n        if (!properties.contains(property)) {\n            throw new RuntimeException(\"Property \" + property + \" does not exist in \" + this);\n        }\n    }\n\n    public List<Index> getMultiIndexes() {\n        return multiIndexes;\n    }\n\n    public boolean isNonDefaultDbName() {\n        return nonDefaultDbName;\n    }\n\n    @Override\n    public String toString() {\n        return \"Entity \" + className + \" (package: \" + javaPackage + \")\";\n    }\n\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/Index.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\n@SuppressWarnings(\"unused\")\npublic class Index extends PropertyOrderList {\n    private String name;\n    private boolean unique;\n    private boolean nonDefaultName;\n\n    public String getName() {\n        return name;\n    }\n\n    public Index setName(String name) {\n        this.name = name;\n        this.nonDefaultName = name != null;\n        return this;\n    }\n\n    public Index makeUnique() {\n        unique = true;\n        return this;\n    }\n\n    public boolean isUnique() {\n        return unique;\n    }\n\n    public boolean isNonDefaultName() {\n        return nonDefaultName;\n    }\n\n    /** used internally to know if name is generated by greenDAO */\n    void setDefaultName(String name) {\n        this.name = name;\n        this.nonDefaultName = false;\n    }\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/Property.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\n/** Model class for an entity's property: a Java property mapped to a data base column. */\n@SuppressWarnings(\"unused\")\npublic class Property {\n\n    public static class PropertyBuilder {\n        private final Property property;\n\n        public PropertyBuilder(Schema schema, Entity entity, PropertyType propertyType, String propertyName) {\n            property = new Property(schema, entity, propertyType, propertyName);\n        }\n\n        @Deprecated\n        /**\n         * @deprecated use dbName\n         */\n        public PropertyBuilder columnName(String columnName) {\n            return dbName(columnName);\n        }\n\n        public PropertyBuilder dbName(String dbName) {\n            property.dbName = dbName;\n            property.nonDefaultDbName = dbName != null;\n            return this;\n        }\n\n        @Deprecated\n        /**\n         * @deprecated use dbType\n         */\n        public PropertyBuilder columnType(String columnType) {\n            return dbType(columnType);\n        }\n\n        public PropertyBuilder dbType(String dbType) {\n            property.dbType = dbType;\n            return this;\n        }\n\n        public PropertyBuilder primaryKey() {\n            property.primaryKey = true;\n            return this;\n        }\n\n        public PropertyBuilder primaryKeyAsc() {\n            property.primaryKey = true;\n            property.pkAsc = true;\n            return this;\n        }\n\n        public PropertyBuilder primaryKeyDesc() {\n            property.primaryKey = true;\n            property.pkDesc = true;\n            return this;\n        }\n\n        public PropertyBuilder autoincrement() {\n            if (!property.primaryKey || property.propertyType != PropertyType.Long) {\n                throw new RuntimeException(\n                        \"AUTOINCREMENT is only available to primary key properties of type long/Long\");\n            }\n            property.pkAutoincrement = true;\n            return this;\n        }\n\n        public PropertyBuilder unique() {\n            property.unique = true;\n            return this;\n        }\n\n        public PropertyBuilder notNull() {\n            property.notNull = true;\n            return this;\n        }\n\n        public PropertyBuilder nonPrimitiveType() {\n            if (!property.propertyType.isScalar()) {\n                throw new RuntimeException(\"Type is already non-primitive\");\n            }\n            property.nonPrimitiveType = true;\n            return this;\n        }\n\n        public PropertyBuilder index() {\n            Index index = new Index();\n            index.addProperty(property);\n            property.entity.addIndex(index);\n            return this;\n        }\n\n        public PropertyBuilder indexAsc(String indexNameOrNull, boolean isUnique) {\n            Index index = new Index();\n            index.addPropertyAsc(property);\n            if (isUnique) {\n                index.makeUnique();\n            }\n            index.setName(indexNameOrNull);\n            property.entity.addIndex(index);\n            return this;\n        }\n\n        public PropertyBuilder indexDesc(String indexNameOrNull, boolean isUnique) {\n            Index index = new Index();\n            index.addPropertyDesc(property);\n            if (isUnique) {\n                index.makeUnique();\n            }\n            index.setName(indexNameOrNull);\n            property.entity.addIndex(index);\n            return this;\n        }\n\n        public PropertyBuilder customType(String customType, String converter) {\n            property.customType = customType;\n            property.customTypeClassName = DaoUtil.getClassnameFromFullyQualified(customType);\n            property.converter = converter;\n            property.converterClassName = DaoUtil.getClassnameFromFullyQualified(converter);\n            return this;\n        }\n\n        public PropertyBuilder codeBeforeField(String code) {\n            property.codeBeforeField = code;\n            return this;\n        }\n\n        public PropertyBuilder codeBeforeGetter(String code) {\n            property.codeBeforeGetter = code;\n            return this;\n        }\n\n        public PropertyBuilder codeBeforeSetter(String code) {\n            property.codeBeforeSetter = code;\n            return this;\n        }\n\n        public PropertyBuilder codeBeforeGetterAndSetter(String code) {\n            property.codeBeforeGetter = code;\n            property.codeBeforeSetter = code;\n            return this;\n        }\n\n        public PropertyBuilder javaDocField(String javaDoc) {\n            property.javaDocField = checkConvertToJavaDoc(javaDoc);\n            return this;\n        }\n\n        private String checkConvertToJavaDoc(String javaDoc) {\n            return DaoUtil.checkConvertToJavaDoc(javaDoc, \"    \");\n        }\n\n        public PropertyBuilder javaDocGetter(String javaDoc) {\n            property.javaDocGetter = checkConvertToJavaDoc(javaDoc);\n            return this;\n        }\n\n        public PropertyBuilder javaDocSetter(String javaDoc) {\n            property.javaDocSetter = checkConvertToJavaDoc(javaDoc);\n            return this;\n        }\n\n        public PropertyBuilder javaDocGetterAndSetter(String javaDoc) {\n            javaDoc = checkConvertToJavaDoc(javaDoc);\n            property.javaDocGetter = javaDoc;\n            property.javaDocSetter = javaDoc;\n            return this;\n        }\n\n        public Property getProperty() {\n            return property;\n        }\n    }\n\n    private final Schema schema;\n    private final Entity entity;\n    private PropertyType propertyType;\n    private final String propertyName;\n\n    private String dbName;\n    private String dbType;\n\n    private String customType;\n    private String customTypeClassName;\n    private String converter;\n    private String converterClassName;\n\n    private String codeBeforeField;\n    private String codeBeforeGetter;\n    private String codeBeforeSetter;\n\n    private String javaDocField;\n    private String javaDocGetter;\n    private String javaDocSetter;\n\n    private boolean primaryKey;\n    private boolean pkAsc;\n    private boolean pkDesc;\n    private boolean pkAutoincrement;\n\n    private boolean unique;\n    private boolean notNull;\n    private boolean nonPrimitiveType;\n\n    /** Initialized in 2nd pass */\n    private String constraints;\n\n    private int ordinal;\n\n    private String javaType;\n\n    private boolean nonDefaultDbName;\n\n    /**\n     * Index, which has only this property\n     * Can be added by user via {@link PropertyBuilder} or via {@link Entity#addIndex(Index)}\n     * Initialized in 2nd pass\n     */\n    private Index index;\n\n    public Property(Schema schema, Entity entity, PropertyType propertyType, String propertyName) {\n        this.schema = schema;\n        this.entity = entity;\n        this.propertyName = propertyName;\n        this.propertyType = propertyType;\n    }\n\n    public String getPropertyName() {\n        return propertyName;\n    }\n\n    public PropertyType getPropertyType() {\n        return propertyType;\n    }\n\n    public void setPropertyType(PropertyType propertyType) {\n        this.propertyType = propertyType;\n    }\n\n    public String getDbName() {\n        return dbName;\n    }\n\n    public boolean isNonDefaultDbName() {\n        return nonDefaultDbName;\n    }\n\n    public String getDbType() {\n        return dbType;\n    }\n\n    public boolean isPrimaryKey() {\n        return primaryKey;\n    }\n\n    public boolean isPkAsc() {\n        return pkAsc;\n    }\n\n    public boolean isPkDesc() {\n        return pkDesc;\n    }\n\n    public boolean isAutoincrement() {\n        return pkAutoincrement;\n    }\n\n    public String getConstraints() {\n        return constraints;\n    }\n\n    public boolean isUnique() {\n        return unique;\n    }\n\n    public boolean isNotNull() {\n        return notNull;\n    }\n\n    public boolean isNonPrimitiveType() {\n        return nonPrimitiveType || !propertyType.isScalar();\n    }\n\n    public String getJavaType() {\n        return javaType;\n    }\n\n    public String getJavaTypeInEntity() {\n        if (customTypeClassName != null) {\n            return customTypeClassName;\n        } else {\n            return javaType;\n        }\n    }\n\n    public int getOrdinal() {\n        return ordinal;\n    }\n\n    void setOrdinal(int ordinal) {\n        this.ordinal = ordinal;\n    }\n\n    public String getCustomType() {\n        return customType;\n    }\n\n    public String getCustomTypeClassName() {\n        return customTypeClassName;\n    }\n\n    public String getConverter() {\n        return converter;\n    }\n\n    public String getConverterClassName() {\n        return converterClassName;\n    }\n\n    public String getCodeBeforeField() {\n        return codeBeforeField;\n    }\n\n    public String getCodeBeforeGetter() {\n        return codeBeforeGetter;\n    }\n\n    public String getCodeBeforeSetter() {\n        return codeBeforeSetter;\n    }\n\n    public String getJavaDocField() {\n        return javaDocField;\n    }\n\n    public String getJavaDocGetter() {\n        return javaDocGetter;\n    }\n\n    public String getJavaDocSetter() {\n        return javaDocSetter;\n    }\n\n    public String getDatabaseValueExpression() {\n        return getDatabaseValueExpression(propertyName);\n    }\n\n    public String getDatabaseValueExpressionNotNull() {\n        return getDatabaseValueExpression(\"entity.get\" + DaoUtil.capFirst(propertyName) + \"()\");\n    }\n\n    // Got too messy in template:\n    // <#if property.customType?has_content>${property.propertyName}Converter.convertToDatabaseValue(</#if><#--\n    // -->entity.get${property.propertyName?cap_first}()<#if property.customType?has_content>)</#if><#if\n    // property.propertyType == \"Boolean\"> ? 1l: 0l</#if><#if property.propertyType == \"Date\">.getTime()</#if>\n    public String getDatabaseValueExpression(String entityValue) {\n        StringBuilder builder = new StringBuilder();\n        if (customType != null) {\n            builder.append(propertyName).append(\"Converter.convertToDatabaseValue(\");\n        }\n        builder.append(entityValue);\n        if (customType != null) {\n            builder.append(')');\n        }\n        if (propertyType == PropertyType.Boolean) {\n            builder.append(\" ? 1L: 0L\");\n        } else if (propertyType == PropertyType.Date) {\n            builder.append(\".getTime()\");\n        }\n        return builder.toString();\n    }\n\n    // Got too messy in template:\n    // <#if property.propertyType == \"Byte\">(byte) </#if>\n    // <#if property.propertyType == \"Date\">new java.util.Date(</#if>\n    // cursor.get${toCursorType[property.propertyType]}(offset + ${property_index})\n    // <#if property.propertyType == \"Boolean\"> != 0</#if>\n    // <#if property.propertyType == \"Date\">)</#if>\n    public String getEntityValueExpression(String databaseValue) {\n        StringBuilder builder = new StringBuilder();\n        if (customType != null) {\n            builder.append(propertyName).append(\"Converter.convertToEntityProperty(\");\n        }\n        if (propertyType == PropertyType.Byte) {\n            builder.append(\"(byte) \");\n        } else if (propertyType == PropertyType.Date) {\n            builder.append(\"new java.util.Date(\");\n        }\n        builder.append(databaseValue);\n        if (propertyType == PropertyType.Boolean) {\n            builder.append(\" != 0\");\n        } else if (propertyType == PropertyType.Date) {\n            builder.append(\")\");\n        }\n        if (customType != null) {\n            builder.append(')');\n        }\n        return builder.toString();\n    }\n\n    public Entity getEntity() {\n        return entity;\n    }\n\n    public Index getIndex() {\n        return index;\n    }\n\n    public void setIndex(Index index) {\n        this.index = index;\n    }\n\n    void init2ndPass() {\n        initConstraint();\n        if (dbType == null) {\n            dbType = schema.mapToDbType(propertyType);\n        }\n        if (dbName == null) {\n            dbName = DaoUtil.dbName(propertyName);\n            nonDefaultDbName = false;\n        } else if (primaryKey && propertyType == PropertyType.Long && dbName.equals(\"_id\")) {\n            nonDefaultDbName = false;\n        }\n\n        // For backwards compatibility, consider notNull. It should be only dependent on nonPrimitiveType in the future.\n        if (notNull && !nonPrimitiveType) {\n            javaType = schema.mapToJavaTypeNotNull(propertyType);\n        } else {\n            javaType = schema.mapToJavaTypeNullable(propertyType);\n        }\n    }\n\n    private void initConstraint() {\n        StringBuilder constraintBuilder = new StringBuilder();\n        if (primaryKey) {\n            constraintBuilder.append(\"PRIMARY KEY\");\n            if (pkAsc) {\n                constraintBuilder.append(\" ASC\");\n            }\n            if (pkDesc) {\n                constraintBuilder.append(\" DESC\");\n            }\n            if (pkAutoincrement) {\n                constraintBuilder.append(\" AUTOINCREMENT\");\n            }\n        }\n        // Always have String PKs NOT NULL because SQLite is pretty strange in this respect:\n        // One could insert multiple rows with NULL PKs\n        if (notNull || (primaryKey && propertyType == PropertyType.String)) {\n            constraintBuilder.append(\" NOT NULL\");\n        }\n        if (unique) {\n            constraintBuilder.append(\" UNIQUE\");\n        }\n        String newContraints = constraintBuilder.toString().trim();\n        if (constraintBuilder.length() > 0) {\n            constraints = newContraints;\n        }\n    }\n\n    void init3ndPass() {\n        // Nothing to do so far\n    }\n\n    @Override\n    public String toString() {\n        return \"Property \" + propertyName + \" of \" + entity.getClassName();\n    }\n\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/PropertyOrderList.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class PropertyOrderList {\n    private List<Property> properties;\n    private List<String> propertiesOrder;\n\n    public PropertyOrderList() {\n        properties = new ArrayList<>();\n        propertiesOrder = new ArrayList<>();\n    }\n\n    public void addProperty(Property property) {\n        properties.add(property);\n        propertiesOrder.add(null);\n    }\n\n    public void addPropertyAsc(Property property) {\n        properties.add(property);\n        propertiesOrder.add(\"ASC\");\n    }\n\n    public void addPropertyDesc(Property property) {\n        properties.add(property);\n        propertiesOrder.add(\"DESC\");\n    }\n\n    @SuppressWarnings(\"unused\")\n    public void addOrderRaw(String order) {\n        properties.add(null);\n        propertiesOrder.add(order);\n    }\n\n    public List<Property> getProperties() {\n        return properties;\n    }\n\n    public List<String> getPropertiesOrder() {\n        return propertiesOrder;\n    }\n\n    public String getCommaSeparatedString(String tablePrefixOrNull) {\n        StringBuilder builder = new StringBuilder();\n        int size = properties.size();\n        for (int i = 0; i < size; i++) {\n            Property property = properties.get(i);\n            String order = propertiesOrder.get(i);\n            if (property != null) {\n                if(tablePrefixOrNull != null) {\n                    builder.append(tablePrefixOrNull).append('.');\n                }\n                builder.append('\\'').append(property.getDbName()).append('\\'').append(' ');\n            }\n            if (order != null) {\n                builder.append(order);\n            }\n            if (i < size - 1) {\n                builder.append(',');\n            }\n        }\n        return builder.toString();\n    }\n\n    public boolean isEmpty() {\n        return properties.isEmpty();\n    }\n\n    public String getOrderSpec() {\n        final List<Property> properties = getProperties();\n        final List<String> propertiesOrder = getPropertiesOrder();\n        final StringBuilder builder = new StringBuilder();\n        final int size = properties.size();\n        for (int i = 0; i < size; i++) {\n            final Property property = properties.get(i);\n            final String order = propertiesOrder.get(i);\n            builder.append(property.getPropertyName());\n            if (order != null) {\n                builder.append(' ').append(order);\n            }\n            if (i < size - 1) {\n                builder.append(\", \");\n            }\n        }\n        return builder.toString();\n    }\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/PropertyType.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\n/**\n * Currently available types for properties.\n *\n * @author Markus\n */\npublic enum PropertyType {\n\n    Byte(true), Short(true), Int(true), Long(true), Boolean(true), Float(true), Double(true),\n    String(false), ByteArray(false), Date(false);\n\n    private final boolean scalar;\n\n    PropertyType(boolean scalar) {\n        this.scalar = scalar;\n    }\n\n    /** True if the type can be prepresented using a scalar (primitive type). */\n    public boolean isScalar() {\n        return scalar;\n    }\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/Query.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/** NOT IMPLEMENTED YET. Check back later. */\npublic class Query {\n    @SuppressWarnings(\"unused\")\n    private String name;\n    private List<QueryParam> parameters;\n    @SuppressWarnings(\"unused\")\n    private boolean distinct;\n\n    public Query(String name) {\n        this.name = name;\n        parameters= new ArrayList<QueryParam>();\n    }\n    \n    public QueryParam addEqualsParam(Property column) {\n        return addParam(column, \"=\");\n    }\n\n    public QueryParam addParam(Property column, String operator) {\n        QueryParam queryParam = new QueryParam(column, operator);\n        parameters.add(queryParam);\n        return queryParam;\n    }\n    \n    public void distinct() {\n        distinct = true;\n    }\n\n\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/QueryParam.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\n/** NOT IMPLEMENTED YET. Check back later. */\npublic class QueryParam {\n    private Property column;\n    private String operator;\n    \n    public QueryParam(Property column, String operator) {\n        this.column = column;\n        this.operator = operator;\n    }\n\n    public Property getColumn() {\n        return column;\n    }\n\n    public String getOperator() {\n        return operator;\n    }\n    \n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/Schema.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\nimport java.util.ArrayList;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * The \"root\" model class to which you can add entities to.\n * \n * @see <a href=\"http://greendao-orm.com/documentation/modelling-entities/\">Modelling Entities (Documentation page)</a>\n */\n@SuppressWarnings(\"unused\")\npublic class Schema {\n    public static final String DEFAULT_NAME = \"default\";\n\n    private final int version;\n    private final String defaultJavaPackage;\n    private String defaultJavaPackageDao;\n    private String defaultJavaPackageTest;\n    private final List<Entity> entities;\n    private Map<PropertyType, String> propertyToDbType;\n    private Map<PropertyType, String> propertyToJavaTypeNotNull;\n    private Map<PropertyType, String> propertyToJavaTypeNullable;\n    private boolean hasKeepSectionsByDefault;\n    private boolean useActiveEntitiesByDefault;\n    private final String name;\n    private final String prefix;\n\n    public Schema(String name, int version, String defaultJavaPackage) {\n        this.name = name;\n        this.prefix = name.equals(DEFAULT_NAME) ? \"\" : DaoUtil.capFirst(name);\n        this.version = version;\n        this.defaultJavaPackage = defaultJavaPackage;\n        this.entities = new ArrayList<>();\n        initTypeMappings();\n    }\n\n    public Schema(int version, String defaultJavaPackage) {\n        this(DEFAULT_NAME, version, defaultJavaPackage);\n    }\n\n    public void enableKeepSectionsByDefault() {\n        hasKeepSectionsByDefault = true;\n    }\n\n    public void enableActiveEntitiesByDefault() {\n        useActiveEntitiesByDefault = true;\n    }\n\n    private void initTypeMappings() {\n        propertyToDbType = new HashMap<>();\n        propertyToDbType.put(PropertyType.Boolean, \"INTEGER\");\n        propertyToDbType.put(PropertyType.Byte, \"INTEGER\");\n        propertyToDbType.put(PropertyType.Short, \"INTEGER\");\n        propertyToDbType.put(PropertyType.Int, \"INTEGER\");\n        propertyToDbType.put(PropertyType.Long, \"INTEGER\");\n        propertyToDbType.put(PropertyType.Float, \"REAL\");\n        propertyToDbType.put(PropertyType.Double, \"REAL\");\n        propertyToDbType.put(PropertyType.String, \"TEXT\");\n        propertyToDbType.put(PropertyType.ByteArray, \"BLOB\");\n        propertyToDbType.put(PropertyType.Date, \"INTEGER\");\n\n        propertyToJavaTypeNotNull = new HashMap<>();\n        propertyToJavaTypeNotNull.put(PropertyType.Boolean, \"boolean\");\n        propertyToJavaTypeNotNull.put(PropertyType.Byte, \"byte\");\n        propertyToJavaTypeNotNull.put(PropertyType.Short, \"short\");\n        propertyToJavaTypeNotNull.put(PropertyType.Int, \"int\");\n        propertyToJavaTypeNotNull.put(PropertyType.Long, \"long\");\n        propertyToJavaTypeNotNull.put(PropertyType.Float, \"float\");\n        propertyToJavaTypeNotNull.put(PropertyType.Double, \"double\");\n        propertyToJavaTypeNotNull.put(PropertyType.String, \"String\");\n        propertyToJavaTypeNotNull.put(PropertyType.ByteArray, \"byte[]\");\n        propertyToJavaTypeNotNull.put(PropertyType.Date, \"java.util.Date\");\n\n        propertyToJavaTypeNullable = new HashMap<>();\n        propertyToJavaTypeNullable.put(PropertyType.Boolean, \"Boolean\");\n        propertyToJavaTypeNullable.put(PropertyType.Byte, \"Byte\");\n        propertyToJavaTypeNullable.put(PropertyType.Short, \"Short\");\n        propertyToJavaTypeNullable.put(PropertyType.Int, \"Integer\");\n        propertyToJavaTypeNullable.put(PropertyType.Long, \"Long\");\n        propertyToJavaTypeNullable.put(PropertyType.Float, \"Float\");\n        propertyToJavaTypeNullable.put(PropertyType.Double, \"Double\");\n        propertyToJavaTypeNullable.put(PropertyType.String, \"String\");\n        propertyToJavaTypeNullable.put(PropertyType.ByteArray, \"byte[]\");\n        propertyToJavaTypeNullable.put(PropertyType.Date, \"java.util.Date\");\n    }\n\n    /**\n     * Adds a new entity to the schema. There can be multiple entities per table, but only one may be the primary entity\n     * per table to create table scripts, etc.\n     */\n    public Entity addEntity(String className) {\n        Entity entity = new Entity(this, className);\n        entities.add(entity);\n        return entity;\n    }\n\n    /**\n     * Adds a new protocol buffers entity to the schema. There can be multiple entities per table, but only one may be\n     * the primary entity per table to create table scripts, etc.\n     */\n    public Entity addProtobufEntity(String className) {\n        Entity entity = addEntity(className);\n        entity.useProtobuf();\n        return entity;\n    }\n\n    public String mapToDbType(PropertyType propertyType) {\n        return mapType(propertyToDbType, propertyType);\n    }\n\n    public String mapToJavaTypeNullable(PropertyType propertyType) {\n        return mapType(propertyToJavaTypeNullable, propertyType);\n    }\n\n    public String mapToJavaTypeNotNull(PropertyType propertyType) {\n        return mapType(propertyToJavaTypeNotNull, propertyType);\n    }\n\n    private String mapType(Map<PropertyType, String> map, PropertyType propertyType) {\n        String dbType = map.get(propertyType);\n        if (dbType == null) {\n            throw new IllegalStateException(\"No mapping for \" + propertyType);\n        }\n        return dbType;\n    }\n\n    public int getVersion() {\n        return version;\n    }\n\n    public String getDefaultJavaPackage() {\n        return defaultJavaPackage;\n    }\n\n    public String getDefaultJavaPackageDao() {\n        return defaultJavaPackageDao;\n    }\n\n    public void setDefaultJavaPackageDao(String defaultJavaPackageDao) {\n        this.defaultJavaPackageDao = defaultJavaPackageDao;\n    }\n\n    public String getDefaultJavaPackageTest() {\n        return defaultJavaPackageTest;\n    }\n\n    public void setDefaultJavaPackageTest(String defaultJavaPackageTest) {\n        this.defaultJavaPackageTest = defaultJavaPackageTest;\n    }\n\n    public List<Entity> getEntities() {\n        return entities;\n    }\n\n    public boolean isHasKeepSectionsByDefault() {\n        return hasKeepSectionsByDefault;\n    }\n\n    public boolean isUseActiveEntitiesByDefault() {\n        return useActiveEntitiesByDefault;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public String getPrefix() {\n        return prefix;\n    }\n\n    void init2ndPass() {\n        if (defaultJavaPackageDao == null) {\n            defaultJavaPackageDao = defaultJavaPackage;\n        }\n        if (defaultJavaPackageTest == null) {\n            defaultJavaPackageTest = defaultJavaPackageDao;\n        }\n        for (Entity entity : entities) {\n            entity.init2ndPass();\n        }\n    }\n\n    void init3rdPass() {\n        for (Entity entity : entities) {\n            entity.init3rdPass();\n        }\n    }\n\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/ToMany.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\nimport java.util.List;\n\n/** To-many relationship from a source entity to many target entities. */\n@SuppressWarnings(\"unused\")\npublic class ToMany extends ToManyBase {\n    private Property[] sourceProperties;\n    private final Property[] targetProperties;\n\n    public ToMany(Schema schema, Entity sourceEntity, Property[] sourceProperties, Entity targetEntity,\n            Property[] targetProperties) {\n        super(schema, sourceEntity, targetEntity);\n        this.sourceProperties = sourceProperties;\n        this.targetProperties = targetProperties;\n    }\n\n    public Property[] getSourceProperties() {\n        return sourceProperties;\n    }\n\n    public void setSourceProperties(Property[] sourceProperties) {\n        this.sourceProperties = sourceProperties;\n    }\n\n    public Property[] getTargetProperties() {\n        return targetProperties;\n    }\n\n    void init2ndPass() {\n        super.init2ndPass();\n        if (sourceProperties == null) {\n            List<Property> pks = sourceEntity.getPropertiesPk();\n            if (pks.isEmpty()) {\n                throw new RuntimeException(\"Source entity has no primary key, but we need it for \" + this);\n            }\n            sourceProperties = new Property[pks.size()];\n            sourceProperties = pks.toArray(sourceProperties);\n        }\n        int count = sourceProperties.length;\n        if (count != targetProperties.length) {\n            throw new RuntimeException(\"Source properties do not match target properties: \" + this);\n        }\n\n        for (int i = 0; i < count; i++) {\n            Property sourceProperty = sourceProperties[i];\n            Property targetProperty = targetProperties[i];\n\n            PropertyType sourceType = sourceProperty.getPropertyType();\n            PropertyType targetType = targetProperty.getPropertyType();\n            if (sourceType == null || targetType == null) {\n                throw new RuntimeException(\"Property type uninitialized\");\n            }\n            if (sourceType != targetType) {\n                System.err.println(\"Warning to-one property type does not match target key type: \" + this);\n            }\n        }\n    }\n\n    void init3rdPass() {\n        super.init3rdPass();\n    }\n\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/ToManyBase.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\n/** Base class for to-many relationship from source entities to target entities. */\n@SuppressWarnings(\"unused\")\npublic abstract class ToManyBase {\n    @SuppressWarnings(\"unused\")\n    private final Schema schema;\n    private String name;\n    protected final Entity sourceEntity;\n    protected final Entity targetEntity;\n    private final PropertyOrderList propertyOrderList;\n\n    public ToManyBase(Schema schema, Entity sourceEntity, Entity targetEntity) {\n        this.schema = schema;\n        this.sourceEntity = sourceEntity;\n        this.targetEntity = targetEntity;\n        propertyOrderList = new PropertyOrderList();\n    }\n\n    public Entity getSourceEntity() {\n        return sourceEntity;\n    }\n\n    public Entity getTargetEntity() {\n        return targetEntity;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    /**\n     * Sets the name of the relation, which is used as the property name in the entity (the source entity owning the\n     * to-many relationship).\n     */\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    /** Property of target entity used for ascending order. */\n    public void orderAsc(Property... properties) {\n        for (Property property : properties) {\n            targetEntity.validatePropertyExists(property);\n            propertyOrderList.addPropertyAsc(property);\n        }\n    }\n\n    /** Property of target entity used for descending order. */\n    public void orderDesc(Property... properties) {\n        for (Property property : properties) {\n            targetEntity.validatePropertyExists(property);\n            propertyOrderList.addPropertyDesc(property);\n        }\n    }\n\n    public String getOrder() {\n        if (propertyOrderList.isEmpty()) {\n            return null;\n        } else {\n            // Table prefix must match default of QueryBuilder in DaoCore\n            return propertyOrderList.getCommaSeparatedString(\"T\");\n        }\n    }\n\n    /** order spec to be used in generated @OrderBy annotation */\n    public String getOrderSpec() {\n        if (propertyOrderList.isEmpty()) {\n            return null;\n        } else {\n            return propertyOrderList.getOrderSpec();\n        }\n    }\n\n    void init2ndPass() {\n        if (name == null) {\n            char[] nameCharArray = targetEntity.getClassName().toCharArray();\n            nameCharArray[0] = Character.toLowerCase(nameCharArray[0]);\n            name = new String(nameCharArray) + \"List\";\n        }\n    }\n\n    void init3rdPass() {\n    }\n\n    @Override\n    public String toString() {\n        String sourceName = sourceEntity != null ? sourceEntity.getClassName() : null;\n        String targetName = targetEntity != null ? targetEntity.getClassName() : null;\n        return \"ToMany '\" + name + \"' from \" + sourceName + \" to \" + targetName;\n    }\n\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/ToManyWithJoinEntity.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\nimport java.util.List;\n\n/** To-many relationship to many target entities using a join entity (aka JOIN table). */\n@SuppressWarnings(\"unused\")\npublic class ToManyWithJoinEntity extends ToManyBase {\n    private final Entity joinEntity;\n    private final Property sourceProperty;\n    private final Property targetProperty;\n\n    public ToManyWithJoinEntity(Schema schema, Entity sourceEntity, Entity targetEntity, Entity joinEntity,\n                                Property sourceProperty, Property targetProperty) {\n        super(schema, sourceEntity, targetEntity);\n        this.joinEntity = joinEntity;\n        this.sourceProperty = sourceProperty;\n        this.targetProperty = targetProperty;\n    }\n\n    public Entity getJoinEntity() {\n        return joinEntity;\n    }\n\n    public Property getSourceProperty() {\n        return sourceProperty;\n    }\n\n    public Property getTargetProperty() {\n        return targetProperty;\n    }\n\n    void init3rdPass() {\n        super.init3rdPass();\n        List<Property> pks = sourceEntity.getPropertiesPk();\n        if (pks.isEmpty()) {\n            throw new RuntimeException(\"Source entity has no primary key, but we need it for \" + this);\n        }\n        List<Property> pks2 = targetEntity.getPropertiesPk();\n        if (pks2.isEmpty()) {\n            throw new RuntimeException(\"Target entity has no primary key, but we need it for \" + this);\n        }\n    }\n\n}\n"
  },
  {
    "path": "DaoGenerator/src/org/greenrobot/greendao/generator/ToOne.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\n/** To-one relationship from a source entity to one (or zero) target entity. */\n@SuppressWarnings(\"unused\")\npublic class ToOne {\n    private final Schema schema;\n    private final Entity sourceEntity;\n    private final Entity targetEntity;\n    private final Property[] fkProperties;\n    private final String[] resolvedKeyJavaType;\n    private final boolean[] resolvedKeyUseEquals;\n    private String name;\n    private final boolean useFkProperty;\n\n    public ToOne(Schema schema, Entity sourceEntity, Entity targetEntity, Property[] fkProperties, boolean useFkProperty) {\n        this.schema = schema;\n        this.sourceEntity = sourceEntity;\n        this.targetEntity = targetEntity;\n        this.fkProperties = fkProperties;\n        this.useFkProperty = useFkProperty;\n        resolvedKeyJavaType = new String[fkProperties.length];\n        resolvedKeyUseEquals = new boolean[fkProperties.length];\n    }\n\n    public Entity getSourceEntity() {\n        return sourceEntity;\n    }\n\n    public Entity getTargetEntity() {\n        return targetEntity;\n    }\n\n    public Property[] getFkProperties() {\n        return fkProperties;\n    }\n\n    public String[] getResolvedKeyJavaType() {\n        return resolvedKeyJavaType;\n    }\n\n    public boolean[] getResolvedKeyUseEquals() {\n        return resolvedKeyUseEquals;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    /**\n     * Sets the name of the relation, which is used as the property name in the entity (the source entity owning the\n     * to-many relationship).\n     */\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public boolean isUseFkProperty() {\n        return useFkProperty;\n    }\n\n    void init2ndPass() {\n        if (name == null) {\n            char[] nameCharArray = targetEntity.getClassName().toCharArray();\n            nameCharArray[0] = Character.toLowerCase(nameCharArray[0]);\n            name = new String(nameCharArray);\n        }\n\n    }\n\n    /** Constructs fkColumns. Depends on 2nd pass of target key properties. */\n    void init3ndPass() {\n\n        Property targetPkProperty = targetEntity.getPkProperty();\n        if (fkProperties.length != 1 || targetPkProperty == null) {\n            throw new RuntimeException(\"Currently only single FK columns are supported: \" + this);\n        }\n\n        Property property = fkProperties[0];\n        PropertyType propertyType = property.getPropertyType();\n        if (propertyType == null) {\n            propertyType = targetPkProperty.getPropertyType();\n            property.setPropertyType(propertyType);\n            // Property is not a regular property with primitive getters/setters, so let it catch up\n            property.init2ndPass();\n            property.init3ndPass();\n        } else if (propertyType != targetPkProperty.getPropertyType()) {\n            System.err.println(\"Warning to-one property type does not match target key type: \" + this);\n        }\n        resolvedKeyJavaType[0] = schema.mapToJavaTypeNullable(propertyType);\n        resolvedKeyUseEquals[0] = checkUseEquals(propertyType);\n    }\n\n    protected boolean checkUseEquals(PropertyType propertyType) {\n        boolean useEquals;\n        switch (propertyType) {\n        case Byte:\n        case Short:\n        case Int:\n        case Long:\n        case Boolean:\n        case Float:\n            useEquals = true;\n            break;\n        default:\n            useEquals = false;\n            break;\n        }\n        return useEquals;\n    }\n\n    @Override\n    public String toString() {\n        String sourceName = sourceEntity != null ? sourceEntity.getClassName() : null;\n        String targetName = targetEntity != null ? targetEntity.getClassName() : null;\n        return \"ToOne '\" + name + \"' from \" + sourceName + \" to \" + targetName;\n    }\n\n}\n"
  },
  {
    "path": "DaoGenerator/src-template/content-provider.ftl",
    "content": "<#-- @ftlvariable name=\"entity\" type=\"org.greenrobot.greendao.generator.Entity\" -->\n<#-- @ftlvariable name=\"contentProvider\" type=\"org.greenrobot.greendao.generator.ContentProvider\" -->\n<#-- @ftlvariable name=\"schema\" type=\"org.greenrobot.greendao.generator.Schema\" -->\npackage ${contentProvider.javaPackage};\n\nimport android.content.ContentProvider;\nimport android.content.ContentResolver;\nimport android.content.ContentValues;\nimport android.content.UriMatcher;\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteQueryBuilder;\nimport android.net.Uri;\n\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.database.StandardDatabase;\nimport org.greenrobot.greendao.database.Database;\n\nimport ${schema.defaultJavaPackageDao}.${schema.prefix}DaoSession;\nimport ${entity.javaPackageDao}.${entity.classNameDao};\n\n/* Copy this code snippet into your AndroidManifest.xml inside the <application> element:\n\n    <provider\n        android:name=\"${contentProvider.javaPackage}.${contentProvider.className}\"\n        android:authorities=\"${contentProvider.authority}\" />\n*/\n\npublic class ${contentProvider.className} extends ContentProvider {\n\n    public static final String AUTHORITY = \"${contentProvider.authority}\";\n    public static final String BASE_PATH = \"${contentProvider.basePath}\";\n    public static final Uri CONTENT_URI = Uri.parse(\"content://\" + AUTHORITY + \"/\" + BASE_PATH);\n    public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE\n            + \"/\" + BASE_PATH;\n    public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE\n            + \"/\" + BASE_PATH;\n\n    private static final String TABLENAME = ${entity.classNameDao}.TABLENAME;\n    private static final String PK = ${entity.classNameDao}.Properties.${entity.pkProperty.propertyName?cap_first}.columnName;\n\n<#assign counter = 0>\n    private static final int ${entity.className?upper_case}_DIR = ${counter};\n    private static final int ${entity.className?upper_case}_ID = ${counter+1};\n\n    private static final UriMatcher sURIMatcher;\n\n    static {\n        sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);\n        sURIMatcher.addURI(AUTHORITY, BASE_PATH, ${entity.className?upper_case}_DIR);\n        sURIMatcher.addURI(AUTHORITY, BASE_PATH + \"/#\", ${entity.className?upper_case}_ID);\n    }\n\n    /**\n    * This must be set from outside, it's recommended to do this inside your Application object.\n    * Subject to change (static isn't nice).\n    */\n    public static ${schema.prefix}DaoSession daoSession;\n\n    @Override\n    public boolean onCreate() {\n        // if(daoSession == null) {\n        //     throw new IllegalStateException(\"${schema.prefix}DaoSession must be set before content provider is created\");\n        // }\n        DaoLog.d(\"Content Provider started: \" + CONTENT_URI);\n        return true;\n    }\n\n    protected Database getDatabase() {\n        if(daoSession == null) {\n            throw new IllegalStateException(\"${schema.prefix}DaoSession must be set during content provider is active\");\n        }\n        return daoSession.getDatabase();\n    }\n\n<#--\n##########################################\n########## Insert ##############\n##########################################\n-->\n    @Override\n    public Uri insert(Uri uri, ContentValues values) {\n<#if contentProvider.isReadOnly()>\n        throw new UnsupportedOperationException(\"This content provider is readonly\");\n<#else>\n        int uriType = sURIMatcher.match(uri);\n        long id = 0;\n        String path = \"\";\n        switch (uriType) {\n        case ${entity.className?upper_case}_DIR:\n            id = getDatabase().insert(TABLENAME, null, values);\n            path = BASE_PATH + \"/\" + id;\n            break;\n        default:\n            throw new IllegalArgumentException(\"Unknown URI: \" + uri);\n        }\n        getContext().getContentResolver().notifyChange(uri, null);\n        return Uri.parse(path);\n\n</#if>\n    }\n\n<#--\n##########################################\n########## Delete ##############\n##########################################\n-->\n    @Override\n    public int delete(Uri uri, String selection, String[] selectionArgs) {\n<#if contentProvider.isReadOnly()>\n        throw new UnsupportedOperationException(\"This content provider is readonly\");\n<#else>\n        int uriType = sURIMatcher.match(uri);\n        Database db = getDatabase();\n        int rowsDeleted = 0;\n        String id;\n        switch (uriType) {\n        case ${entity.className?upper_case}_DIR:\n                rowsDeleted = db.delete(TABLENAME, selection, selectionArgs);\n                break;\n        case ${entity.className?upper_case}_ID:\n            id = uri.getLastPathSegment();\n            if (TextUtils.isEmpty(selection)) {\n                rowsDeleted = db.delete(TABLENAME, PK + \"=\" + id, null);\n            } else {\n                rowsDeleted = db.delete(TABLENAME, PK + \"=\" + id + \" and \"\n                                + selection, selectionArgs);\n            }\n            break;\n        default:\n            throw new IllegalArgumentException(\"Unknown URI: \" + uri);\n        }\n        getContext().getContentResolver().notifyChange(uri, null);\n        return rowsDeleted;\n</#if>\n    }\n\n    <#--\n##########################################\n########## Update ##############\n##########################################\n-->\n    @Override\n    public int update(Uri uri, ContentValues values, String selection,\n            String[] selectionArgs) {\n<#if contentProvider.isReadOnly()>\n        throw new UnsupportedOperationException(\"This content provider is readonly\");\n<#else>\n        int uriType = sURIMatcher.match(uri);\n        Database db = getDatabase();\n        int rowsUpdated = 0;\n        String id;\n        switch (uriType) {\n        case ${entity.className?upper_case}_DIR:\n            rowsUpdated = db.update(TABLENAME, values, selection, selectionArgs);\n            break;\n        case ${entity.className?upper_case}_ID:\n            id = uri.getLastPathSegment();\n            if (TextUtils.isEmpty(selection)) {\n                    rowsUpdated = db.update(TABLENAME, values, PK + \"=\" + id, null);\n            } else {\n                    rowsUpdated = db.update(TABLENAME, values, PK + \"=\" + id\n                                    + \" and \" + selection, selectionArgs);\n            }\n            break;\n        default:\n            throw new IllegalArgumentException(\"Unknown URI: \" + uri);\n        }\n        getContext().getContentResolver().notifyChange(uri, null);\n        return rowsUpdated;\n</#if>\n    }\n\n     <#--\n##########################################\n########## Query ##############\n##########################################\n-->\n    @Override\n    public Cursor query(Uri uri, String[] projection, String selection,\n            String[] selectionArgs, String sortOrder) {\n\n        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();\n        int uriType = sURIMatcher.match(uri);\n        switch (uriType) {\n        case ${entity.className?upper_case}_DIR:\n            queryBuilder.setTables(TABLENAME);\n            break;\n        case ${entity.className?upper_case}_ID:\n            queryBuilder.setTables(TABLENAME);\n            queryBuilder.appendWhere(PK + \"=\"\n                    + uri.getLastPathSegment());\n            break;\n        default:\n            throw new IllegalArgumentException(\"Unknown URI: \" + uri);\n        }\n\n        Database db = getDatabase();\n        Cursor cursor = queryBuilder.query(((StandardDatabase) db).getSQLiteDatabase(), projection, selection,\n                selectionArgs, null, null, sortOrder);\n        cursor.setNotificationUri(getContext().getContentResolver(), uri);\n\n        return cursor;\n    }\n\n    <#--\n##########################################\n########## GetType ##############\n##########################################\n-->\n    @Override\n    public final String getType(Uri uri) {\n        switch (sURIMatcher.match(uri)) {\n        case ${entity.className?upper_case}_DIR:\n            return CONTENT_TYPE;\n        case ${entity.className?upper_case}_ID:\n            return CONTENT_ITEM_TYPE;\n        default :\n            throw new IllegalArgumentException(\"Unsupported URI: \" + uri);\n        }\n    }\n}\n"
  },
  {
    "path": "DaoGenerator/src-template/dao-deep.ftl",
    "content": "<#--\n\nCopyright (C) 2011-2015 Markus Junginger, greenrobot (http://greenrobot.de)\n                                                                           \nThis file is part of greenDAO Generator.                                   \n                                                                           \ngreenDAO Generator is free software: you can redistribute it and/or modify \nit under the terms of the GNU General Public License as published by       \nthe Free Software Foundation, either version 3 of the License, or          \n(at your option) any later version.                                        \ngreenDAO Generator is distributed in the hope that it will be useful,      \nbut WITHOUT ANY WARRANTY; without even the implied warranty of             \nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              \nGNU General Public License for more details.                               \n                                                                           \nYou should have received a copy of the GNU General Public License          \nalong with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n\n-->\n<#if entity.toOneRelations?has_content>\n    private String selectDeep;\n\n    protected String getSelectDeep() {\n        if (selectDeep == null) {\n            StringBuilder builder = new StringBuilder(\"SELECT \");\n            SqlUtils.appendColumns(builder, \"T\", getAllColumns());\n            builder.append(',');\n<#list entity.toOneRelations as toOne>\n            SqlUtils.appendColumns(builder, \"T${toOne_index}\", daoSession.get${toOne.targetEntity.classNameDao}().getAllColumns());\n<#if toOne_has_next>\n            builder.append(',');\n</#if>\n</#list>\n            builder.append(\" FROM ${entity.dbName} T\");\n<#list entity.toOneRelations as toOne>\n            builder.append(\" LEFT JOIN ${toOne.targetEntity.dbName} T${toOne_index}<#--\n--> ON T.\\\"${toOne.fkProperties[0].dbName}\\\"=T${toOne_index}.\\\"${toOne.targetEntity.pkProperty.dbName}\\\"\");\n</#list>\n            builder.append(' ');\n            selectDeep = builder.toString();\n        }\n        return selectDeep;\n    }\n    \n    protected ${entity.className} loadCurrentDeep(Cursor cursor, boolean lock) {\n        ${entity.className} entity = loadCurrent(cursor, 0, lock);\n        int offset = getAllColumns().length;\n\n<#list entity.toOneRelations as toOne>\n        ${toOne.targetEntity.className} ${toOne.name} = loadCurrentOther(daoSession.get${toOne.targetEntity.classNameDao}(), cursor, offset);\n<#if toOne.fkProperties[0].notNull>         if(${toOne.name} != null) {\n    </#if>        entity.set${toOne.name?cap_first}(${toOne.name});\n<#if toOne.fkProperties[0].notNull>\n        }\n</#if>\n<#if toOne_has_next>\n        offset += daoSession.get${toOne.targetEntity.classNameDao}().getAllColumns().length;\n</#if>\n\n</#list>\n        return entity;    \n    }\n\n    public ${entity.className} loadDeep(Long key) {\n        assertSinglePk();\n        if (key == null) {\n            return null;\n        }\n\n        StringBuilder builder = new StringBuilder(getSelectDeep());\n        builder.append(\"WHERE \");\n        SqlUtils.appendColumnsEqValue(builder, \"T\", getPkColumns());\n        String sql = builder.toString();\n        \n        String[] keyArray = new String[] { key.toString() };\n        Cursor cursor = db.rawQuery(sql, keyArray);\n        \n        try {\n            boolean available = cursor.moveToFirst();\n            if (!available) {\n                return null;\n            } else if (!cursor.isLast()) {\n                throw new IllegalStateException(\"Expected unique result, but count was \" + cursor.getCount());\n            }\n            return loadCurrentDeep(cursor, true);\n        } finally {\n            cursor.close();\n        }\n    }\n    \n    /** Reads all available rows from the given cursor and returns a list of new ImageTO objects. */\n    public List<${entity.className}> loadAllDeepFromCursor(Cursor cursor) {\n        int count = cursor.getCount();\n        List<${entity.className}> list = new ArrayList<${entity.className}>(count);\n        \n        if (cursor.moveToFirst()) {\n            if (identityScope != null) {\n                identityScope.lock();\n                identityScope.reserveRoom(count);\n            }\n            try {\n                do {\n                    list.add(loadCurrentDeep(cursor, false));\n                } while (cursor.moveToNext());\n            } finally {\n                if (identityScope != null) {\n                    identityScope.unlock();\n                }\n            }\n        }\n        return list;\n    }\n    \n    protected List<${entity.className}> loadDeepAllAndCloseCursor(Cursor cursor) {\n        try {\n            return loadAllDeepFromCursor(cursor);\n        } finally {\n            cursor.close();\n        }\n    }\n    \n\n    /** A raw-style query where you can pass any WHERE clause and arguments. */\n    public List<${entity.className}> queryDeep(String where, String... selectionArg) {\n        Cursor cursor = db.rawQuery(getSelectDeep() + where, selectionArg);\n        return loadDeepAllAndCloseCursor(cursor);\n    }\n \n</#if>"
  },
  {
    "path": "DaoGenerator/src-template/dao-master.ftl",
    "content": "<#--\n\nCopyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n                                                                           \nThis file is part of greenDAO Generator.                                   \n                                                                           \ngreenDAO Generator is free software: you can redistribute it and/or modify \nit under the terms of the GNU General Public License as published by       \nthe Free Software Foundation, either version 3 of the License, or          \n(at your option) any later version.                                        \ngreenDAO Generator is distributed in the hope that it will be useful,      \nbut WITHOUT ANY WARRANTY; without even the implied warranty of             \nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              \nGNU General Public License for more details.                               \n                                                                           \nYou should have received a copy of the GNU General Public License          \nalong with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n\n-->\n<#-- @ftlvariable name=\"schema\" type=\"org.greenrobot.greendao.generator.Schema\" -->\npackage ${schema.defaultJavaPackageDao};\n\nimport android.content.Context;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.database.sqlite.SQLiteDatabase.CursorFactory;\nimport android.util.Log;\n\nimport org.greenrobot.greendao.AbstractDaoMaster;\nimport org.greenrobot.greendao.database.StandardDatabase;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseOpenHelper;\nimport org.greenrobot.greendao.identityscope.IdentityScopeType;\n\n<#list schema.entities as entity>\n<#if schema.defaultJavaPackageDao != entity.javaPackageDao>\nimport ${entity.javaPackageDao}.${entity.classNameDao};\n</#if>\n</#list>\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/**\n * Master of DAO (schema version ${schema.version?c}): knows all DAOs.\n */\npublic class ${schema.prefix}DaoMaster extends AbstractDaoMaster {\n    public static final int SCHEMA_VERSION = ${schema.version?c};\n\n    /** Creates underlying database table using DAOs. */\n    public static void createAllTables(Database db, boolean ifNotExists) {\n<#list schema.entities as entity>\n<#if !entity.skipCreationInDb>\n        ${entity.classNameDao}.createTable(db, ifNotExists);\n</#if>\n</#list>\n    }\n\n    /** Drops underlying database table using DAOs. */\n    public static void dropAllTables(Database db, boolean ifExists) {\n<#list schema.entities as entity>\n<#if !entity.skipCreationInDb>\n        ${entity.classNameDao}.dropTable(db, ifExists);\n</#if>\n</#list>\n    }\n\n    /**\n     * WARNING: Drops all table on Upgrade! Use only during development.\n     * Convenience method using a {@link DevOpenHelper}.\n     */\n    public static ${schema.prefix}DaoSession newDevSession(Context context, String name) {\n        Database db = new DevOpenHelper(context, name).getWritableDb();\n        ${schema.prefix}DaoMaster daoMaster = new ${schema.prefix}DaoMaster(db);\n        return daoMaster.newSession();\n    }\n\n    public ${schema.prefix}DaoMaster(SQLiteDatabase db) {\n        this(new StandardDatabase(db));\n    }\n\n    public ${schema.prefix}DaoMaster(Database db) {\n        super(db, SCHEMA_VERSION);\n<#list schema.entities as entity>\n        registerDaoClass(${entity.classNameDao}.class);\n</#list>\n    }\n\n    public ${schema.prefix}DaoSession newSession() {\n        return new ${schema.prefix}DaoSession(db, IdentityScopeType.Session, daoConfigMap);\n    }\n\n    public ${schema.prefix}DaoSession newSession(IdentityScopeType type) {\n        return new ${schema.prefix}DaoSession(db, type, daoConfigMap);\n    }\n\n    /**\n     * Calls {@link #createAllTables(Database, boolean)} in {@link #onCreate(Database)} -\n     */\n    public static abstract class OpenHelper extends DatabaseOpenHelper {\n        public OpenHelper(Context context, String name) {\n            super(context, name, SCHEMA_VERSION);\n        }\n\n        public OpenHelper(Context context, String name, CursorFactory factory) {\n            super(context, name, factory, SCHEMA_VERSION);\n        }\n\n        @Override\n        public void onCreate(Database db) {\n            Log.i(\"greenDAO\", \"Creating tables for schema version \" + SCHEMA_VERSION);\n            createAllTables(db, false);\n        }\n    }\n\n    /** WARNING: Drops all table on Upgrade! Use only during development. */\n    public static class DevOpenHelper extends OpenHelper {\n        public DevOpenHelper(Context context, String name) {\n            super(context, name);\n        }\n\n        public DevOpenHelper(Context context, String name, CursorFactory factory) {\n            super(context, name, factory);\n        }\n\n        @Override\n        public void onUpgrade(Database db, int oldVersion, int newVersion) {\n            Log.i(\"greenDAO\", \"Upgrading schema from version \" + oldVersion + \" to \" + newVersion + \" by dropping all tables\");\n            dropAllTables(db, true);\n            onCreate(db);\n        }\n    }\n\n}\n"
  },
  {
    "path": "DaoGenerator/src-template/dao-session.ftl",
    "content": "<#--\n\nCopyright (C) 2011 Markus Junginger, greenrobot (http://greenrobot.de)     \n                                                                           \nThis file is part of greenDAO Generator.                                   \n                                                                           \ngreenDAO Generator is free software: you can redistribute it and/or modify \nit under the terms of the GNU General Public License as published by       \nthe Free Software Foundation, either version 3 of the License, or          \n(at your option) any later version.                                        \ngreenDAO Generator is distributed in the hope that it will be useful,      \nbut WITHOUT ANY WARRANTY; without even the implied warranty of             \nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              \nGNU General Public License for more details.                               \n                                                                           \nYou should have received a copy of the GNU General Public License          \nalong with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n\n-->\npackage ${schema.defaultJavaPackageDao};\n\nimport java.util.Map;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.AbstractDaoSession;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.identityscope.IdentityScopeType;\nimport org.greenrobot.greendao.internal.DaoConfig;\n\n<#list schema.entities as entity>\nimport ${entity.javaPackage}.${entity.className};\n</#list>\n\n<#list schema.entities as entity>\nimport ${entity.javaPackageDao}.${entity.classNameDao};\n</#list>\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n\n/**\n * {@inheritDoc}\n * \n * @see org.greenrobot.greendao.AbstractDaoSession\n */\npublic class ${schema.prefix}DaoSession extends AbstractDaoSession {\n\n<#list schema.entities as entity>\n    private final DaoConfig ${entity.classNameDao?uncap_first}Config;\n</#list>        \n\n<#list schema.entities as entity>\n    private final ${entity.classNameDao} ${entity.classNameDao?uncap_first};\n</#list>        \n\n    public ${schema.prefix}DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>\n            daoConfigMap) {\n        super(db);\n\n<#list schema.entities as entity>\n        ${entity.classNameDao?uncap_first}Config = daoConfigMap.get(${entity.classNameDao}.class).clone();\n        ${entity.classNameDao?uncap_first}Config.initIdentityScope(type);\n\n</#list>        \n<#list schema.entities as entity>\n        ${entity.classNameDao?uncap_first} = new ${entity.classNameDao}<#--\n-->(${entity.classNameDao?uncap_first}Config, this);\n</#list>        \n\n<#list schema.entities as entity>\n        registerDao(${entity.className}.class, ${entity.classNameDao?uncap_first});\n</#list>        \n    }\n    \n    public void clear() {\n<#list schema.entities as entity>\n        ${entity.classNameDao?uncap_first}Config.clearIdentityScope();\n</#list>    \n    }\n\n<#list schema.entities as entity>\n    public ${entity.classNameDao} get${entity.classNameDao?cap_first}() {\n        return ${entity.classNameDao?uncap_first};\n    }\n\n</#list>        \n}\n"
  },
  {
    "path": "DaoGenerator/src-template/dao-unit-test.ftl",
    "content": "<#--\n\nCopyright (C) 2011 Markus Junginger, greenrobot (http://greenrobot.de)     \n                                                                           \nThis file is part of greenDAO Generator.                                   \n                                                                           \ngreenDAO Generator is free software: you can redistribute it and/or modify \nit under the terms of the GNU General Public License as published by       \nthe Free Software Foundation, either version 3 of the License, or          \n(at your option) any later version.                                        \ngreenDAO Generator is distributed in the hope that it will be useful,      \nbut WITHOUT ANY WARRANTY; without even the implied warranty of             \nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              \nGNU General Public License for more details.                               \n                                                                           \nYou should have received a copy of the GNU General Public License          \nalong with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n\n-->\npackage ${entity.javaPackageTest};\n\n<#assign isStringPK = entity.pkProperty?? && entity.pkProperty.propertyType == \"String\" />\n<#if isStringPK>\nimport org.greenrobot.greendao.test.AbstractDaoTestStringPk;\n<#else>\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\n</#if>\n\nimport ${entity.javaPackage}.${entity.className};\nimport ${entity.javaPackageDao}.${entity.classNameDao};\n\npublic class ${entity.classNameTest} extends <#if\nisStringPK>AbstractDaoTestStringPk<${entity.classNameDao}, ${entity.className}><#else>AbstractDaoTestLongPk<${entity.classNameDao}, ${entity.className}></#if> {\n\n    public ${entity.classNameTest}() {\n        super(${entity.classNameDao}.class);\n    }\n\n    @Override\n    protected ${entity.className} createEntity(<#if isStringPK>String<#else>Long</#if> key) {\n        ${entity.className} entity = new ${entity.className}();\n<#if entity.pkProperty??>\n        entity.set${entity.pkProperty.propertyName?cap_first}(key);\n</#if>\n<#list entity.properties as property>\n<#if property.notNull>\n        entity.set${property.propertyName?cap_first}();\n</#if> \n</#list>\n        return entity;\n    }\n\n}\n"
  },
  {
    "path": "DaoGenerator/src-template/dao.ftl",
    "content": "<#--\n\nCopyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n                                                                           \nThis file is part of greenDAO Generator.                                   \n                                                                           \ngreenDAO Generator is free software: you can redistribute it and/or modify \nit under the terms of the GNU General Public License as published by       \nthe Free Software Foundation, either version 3 of the License, or          \n(at your option) any later version.                                        \ngreenDAO Generator is distributed in the hope that it will be useful,      \nbut WITHOUT ANY WARRANTY; without even the implied warranty of             \nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              \nGNU General Public License for more details.                               \n                                                                           \nYou should have received a copy of the GNU General Public License          \nalong with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n\n-->\n<#-- @ftlvariable name=\"entity\" type=\"org.greenrobot.greendao.generator.Entity\" -->\n<#-- @ftlvariable name=\"schema\" type=\"org.greenrobot.greendao.generator.Schema\" -->\n\n<#assign toBindType = {\"Boolean\":\"Long\", \"Byte\":\"Long\", \"Short\":\"Long\", \"Int\":\"Long\", \"Long\":\"Long\", \"Float\":\"Double\", \"Double\":\"Double\", \"String\":\"String\", \"ByteArray\":\"Blob\", \"Date\": \"Long\" } />\n<#assign toCursorType = {\"Boolean\":\"Short\", \"Byte\":\"Short\", \"Short\":\"Short\", \"Int\":\"Int\", \"Long\":\"Long\", \"Float\":\"Float\", \"Double\":\"Double\", \"String\":\"String\", \"ByteArray\":\"Blob\", \"Date\": \"Long\"  } />\npackage ${entity.javaPackageDao};\n\n<#if entity.toOneRelations?has_content || entity.incomingToManyRelations?has_content>\nimport java.util.List;\n</#if>\n<#if entity.toOneRelations?has_content>\nimport java.util.ArrayList;\n</#if>\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\n<#if entity.toOneRelations?has_content>\nimport org.greenrobot.greendao.internal.SqlUtils;\n</#if>\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n<#if entity.incomingToManyRelations?has_content>\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\n</#if>\n\n<#if entity.javaPackageDao != schema.defaultJavaPackageDao>\nimport ${schema.defaultJavaPackageDao}.${schema.prefix}DaoSession;\n\n</#if>\n<#if entity.additionalImportsDao?has_content>\n<#list entity.additionalImportsDao as additionalImport>\nimport ${additionalImport};\n</#list>\n\n</#if>\n<#if entity.javaPackageDao != entity.javaPackage>\nimport ${entity.javaPackage}.${entity.className};\n\n</#if>\n<#if entity.protobuf>\nimport ${entity.javaPackage}.${entity.className}.Builder;\n\n</#if>\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"${entity.dbName}\".\n*/\npublic class ${entity.classNameDao} extends AbstractDao<${entity.className}, ${entity.pkType}> {\n\n    public static final String TABLENAME = \"${entity.dbName}\";\n\n    /**\n     * Properties of entity ${entity.className}.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n<#list entity.propertiesColumns as property>\n        public final static Property ${property.propertyName?cap_first} = new Property(${property_index}, ${property.javaType}.class, \"${property.propertyName}\", ${property.primaryKey?string}, \"${property.dbName}\");\n</#list>\n    }\n\n<#if entity.active>\n    private ${schema.prefix}DaoSession daoSession;\n\n</#if>\n<#list entity.properties as property><#if property.customType?has_content><#--\n-->    private final ${property.converterClassName} ${property.propertyName}Converter = new ${property.converterClassName}();\n</#if></#list>\n<#list entity.incomingToManyRelations as toMany>\n    private Query<${toMany.targetEntity.className}> ${toMany.sourceEntity.className?uncap_first}_${toMany.name?cap_first}Query;\n</#list>\n\n    public ${entity.classNameDao}(DaoConfig config) {\n        super(config);\n    }\n    \n    public ${entity.classNameDao}(DaoConfig config, ${schema.prefix}DaoSession daoSession) {\n        super(config, daoSession);\n<#if entity.active>        \n        this.daoSession = daoSession;\n</#if>\n    }\n\n<#if !entity.skipCreationInDb>\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"${entity.dbName}\\\" (\" + //\n<#list entity.propertiesColumns as property>\n                \"\\\"${property.dbName}\\\" ${property.dbType}<#if property.constraints??> ${property.constraints} </#if><#if property_has_next>,\" +<#else>);\");</#if> // ${property_index}: ${property.propertyName}\n</#list>\n<#if entity.indexes?has_content >\n        // Add Indexes\n<#list entity.indexes as index>\n        db.execSQL(\"CREATE <#if index.unique>UNIQUE </#if>INDEX \" + constraint + \"${index.name} ON \\\"${entity.dbName}\\\"\" +\n                \" (<#list index.properties \nas property>\\\"${property.dbName}\\\"<#if (index.propertiesOrder[property_index])??> ${index.propertiesOrder[property_index]}</#if><#sep>,</#list>);\");\n</#list>\n</#if>         \n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"${entity.dbName}\\\"\";\n        db.execSQL(sql);\n    }\n\n</#if>\n<#assign stmtTypes = [\"DatabaseStatement\", \"SQLiteStatement\"] />\n<#list stmtTypes as stmtType>\n    @Override\n    protected final void bindValues(${stmtType} stmt, ${entity.className} entity) {\n        stmt.clearBindings();\n<#list entity.properties as property>\n<#if property.notNull || entity.protobuf>\n<#if entity.protobuf>\n        if(entity.has${property.propertyName?cap_first}()) {\n    </#if>        stmt.bind${toBindType[property.propertyType]}(${property_index + 1}, ${property.databaseValueExpressionNotNull});\n<#if entity.protobuf>\n        }\n</#if>\n<#else> <#-- nullable, non-protobuff -->\n        ${property.javaTypeInEntity} ${property.propertyName} = entity.get${property.propertyName?cap_first}();\n        if (${property.propertyName} != null) {\n            stmt.bind${toBindType[property.propertyType]}(${property_index + 1}, ${property.databaseValueExpression});\n        }\n</#if>\n</#list>\n<#list entity.toOneRelations as toOne>\n<#if !toOne.fkProperties?has_content>\n\n        ${toOne.targetEntity.className} ${toOne.name} = entity.peak${toOne.name?cap_first}();\n        if(${toOne.name} != null) {\n            ${toOne.targetEntity.pkProperty.javaType} ${toOne.name}__targetKey = ${toOne.name}.get${toOne.targetEntity.pkProperty.propertyName?cap_first}();\n<#if !toOne.targetEntity.pkProperty.notNull>\n            if(${toOne.name}__targetKey != null) {\n                // TODO bind ${toOne.name}__targetKey\n            }\n<#else>\n            // TODO bind ${toOne.name}__targetKey\n</#if>\n        }\n</#if>\n</#list>\n    }\n\n</#list>\n<#if entity.active && !entity.protobuf>\n    @Override\n    protected final void attachEntity(${entity.className} entity) {\n        super.attachEntity(entity);\n        entity.__setDaoSession(daoSession);\n    }\n\n</#if>\n    @Override\n    public ${entity.pkType} readKey(Cursor cursor, int offset) {\n<#if entity.pkProperty??>\n        return <#if !entity.pkProperty.notNull>cursor.isNull(offset + ${entity.pkProperty.ordinal}) ? null : </#if><#if\n            entity.pkProperty.propertyType == \"Byte\">(byte) </#if><#if\n            entity.pkProperty.propertyType == \"Date\">new java.util.Date(</#if>cursor.get${toCursorType[entity.pkProperty.propertyType]}(offset + ${entity.pkProperty.ordinal})<#if\n            entity.pkProperty.propertyType == \"Boolean\"> != 0</#if><#if\n            entity.pkProperty.propertyType == \"Date\">)</#if>;\n<#else>\n        return null;\n</#if>  \n    }    \n\n    @Override\n    public ${entity.className} readEntity(Cursor cursor, int offset) {\n<#if entity.protobuf>\n        Builder builder = ${entity.className}.newBuilder();\n<#list entity.properties as property>\n<#if !property.notNull>\n        if (!cursor.isNull(offset + ${property_index})) {\n    </#if>        builder.set${property.propertyName?cap_first}(cursor.get${toCursorType[property.propertyType]}(offset + ${property_index}));\n<#if !property.notNull>\n        }\n</#if>        \n</#list>        \n        return builder.build();\n<#elseif entity.constructors>\n<#--\n############################## readEntity non-protobuff, constructor ############################## \n-->\n        ${entity.className} entity = new ${entity.className}( //\n<#list entity.properties as property>\n            <#if !property.notNull>cursor.isNull(offset + ${property_index}) ? null : </#if><#--\n            -->${property.getEntityValueExpression(\"cursor.get${toCursorType[property.propertyType]}(offset + ${property_index})\")}<#--\n            --><#if property_has_next>,</#if> // ${property.propertyName}\n</#list>        \n        );\n        return entity;\n<#else>\n<#--\n############################## readEntity non-protobuff, setters ############################## \n-->\n        ${entity.className} entity = new ${entity.className}();\n        readEntity(cursor, entity, offset);\n        return entity;\n</#if>\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, ${entity.className} entity, int offset) {\n<#if entity.protobuf>\n        throw new UnsupportedOperationException(\"Protobuf objects cannot be modified\");\n<#else> \n<#list entity.properties as property>\n        entity.set${property.propertyName?cap_first}(<#if !property.notNull>cursor.isNull(offset + ${property_index}) ? null : </#if><#--\n            -->${property.getEntityValueExpression(\"cursor.get${toCursorType[property.propertyType]}(offset + ${property_index})\")});\n</#list>\n</#if>\n     }\n    \n    @Override\n    protected final ${entity.pkType} updateKeyAfterInsert(${entity.className} entity, long rowId) {\n<#if entity.pkProperty??>\n<#if entity.pkProperty.propertyType == \"Long\">\n<#if !entity.protobuf>\n        entity.set${entity.pkProperty.propertyName?cap_first}(rowId);\n</#if>\n        return rowId;\n<#else>\n        return entity.get${entity.pkProperty.propertyName?cap_first}();\n</#if>\n<#else>\n        // Unsupported or missing PK type\n        return null;\n</#if>\n    }\n    \n    @Override\n    public ${entity.pkType} getKey(${entity.className} entity) {\n<#if entity.pkProperty??>\n        if(entity != null) {\n            return entity.get${entity.pkProperty.propertyName?cap_first}();\n        } else {\n            return null;\n        }\n<#else>\n        return null;\n</#if>    \n    }\n\n    @Override\n    public boolean hasKey(${entity.className} entity) {\n<#if entity.pkProperty??>\n<#if entity.pkProperty.notNull>\n        throw new UnsupportedOperationException(\"Unsupported for entities with a non-null key\");\n<#else>\n<#if entity.protobuf>\n        return entity.has${entity.pkProperty.propertyName?cap_first}();\n<#else>\n        return entity.get${entity.pkProperty.propertyName?cap_first}() != null;\n</#if>\n</#if>\n<#else>\n        // TODO\n        return false;\n</#if>\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return ${(!entity.protobuf)?string};\n    }\n    \n<#list entity.incomingToManyRelations as toMany>\n    /** Internal query to resolve the \"${toMany.name}\" to-many relationship of ${toMany.sourceEntity.className}. */\n    public List<${toMany.targetEntity.className}> _query${toMany.sourceEntity.className?cap_first}_${toMany.name?cap_first}(<#--\n    --><#if toMany.targetProperties??><#list toMany.targetProperties as property><#--\n    -->${property.javaType} ${property.propertyName}<#if property_has_next>, </#if></#list><#else><#--\n    -->${toMany.sourceProperty.javaType} ${toMany.sourceProperty.propertyName}</#if>) {\n        synchronized (this) {\n            if (${toMany.sourceEntity.className?uncap_first}_${toMany.name?cap_first}Query == null) {\n                QueryBuilder<${toMany.targetEntity.className}> queryBuilder = queryBuilder();\n<#if toMany.targetProperties??>\n    <#list toMany.targetProperties as property>\n                queryBuilder.where(Properties.${property.propertyName?cap_first}.eq(null));\n    </#list>\n<#else>\n                queryBuilder.join(${toMany.joinEntity.className}.class, ${toMany.joinEntity.classNameDao}.Properties.${toMany.targetProperty.propertyName?cap_first})\n                    .where(${toMany.joinEntity.classNameDao}.Properties.${toMany.sourceProperty.propertyName?cap_first}.eq(${toMany.sourceProperty.propertyName}));\n</#if>\n<#if toMany.order?has_content>\n                queryBuilder.orderRaw(\"${toMany.order}\");\n</#if>\n                ${toMany.sourceEntity.className?uncap_first}_${toMany.name?cap_first}Query = queryBuilder.build();\n            }\n        }\n        Query<${toMany.targetEntity.className}> query = ${toMany.sourceEntity.className?uncap_first}_${toMany.name?cap_first}Query.forCurrentThread();\n<#if toMany.targetProperties??>\n    <#list toMany.targetProperties as property>\n        query.setParameter(${property_index}, ${property.propertyName});\n    </#list>\n<#else>\n        query.setParameter(0, ${toMany.sourceProperty.propertyName});\n</#if>\n        return query.list();\n    }\n\n</#list>   \n<#if entity.toOneRelations?has_content>\n    <#include \"dao-deep.ftl\">\n</#if>\n}\n"
  },
  {
    "path": "DaoGenerator/src-template/entity.ftl",
    "content": "<#--\n\nCopyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n                                                                           \nThis file is part of greenDAO Generator.                                   \n                                                                           \ngreenDAO Generator is free software: you can redistribute it and/or modify \nit under the terms of the GNU General Public License as published by       \nthe Free Software Foundation, either version 3 of the License, or          \n(at your option) any later version.                                        \ngreenDAO Generator is distributed in the hope that it will be useful,      \nbut WITHOUT ANY WARRANTY; without even the implied warranty of             \nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              \nGNU General Public License for more details.                               \n                                                                           \nYou should have received a copy of the GNU General Public License          \nalong with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n\n-->\n<#-- @ftlvariable name=\"entity\" type=\"org.greenrobot.greendao.generator.Entity\" -->\n<#-- @ftlvariable name=\"schema\" type=\"org.greenrobot.greendao.generator.Schema\" -->\n\n<#assign toBindType = {\"Boolean\":\"Long\", \"Byte\":\"Long\", \"Short\":\"Long\", \"Int\":\"Long\", \"Long\":\"Long\", \"Float\":\"Double\", \"Double\":\"Double\", \"String\":\"String\", \"ByteArray\":\"Blob\" }/>\n<#assign toCursorType = {\"Boolean\":\"Short\", \"Byte\":\"Short\", \"Short\":\"Short\", \"Int\":\"Int\", \"Long\":\"Long\", \"Float\":\"Float\", \"Double\":\"Double\", \"String\":\"String\", \"ByteArray\":\"Blob\" }/>\n<#assign primitiveTypes = [\"boolean\", \"byte\", \"int\", \"long\", \"float\", \"double\", \"short\"]/>\n<#macro multiIndexes>\n{\n<#list entity.multiIndexes as index>\n    @Index(value = \"${index.orderSpec}\"<#if index.nonDefaultName>, name = \"${index.name}\"</#if><#if index.unique>, unique = true</#if>)<#sep>,\n</#list>\n\n}</#macro>\npackage ${entity.javaPackage};\n\nimport org.greenrobot.greendao.annotation.*;\n\n<#if entity.toManyRelations?has_content>\nimport java.util.List;\n</#if>\n<#if entity.active>\nimport ${schema.defaultJavaPackageDao}.${schema.prefix}DaoSession;\nimport org.greenrobot.greendao.DaoException;\n\n</#if>\n<#if entity.additionalImportsEntity?has_content>\n<#list entity.additionalImportsEntity as additionalImport>\nimport ${additionalImport};\n</#list>\n\n</#if>\n<#if entity.hasKeepSections>\n// THIS CODE IS GENERATED BY greenDAO, EDIT ONLY INSIDE THE \"KEEP\"-SECTIONS\n\n// KEEP INCLUDES - put your custom includes here\n<#if keepIncludes?has_content>${keepIncludes!}</#if>// KEEP INCLUDES END\n<#else>\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n</#if>\n\n<#if entity.javaDoc ??>\n${entity.javaDoc}\n<#else>\n/**\n * Entity mapped to table \"${entity.dbName}\".\n */\n</#if>\n<#if entity.codeBeforeClass ??>\n${entity.codeBeforeClass}\n</#if>\n<#assign entityAttrs = []>\n<#if schema.name != \"default\"><#assign entityAttrs = entityAttrs + [\"schema = \\\"${schema.name}\\\"\"]></#if>\n<#if entity.active><#assign entityAttrs = entityAttrs + [\"active = true\"]></#if>\n<#if entity.nonDefaultDbName><#assign entityAttrs = entityAttrs + [\"nameInDb = \\\"${entity.dbName}\\\"\"]></#if>\n<#if (entity.multiIndexes?size > 0)>\n    <#assign idxAttr>indexes = <@multiIndexes/></#assign>\n    <#assign entityAttrs = entityAttrs + [idxAttr]>\n</#if>\n<#if entity.skipCreationInDb><#assign entityAttrs = entityAttrs + [\"createInDb = false\"]></#if>\n@Entity<#if (entityAttrs?size > 0)>(${entityAttrs?join(\", \")})</#if>\npublic class ${entity.className}<#if\nentity.superclass?has_content> extends ${entity.superclass} </#if><#if\nentity.interfacesToImplement?has_content> implements <#list entity.interfacesToImplement\nas ifc>${ifc}<#if ifc_has_next>, </#if></#list></#if> {\n<#list entity.properties as property>\n<#assign notNull = property.notNull && !primitiveTypes?seq_contains(property.javaTypeInEntity)>\n<#if property.primaryKey||notNull||property.unique||property.index??||property.nonDefaultDbName||property.converter??>\n\n</#if>\n<#if property.javaDocField ??>\n${property.javaDocField}\n</#if>\n<#if property.codeBeforeField ??>\n    ${property.codeBeforeField}\n</#if>\n<#if property.primaryKey>\n    @Id<#if property.autoincrement>(autoincrement = true)</#if>\n</#if>\n<#if property.nonDefaultDbName>\n    @Property(nameInDb = \"${property.dbName}\")\n</#if>\n<#if property.converter??>\n    @Convert(converter = ${property.converter}.class, columnType = ${property.javaType}.class)\n</#if>\n<#if notNull>\n    @NotNull\n</#if>\n<#if property.unique>\n    @Unique\n</#if>\n<#if ((property.index.nonDefaultName)!false) && (property.index.unique)!false>\n    @Index(name = \"${property.index.name}\", unique = true)\n<#elseif (property.index.nonDefaultName)!false>\n    @Index(name = \"${property.index.name}\")\n<#elseif (property.index.unique)!false>\n    @Index(unique = true)\n<#elseif property.index??>\n    @Index\n</#if>\n    private ${property.javaTypeInEntity} ${property.propertyName};\n</#list>\n\n<#if entity.active>\n    /** Used to resolve relations */\n    @Generated\n    private transient ${schema.prefix}DaoSession daoSession;\n\n    /** Used for active entity operations. */\n    @Generated\n    private transient ${entity.classNameDao} myDao;\n<#list entity.toOneRelations as toOne>\n\n<#if toOne.useFkProperty>\n    @ToOne(joinProperty = \"${toOne.fkProperties[0].propertyName}\")\n    private ${toOne.targetEntity.className} ${toOne.name};\n\n    @Generated\n    private transient ${toOne.resolvedKeyJavaType[0]} ${toOne.name}__resolvedKey;\n<#else>\n    @ToOne\n<#if toOne.fkProperties[0].nonDefaultDbName>\n    @Property(nameInDb = \"${toOne.fkProperties[0].dbName}\")\n</#if>\n<#if toOne.fkProperties[0].unique>\n    @Unique\n</#if>\n<#if toOne.fkProperties[0].notNull>\n    @NotNull\n</#if>\n    private ${toOne.targetEntity.className} ${toOne.name};\n\n    @Generated\n    private transient boolean ${toOne.name}__refreshed;\n</#if>\n</#list>\n<#list entity.toManyRelations as toMany>\n\n<#if toMany.sourceProperties??>\n    @ToMany(joinProperties = {\n<#list toMany.sourceProperties as sourceProperty>\n        @JoinProperty(name = \"${sourceProperty.propertyName}\", referencedName = \"${toMany.targetProperties[sourceProperty_index].propertyName}\")<#sep>,\n</#list>\n\n    })\n<#elseif toMany.targetProperties??>\n    @ToMany(mappedBy = \"${toMany.targetProperties[0]}\")\n<#else>\n    @ToMany\n    @JoinEntity(entity = ${toMany.joinEntity.className}.class, sourceProperty = \"${toMany.sourceProperty.propertyName}\", targetProperty = \"${toMany.targetProperty.propertyName}\")\n</#if>\n<#assign orderSpec = (toMany.orderSpec)!\"0\">\n<#if orderSpec != \"0\">\n    @OrderBy(\"${orderSpec}\")\n</#if>\n    private List<${toMany.targetEntity.className}> ${toMany.name};\n</#list>\n\n</#if>\n<#if entity.hasKeepSections>\n    // KEEP FIELDS - put your custom fields here\n${keepFields!}    // KEEP FIELDS END\n\n</#if>\n<#if entity.constructors>\n    @Generated\n    public ${entity.className}() {\n    }\n<#if entity.propertiesPk?has_content && entity.propertiesPk?size != entity.properties?size>\n\n    public ${entity.className}(<#list entity.propertiesPk as\nproperty>${property.javaType} ${property.propertyName}<#if property_has_next>, </#if></#list>) {\n<#list entity.propertiesPk as property>\n        this.${property.propertyName} = ${property.propertyName};\n</#list>\n    }\n</#if>\n\n    @Generated\n    public ${entity.className}(<#list entity.properties as\nproperty>${property.javaTypeInEntity} ${property.propertyName}<#if property_has_next>, </#if></#list>) {\n<#list entity.properties as property>\n        this.${property.propertyName} = ${property.propertyName};\n</#list>\n    }\n</#if>\n\n<#if entity.active>\n    /** called by internal mechanisms, do not call yourself. */\n    @Generated\n    public void __setDaoSession(${schema.prefix}DaoSession daoSession) {\n        this.daoSession = daoSession;\n        myDao = daoSession != null ? daoSession.get${entity.classNameDao?cap_first}() : null;\n    }\n\n</#if>\n<#list entity.properties as property>\n<#if property.javaDocGetter ??>\n${property.javaDocGetter}\n</#if>\n<#if property.codeBeforeGetter ??>\n    ${property.codeBeforeGetter}\n</#if>\n<#if property.notNull && !primitiveTypes?seq_contains(property.javaTypeInEntity)>\n    @NotNull\n</#if>\n    public ${property.javaTypeInEntity} get${property.propertyName?cap_first}() {\n        return ${property.propertyName};\n    }\n\n<#if property.notNull && !primitiveTypes?seq_contains(property.javaTypeInEntity)>\n    /** Not-null value; ensure this value is available before it is saved to the database. */\n</#if>\n<#if property.javaDocSetter ??>\n${property.javaDocSetter}\n</#if>\n<#if property.codeBeforeSetter ??>\n    ${property.codeBeforeSetter}\n</#if>\n    public void set${property.propertyName?cap_first}(<#if property.notNull && !primitiveTypes?seq_contains(property.javaTypeInEntity)>@NotNull </#if>${property.javaTypeInEntity} ${property.propertyName}) {\n        this.${property.propertyName} = ${property.propertyName};\n    }\n\n</#list>\n<#--\n##########################################\n########## To-One Relations ##############\n##########################################\n-->\n<#list entity.toOneRelations as toOne>\n    /** To-one relationship, resolved on first access. */\n    @Generated\n    public ${toOne.targetEntity.className} get${toOne.name?cap_first}() {\n<#if toOne.useFkProperty>\n        ${toOne.fkProperties[0].javaType} __key = this.${toOne.fkProperties[0].propertyName};\n        if (${toOne.name}__resolvedKey == null || <#--\n        --><#if toOne.resolvedKeyUseEquals[0]>!${toOne.name}__resolvedKey.equals(__key)<#--\n        --><#else>${toOne.name}__resolvedKey != __key</#if>) {\n            __throwIfDetached();\n            ${toOne.targetEntity.classNameDao} targetDao = daoSession.get${toOne.targetEntity.classNameDao?cap_first}();\n            ${toOne.targetEntity.className} ${toOne.name}New = targetDao.load(__key);\n            synchronized (this) {\n                ${toOne.name} = ${toOne.name}New;\n            \t${toOne.name}__resolvedKey = __key;\n            }\n        }\n<#else>\n        if (${toOne.name} != null || !${toOne.name}__refreshed) {\n            __throwIfDetached();\n            ${toOne.targetEntity.classNameDao} targetDao = daoSession.get${toOne.targetEntity.classNameDao?cap_first}();\n            targetDao.refresh(${toOne.name});\n            ${toOne.name}__refreshed = true;\n        }\n</#if>\n        return ${toOne.name};\n    }\n<#if !toOne.useFkProperty>\n\n    /** To-one relationship, returned entity is not refreshed and may carry only the PK property. */\n    @Generated\n    public ${toOne.targetEntity.className} peak${toOne.name?cap_first}() {\n        return ${toOne.name};\n    }\n</#if>\n\n    @Generated\n    public void set${toOne.name?cap_first}(<#if toOne.fkProperties[0].notNull && !primitiveTypes?seq_contains(toOne.fkProperties[0].javaTypeInEntity)>@NotNull </#if>${toOne.targetEntity.className} ${toOne.name}) {\n<#if toOne.fkProperties[0].notNull>\n        if (${toOne.name} == null) {\n            throw new DaoException(\"To-one property '${toOne.fkProperties[0].propertyName}' has not-null constraint; cannot set to-one to null\");\n        }\n</#if>\n        synchronized (this) {\n            this.${toOne.name} = ${toOne.name};\n<#if toOne.useFkProperty>        \n            ${toOne.fkProperties[0].propertyName} = <#if !toOne.fkProperties[0].notNull>${toOne.name} == null ? null : </#if>${toOne.name}.get${toOne.targetEntity.pkProperty.propertyName?cap_first}();\n            ${toOne.name}__resolvedKey = ${toOne.fkProperties[0].propertyName};\n<#else>\n            ${toOne.name}__refreshed = true;\n</#if>\n        }\n    }\n\n</#list>\n<#--\n##########################################\n########## To-Many Relations #############\n##########################################\n-->\n<#list entity.toManyRelations as toMany>\n    /** To-many relationship, resolved on first access (and after reset). Changes to to-many relations are not persisted, make changes to the target entity. */\n    @Generated\n    public List<${toMany.targetEntity.className}> get${toMany.name?cap_first}() {\n        if (${toMany.name} == null) {\n            __throwIfDetached();\n            ${toMany.targetEntity.classNameDao} targetDao = daoSession.get${toMany.targetEntity.classNameDao?cap_first}();\n            List<${toMany.targetEntity.className}> ${toMany.name}New = targetDao._query${toMany.sourceEntity.className?cap_first}_${toMany.name?cap_first}(<#--\n                --><#if toMany.sourceProperties??><#list toMany.sourceProperties as property>${property.propertyName}<#if property_has_next>, </#if></#list><#else><#--\n                -->${entity.pkProperty.propertyName}</#if>);\n            synchronized (this) {<#-- Check if another thread was faster, we cannot lock while doing the query to prevent deadlocks -->\n                if(${toMany.name} == null) {\n                    ${toMany.name} = ${toMany.name}New;\n                }\n            }\n        }\n        return ${toMany.name};\n    }\n\n    /** Resets a to-many relationship, making the next get call to query for a fresh result. */\n    @Generated\n    public synchronized void reset${toMany.name?cap_first}() {\n        ${toMany.name} = null;\n    }\n\n</#list>\n<#--\n##########################################\n########## Active entity operations ######\n##########################################\n-->\n<#if entity.active>\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void delete() {\n        __throwIfDetached();\n        myDao.delete(this);\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void update() {\n        __throwIfDetached();\n        myDao.update(this);\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void refresh() {\n        __throwIfDetached();\n        myDao.refresh(this);\n    }\n\n    @Generated\n    private void __throwIfDetached() {\n        if (myDao == null) {\n            throw new DaoException(\"Entity is detached from DAO context\");\n        }\n    }\n\n</#if>\n<#if entity.hasKeepSections>\n    // KEEP METHODS - put your custom methods here\n${keepMethods!}    // KEEP METHODS END\n\n</#if>\n}\n"
  },
  {
    "path": "DaoGenerator/src-test/org/greenrobot/greendao/generator/SimpleDaoGeneratorTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator;\n\nimport org.junit.Test;\n\nimport java.io.File;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertFalse;\nimport static org.junit.Assert.assertTrue;\n\npublic class SimpleDaoGeneratorTest {\n\n    @Test\n    public void testMinimalSchema() throws Exception {\n        Schema schema = new Schema(1, \"org.greenrobot.testdao\");\n        Entity addressEntity = schema.addEntity(\"Addresse\");\n        Property idProperty = addressEntity.addIdProperty().getProperty();\n        addressEntity.addIntProperty(\"count\").index();\n        addressEntity.addIntProperty(\"dummy\").notNull();\n        assertEquals(1, schema.getEntities().size());\n        assertEquals(3, addressEntity.getProperties().size());\n\n        File outputDir = new File(\"build/test-out\");\n        outputDir.mkdirs();\n\n        File daoFile = new File(outputDir, \"org/greenrobot/testdao/\" + addressEntity.getClassName() + \"Dao.java\");\n        daoFile.delete();\n        assertFalse(daoFile.exists());\n\n        new DaoGenerator().generateAll(schema, outputDir.getPath());\n\n        assertEquals(\"PRIMARY KEY\", idProperty.getConstraints());\n        assertTrue(daoFile.toString(), daoFile.exists());\n    }\n\n    @Test\n    public void testDbName() {\n        assertEquals(\"NORMAL\", DaoUtil.dbName(\"normal\"));\n        assertEquals(\"NORMAL\", DaoUtil.dbName(\"Normal\"));\n        assertEquals(\"CAMEL_CASE\", DaoUtil.dbName(\"CamelCase\"));\n        assertEquals(\"CAMEL_CASE_THREE\", DaoUtil.dbName(\"CamelCaseThree\"));\n        assertEquals(\"CAMEL_CASE_XXXX\", DaoUtil.dbName(\"CamelCaseXXXX\"));\n    }\n\n    @Test(expected = RuntimeException.class)\n    public void testInterfacesError() throws Exception {\n        Schema schema = new Schema(1, \"org.greenrobot.testdao\");\n        Entity addressTable = schema.addEntity(\"Addresse\");\n        addressTable.implementsInterface(\"Dummy\");\n        addressTable.implementsInterface(\"Dummy\");\n    }\n}\n"
  },
  {
    "path": "README.md",
    "content": "⚠️ **This project is not longer actively maintained.** If you are looking for an easy to use and efficient database solution,\nplease:\n\nCheck out ObjectBox\n===================\n\n<a href=\"https://objectbox.io/\"><img width=\"466\" src=\"https://github.com/greenrobot/greenDAO/raw/master/images/objectbox-logo.png\"></a>\n\n**Check out our new mobile database [ObjectBox](https://objectbox.io/) ([GitHub repo](https://github.com/objectbox/objectbox-java)).**\n\nObjectBox is a superfast object-oriented database with strong relation support. ObjectBox is embedded into your Android, Linux, macOS, or Windows app. \n\ngreenDAO\n========\ngreenDAO is a light & fast ORM for Android that maps objects to SQLite databases. Being highly optimized for Android, greenDAO offers great performance and consumes minimal memory.\n\n**<font size=\"+1\">Home page, documentation, and support links: https://greenrobot.org/greendao/</font>**\n\n[![Build Status](https://travis-ci.org/greenrobot/greenDAO.svg?branch=master)](https://travis-ci.org/greenrobot/greenDAO)\n[![Follow greenrobot on Twitter](https://img.shields.io/twitter/follow/greenrobot_de.svg?style=flat-square&logo=twitter)](https://twitter.com/greenrobot_de)\n\nFeatures\n--------\ngreenDAO's unique set of features:\n\n* Rock solid: greenDAO has been around since 2011 and is used by countless famous apps\n* Super simple: concise and straight-forward API, in V3 with annotations\n* Small: The library is <150K and it's just plain Java jar (no CPU dependent native parts)\n* Fast: Probably the fastest ORM for Android, driven by intelligent code generation\n* Safe and expressive query API: QueryBuilder uses property constants to avoid typos\n* Powerful joins: query across entities and even chain joins for complex relations\n* Flexible property types: use custom classes or enums to represent data in your entity\n* Encryption: supports SQLCipher encrypted databases\n\nAdd greenDAO to your project\n----------------------------\ngreenDAO is available on Maven Central. Please ensure that you are using the latest versions of the [greendao](https://search.maven.org/search?q=g:org.greenrobot%20AND%20a:greendao) and [greendao-gradle-plugin](https://search.maven.org/search?q=g:org.greenrobot%20AND%20a:greendao-gradle-plugin) artifact.\n\nAdd the following Gradle configuration to your Android project. In your root `build.gradle` file:\n```groovy\nbuildscript {\n    repositories {\n        jcenter()\n        mavenCentral() // add repository\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:<agp-version>'\n        classpath 'org.greenrobot:greendao-gradle-plugin:3.3.1' // add plugin\n    }\n}\n```\nIn your app modules `app/build.gradle` file:\n```groovy\napply plugin: 'com.android.application'\napply plugin: 'org.greenrobot.greendao' // apply plugin\n \ndependencies {\n    implementation 'org.greenrobot:greendao:3.3.0' // add library\n}\n```\n\nNote that this hooks up the greenDAO Gradle plugin to your build process. When you build your project, it generates classes like DaoMaster, DaoSession and DAOs.\n\nContinue at the [Getting Started](https://greenrobot.org/greendao/documentation/how-to-get-started/) page.\n\nR8, ProGuard\n------------\n\nIf your project uses R8 or ProGuard add the following rules:\n\n```bash\n-keepclassmembers class * extends org.greenrobot.greendao.AbstractDao {\npublic static java.lang.String TABLENAME;\n}\n-keep class **$Properties { *; }\n\n# If you DO use SQLCipher:\n-keep class org.greenrobot.greendao.database.SqlCipherEncryptedHelper { *; }\n\n# If you do NOT use SQLCipher:\n-dontwarn net.sqlcipher.database.**\n# If you do NOT use RxJava:\n-dontwarn rx.**\n```\n\nHomepage, Documentation, Links\n------------------------------\nFor more details on greenDAO please check [greenDAO's website](https://greenrobot.org/greendao). Here are some direct links you may find useful:\n\n[Features](https://greenrobot.org/greendao/features/)\n\n[Getting Started](https://greenrobot.org/greendao/documentation/how-to-get-started/)\n\n[Documentation](https://greenrobot.org/greendao/documentation/)\n\n[Changelog](https://greenrobot.org/greendao/changelog/)\n\n[Technical FAQ](https://greenrobot.org/greendao/documentation/technical-faq/)\n\n[Non-Technical FAQ](https://greenrobot.org/greendao/documentation/faq/)\n\n[Migrating to greenDAO 3](https://greenrobot.org/greendao/documentation/updating-to-greendao-3-and-annotations/)\n\nMore Open Source by greenrobot\n==============================\n[__ObjectBox__](https://github.com/objectbox/objectbox-java) is a new superfast object-oriented database for mobile.\n\n[__EventBus__](https://github.com/greenrobot/EventBus) is a central publish/subscribe bus for Android with optional delivery threads, priorities, and sticky events. A great tool to decouple components (e.g. Activities, Fragments, logic components) from each other.\n\n[__Essentials__](https://github.com/greenrobot/essentials) is a set of utility classes and hash functions for Android & Java projects.\n"
  },
  {
    "path": "build.gradle",
    "content": "// Sub projects may reference rootProject.version\nversion = '3.3.0'\n\nwrapper {\n    distributionType = Wrapper.DistributionType.ALL\n}\n\next {\n    compileSdkVersion = 29\n\n    minSdkVersion = 7\n    targetSdkVersion = 25\n\n    // common dependencies for Android projects (not to be used in example projects for better copy and paste)\n    dep = [\n            androidPlugin: 'com.android.tools.build:gradle:3.5.3',\n\n            // Used only in tests, should point to the latest *published* version (not relevant to publishing)\n            greendaoPlugin: 'org.greenrobot:greendao-gradle-plugin:3.3.1'\n    ]\n}\n\nif (JavaVersion.current().isJava8Compatible()) {\n    allprojects {\n        tasks.withType(Javadoc) {\n            options.addStringOption('Xdoclint:none', '-quiet')\n        }\n    }\n}\n\nsubprojects {\n    repositories {\n        mavenCentral()\n        jcenter()\n        google()\n    }\n}\n"
  },
  {
    "path": "examples/DaoExample/build.gradle",
    "content": "buildscript {\n    repositories {\n        jcenter()\n        google()\n        mavenCentral()\n    }\n\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.5.3'\n        classpath(\"org.greenrobot:greendao-gradle-plugin:3.3.1\")\n    }\n}\n\napply plugin: 'com.android.application'\napply plugin: 'org.greenrobot.greendao'\n\nandroid {\n    compileSdkVersion 29\n\n    // To use deprecated test classes on SDK 28+. https://developer.android.com/training/testing/set-up-project\n    useLibrary 'android.test.runner'\n    useLibrary 'android.test.base'\n\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n\n    defaultConfig {\n        applicationId \"org.greenrobot.greendao.example\"\n        minSdkVersion 15\n        targetSdkVersion 29\n        versionCode 1\n        versionName \"3\"\n\n        testInstrumentationRunner \"android.test.InstrumentationTestRunner\"\n    }\n}\n\ngreendao {\n    schemaVersion 1000\n}\n\ndependencies {\n    implementation 'org.greenrobot:greendao:3.3.0'\n\n    // optional: add if you want to use encrypted databases, see the App class for details\n    // implementation 'net.zetetic:android-database-sqlcipher:3.5.6'\n\n    implementation 'androidx.appcompat:appcompat:1.1.0'\n    implementation 'androidx.recyclerview:recyclerview:1.1.0'\n}\n\nuploadArchives.enabled = false\n"
  },
  {
    "path": "examples/DaoExample/src/androidTest/java/org/greenrobot/greendao/example/NoteTest.java",
    "content": "/*\n * Copyright (C) 2011 Markus Junginger, greenrobot (http://greenrobot.de)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.example;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\n\npublic class NoteTest extends AbstractDaoTestLongPk<NoteDao, Note> {\n\n    public NoteTest() {\n        super(NoteDao.class);\n    }\n\n    @Override\n    protected Note createEntity(Long key) {\n        Note entity = new Note();\n        entity.setId(key);\n        entity.setText(\"green note\"); // Has to be set as it is \"not null\"\n        return entity;\n    }\n\n}\n"
  },
  {
    "path": "examples/DaoExample/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"org.greenrobot.greendao.example\">\n\n    <application\n        android:name=\".App\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".NoteActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "examples/DaoExample/src/main/java/org/greenrobot/greendao/example/App.java",
    "content": "package org.greenrobot.greendao.example;\n\nimport android.app.Application;\nimport android.content.Context;\n\nimport org.greenrobot.greendao.database.Database;\n\npublic class App extends Application {\n\n    private DaoSession daoSession;\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n\n        // regular SQLite database\n        ExampleOpenHelper helper = new ExampleOpenHelper(this, \"notes-db\");\n        Database db = helper.getWritableDb();\n\n        // encrypted SQLCipher database\n        // note: you need to add SQLCipher to your dependencies, check the build.gradle file\n        // ExampleOpenHelper helper = new ExampleOpenHelper(this, \"notes-db-encrypted\");\n        // Database db = helper.getEncryptedWritableDb(\"encryption-key\");\n\n        daoSession = new DaoMaster(db).newSession();\n    }\n\n    public DaoSession getDaoSession() {\n        return daoSession;\n    }\n\n    public static class ExampleOpenHelper extends DaoMaster.OpenHelper {\n\n        public ExampleOpenHelper(Context context, String name) {\n            super(context, name);\n        }\n\n        @Override\n        public void onCreate(Database db) {\n            super.onCreate(db);\n\n            // Insert some example data.\n            // INSERT INTO NOTE (_id, DATE, TEXT) VALUES(1, 0, 'Example Note')\n            db.execSQL(\"INSERT INTO \" + NoteDao.TABLENAME + \" (\" +\n                    NoteDao.Properties.Id.columnName + \", \" +\n                    NoteDao.Properties.Date.columnName + \", \" +\n                    NoteDao.Properties.Text.columnName +\n                    \") VALUES(1, 0, 'Example Note')\");\n        }\n    }\n}\n"
  },
  {
    "path": "examples/DaoExample/src/main/java/org/greenrobot/greendao/example/Note.java",
    "content": "package org.greenrobot.greendao.example;\n\nimport org.greenrobot.greendao.annotation.Convert;\nimport org.greenrobot.greendao.annotation.Entity;\nimport org.greenrobot.greendao.annotation.Generated;\nimport org.greenrobot.greendao.annotation.Id;\nimport org.greenrobot.greendao.annotation.Index;\nimport org.greenrobot.greendao.annotation.NotNull;\n\n/**\n * Entity mapped to table \"NOTE\".\n */\n@Entity(indexes = {\n    @Index(value = \"text, date DESC\", unique = true)\n})\npublic class Note {\n\n    @Id\n    private Long id;\n\n    @NotNull\n    private String text;\n    private String comment;\n    private java.util.Date date;\n\n    @Convert(converter = NoteTypeConverter.class, columnType = String.class)\n    private NoteType type;\n\n    @Generated(hash = 1272611929)\n    public Note() {\n    }\n\n    public Note(Long id) {\n        this.id = id;\n    }\n\n    @Generated(hash = 1686394253)\n    public Note(Long id, @NotNull String text, String comment, java.util.Date date, NoteType type) {\n        this.id = id;\n        this.text = text;\n        this.comment = comment;\n        this.date = date;\n        this.type = type;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    @NotNull\n    public String getText() {\n        return text;\n    }\n\n    /** Not-null value; ensure this value is available before it is saved to the database. */\n    public void setText(@NotNull String text) {\n        this.text = text;\n    }\n\n    public String getComment() {\n        return comment;\n    }\n\n    public void setComment(String comment) {\n        this.comment = comment;\n    }\n\n    public java.util.Date getDate() {\n        return date;\n    }\n\n    public void setDate(java.util.Date date) {\n        this.date = date;\n    }\n\n    public NoteType getType() {\n        return type;\n    }\n\n    public void setType(NoteType type) {\n        this.type = type;\n    }\n\n}\n"
  },
  {
    "path": "examples/DaoExample/src/main/java/org/greenrobot/greendao/example/NoteActivity.java",
    "content": "/*\n * Copyright (C) 2011 Markus Junginger, greenrobot (http://greenrobot.de)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.example;\n\nimport android.os.Bundle;\nimport android.text.Editable;\nimport android.text.TextWatcher;\nimport android.util.Log;\nimport android.view.View;\nimport android.view.inputmethod.EditorInfo;\nimport android.widget.EditText;\n\nimport org.greenrobot.greendao.query.Query;\n\nimport java.text.DateFormat;\nimport java.util.Date;\nimport java.util.List;\n\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\n\npublic class NoteActivity extends AppCompatActivity {\n\n    private EditText editText;\n    private View addNoteButton;\n\n    private NoteDao noteDao;\n    private Query<Note> notesQuery;\n    private NotesAdapter notesAdapter;\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.main);\n\n        setUpViews();\n\n        // get the note DAO\n        DaoSession daoSession = ((App) getApplication()).getDaoSession();\n        noteDao = daoSession.getNoteDao();\n\n        // query all notes, sorted a-z by their text\n        notesQuery = noteDao.queryBuilder().orderAsc(NoteDao.Properties.Text).build();\n        updateNotes();\n    }\n\n    private void updateNotes() {\n        List<Note> notes = notesQuery.list();\n        notesAdapter.setNotes(notes);\n    }\n\n    protected void setUpViews() {\n        RecyclerView recyclerView = findViewById(R.id.recyclerViewNotes);\n        recyclerView.setHasFixedSize(true);\n        recyclerView.setLayoutManager(new LinearLayoutManager(this));\n\n        notesAdapter = new NotesAdapter(noteClickListener);\n        recyclerView.setAdapter(notesAdapter);\n\n        addNoteButton = findViewById(R.id.buttonAdd);\n        addNoteButton.setEnabled(false);\n\n        editText = findViewById(R.id.editTextNote);\n        editText.setOnEditorActionListener((v, actionId, event) -> {\n            if (actionId == EditorInfo.IME_ACTION_DONE) {\n                addNote();\n                return true;\n            }\n            return false;\n        });\n        editText.addTextChangedListener(new TextWatcher() {\n\n            @Override\n            public void onTextChanged(CharSequence s, int start, int before, int count) {\n                boolean enable = s.length() != 0;\n                addNoteButton.setEnabled(enable);\n            }\n\n            @Override\n            public void beforeTextChanged(CharSequence s, int start, int count, int after) {\n            }\n\n            @Override\n            public void afterTextChanged(Editable s) {\n            }\n        });\n    }\n\n    public void onAddButtonClick(View view) {\n        addNote();\n    }\n\n    private void addNote() {\n        String noteText = editText.getText().toString();\n        editText.setText(\"\");\n\n        final DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);\n        String comment = \"Added on \" + df.format(new Date());\n\n        Note note = new Note();\n        note.setText(noteText);\n        note.setComment(comment);\n        note.setDate(new Date());\n        note.setType(NoteType.TEXT);\n        noteDao.insert(note);\n        Log.d(\"DaoExample\", \"Inserted new note, ID: \" + note.getId());\n\n        updateNotes();\n    }\n\n    NotesAdapter.NoteClickListener noteClickListener = new NotesAdapter.NoteClickListener() {\n        @Override\n        public void onNoteClick(int position) {\n            Note note = notesAdapter.getNote(position);\n            Long noteId = note.getId();\n\n            noteDao.deleteByKey(noteId);\n            Log.d(\"DaoExample\", \"Deleted note, ID: \" + noteId);\n\n            updateNotes();\n        }\n    };\n}"
  },
  {
    "path": "examples/DaoExample/src/main/java/org/greenrobot/greendao/example/NoteType.java",
    "content": "package org.greenrobot.greendao.example;\n\npublic enum NoteType {\n    TEXT, LIST, PICTURE\n}\n"
  },
  {
    "path": "examples/DaoExample/src/main/java/org/greenrobot/greendao/example/NoteTypeConverter.java",
    "content": "package org.greenrobot.greendao.example;\n\nimport org.greenrobot.greendao.converter.PropertyConverter;\n\npublic class NoteTypeConverter implements PropertyConverter<NoteType, String> {\n    @Override\n    public NoteType convertToEntityProperty(String databaseValue) {\n        return NoteType.valueOf(databaseValue);\n    }\n\n    @Override\n    public String convertToDatabaseValue(NoteType entityProperty) {\n        return entityProperty.name();\n    }\n}\n"
  },
  {
    "path": "examples/DaoExample/src/main/java/org/greenrobot/greendao/example/NotesAdapter.java",
    "content": "package org.greenrobot.greendao.example;\n\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.TextView;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport androidx.annotation.NonNull;\nimport androidx.recyclerview.widget.RecyclerView;\n\npublic class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.NoteViewHolder> {\n\n    private NoteClickListener clickListener;\n    private List<Note> dataset;\n\n    public interface NoteClickListener {\n        void onNoteClick(int position);\n    }\n\n    static class NoteViewHolder extends RecyclerView.ViewHolder {\n\n        public TextView text;\n        public TextView comment;\n\n        public NoteViewHolder(View itemView, final NoteClickListener clickListener) {\n            super(itemView);\n            text = itemView.findViewById(R.id.textViewNoteText);\n            comment = itemView.findViewById(R.id.textViewNoteComment);\n            itemView.setOnClickListener(view -> {\n                if (clickListener != null) {\n                    clickListener.onNoteClick(getAdapterPosition());\n                }\n            });\n        }\n    }\n\n    public NotesAdapter(NoteClickListener clickListener) {\n        this.clickListener = clickListener;\n        this.dataset = new ArrayList<>();\n    }\n\n    public void setNotes(@NonNull List<Note> notes) {\n        dataset = notes;\n        notifyDataSetChanged();\n    }\n\n    public Note getNote(int position) {\n        return dataset.get(position);\n    }\n\n    @NonNull\n    @Override\n    public NotesAdapter.NoteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {\n        View view = LayoutInflater.from(parent.getContext())\n                .inflate(R.layout.item_note, parent, false);\n        return new NoteViewHolder(view, clickListener);\n    }\n\n    @Override\n    public void onBindViewHolder(NotesAdapter.NoteViewHolder holder, int position) {\n        Note note = dataset.get(position);\n        holder.text.setText(note.getText());\n        holder.comment.setText(note.getComment());\n    }\n\n    @Override\n    public int getItemCount() {\n        return dataset.size();\n    }\n}\n"
  },
  {
    "path": "examples/DaoExample/src/main/res/layout/item_note.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"?android:attr/selectableItemBackground\"\n    android:orientation=\"vertical\"\n    android:padding=\"16dp\">\n\n    <TextView\n        android:id=\"@+id/textViewNoteText\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:textSize=\"14sp\"\n        tools:text=\"Note Text\" />\n\n    <TextView\n        android:id=\"@+id/textViewNoteComment\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:textSize=\"12sp\"\n        tools:text=\"Note Comment\" />\n\n</LinearLayout>"
  },
  {
    "path": "examples/DaoExample/src/main/res/layout/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                xmlns:tools=\"http://schemas.android.com/tools\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:paddingBottom=\"@dimen/activity_vertical_margin\"\n                android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                android:paddingRight=\"@dimen/activity_horizontal_margin\"\n                android:paddingTop=\"@dimen/activity_vertical_margin\"\n                tools:context=\"org.greenrobot.greendao.example.NoteActivity\"\n                tools:ignore=\"RtlHardcoded\">\n\n    <Button\n        android:id=\"@+id/buttonAdd\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentRight=\"true\"\n        android:onClick=\"onAddButtonClick\"\n        android:text=\"@string/add\"/>\n\n    <EditText\n        android:id=\"@+id/editTextNote\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_toLeftOf=\"@id/buttonAdd\"\n        android:hint=\"@string/enter_new_note\"\n        android:imeOptions=\"actionDone\"\n        android:inputType=\"text\"/>\n\n    <TextView\n        android:id=\"@+id/textViewNoteInstructions\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_below=\"@id/editTextNote\"\n        android:gravity=\"center_horizontal\"\n        android:paddingBottom=\"8dp\"\n        android:paddingLeft=\"8dp\"\n        android:paddingRight=\"8dp\"\n        android:text=\"@string/click_to_remove\"\n        android:textSize=\"12sp\"/>\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/recyclerViewNotes\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_below=\"@id/textViewNoteInstructions\"\n        android:scrollbars=\"vertical\"/>\n\n</RelativeLayout>\n"
  },
  {
    "path": "examples/DaoExample/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#7FCD55</color>\n</resources>\n"
  },
  {
    "path": "examples/DaoExample/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n</resources>\n"
  },
  {
    "path": "examples/DaoExample/src/main/res/values/strings.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n\n    <string name=\"app_name\">greenDAO Note Example</string>\n\n    <string name=\"enter_new_note\">Enter new note</string>\n    <string name=\"add\">Add</string>\n    <string name=\"click_to_remove\">Click a note to remove it</string>\n\n</resources>\n"
  },
  {
    "path": "examples/DaoExample/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "examples/RxDaoExample/build.gradle",
    "content": "buildscript {\n    repositories {\n        jcenter()\n        google()\n        mavenCentral()\n    }\n\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.5.3'\n        classpath 'org.greenrobot:greendao-gradle-plugin:3.3.1'\n    }\n}\n\napply plugin: 'com.android.application'\napply plugin: 'org.greenrobot.greendao'\n\nandroid {\n    compileSdkVersion 29\n\n    compileOptions {\n        sourceCompatibility JavaVersion.VERSION_1_8\n        targetCompatibility JavaVersion.VERSION_1_8\n    }\n\n    defaultConfig {\n        applicationId \"org.greenrobot.greendao.rxexample\"\n        minSdkVersion 15\n        targetSdkVersion 29\n        versionCode 1\n        versionName \"1.0\"\n    }\n}\n\ngreendao {\n    schemaVersion 1000\n}\n\ndependencies {\n    implementation 'org.greenrobot:greendao:3.3.0'\n\n    // optional: add if you want to use encrypted databases, see the App class for details\n    // implementation 'net.zetetic:android-database-sqlcipher:3.5.6'\n\n    implementation 'com.jakewharton.rxbinding:rxbinding:1.0.1'\n    implementation 'io.reactivex:rxandroid:1.2.1'\n    implementation 'io.reactivex:rxjava:1.3.0'\n\n    implementation 'androidx.appcompat:appcompat:1.1.0'\n    implementation 'androidx.recyclerview:recyclerview:1.1.0'\n}\n\nuploadArchives.enabled = false\n"
  },
  {
    "path": "examples/RxDaoExample/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"org.greenrobot.greendao.rxexample\">\n\n    <application\n        android:name=\".App\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/AppTheme\">\n        <activity android:name=\".MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n    </application>\n\n</manifest>"
  },
  {
    "path": "examples/RxDaoExample/src/main/java/org/greenrobot/greendao/rxexample/App.java",
    "content": "package org.greenrobot.greendao.rxexample;\n\nimport android.app.Application;\nimport android.content.Context;\n\nimport org.greenrobot.greendao.database.Database;\n\npublic class App extends Application {\n\n    private DaoSession daoSession;\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n\n        // regular SQLite database\n        ExampleOpenHelper helper = new ExampleOpenHelper(this, \"notes-db\");\n        Database db = helper.getWritableDb();\n\n        // encrypted SQLCipher database\n        // note: you need to add SQLCipher to your dependencies, check the build.gradle file\n        // ExampleOpenHelper helper = new ExampleOpenHelper(this, \"notes-db-encrypted\");\n        // Database db = helper.getEncryptedWritableDb(\"encryption-key\");\n\n        daoSession = new DaoMaster(db).newSession();\n    }\n\n    public DaoSession getDaoSession() {\n        return daoSession;\n    }\n\n    public static class ExampleOpenHelper extends DaoMaster.OpenHelper {\n\n        public ExampleOpenHelper(Context context, String name) {\n            super(context, name);\n        }\n\n        @Override\n        public void onCreate(Database db) {\n            super.onCreate(db);\n\n            // Insert some example data.\n            // INSERT INTO NOTE (_id, DATE, TEXT) VALUES(1, 0, 'Example Note')\n            db.execSQL(\"INSERT INTO \" + NoteDao.TABLENAME + \" (\" +\n                    NoteDao.Properties.Id.columnName + \", \" +\n                    NoteDao.Properties.Date.columnName + \", \" +\n                    NoteDao.Properties.Text.columnName +\n                    \") VALUES(1, 0, 'Example Note')\");\n        }\n    }\n}\n"
  },
  {
    "path": "examples/RxDaoExample/src/main/java/org/greenrobot/greendao/rxexample/MainActivity.java",
    "content": "package org.greenrobot.greendao.rxexample;\n\nimport android.os.Bundle;\nimport android.util.Log;\nimport android.view.View;\nimport android.view.inputmethod.EditorInfo;\nimport android.widget.EditText;\n\nimport com.jakewharton.rxbinding.widget.RxTextView;\n\nimport org.greenrobot.greendao.rx.RxDao;\nimport org.greenrobot.greendao.rx.RxQuery;\n\nimport java.text.DateFormat;\nimport java.util.Date;\n\nimport androidx.appcompat.app.AppCompatActivity;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\nimport rx.android.schedulers.AndroidSchedulers;\n\npublic class MainActivity extends AppCompatActivity {\n\n    private EditText editText;\n    private View addNoteButton;\n\n    private RxDao<Note, Long> noteDao;\n    private RxQuery<Note> notesQuery;\n    private NotesAdapter notesAdapter;\n\n    @Override\n    public void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n\n        setUpViews();\n\n        // get the Rx variant of the note DAO\n        DaoSession daoSession = ((App) getApplication()).getDaoSession();\n        noteDao = daoSession.getNoteDao().rx();\n\n        // query all notes, sorted a-z by their text\n        notesQuery = daoSession.getNoteDao().queryBuilder().orderAsc(NoteDao.Properties.Text).rx();\n        updateNotes();\n    }\n\n    private void updateNotes() {\n        notesQuery.list()\n                .observeOn(AndroidSchedulers.mainThread())\n                .subscribe(notes -> notesAdapter.setNotes(notes));\n    }\n\n    protected void setUpViews() {\n        RecyclerView recyclerView = findViewById(R.id.recyclerViewNotes);\n        recyclerView.setHasFixedSize(true);\n        recyclerView.setLayoutManager(new LinearLayoutManager(this));\n\n        notesAdapter = new NotesAdapter(noteClickListener);\n        recyclerView.setAdapter(notesAdapter);\n\n        addNoteButton = findViewById(R.id.buttonAdd);\n\n        editText = findViewById(R.id.editTextNote);\n        RxTextView.editorActions(editText).observeOn(AndroidSchedulers.mainThread())\n                .subscribe(actionId -> {\n                    if (actionId == EditorInfo.IME_ACTION_DONE) {\n                        addNote();\n                    }\n                });\n        RxTextView.afterTextChangeEvents(editText).observeOn(AndroidSchedulers.mainThread())\n                .subscribe(textViewAfterTextChangeEvent -> {\n                    boolean enable = textViewAfterTextChangeEvent.editable().length() > 0;\n                    addNoteButton.setEnabled(enable);\n                });\n    }\n\n    public void onAddButtonClick(View view) {\n        addNote();\n    }\n\n    private void addNote() {\n        String noteText = editText.getText().toString();\n        editText.setText(\"\");\n\n        final DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM);\n        String comment = \"Added on \" + df.format(new Date());\n\n        Note note = new Note(null, noteText, comment, new Date(), NoteType.TEXT);\n        noteDao.insert(note)\n                .observeOn(AndroidSchedulers.mainThread())\n                .subscribe(note1 -> {\n                    Log.d(\"DaoExample\", \"Inserted new note, ID: \" + note1.getId());\n                    updateNotes();\n                });\n    }\n\n    NotesAdapter.NoteClickListener noteClickListener = new NotesAdapter.NoteClickListener() {\n        @Override\n        public void onNoteClick(int position) {\n            Note note = notesAdapter.getNote(position);\n            final Long noteId = note.getId();\n\n            noteDao.deleteByKey(noteId)\n                    .observeOn(AndroidSchedulers.mainThread())\n                    .subscribe(aVoid -> {\n                        Log.d(\"DaoExample\", \"Deleted note, ID: \" + noteId);\n                        updateNotes();\n                    });\n        }\n    };\n}\n"
  },
  {
    "path": "examples/RxDaoExample/src/main/java/org/greenrobot/greendao/rxexample/Note.java",
    "content": "package org.greenrobot.greendao.rxexample;\n\nimport org.greenrobot.greendao.annotation.Convert;\nimport org.greenrobot.greendao.annotation.Entity;\nimport org.greenrobot.greendao.annotation.Generated;\nimport org.greenrobot.greendao.annotation.Id;\nimport org.greenrobot.greendao.annotation.Index;\nimport org.greenrobot.greendao.annotation.NotNull;\n\n/**\n * Entity mapped to table \"NOTE\".\n */\n@Entity(indexes = {\n    @Index(value = \"text, date DESC\", unique = true)\n})\npublic class Note {\n\n    @Id\n    private Long id;\n\n    @NotNull\n    private String text;\n    private String comment;\n    private java.util.Date date;\n\n    @Convert(converter = NoteTypeConverter.class, columnType = String.class)\n    private NoteType type;\n\n    @Generated(hash = 1272611929)\n    public Note() {\n    }\n\n    public Note(Long id) {\n        this.id = id;\n    }\n\n    @Generated(hash = 1686394253)\n    public Note(Long id, @NotNull String text, String comment, java.util.Date date, NoteType type) {\n        this.id = id;\n        this.text = text;\n        this.comment = comment;\n        this.date = date;\n        this.type = type;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    @NotNull\n    public String getText() {\n        return text;\n    }\n\n    /** Not-null value; ensure this value is available before it is saved to the database. */\n    public void setText(@NotNull String text) {\n        this.text = text;\n    }\n\n    public String getComment() {\n        return comment;\n    }\n\n    public void setComment(String comment) {\n        this.comment = comment;\n    }\n\n    public java.util.Date getDate() {\n        return date;\n    }\n\n    public void setDate(java.util.Date date) {\n        this.date = date;\n    }\n\n    public NoteType getType() {\n        return type;\n    }\n\n    public void setType(NoteType type) {\n        this.type = type;\n    }\n\n}\n"
  },
  {
    "path": "examples/RxDaoExample/src/main/java/org/greenrobot/greendao/rxexample/NoteType.java",
    "content": "package org.greenrobot.greendao.rxexample;\n\npublic enum NoteType {\n    TEXT, LIST, PICTURE\n}\n"
  },
  {
    "path": "examples/RxDaoExample/src/main/java/org/greenrobot/greendao/rxexample/NoteTypeConverter.java",
    "content": "package org.greenrobot.greendao.rxexample;\n\nimport org.greenrobot.greendao.converter.PropertyConverter;\n\npublic class NoteTypeConverter implements PropertyConverter<NoteType, String> {\n    @Override\n    public NoteType convertToEntityProperty(String databaseValue) {\n        return NoteType.valueOf(databaseValue);\n    }\n\n    @Override\n    public String convertToDatabaseValue(NoteType entityProperty) {\n        return entityProperty.name();\n    }\n}\n"
  },
  {
    "path": "examples/RxDaoExample/src/main/java/org/greenrobot/greendao/rxexample/NotesAdapter.java",
    "content": "package org.greenrobot.greendao.rxexample;\n\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.TextView;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport androidx.annotation.NonNull;\nimport androidx.recyclerview.widget.RecyclerView;\n\npublic class NotesAdapter extends RecyclerView.Adapter<NotesAdapter.NoteViewHolder> {\n\n    private NoteClickListener clickListener;\n    private List<Note> dataset;\n\n    public interface NoteClickListener {\n        void onNoteClick(int position);\n    }\n\n    static class NoteViewHolder extends RecyclerView.ViewHolder {\n\n        public TextView text;\n        public TextView comment;\n\n        public NoteViewHolder(View itemView, final NoteClickListener clickListener) {\n            super(itemView);\n            text = itemView.findViewById(R.id.textViewNoteText);\n            comment = itemView.findViewById(R.id.textViewNoteComment);\n            itemView.setOnClickListener(view -> {\n                if (clickListener != null) {\n                    clickListener.onNoteClick(getAdapterPosition());\n                }\n            });\n        }\n    }\n\n    public NotesAdapter(NoteClickListener clickListener) {\n        this.clickListener = clickListener;\n        this.dataset = new ArrayList<>();\n    }\n\n    public void setNotes(@NonNull List<Note> notes) {\n        dataset = notes;\n        notifyDataSetChanged();\n    }\n\n    public Note getNote(int position) {\n        return dataset.get(position);\n    }\n\n    @NonNull\n    @Override\n    public NotesAdapter.NoteViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {\n        View view = LayoutInflater.from(parent.getContext())\n                .inflate(R.layout.item_note, parent, false);\n        return new NoteViewHolder(view, clickListener);\n    }\n\n    @Override\n    public void onBindViewHolder(NotesAdapter.NoteViewHolder holder, int position) {\n        Note note = dataset.get(position);\n        holder.text.setText(note.getText());\n        holder.comment.setText(note.getComment());\n    }\n\n    @Override\n    public int getItemCount() {\n        return dataset.size();\n    }\n}\n"
  },
  {
    "path": "examples/RxDaoExample/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<RelativeLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n                xmlns:tools=\"http://schemas.android.com/tools\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"match_parent\"\n                android:paddingBottom=\"@dimen/activity_vertical_margin\"\n                android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n                android:paddingRight=\"@dimen/activity_horizontal_margin\"\n                android:paddingTop=\"@dimen/activity_vertical_margin\"\n                tools:context=\"org.greenrobot.greendao.rxexample.MainActivity\"\n                tools:ignore=\"RtlHardcoded\">\n\n    <Button\n        android:id=\"@+id/buttonAdd\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_alignParentRight=\"true\"\n        android:onClick=\"onAddButtonClick\"\n        android:text=\"@string/add\"/>\n\n    <EditText\n        android:id=\"@+id/editTextNote\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_toLeftOf=\"@id/buttonAdd\"\n        android:hint=\"@string/enter_new_note\"\n        android:imeOptions=\"actionDone\"\n        android:inputType=\"text\"/>\n\n    <TextView\n        android:id=\"@+id/textViewNoteInstructions\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_below=\"@id/editTextNote\"\n        android:gravity=\"center_horizontal\"\n        android:paddingBottom=\"8dp\"\n        android:paddingLeft=\"8dp\"\n        android:paddingRight=\"8dp\"\n        android:text=\"@string/click_to_remove\"\n        android:textSize=\"12sp\"/>\n\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/recyclerViewNotes\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_below=\"@id/textViewNoteInstructions\"\n        android:scrollbars=\"vertical\"/>\n\n</RelativeLayout>\n"
  },
  {
    "path": "examples/RxDaoExample/src/main/res/layout/item_note.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:background=\"?android:attr/selectableItemBackground\"\n    android:orientation=\"vertical\"\n    android:padding=\"16dp\">\n\n    <TextView\n        android:id=\"@+id/textViewNoteText\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:textSize=\"14sp\"\n        tools:text=\"Note Text\" />\n\n    <TextView\n        android:id=\"@+id/textViewNoteComment\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:textSize=\"12sp\"\n        tools:text=\"Note Comment\" />\n\n</LinearLayout>"
  },
  {
    "path": "examples/RxDaoExample/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#7FCD55</color>\n</resources>\n"
  },
  {
    "path": "examples/RxDaoExample/src/main/res/values/dimens.xml",
    "content": "<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n</resources>\n"
  },
  {
    "path": "examples/RxDaoExample/src/main/res/values/strings.xml",
    "content": "<resources>\n\n    <string name=\"app_name\">greenDAO Rx Note Example</string>\n\n    <string name=\"enter_new_note\">Enter new note</string>\n    <string name=\"add\">Add</string>\n    <string name=\"click_to_remove\">Click a note to remove it</string>\n\n</resources>\n"
  },
  {
    "path": "examples/RxDaoExample/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "gradle/publish.gradle",
    "content": "// Configures common publishing settings\n\napply plugin: \"maven\"\napply plugin: \"signing\"\n\nconfigurations {\n    deployerJars\n}\n\ndependencies {\n    // Using an older version to remain compatible with Wagon API used by Gradle/Maven\n    deployerJars 'org.apache.maven.wagon:wagon-webdav-jackrabbit:3.2.0'\n    deployerJars 'org.apache.maven.wagon:wagon-ftp:3.3.2'\n}\n\njavadoc {\n    if(JavaVersion.current().isJava8Compatible()) {\n        options.addStringOption('Xdoclint:none', '-quiet')\n    }\n}\n\nsigning {\n    if (project.hasProperty('signing.keyId') && project.hasProperty('signing.password') &&\n            project.hasProperty('signing.secretKeyRingFile')) {\n        sign configurations.archives\n    } else {\n        println \"Signing information missing/incomplete for ${project.name}\"\n    }\n}\n\n// Use afterEvaluate or dependencies might be lost in the generated POM\nafterEvaluate { project ->\n    uploadArchives {\n        repositories {\n            mavenDeployer {\n                def preferredRepo = project.findProperty('preferredRepo')\n                println \"preferredRepo=$preferredRepo\"\n\n                if (preferredRepo == 'local') {\n                    repository url: repositories.mavenLocal().url\n                } else if (preferredRepo != null\n                        && project.hasProperty('preferredUsername')\n                        && project.hasProperty('preferredPassword')) {\n                    configuration = configurations.deployerJars\n                    // replace placeholders\n                    def repositoryUrl = preferredRepo\n                            .replace('__groupId__', project.group)\n                            .replace('__artifactId__', project.archivesBaseName)\n                    repository(url: repositoryUrl) {\n                        authentication(userName: preferredUsername, password: preferredPassword)\n                    }\n                } else if (project.hasProperty('sonatypeUsername')\n                        && project.hasProperty('sonatypePassword')) {\n                    beforeDeployment { MavenDeployment deployment -> signing.signPom(deployment) }\n                    def isSnapshot = version.endsWith('-SNAPSHOT')\n                    def sonatypeRepositoryUrl = isSnapshot ?\n                            \"https://oss.sonatype.org/content/repositories/snapshots/\"\n                            : \"https://oss.sonatype.org/service/local/staging/deploy/maven2/\"\n                    repository(url: sonatypeRepositoryUrl) {\n                        authentication(userName: sonatypeUsername, password: sonatypePassword)\n                    }\n                } else {\n                    println \"Deployment settings missing/incomplete for ${project.name}.\"\n                }\n\n                // Common properties, projects still need to set name, description and license\n                pom.project {\n                    packaging 'jar'\n                    url 'https://github.com/greenrobot/greenDAO'\n\n                    scm {\n                        url 'https://github.com/greenrobot/greenDAO'\n                        connection 'scm:git@github.com:greenrobot/greenDAO.git'\n                        developerConnection 'scm:git@github.com:greenrobot/greenDAO.git'\n                    }\n\n                    developers {\n                        developer {\n                            id 'greenrobot'\n                            name 'greenrobot'\n                        }\n                    }\n\n                    issueManagement {\n                        system 'GitHub Issues'\n                        url 'https://github.com/greenrobot/greenDAO/issues'\n                    }\n\n                    organization {\n                        name 'greenrobot'\n                        url 'https://greenrobot.org'\n                    }\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "distributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-5.6.4-all.zip\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\n"
  },
  {
    "path": "gradle.properties",
    "content": "## For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n#\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\n# Default value: -Xmx1024m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\n#\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n#Tue Jan 28 11:11:04 CET 2020\norg.gradle.jvmargs=-Xmx1536M\n\nandroid.enableJetifier=true\nandroid.useAndroidX=true\n\n# TODO Update Robolectric to latest 4.x and remove this.\nandroid.enableUnitTestBinaryResources=false\n"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n#      https://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS='\"-Xmx64m\" \"-Xms64m\"'\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn () {\n    echo \"$*\"\n}\n\ndie () {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\nnonstop=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\n  NONSTOP* )\n    nonstop=true\n    ;;\nesac\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" -a \"$nonstop\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin or MSYS, switch paths to Windows format before running java\nif [ \"$cygwin\" = \"true\" -o \"$msys\" = \"true\" ] ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Escape application args\nsave () {\n    for i do printf %s\\\\n \"$i\" | sed \"s/'/'\\\\\\\\''/g;1s/^/'/;\\$s/\\$/' \\\\\\\\/\" ; done\n    echo \" \"\n}\nAPP_ARGS=$(save \"$@\")\n\n# Collect all arguments for the java command, following the shell quoting and substitution rules\neval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS \"\\\"-Dorg.gradle.appname=$APP_BASE_NAME\\\"\" -classpath \"\\\"$CLASSPATH\\\"\" org.gradle.wrapper.GradleWrapperMain \"$APP_ARGS\"\n\n# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong\nif [ \"$(uname)\" = \"Darwin\" ] && [ \"$HOME\" = \"$PWD\" ]; then\n  cd \"$(dirname \"$0\")\"\nfi\n\nexec \"$JAVACMD\" \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@rem\n@rem Copyright 2015 the original author or authors.\n@rem\n@rem Licensed under the Apache License, Version 2.0 (the \"License\");\n@rem you may not use this file except in compliance with the License.\n@rem You may obtain a copy of the License at\n@rem\n@rem      https://www.apache.org/licenses/LICENSE-2.0\n@rem\n@rem Unless required by applicable law or agreed to in writing, software\n@rem distributed under the License is distributed on an \"AS IS\" BASIS,\n@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n@rem See the License for the specific language governing permissions and\n@rem limitations under the License.\n@rem\n\n@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\"-Xmx64m\" \"-Xms64m\"\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windows variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "greendao-api/LICENSE",
    "content": "\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "greendao-api/NOTICE",
    "content": "greenrobot greenDAO (c) Copyright 2011-2016 by Markus Junginger / greenrobot.org\nAll rights reserved\n\nThis product includes software developed at greenrobot.org"
  },
  {
    "path": "greendao-api/build.gradle",
    "content": "apply plugin: 'java'\n\ngroup = 'org.greenrobot'\nversion = rootProject.version\n\nsourceCompatibility = 1.7\ntargetCompatibility = 1.7\n\napply from: rootProject.file(\"gradle/publish.gradle\")\n\njavadoc {\n    failOnError = false\n    title = \" greenDAO API ${version} API\"\n    options.bottom = 'Available under the Apache License, Version 2.0 - <i>Copyright &#169; 2011-2020 <a href=\"http://greenrobot.org/\">greenrobot.org</a>. All Rights Reserved.</i>'\n    doLast {\n        copy {\n            from '../javadoc-style'\n            into \"build/docs/javadoc/\"\n        }\n    }\n}\n\ntask javadocJar(type: Jar, dependsOn: javadoc) {\n    classifier = 'javadoc'\n    from 'build/docs/javadoc'\n}\n\ntask sourcesJar(type: Jar) {\n    from sourceSets.main.allSource\n    classifier = 'sources'\n}\n\nartifacts {\n    // jar added by Java plugin.\n    archives javadocJar\n    archives sourcesJar\n}\n\nuploadArchives {\n    repositories {\n        mavenDeployer {\n            // Basic definitions are defined in root project\n            pom.project {\n                name 'greenDAO API'\n                description 'greenDAO is a light and fast ORM for Android'\n\n                licenses {\n                    license {\n                        name 'The Apache Software License, Version 2.0'\n                        url 'http://www.apache.org/licenses/LICENSE-2.0.txt'\n                        distribution 'repo'\n                    }\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/Convert.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport org.greenrobot.greendao.converter.PropertyConverter;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Specifies {@link PropertyConverter} for the field to support custom types\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target(ElementType.FIELD)\npublic @interface Convert {\n    /** Converter class */\n    Class<? extends PropertyConverter> converter();\n\n    /**\n     * Class of the column which can be persisted in DB.\n     * This is limited to all java classes which are supported natively by greenDAO.\n     */\n    Class columnType();\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/Entity.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Annotation for entities\n * greenDAO only persist objects of classes which are marked with this annotation\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target(ElementType.TYPE)\npublic @interface Entity {\n\n    /**\n     * Specifies the name on the DB side (e.g. table name) this entity maps to. By default, the name is based on the entities class name.\n     */\n    String nameInDb() default \"\";\n\n    /**\n     * Indexes for the entity.\n     * <p/>\n     * Note: To create a single-column index consider using {@link Index} on the property itself\n     */\n    Index[] indexes() default {};\n\n    /**\n     * Advanced flag to disable table creation in the database (when set to false). This can be used to create partial\n     * entities, which may use only a sub set of properties. Be aware however that greenDAO does not sync multiple\n     * entities, e.g. in caches.\n     */\n    boolean createInDb() default true;\n\n    /**\n     * Specifies schema name for the entity: greenDAO can generate independent sets of classes for each schema.\n     * Entities which belong to different schemas should <strong>not</strong> have relations.\n     */\n    String schema() default \"default\";\n\n    /**\n     * Whether update/delete/refresh methods should be generated.\n     * If entity has defined {@link ToMany} or {@link ToOne} relations, then it is active independently from this value\n     */\n    boolean active() default false;\n\n    /**\n     * Whether an all properties constructor should be generated. A no-args constructor is always required.\n     */\n    boolean generateConstructors() default true;\n\n    /**\n     * Whether getters and setters for properties should be generated if missing.\n     */\n    boolean generateGettersSetters() default true;\n\n    /**\n     * Define a protobuf class of this entity to create an additional, special DAO for.\n     */\n    Class protobuf() default void.class;\n\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/Generated.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Marks that a field, constructor or method was generated by greenDAO\n * All the code elements that are marked with this annotation can be changed/removed during next run of generation in\n * respect of model changes.\n *\n * @see Keep\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target({ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD})\npublic @interface Generated {\n    int hash() default -1;\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/Id.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Marks field is the primary key of the entity's table\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target(ElementType.FIELD)\npublic @interface Id {\n    /**\n     * Specifies that id should be auto-incremented (works only for Long/long fields)\n     * Autoincrement on SQLite introduces additional resources usage and usually can be avoided\n     * @see <a href=\"https://www.sqlite.org/autoinc.html\">SQLite documentation</a>\n     */\n    boolean autoincrement() default false;\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/Index.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Can be used to:\n * - specifies that the property should be indexed\n * - define multi-column index through {@link Entity#indexes()}\n *\n * @see Entity#indexes()\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target(ElementType.FIELD)\npublic @interface Index {\n    /**\n     * Comma-separated list of properties that should be indexed, e.g. \"propertyA, propertyB, propertyC\"\n     * To specify order, add ASC or DESC after column name, e.g.: \"propertyA DESC, propertyB ASC\"\n     * This should be only set if this annotation is used in {@link Entity#indexes()}\n     */\n    String value() default \"\";\n\n    /**\n     * Optional name of the index.\n     * If omitted, then generated automatically by greenDAO with base on property/properties column name(s)\n     */\n    String name() default \"\";\n\n    /**\n     * Whether the unique constraint should be created with base on this index\n     */\n    boolean unique() default false;\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/JoinEntity.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Defines *-to-* relation with join table\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target(ElementType.FIELD)\npublic @interface JoinEntity {\n    /** Reference to join-entity class, which holds the source and the target properties */\n    Class<?> entity();\n\n    /** Name of the property inside the join entity which holds id of the source (current) entity */\n    String sourceProperty();\n\n    /** Name of the property inside the join entity which holds id of the target entity */\n    String targetProperty();\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/JoinProperty.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Defines name and referencedName properties for relations\n *\n * @see ToMany\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target({})\npublic @interface JoinProperty {\n    /** Name of the property in the name entity, which matches {@link #referencedName()} */\n    String name();\n\n    /** Name of the property in the referencedName entity, which matches {@link #name()} */\n    String referencedName();\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/Keep.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Specifies that the target should be kept during next run of greenDAO generation.\n * <p>\n * Using this annotation on an Entity class itself silently disables any class modification.\n * The user is responsible to write and support any code which is required for greenDAO.\n * </p>\n * <p>\n * Don't use this annotation on a class member if you are not completely sure what you are doing, because in\n * case of model changes greenDAO will not be able to make corresponding changes into the code of the target.\n * </p>\n *\n * @see Generated\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target({ElementType.FIELD, ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.TYPE})\npublic @interface Keep {\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/NotNull.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Specifies that property is not null\n * <p>\n * You can also use any another NotNull or NonNull annotation (from any library or your own),\n * they are equal to using this\n * </p>\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})\npublic @interface NotNull {\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/OrderBy.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Specifies ordering of related collection of {@link ToMany} relation\n * E.g.: @OrderBy(\"name, age DESC\") List collection;\n * If used as marker (@OrderBy List collection), then collection is ordered by primary key\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target(ElementType.FIELD)\npublic @interface OrderBy {\n    /**\n     * Comma-separated list of properties, e.g. \"propertyA, propertyB, propertyC\"\n     * To specify direction, add ASC or DESC after property name, e.g.: \"propertyA DESC, propertyB ASC\"\n     * Default direction for each property is ASC\n     * If value is omitted, then collection is ordered by primary key\n     */\n    String value() default \"\";\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/Property.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Optional: configures the mapped column for a persistent field.\n * This annotation is also applicable with @ToOne without additional foreign key property\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target(ElementType.FIELD)\npublic @interface Property {\n    /**\n     * Name of the database column for this property. Default is field name.\n     */\n    String nameInDb() default \"\";\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/ToMany.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Defines *-to-N relation\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target(ElementType.FIELD)\npublic @interface ToMany {\n    /**\n     * Name of the property inside the target entity which holds id of the source (current) entity\n     * Required unless no {@link JoinProperty} or {@link JoinEntity} is specified\n     */\n    String referencedJoinProperty() default \"\";\n\n    /**\n     * Array of matching source -&gt; target properties\n     * Required unless {@link #referencedJoinProperty()} or {@link JoinEntity} is specified\n     */\n    JoinProperty[] joinProperties() default {};\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/ToOne.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Defines *-to-1 relation with base on existing property as foreign key or with base on\n * automatically created backing column\n *\n * In case foreignKey is not specified, the following annotations can be applied together with @ToOne:\n * - {@link Property} to specify backing column name\n * - {@link Unique} to put the unique constraint on backing column during table creation\n * - {@link NotNull} to put the NOT NULL constraint on backing column during table creation\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target(ElementType.FIELD)\npublic @interface ToOne {\n    /**\n     * Name of the property inside the current entity which holds the key of related entity.\n     * If this parameter is absent, then an additional column is automatically created to hold the key.\n     */\n    String joinProperty() default \"\";\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/Transient.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.Target;\n\nimport static java.lang.annotation.RetentionPolicy.SOURCE;\n\n/**\n * Transient fields are not persisted in the database.\n */\n@Retention(SOURCE)\n@Target(ElementType.FIELD)\npublic @interface Transient {\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/Unique.java",
    "content": "package org.greenrobot.greendao.annotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Marks property should have a UNIQUE constraint during table creation.\n * This annotation is also applicable with @ToOne without additional foreign key property\n *\n * <p>\n * To have a unique constraint after table creation you can use {@link Index#unique()}\n * </p>\n *\n * <p>\n * Note having both @Unique and {@link Index} is redundant and causes performance decrease\n * on DB level. See <a href=\"https://www.sqlite.org/lang_createtable.html\">here</a> for more information.\n * </p>\n *\n * @see Index#unique()\n */\n@Retention(RetentionPolicy.SOURCE)\n@Target(ElementType.FIELD)\npublic @interface Unique {\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/apihint/Beta.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.annotation.apihint;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * APIs annotated with @Beta may change and may be even removed in a future release (but is somewhat less likely\n * compared to {@link Experimental}). You can still use this API - just be aware that a future version may require\n * changes of your code. This is intended for getting feedback on planned features.\n */\n@Retention(RetentionPolicy.CLASS)\n@Target({ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})\n@Documented\npublic @interface Beta {\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/apihint/Experimental.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.annotation.apihint;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * APIs annotated with @Experimental are likely to change and may be even removed in a future release.\n * You can use this API - just be aware that a future version may require changes of your code.\n * This is intended for getting feedback on planned features.\n */\n@Retention(RetentionPolicy.CLASS)\n@Target({ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})\n@Documented\npublic @interface Experimental {\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/annotation/apihint/Internal.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.annotation.apihint;\n\nimport java.lang.annotation.Documented;\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * APIs annotated with @Internal must NOT be used.\n * Internal APIs must only be used by greenDAO and may change or be removed in a future release.\n */\n@Retention(RetentionPolicy.CLASS)\n@Target({ElementType.ANNOTATION_TYPE, ElementType.CONSTRUCTOR, ElementType.FIELD, ElementType.METHOD, ElementType.TYPE})\n@Internal\n@Documented\npublic @interface Internal {\n}\n"
  },
  {
    "path": "greendao-api/src/main/java/org/greenrobot/greendao/converter/PropertyConverter.java",
    "content": "/*\n * Copyright (C) 2011-2015 Markus Junginger, greenrobot (http://greenrobot.de)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\npackage org.greenrobot.greendao.converter;\n\n/**\n * To use custom types in your entity, implement this to convert db values to entity values and back.\n * <p/>\n * Notes for implementations:\n * <ul>\n * <li>Converters are created by the default constructor</li>\n * <li>Converters must be implemented thread-safe</li>\n * </ul>\n */\npublic interface PropertyConverter<P, D> {\n    P convertToEntityProperty(D databaseValue);\n\n    D convertToDatabaseValue(P entityProperty);\n}\n"
  },
  {
    "path": "javadoc-style/stylesheet.css",
    "content": "/* Javadoc style sheet */\n/*\nOverall document style\n*/\n\n@import url('resources/fonts/dejavu.css');\n\nbody {\n    background-color:#ffffff;\n    color:#353833;\n    font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;\n    font-size:14px;\n    margin:0;\n}\na:link, a:visited {\n    text-decoration:none;\n    color:#4A6782;\n}\na:hover, a:focus {\n    text-decoration:none;\n    color:#bb7a2a;\n}\na:active {\n    text-decoration:none;\n    color:#4A6782;\n}\na[name] {\n    color:#353833;\n}\na[name]:hover {\n    text-decoration:none;\n    color:#353833;\n}\npre {\n    font-family:'DejaVu Sans Mono', monospace;\n    font-size:14px;\n}\nh1 {\n    font-size:20px;\n}\nh2 {\n    font-size:18px;\n}\nh3 {\n    font-size:16px;\n    font-style:italic;\n}\nh4 {\n    font-size:13px;\n}\nh5 {\n    font-size:12px;\n}\nh6 {\n    font-size:11px;\n}\nul {\n    list-style-type:disc;\n}\ncode, tt {\n    font-family:'DejaVu Sans Mono', monospace;\n    font-size:14px;\n    padding-top:4px;\n    margin-top:8px;\n    line-height:1.4em;\n}\ndt code {\n    font-family:'DejaVu Sans Mono', monospace;\n    font-size:14px;\n    padding-top:4px;\n}\ntable tr td dt code {\n    font-family:'DejaVu Sans Mono', monospace;\n    font-size:14px;\n    vertical-align:top;\n    padding-top:4px;\n}\nsup {\n    font-size:8px;\n}\n/*\nDocument title and Copyright styles\n*/\n.clear {\n    clear:both;\n    height:0px;\n    overflow:hidden;\n}\n.aboutLanguage {\n    float:right;\n    padding:0px 21px;\n    font-size:11px;\n    z-index:200;\n    margin-top:-9px;\n}\n.legalCopy {\n    margin-left:.5em;\n}\n.bar a, .bar a:link, .bar a:visited, .bar a:active {\n    color:#FFFFFF;\n    text-decoration:none;\n}\n.bar a:hover, .bar a:focus {\n    color:#bb7a2a;\n}\n.tab {\n    background-color:#0066FF;\n    color:#ffffff;\n    padding:8px;\n    width:5em;\n    font-weight:bold;\n}\n/*\nNavigation bar styles\n*/\n.bar {\n    background-color:#4D974D;\n    color:#FFFFFF;\n    padding:.8em .5em .4em .8em;\n    height:auto;/*height:1.8em;*/\n    font-size:11px;\n    margin:0;\n}\n.topNav {\n    background-color:#4D974D;\n    color:#FFFFFF;\n    float:left;\n    padding:0;\n    width:100%;\n    clear:right;\n    height:2.8em;\n    padding-top:10px;\n    overflow:hidden;\n    font-size:12px; \n}\n.bottomNav {\n    margin-top:10px;\n    background-color:#4D974D;\n    color:#FFFFFF;\n    float:left;\n    padding:0;\n    width:100%;\n    clear:right;\n    height:2.8em;\n    padding-top:10px;\n    overflow:hidden;\n    font-size:12px;\n}\n.subNav {\n    background-color:#dee3e9;\n    float:left;\n    width:100%;\n    overflow:hidden;\n    font-size:12px;\n}\n.subNav div {\n    clear:left;\n    float:left;\n    padding:0 0 5px 6px;\n    text-transform:uppercase;\n}\nul.navList, ul.subNavList {\n    float:left;\n    margin:0 25px 0 0;\n    padding:0;\n}\nul.navList li{\n    list-style:none;\n    float:left;\n    padding: 5px 6px;\n    text-transform:uppercase;\n}\nul.subNavList li{\n    list-style:none;\n    float:left;\n}\n.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {\n    color:#FFFFFF;\n    text-decoration:none;\n    text-transform:uppercase;\n}\n.topNav a:hover, .bottomNav a:hover {\n    text-decoration:none;\n    color:#bb7a2a;\n    text-transform:uppercase;\n}\n.navBarCell1Rev {\n    background-color:#F8981D;\n    color:#253441;\n    margin: auto 5px;\n}\n.skipNav {\n    position:absolute;\n    top:auto;\n    left:-9999px;\n    overflow:hidden;\n}\n/*\nPage header and footer styles\n*/\n.header, .footer {\n    clear:both;\n    margin:0 20px;\n    padding:5px 0 0 0;\n}\n.indexHeader {\n    margin:10px;\n    position:relative;\n}\n.indexHeader span{\n    margin-right:15px;\n}\n.indexHeader h1 {\n    font-size:13px;\n}\n.title {\n    color:#2c4557;\n    margin:10px 0;\n}\n.subTitle {\n    margin:5px 0 0 0;\n}\n.header ul {\n    margin:0 0 15px 0;\n    padding:0;\n}\n.footer ul {\n    margin:20px 0 5px 0;\n}\n.header ul li, .footer ul li {\n    list-style:none;\n    font-size:13px;\n}\n/*\nHeading styles\n*/\ndiv.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {\n    background-color:#dee3e9;\n    border:1px solid #d0d9e0;\n    margin:0 0 6px -8px;\n    padding:7px 5px;\n}\nul.blockList ul.blockList ul.blockList li.blockList h3 {\n    background-color:#dee3e9;\n    border:1px solid #d0d9e0;\n    margin:0 0 6px -8px;\n    padding:7px 5px;\n}\nul.blockList ul.blockList li.blockList h3 {\n    padding:0;\n    margin:15px 0;\n}\nul.blockList li.blockList h2 {\n    padding:0px 0 20px 0;\n}\n/*\nPage layout container styles\n*/\n.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer {\n    clear:both;\n    padding:10px 20px;\n    position:relative;\n}\n.indexContainer {\n    margin:10px;\n    position:relative;\n    font-size:12px;\n}\n.indexContainer h2 {\n    font-size:13px;\n    padding:0 0 3px 0;\n}\n.indexContainer ul {\n    margin:0;\n    padding:0;\n}\n.indexContainer ul li {\n    list-style:none;\n    padding-top:2px;\n}\n.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {\n    font-size:12px;\n    font-weight:bold;\n    margin:10px 0 0 0;\n    color:#4E4E4E;\n}\n.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {\n    margin:5px 0 10px 0px;\n    font-size:14px;\n    font-family:'DejaVu Sans Mono',monospace;\n}\n.serializedFormContainer dl.nameValue dt {\n    margin-left:1px;\n    font-size:1.1em;\n    display:inline;\n    font-weight:bold;\n}\n.serializedFormContainer dl.nameValue dd {\n    margin:0 0 0 1px;\n    font-size:1.1em;\n    display:inline;\n}\n/*\nList styles\n*/\nul.horizontal li {\n    display:inline;\n    font-size:0.9em;\n}\nul.inheritance {\n    margin:0;\n    padding:0;\n}\nul.inheritance li {\n    display:inline;\n    list-style:none;\n}\nul.inheritance li ul.inheritance {\n    margin-left:15px;\n    padding-left:15px;\n    padding-top:1px;\n}\nul.blockList, ul.blockListLast {\n    margin:10px 0 10px 0;\n    padding:0;\n}\nul.blockList li.blockList, ul.blockListLast li.blockList {\n    list-style:none;\n    margin-bottom:15px;\n    line-height:1.4;\n}\nul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {\n    padding:0px 20px 5px 10px;\n    border:1px solid #ededed; \n    background-color:#f8f8f8;\n}\nul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {\n    padding:0 0 5px 8px;\n    background-color:#ffffff;\n    border:none;\n}\nul.blockList ul.blockList ul.blockList ul.blockList li.blockList {\n    margin-left:0;\n    padding-left:0;\n    padding-bottom:15px;\n    border:none;\n}\nul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {\n    list-style:none;\n    border-bottom:none;\n    padding-bottom:0;\n}\ntable tr td dl, table tr td dl dt, table tr td dl dd {\n    margin-top:0;\n    margin-bottom:1px;\n}\n/*\nTable styles\n*/\n.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary {\n    width:100%;\n    border-left:1px solid #EEE; \n    border-right:1px solid #EEE; \n    border-bottom:1px solid #EEE; \n}\n.overviewSummary, .memberSummary  {\n    padding:0px;\n}\n.overviewSummary caption, .memberSummary caption, .typeSummary caption,\n.useSummary caption, .constantsSummary caption, .deprecatedSummary caption {\n    position:relative;\n    text-align:left;\n    background-repeat:no-repeat;\n    color:#253441;\n    font-weight:bold;\n    clear:none;\n    overflow:hidden;\n    padding:0px;\n    padding-top:10px;\n    padding-left:1px;\n    margin:0px;\n    white-space:pre;\n}\n.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,\n.useSummary caption a:link, .constantsSummary caption a:link, .deprecatedSummary caption a:link,\n.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,\n.useSummary caption a:hover, .constantsSummary caption a:hover, .deprecatedSummary caption a:hover,\n.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,\n.useSummary caption a:active, .constantsSummary caption a:active, .deprecatedSummary caption a:active,\n.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,\n.useSummary caption a:visited, .constantsSummary caption a:visited, .deprecatedSummary caption a:visited {\n    color:#FFFFFF;\n}\n.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,\n.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span {\n    white-space:nowrap;\n    padding-top:5px;\n    padding-left:12px;\n    padding-right:12px;\n    padding-bottom:7px;\n    display:inline-block;\n    float:left;\n    background-color:#F8981D;\n    border: none;\n    height:16px;\n}\n.memberSummary caption span.activeTableTab span {\n    white-space:nowrap;\n    padding-top:5px;\n    padding-left:12px;\n    padding-right:12px;\n    margin-right:3px;\n    display:inline-block;\n    float:left;\n    background-color:#F8981D;\n    height:16px;\n}\n.memberSummary caption span.tableTab span {\n    white-space:nowrap;\n    padding-top:5px;\n    padding-left:12px;\n    padding-right:12px;\n    margin-right:3px;\n    display:inline-block;\n    float:left;\n    background-color:#4D974D;\n    height:16px;\n}\n.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab {\n    padding-top:0px;\n    padding-left:0px;\n    padding-right:0px;\n    background-image:none;\n    float:none;\n    display:inline;\n}\n.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,\n.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd {\n    display:none;\n    width:5px;\n    position:relative;\n    float:left;\n    background-color:#F8981D;\n}\n.memberSummary .activeTableTab .tabEnd {\n    display:none;\n    width:5px;\n    margin-right:3px;\n    position:relative; \n    float:left;\n    background-color:#F8981D;\n}\n.memberSummary .tableTab .tabEnd {\n    display:none;\n    width:5px;\n    margin-right:3px;\n    position:relative;\n    background-color:#4D974D;\n    float:left;\n\n}\n.overviewSummary td, .memberSummary td, .typeSummary td,\n.useSummary td, .constantsSummary td, .deprecatedSummary td {\n    text-align:left;\n    padding:0px 0px 12px 10px;\n    width:100%;\n}\nth.colOne, th.colFirst, th.colLast, .useSummary th, .constantsSummary th,\ntd.colOne, td.colFirst, td.colLast, .useSummary td, .constantsSummary td{\n    vertical-align:top;\n    padding-right:0px;\n    padding-top:8px;\n    padding-bottom:3px;\n}\nth.colFirst, th.colLast, th.colOne, .constantsSummary th {\n    background:#dee3e9;\n    text-align:left;\n    padding:8px 3px 3px 7px;\n}\ntd.colFirst, th.colFirst {\n    white-space:nowrap;\n    font-size:13px;\n}\ntd.colLast, th.colLast {\n    font-size:13px;\n}\ntd.colOne, th.colOne {\n    font-size:13px;\n}\n.overviewSummary td.colFirst, .overviewSummary th.colFirst,\n.overviewSummary td.colOne, .overviewSummary th.colOne,\n.memberSummary td.colFirst, .memberSummary th.colFirst,\n.memberSummary td.colOne, .memberSummary th.colOne,\n.typeSummary td.colFirst{\n    width:25%;\n    vertical-align:top;\n}\ntd.colOne a:link, td.colOne a:active, td.colOne a:visited, td.colOne a:hover, td.colFirst a:link, td.colFirst a:active, td.colFirst a:visited, td.colFirst a:hover, td.colLast a:link, td.colLast a:active, td.colLast a:visited, td.colLast a:hover, .constantValuesContainer td a:link, .constantValuesContainer td a:active, .constantValuesContainer td a:visited, .constantValuesContainer td a:hover {\n    font-weight:bold;\n}\n.tableSubHeadingColor {\n    background-color:#EEEEFF;\n}\n.altColor {\n    background-color:#FFFFFF;\n}\n.rowColor {\n    background-color:#EEEEEF;\n}\n/*\nContent styles\n*/\n.description pre {\n    margin-top:0;\n}\n.deprecatedContent {\n    margin:0;\n    padding:10px 0;\n}\n.docSummary {\n    padding:0;\n}\n\nul.blockList ul.blockList ul.blockList li.blockList h3 {\n    font-style:normal;\n}\n\ndiv.block {\n    font-size:14px;\n    font-family:'DejaVu Serif', Georgia, \"Times New Roman\", Times, serif;\n}\n\ntd.colLast div {\n    padding-top:0px;\n}\n\n\ntd.colLast a {\n    padding-bottom:3px;\n}\n/*\nFormatting effect styles\n*/\n.sourceLineNo {\n    color:green;\n    padding:0 30px 0 0;\n}\nh1.hidden {\n    visibility:hidden;\n    overflow:hidden;\n    font-size:10px;\n}\n.block {\n    display:block;\n    margin:3px 10px 2px 0px;\n    color:#474747;\n}\n.deprecatedLabel, .descfrmTypeLabel, .memberNameLabel, .memberNameLink,\n.overrideSpecifyLabel, .packageHierarchyLabel, .paramLabel, .returnLabel,\n.seeLabel, .simpleTagLabel, .throwsLabel, .typeNameLabel, .typeNameLink {\n    font-weight:bold;\n}\n.deprecationComment, .emphasizedPhrase, .interfaceName {\n    font-style:italic;\n}\n\ndiv.block div.block span.deprecationComment, div.block div.block span.emphasizedPhrase,\ndiv.block div.block span.interfaceName {\n    font-style:normal;\n}\n\ndiv.contentContainer ul.blockList li.blockList h2{\n    padding-bottom:0px;\n}\n"
  },
  {
    "path": "settings.gradle",
    "content": "include 'greendao-api'\ninclude 'DaoCore'\ninclude 'DaoGenerator'\ninclude 'tests'\n\ninclude 'examples:DaoExample'\ninclude 'examples:RxDaoExample'\n\ninclude 'tests:DaoTestBase'\ninclude 'tests:DaoTest'\ninclude 'tests:DaoTestPerformance'\ninclude 'tests:DaoTestGenerator'\ninclude 'tests:DaoTestEntityAnnotation'\n"
  },
  {
    "path": "tests/DaoTest/build.gradle",
    "content": "buildscript {\n    repositories {\n        jcenter()\n        google()\n        mavenCentral()\n    }\n\n    dependencies {\n        classpath dep.androidPlugin\n    }\n}\n\napply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n\n    // To use deprecated test classes on SDK 28+. https://developer.android.com/training/testing/set-up-project\n    useLibrary 'android.test.runner'\n    useLibrary 'android.test.base'\n\n    defaultConfig {\n        minSdkVersion 7\n\n        testApplicationId \"org.greenrobot.greendao.daotest\"\n        testInstrumentationRunner \"android.test.InstrumentationTestRunner\"\n    }\n\n    testOptions {\n        unitTests {\n            includeAndroidResources = true\n        }\n    }\n}\n\ndependencies {\n    implementation project(':tests:DaoTestBase')\n\n    testImplementation \"junit:junit:4.12\"\n    testImplementation 'org.robolectric:robolectric:3.8'\n    testImplementation 'org.mockito:mockito-core:1.10.19'\n\n    androidTestImplementation 'net.zetetic:android-database-sqlcipher:3.5.6'\n    androidTestImplementation 'io.reactivex:rxjava:1.3.0'\n}\n\nuploadArchives.enabled = false\n"
  },
  {
    "path": "tests/DaoTest/proguard.cfg",
    "content": "-optimizationpasses 5\n-dontusemixedcaseclassnames\n-dontskipnonpubliclibraryclasses\n-dontpreverify\n-verbose\n-optimizations !code/simplification/arithmetic,!field/*,!class/merging/*\n\n-keep public class * extends android.app.Activity\n-keep public class * extends android.app.Application\n-keep public class * extends android.app.Service\n-keep public class * extends android.content.BroadcastReceiver\n-keep public class * extends android.content.ContentProvider\n-keep public class * extends android.app.backup.BackupAgentHelper\n-keep public class * extends android.preference.Preference\n-keep public class com.android.vending.licensing.ILicensingService\n\n-keepclasseswithmembernames class * {\n    native <methods>;\n}\n\n-keepclasseswithmembers class * {\n    public <init>(android.content.Context, android.util.AttributeSet);\n}\n\n-keepclasseswithmembers class * {\n    public <init>(android.content.Context, android.util.AttributeSet, int);\n}\n\n-keepclassmembers class * extends android.app.Activity {\n   public void *(android.view.View);\n}\n\n-keepclassmembers enum * {\n    public static **[] values();\n    public static ** valueOf(java.lang.String);\n}\n\n-keep class * implements android.os.Parcelable {\n  public static final android.os.Parcelable$Creator *;\n}\n"
  },
  {
    "path": "tests/DaoTest/project.properties",
    "content": "# This file is automatically generated by Android Tools.\n# Do not modify this file -- YOUR CHANGES WILL BE ERASED!\n#\n# This file must be checked in Version Control Systems.\n#\n# To customize properties used by the Ant build system use,\n# \"ant.properties\", and override values to adapt the script to your\n# project structure.\n\nandroid.library.reference.1=../DaoCore\n# Project target.\ntarget=android-4\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/DaoSessionConcurrentTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest;\n\nimport java.util.concurrent.CountDownLatch;\n\nimport android.os.SystemClock;\n\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\nimport org.greenrobot.greendao.query.DeleteQuery;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\n\npublic class DaoSessionConcurrentTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n    class TestThread extends Thread {\n        final Runnable runnable;\n\n        public TestThread(Runnable runnable) {\n            this.runnable = runnable;\n        }\n\n        @Override\n        public void run() {\n            latchThreadsReady.countDown();\n            try {\n                latchInsideTx.await();\n            } catch (InterruptedException e) {\n                throw new RuntimeException(e);\n            }\n            runnable.run();\n            latchThreadsDone.countDown();\n        }\n\n    }\n\n    private final static int TIME_TO_WAIT_FOR_THREAD = 100; // Use 1000 to be on the safe side, 100 once stable\n\n    protected TestEntityDao dao;\n\n    protected CountDownLatch latchThreadsReady;\n    protected CountDownLatch latchInsideTx;\n    protected CountDownLatch latchThreadsDone;\n\n    public DaoSessionConcurrentTest() {\n        super(DaoMaster.class);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        dao = daoSession.getTestEntityDao();\n    }\n\n    protected void initThreads(Runnable... runnables) throws InterruptedException {\n        latchThreadsReady = new CountDownLatch(runnables.length);\n        latchInsideTx = new CountDownLatch(1);\n        latchThreadsDone = new CountDownLatch(runnables.length);\n        for (Runnable runnable : runnables) {\n            new TestThread(runnable).start();\n        }\n        latchThreadsReady.await();\n    }\n\n    public void testConcurrentInsertDuringTx() throws InterruptedException {\n        Runnable runnable1 = new Runnable() {\n            @Override\n            public void run() {\n                dao.insert(createEntity(null));\n            }\n        };\n        Runnable runnable2 = new Runnable() {\n            @Override\n            public void run() {\n                dao.insertInTx(createEntity(null));\n            }\n        };\n        Runnable runnable3 = new Runnable() {\n            @Override\n            public void run() {\n                daoSession.runInTx(new Runnable() {\n                    @Override\n                    public void run() {\n                        dao.insert(createEntity(null));\n                    }\n                });\n            }\n        };\n        Runnable runnable4 = new Runnable() {\n            @Override\n            public void run() {\n                dao.insertWithoutSettingPk(createEntity(null));\n            }\n        };\n        Runnable runnable5 = new Runnable() {\n            @Override\n            public void run() {\n                dao.insertOrReplace(createEntity(null));\n            }\n        };\n        initThreads(runnable1, runnable2, runnable3, runnable4, runnable5);\n        // Builds the statement so it is ready immediately in the thread\n        dao.insert(createEntity(null));\n        doTx(new Runnable() {\n            @Override\n            public void run() {\n                dao.insert(createEntity(null));\n            }\n        });\n        latchThreadsDone.await();\n        assertEquals(7, dao.count());\n    }\n\n    public void testConcurrentUpdateDuringTx() throws InterruptedException {\n        final TestEntity entity = createEntity(null);\n        dao.insert(entity);\n        Runnable runnable1 = new Runnable() {\n            @Override\n            public void run() {\n                dao.update(entity);\n            }\n        };\n        Runnable runnable2 = new Runnable() {\n            @Override\n            public void run() {\n                dao.updateInTx(entity);\n            }\n        };\n        Runnable runnable3 = new Runnable() {\n            @Override\n            public void run() {\n                daoSession.runInTx(new Runnable() {\n                    @Override\n                    public void run() {\n                        dao.update(entity);\n                    }\n                });\n            }\n        };\n        initThreads(runnable1, runnable2, runnable3);\n        // Builds the statement so it is ready immediately in the thread\n        dao.update(entity);\n        doTx(new Runnable() {\n            @Override\n            public void run() {\n                dao.update(entity);\n            }\n        });\n        latchThreadsDone.await();\n    }\n\n    public void testConcurrentDeleteDuringTx() throws InterruptedException {\n        final TestEntity entity = createEntity(null);\n        dao.insert(entity);\n        Runnable runnable1 = new Runnable() {\n            @Override\n            public void run() {\n                dao.delete(entity);\n            }\n        };\n        Runnable runnable2 = new Runnable() {\n            @Override\n            public void run() {\n                dao.deleteInTx(entity);\n            }\n        };\n        Runnable runnable3 = new Runnable() {\n            @Override\n            public void run() {\n                daoSession.runInTx(new Runnable() {\n                    @Override\n                    public void run() {\n                        dao.delete(entity);\n                    }\n                });\n            }\n        };\n        initThreads(runnable1, runnable2, runnable3);\n        // Builds the statement so it is ready immediately in the thread\n        dao.delete(entity);\n        doTx(new Runnable() {\n            @Override\n            public void run() {\n                dao.delete(entity);\n            }\n        });\n        latchThreadsDone.await();\n    }\n\n    // Query doesn't involve any statement locking currently, but just to stay on the safe side...\n    public void testConcurrentQueryDuringTx() throws InterruptedException {\n        final TestEntity entity = createEntity(null);\n        dao.insert(entity);\n        final Query<TestEntity> query = dao.queryBuilder().build();\n        Runnable runnable1 = new Runnable() {\n            @Override\n            public void run() {\n                query.forCurrentThread().list();\n            }\n        };\n\n        initThreads(runnable1);\n        // Builds the statement so it is ready immediately in the thread\n        query.list();\n        doTx(new Runnable() {\n            @Override\n            public void run() {\n                query.list();\n            }\n        });\n        latchThreadsDone.await();\n    }\n\n    public void testConcurrentLockAndQueryDuringTx() throws InterruptedException {\n        final TestEntity entity = createEntity(null);\n        dao.insert(entity);\n        final Query<TestEntity> query = dao.queryBuilder().build();\n        Runnable runnable1 = new Runnable() {\n            @Override\n            public void run() {\n                query.forCurrentThread().list();\n            }\n        };\n\n        initThreads(runnable1);\n        // Builds the statement so it is ready immediately in the thread\n        query.list();\n        doTx(new Runnable() {\n            @Override\n            public void run() {\n                query.list();\n            }\n        });\n        latchThreadsDone.await();\n    }\n\n    public void testConcurrentDeleteQueryDuringTx() throws InterruptedException {\n        final TestEntity entity = createEntity(null);\n        dao.insert(entity);\n        final DeleteQuery<TestEntity> query = dao.queryBuilder().buildDelete();\n        Runnable runnable1 = new Runnable() {\n            @Override\n            public void run() {\n                query.forCurrentThread().executeDeleteWithoutDetachingEntities();\n            }\n        };\n\n        initThreads(runnable1);\n        // Builds the statement so it is ready immediately in the thread\n        query.executeDeleteWithoutDetachingEntities();\n        doTx(new Runnable() {\n            @Override\n            public void run() {\n                query.executeDeleteWithoutDetachingEntities();\n            }\n        });\n        latchThreadsDone.await();\n    }\n\n    public void testConcurrentResolveToMany() throws InterruptedException {\n        final ToManyEntity entity = new ToManyEntity();\n        ToManyEntityDao toManyDao = daoSession.getToManyEntityDao();\n        toManyDao.insert(entity);\n\n        Runnable runnable1 = new Runnable() {\n            @Override\n            public void run() {\n                entity.getToManyTargetEntityList();\n            }\n        };\n\n        initThreads(runnable1);\n        doTx(new Runnable() {\n            @Override\n            public void run() {\n                entity.getToManyTargetEntityList();\n            }\n        });\n        latchThreadsDone.await();\n    }\n\n    public void testConcurrentResolveToOne() throws InterruptedException {\n        final TreeEntity entity = new TreeEntity();\n        TreeEntityDao toOneDao = daoSession.getTreeEntityDao();\n        toOneDao.insert(entity);\n\n        Runnable runnable1 = new Runnable() {\n            @Override\n            public void run() {\n                entity.getParent();\n            }\n        };\n\n        initThreads(runnable1);\n        doTx(new Runnable() {\n            @Override\n            public void run() {\n                entity.getParent();\n            }\n        });\n        latchThreadsDone.await();\n    }\n\n    /**\n     * We could put the statements inside ThreadLocals (fast enough), but it comes with initialization penalty for new\n     * threads and costs more memory.\n     */\n    public void _testThreadLocalSpeed() {\n        final Database db = dao.getDatabase();\n        ThreadLocal<DatabaseStatement> threadLocal = new ThreadLocal<DatabaseStatement>() {\n            @Override\n            protected DatabaseStatement initialValue() {\n                return db.compileStatement(\"SELECT 42\");\n            }\n        };\n        threadLocal.get();\n        long start = SystemClock.currentThreadTimeMillis();\n        for (int i = 0; i < 1000; i++) {\n            DatabaseStatement sqLiteStatement = threadLocal.get();\n            assertNotNull(sqLiteStatement);\n        }\n        Long time = SystemClock.currentThreadTimeMillis() - start;\n        DaoLog.d(\"TIME: \" + time + \"ms\");\n        // Around 1ms on a S3\n        assertTrue(time < 10);\n    }\n\n    protected void doTx(final Runnable runnableInsideTx) {\n        daoSession.runInTx(new Runnable() {\n            @Override\n            public void run() {\n                latchInsideTx.countDown();\n                // Give the concurrent thread time so it will try to acquire locks\n                try {\n                    Thread.sleep(TIME_TO_WAIT_FOR_THREAD);\n                } catch (InterruptedException e) {\n                    throw new RuntimeException(e);\n                }\n                runnableInsideTx.run();\n            }\n        });\n    }\n\n    protected TestEntity createEntity(Long key) {\n        TestEntity entity = new TestEntity(key);\n        entity.setSimpleStringNotNull(\"green\");\n        return entity;\n    }\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/DaoSessionConcurrentWALTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest;\n\nimport android.database.sqlite.SQLiteDatabase;\nimport android.os.Build;\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.database.StandardDatabase;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.query.Query;\n\nimport java.lang.reflect.Method;\n\npublic class DaoSessionConcurrentWALTest extends DaoSessionConcurrentTest {\n\n    @Override\n    protected Database createDatabase() {\n        int MODE_ENABLE_WRITE_AHEAD_LOGGING = 8;\n        getContext().deleteDatabase(DB_NAME);\n        SQLiteDatabase sqLiteDatabase = getContext().openOrCreateDatabase(DB_NAME, MODE_ENABLE_WRITE_AHEAD_LOGGING, null);\n        return new StandardDatabase(sqLiteDatabase);\n    }\n\n    public void testConcurrentLockAndQueryDuringTxWAL() throws InterruptedException {\n        if (Build.VERSION.SDK_INT >= 16) {\n            try {\n                Object rawDatabase = db.getRawDatabase();\n                Method method = rawDatabase.getClass().getMethod(\"isWriteAheadLoggingEnabled\");\n                boolean walEnabled = (Boolean) method.invoke(rawDatabase);\n                if (!walEnabled) {\n                    throw new RuntimeException(\"WAL is disabled. This test will deadlock without WAL\");\n                }\n            } catch (Exception e) {\n                throw new RuntimeException(e);\n            }\n        } else {\n            DaoLog.e(\"Sorry, we need at least API level 16 for WAL\");\n            return;\n        }\n\n        final TestEntity entity = createEntity(null);\n        dao.insert(entity);\n        final Query<TestEntity> query = dao.queryBuilder().build();\n        Runnable runnable1 = new Runnable() {\n            @Override\n            public void run() {\n                synchronized (query) {\n                    query.forCurrentThread().list();\n                }\n            }\n        };\n\n        initThreads(runnable1);\n        // Builds the statement so it is ready immediately in the thread\n        query.list();\n        doTx(new Runnable() {\n            @Override\n            public void run() {\n                synchronized (query) {\n                    query.list();\n                }\n            }\n        });\n        latchThreadsDone.await();\n    }\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/DaoSessionTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.daotest.SimpleEntity;\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\n\npublic class DaoSessionTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n\n    public DaoSessionTest() {\n        super(DaoMaster.class);\n    }\n\n    public void testInsertAndLoad() {\n        SimpleEntity entity = new SimpleEntity();\n        daoSession.insert(entity);\n        Long id = entity.getId();\n        assertNotNull(id);\n        SimpleEntity entity2 = daoSession.load(SimpleEntity.class, id);\n        assertNotNull(entity2);\n    }\n\n    public void testIdentity() {\n        SimpleEntity entity = new SimpleEntity();\n        daoSession.insert(entity);\n        SimpleEntity entity2 = daoSession.load(SimpleEntity.class, entity.getId());\n        SimpleEntity entity3 = daoSession.load(SimpleEntity.class, entity.getId());\n        assertSame(entity, entity2);\n        assertSame(entity, entity3);\n    }\n\n    public void testIdentityPerSession() {\n        SimpleEntity entity = new SimpleEntity();\n        daoSession.insert(entity);\n        DaoSession session2 = daoMaster.newSession();\n        SimpleEntity entity2 = session2.load(SimpleEntity.class, entity.getId());\n        assertNotSame(entity, entity2);\n    }\n\n    public void testSessionReset() {\n        SimpleEntity entity = new SimpleEntity();\n        daoSession.insert(entity);\n        daoSession.clear();\n        SimpleEntity entity2 = daoSession.load(SimpleEntity.class, entity.getId());\n        assertNotSame(entity, entity2);\n    }\n}"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/DbTestTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest;\n\nimport android.app.Application;\nimport org.greenrobot.greendao.test.DbTest;\nimport junit.framework.AssertionFailedError;\n\npublic class DbTestTest extends DbTest {\n    public static class MyApp extends Application {\n        static int onCreateCounterStatic;\n        static int onTerminateCounterStatic;\n\n        int onCreateCounter;\n        int onTerminateCounter;\n\n        @Override\n        public void onCreate() {\n            super.onCreate();\n            onCreateCounter++;\n            onCreateCounterStatic++;\n        }\n\n        @Override\n        public void onTerminate() {\n            super.onTerminate();\n            onTerminateCounterStatic++;\n            onTerminateCounter++;\n        }\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        MyApp.onCreateCounterStatic = 0;\n        MyApp.onTerminateCounterStatic = 0;\n    }\n\n    @Override\n    protected void tearDown() throws Exception {\n        super.tearDown();\n        assertEquals(MyApp.onCreateCounterStatic, MyApp.onTerminateCounterStatic);\n    }\n\n    public void testCreateApplication() {\n        MyApp app = createApplication(MyApp.class);\n        assertNotNull(app);\n\n        assertEquals(1, app.onCreateCounter);\n        assertEquals(1, MyApp.onCreateCounterStatic);\n        assertEquals(0, app.onTerminateCounter);\n        assertEquals(0, MyApp.onTerminateCounterStatic);\n    }\n\n    public void testTerminateApplication() {\n        MyApp app = createApplication(MyApp.class);\n        terminateApplication();\n\n        assertEquals(1, app.onCreateCounter);\n        assertEquals(1, MyApp.onCreateCounterStatic);\n        assertEquals(1, app.onTerminateCounter);\n        assertEquals(1, MyApp.onTerminateCounterStatic);\n    }\n\n    public void testGetApplicationBeforeCreate() {\n        try {\n            getApplication();\n            fail(\"Should have thrown\");\n        } catch (AssertionFailedError e) {\n            // Expected\n        }\n    }\n\n    public void testGetApplication() {\n        try {\n            getApplication();\n            fail(\"Should have thrown\");\n        } catch (AssertionFailedError e) {\n            // Expected\n        }\n\n        MyApp app = createApplication(MyApp.class);\n        MyApp app2 = getApplication();\n        assertSame(app, app2);\n    }\n\n    public void testGetApplicationAfterTerminate() {\n        MyApp app = createApplication(MyApp.class);\n        terminateApplication();\n        try {\n            getApplication();\n            fail(\"Should have thrown\");\n        } catch (AssertionFailedError e) {\n            // Expected\n        }\n    }\n\n\n    public void testMultipleApplications() {\n        MyApp app1 = createApplication(MyApp.class);\n        terminateApplication();\n\n        MyApp app2 = createApplication(MyApp.class);\n        assertNotSame(app2, app1);\n\n        MyApp app = getApplication();\n        assertSame(app2, app);\n\n        assertEquals(1, app1.onCreateCounter);\n        assertEquals(1, app1.onTerminateCounter);\n        assertEquals(1, app2.onCreateCounter);\n        assertEquals(0, app2.onTerminateCounter);\n\n        assertEquals(2, MyApp.onCreateCounterStatic);\n        assertEquals(1, MyApp.onTerminateCounterStatic);\n    }\n\n\n}"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/DbUtilsTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteDatabase;\nimport org.greenrobot.greendao.DbUtils;\nimport org.greenrobot.greendao.database.StandardDatabase;\nimport org.greenrobot.greendao.test.DbTest;\n\nimport java.io.IOException;\n\npublic class DbUtilsTest extends DbTest {\n    public void testExecuteSqlScript() throws IOException {\n        DbUtils.executeSqlScript(getContext(), db, \"minimal-entity.sql\");\n        Cursor cursor = db.rawQuery(\"SELECT count(*) from MINIMAL_ENTITY\", null);\n        try {\n            cursor.moveToFirst();\n            assertEquals(5, cursor.getInt(0));\n        } finally {\n            cursor.close();\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/DeadlockPreventionTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\n\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao;\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\n\n/**\n * Test to reproduce https://github.com/greenrobot/greenDAO/issues/223 (works at least on a Android 2.3 emulator).\n */\npublic class DeadlockPreventionTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n\n    CountDownLatch done = new CountDownLatch(1);\n    private TestEntityDao dao;\n\n    public DeadlockPreventionTest() {\n        super(DaoMaster.class);\n    }\n\n    // Runs pretty long, only run manually\n    public void _testLoadAll() throws InterruptedException {\n        dao = daoSession.getTestEntityDao();\n        List<TestEntity> entities = new ArrayList<>();\n        for (int i = 0; i < 10000; i++) {\n            TestEntity entity = new TestEntity();\n            entity.setSimpleStringNotNull(\"Text\" + i);\n            entities.add(entity);\n        }\n        dao.insertInTx(entities);\n        System.out.println(\"Entities inserted\");\n\n        LoadThread loadThread = new LoadThread();\n        InsertThread insertThread = new InsertThread();\n        InsertBatchThread insertBatchThread = new InsertBatchThread();\n        loadThread.start();\n        insertThread.start();\n        insertBatchThread.start();\n\n        int lastCounterInsert = insertThread.counter;\n        int lastCounterInsertBatch = insertBatchThread.counter;\n        int noProgressCount = 0;\n        while (!done.await(10, TimeUnit.SECONDS)) {\n            if (lastCounterInsert == insertThread.counter && lastCounterInsertBatch == insertBatchThread.counter) {\n                noProgressCount++;\n                System.err.println(\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\");\n                System.err.println(\"No progress #\" + noProgressCount + \", dumping threads\");\n                System.err.println(\"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\");\n                dumpStacktrace(\"LOAD\", loadThread);\n                dumpStacktrace(\"INSERT\", insertThread);\n                dumpStacktrace(\"INSERT BATCH\", insertBatchThread);\n\n                if (noProgressCount >= 3) {\n                    // Test seems to be stuck, kill everything!\n                    System.exit(1);\n                }\n            } else {\n                lastCounterInsert = insertThread.counter;\n                lastCounterInsertBatch = insertBatchThread.counter;\n                noProgressCount = 0;\n            }\n        }\n\n        loadThread.join();\n        insertThread.join();\n        insertBatchThread.join();\n    }\n\n    private void dumpStacktrace(String name, Thread thread) {\n        System.err.println(\"--- Thread dump of \" + name + \" ------------------------\");\n        for (StackTraceElement element : thread.getStackTrace()) {\n            System.err.println(element);\n        }\n    }\n\n    private class LoadThread extends Thread {\n        @Override\n        public void run() {\n            for (int i = 0; i < 10; i++) {\n                System.out.println(\"Starting loadAll #\" + i);\n                dao.loadAll();\n            }\n            done.countDown();\n        }\n    }\n\n\n    private class InsertThread extends Thread {\n        volatile int counter = 0;\n\n        @Override\n        public void run() {\n            List<TestEntity> toDelete = new ArrayList<>();\n            while (done.getCount() > 0) {\n                TestEntity entity = new TestEntity();\n                entity.setSimpleStringNotNull(\"TextThread\" + counter);\n                dao.insert(entity);\n                toDelete.add(entity);\n                counter++;\n                if (counter % 10 == 0) {\n                    System.out.println(\"Thread inserted \" + counter+ \", now deleting\");\n                    dao.deleteInTx(toDelete);\n                    toDelete.clear();\n                }\n            }\n        }\n    }\n\n    private class InsertBatchThread extends Thread {\n        volatile int counter = 0;\n\n        @Override\n        public void run() {\n            List<TestEntity> batch = new ArrayList<>();\n            List<TestEntity> toDelete = new ArrayList<>();\n            while (done.getCount() > 0) {\n                TestEntity entity = new TestEntity();\n                entity.setSimpleStringNotNull(\"TextThreadBatch\" + counter);\n                batch.add(entity);\n                counter++;\n                if (counter % 10 == 0) {\n                    dao.insertInTx(batch);\n                    System.out.println(\"Batch Thread inserted \" + counter);\n                    toDelete.addAll(batch);\n                    batch.clear();\n                }\n                if (counter % 1000 == 0) {\n                    dao.deleteInTx(toDelete);\n                    toDelete.clear();\n                    System.out.println(\"Batch Thread deleted \" + counter);\n                }\n            }\n        }\n    }\n}"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/IndexTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest;\n\nimport java.util.List;\n\nimport junit.framework.Assert;\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.daotest.SqliteMaster;\nimport org.greenrobot.greendao.daotest.SqliteMasterDao;\nimport org.greenrobot.greendao.daotest.TestEntityDao;\nimport org.greenrobot.greendao.test.AbstractDaoTest;\nimport org.greenrobot.greendao.daotest.SqliteMasterDao.Properties;\n\npublic class IndexTest extends AbstractDaoTest<SqliteMasterDao, SqliteMaster, Void> {\n\n    public IndexTest() {\n        super(SqliteMasterDao.class);\n    }\n\n    public void testIndexesCreated() {\n        Assert.assertEquals(0, getIndexes().size());\n\n        TestEntityDao.createTable(db, false);\n        List<SqliteMaster> indexes = getIndexes();\n        Assert.assertEquals(2, indexes.size());\n\n        SqliteMaster index1 = indexes.get(0);\n        SqliteMaster index2 = indexes.get(1);\n        Assert.assertEquals(TestEntityDao.TABLENAME, index1.getTableName());\n        Assert.assertEquals(TestEntityDao.TABLENAME, index2.getTableName());\n        Assert.assertEquals(\"IDX_TEST_ENTITY_INDEXED_STRING\", index1.getName());\n        Assert.assertEquals(\"IDX_TEST_ENTITY_INDEXED_STRING_ASC_UNIQUE\", index2.getName());\n\n        for (SqliteMaster index : indexes) {\n            DaoLog.v(index.toString());\n        }\n    }\n    \n    public void testIndexCreateIfNotExists() {\n        Assert.assertEquals(0, getIndexes().size());\n        TestEntityDao.createTable(db, false);\n        Assert.assertEquals(2, getIndexes().size());\n        TestEntityDao.createTable(db, true);\n        Assert.assertEquals(2, getIndexes().size());\n    }\n\n    private List<SqliteMaster> getIndexes() {\n        String where = \"WHERE \" + Properties.Type.columnName + \"=? ORDER BY \" + Properties.Name.columnName;\n        List<SqliteMaster> indexes = dao.queryRaw(where, \"index\");\n        return indexes;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/LongHashMapTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest;\n\nimport java.util.Random;\n\nimport junit.framework.TestCase;\nimport org.greenrobot.greendao.internal.LongHashMap;\n\npublic class LongHashMapTest extends TestCase {\n\n    Random random;\n    private String traceName;\n    private long start;\n\n    public LongHashMapTest() {\n        this.random = new Random();\n    }\n\n    public void testLongHashMapSimple() {\n        LongHashMap<Object> map = new LongHashMap<Object>();\n\n        map.put(1l << 33, \"OK\");\n        assertNull(map.get(0));\n        assertEquals(\"OK\", map.get(1l << 33));\n\n        long keyLong = 0x7fffffffl << 33l + 14;\n        assertNull(map.remove(keyLong));\n        map.put(keyLong, \"OK\");\n        assertTrue(map.containsKey(keyLong));\n        assertEquals(\"OK\", map.remove(keyLong));\n\n        keyLong = Long.MAX_VALUE;\n        map.put(keyLong, \"OK\");\n        assertTrue(map.containsKey(keyLong));\n\n        keyLong = 8064216579113853113l;\n        map.put(keyLong, \"OK\");\n        assertTrue(map.containsKey(keyLong));\n\n    }\n\n    public void testLongHashMapRandom() {\n        LongHashMap<Object> map = new LongHashMap<Object>();\n        for (int i = 0; i < 5000; i++) {\n            long key = random.nextLong();\n            String value = \"Value-\" + key;\n            map.put(key, value);\n            assertTrue(\"\" + key, map.containsKey(key));\n\n            int keyInt = (int) key;\n            String valueInt = \"Value-\" + keyInt;\n            map.put(keyInt, valueInt);\n            assertTrue(map.containsKey(keyInt));\n\n            assertEquals(value, map.get(key));\n            assertEquals(valueInt, map.get(keyInt));\n\n            assertEquals(value, map.remove(key));\n            assertEquals(valueInt, map.remove(keyInt));\n\n            assertNull(map.get(key));\n            assertNull(map.get(keyInt));\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/async/AbstractAsyncTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.async;\n\nimport java.util.List;\nimport java.util.concurrent.CopyOnWriteArrayList;\n\nimport org.greenrobot.greendao.async.AsyncOperation;\nimport org.greenrobot.greendao.async.AsyncOperationListener;\nimport org.greenrobot.greendao.async.AsyncSession;\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\n\npublic abstract class AbstractAsyncTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> implements\n        AsyncOperationListener {\n\n    protected AsyncSession asyncSession;\n    protected List<AsyncOperation> completedOperations;\n\n    public AbstractAsyncTest() {\n        super(DaoMaster.class);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        asyncSession = daoSession.startAsyncSession();\n        asyncSession.setListener(this);\n        completedOperations = new CopyOnWriteArrayList<AsyncOperation>();\n    }\n\n    public void assertWaitForCompletion1Sec() {\n        assertTrue(asyncSession.waitForCompletion(1000));\n        assertTrue(asyncSession.isCompleted());\n    }\n\n    @Override\n    public void onAsyncOperationCompleted(AsyncOperation operation) {\n        completedOperations.add(operation);\n    }\n\n    protected void assertSingleOperationCompleted(AsyncOperation operation) {\n        assertSame(operation, completedOperations.get(0));\n        assertEquals(1, completedOperations.size());\n        assertTrue(operation.isCompleted());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/async/BasicAsyncTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.async;\n\nimport java.util.concurrent.Callable;\n\nimport android.os.Looper;\nimport org.greenrobot.greendao.async.AsyncDaoException;\nimport org.greenrobot.greendao.async.AsyncOperation;\nimport org.greenrobot.greendao.async.AsyncOperationListener;\nimport org.greenrobot.greendao.daotest.SimpleEntity;\n\npublic class BasicAsyncTest extends AbstractAsyncTest {\n\n    Thread txThread;\n    boolean testListenerMainThread_done;\n\n    public void testSequenceNumber() {\n        AsyncOperation op1 = asyncSession.count(SimpleEntity.class);\n        assertEquals(1, op1.getSequenceNumber());\n        AsyncOperation op2 = asyncSession.count(SimpleEntity.class);\n        assertEquals(2, op2.getSequenceNumber());\n    }\n\n    public void testWaitForCompletionNoOps() {\n        assertTrue(asyncSession.isCompleted());\n        assertTrue(asyncSession.waitForCompletion(1));\n        asyncSession.waitForCompletion();\n    }\n\n    public void testAsyncInsert() {\n        SimpleEntity entity = new SimpleEntity();\n        entity.setSimpleString(\"heho\");\n        AsyncOperation operation = asyncSession.insert(entity);\n        assertWaitForCompletion1Sec();\n        SimpleEntity entity2 = daoSession.load(SimpleEntity.class, entity.getId());\n        assertNotNull(entity2);\n        assertEquals(\"heho\", entity2.getSimpleString());\n        assertFalse(operation.isFailed());\n        assertSingleOperationCompleted(operation);\n    }\n\n    public void testAsyncUpdate() {\n        SimpleEntity entity = new SimpleEntity();\n        entity.setSimpleString(\"heho\");\n        daoSession.insert(entity);\n        entity.setSimpleString(\"updated\");\n        AsyncOperation operation = asyncSession.update(entity);\n        assertWaitForCompletion1Sec();\n        daoSession.clear();\n        SimpleEntity entity2 = daoSession.load(SimpleEntity.class, entity.getId());\n        assertNotNull(entity2);\n        assertEquals(\"updated\", entity2.getSimpleString());\n        assertFalse(operation.isFailed());\n        assertSingleOperationCompleted(operation);\n    }\n\n    public void testOperationGetResult() {\n        SimpleEntity entity = new SimpleEntity();\n        entity.setSimpleString(\"heho\");\n        daoSession.insert(entity);\n        daoSession.clear();\n\n        AsyncOperation operation = asyncSession.load(SimpleEntity.class, entity.getId());\n        SimpleEntity result = (SimpleEntity) operation.getResult();\n        assertTrue(operation.isCompleted());\n        assertTrue(operation.isCompletedSucessfully());\n        assertNotNull(result);\n        assertNotSame(entity, result);\n        assertEquals(entity.getId(), result.getId());\n        assertEquals(entity.getSimpleString(), result.getSimpleString());\n    }\n\n    public void testOperationGetResultException() {\n        SimpleEntity entity = new SimpleEntity();\n        daoSession.insert(entity);\n        AsyncOperation operation = asyncSession.insert(entity);\n        try {\n            operation.getResult();\n            fail(\"getResult should have thrown\");\n        } catch (AsyncDaoException expected) {\n            // OK\n        }\n        assertTrue(operation.isCompleted());\n        assertFalse(operation.isCompletedSucessfully());\n        assertTrue(operation.isFailed());\n    }\n\n    public void testAsyncException() {\n        SimpleEntity entity = new SimpleEntity();\n        daoSession.insert(entity);\n        AsyncOperation operation = asyncSession.insert(entity);\n        assertWaitForCompletion1Sec();\n        assertSingleOperationCompleted(operation);\n\n        assertTrue(operation.isFailed());\n        assertNotNull(operation.getThrowable());\n    }\n\n    public void testAsyncExceptionCreator() {\n        SimpleEntity entity = new SimpleEntity();\n        daoSession.insert(entity);\n        AsyncOperation operation = asyncSession.insert(entity);\n        assertWaitForCompletion1Sec();\n        assertNull(operation.getCreatorStacktrace());\n\n        operation = asyncSession.insert(entity, AsyncOperation.FLAG_TRACK_CREATOR_STACKTRACE);\n        assertWaitForCompletion1Sec();\n        assertNotNull(operation.getCreatorStacktrace());\n\n        asyncSession.setSessionFlags(AsyncOperation.FLAG_TRACK_CREATOR_STACKTRACE);\n        operation = asyncSession.insert(entity);\n        assertWaitForCompletion1Sec();\n        assertNotNull(operation.getCreatorStacktrace());\n        StackTraceElement[] stack = operation.getCreatorStacktrace().getStackTrace();\n        boolean found = false;\n        for (StackTraceElement stackTraceElement : stack) {\n            found |= stackTraceElement.getClassName().equals(getClass().getName());\n        }\n        assertTrue(found);\n    }\n\n    public void testAsyncOperationWaitMillis() {\n        AsyncOperation operation = asyncSession.insert(new SimpleEntity());\n        assertTrue(asyncSession.waitForCompletion(1000));\n        assertSingleOperationCompleted(operation);\n    }\n\n    public void testAsyncOperationWait() {\n        AsyncOperation operation = asyncSession.insert(new SimpleEntity());\n        asyncSession.waitForCompletion();\n        assertSingleOperationCompleted(operation);\n    }\n\n    public void testAsyncRunInTx() {\n        AsyncOperation operation = asyncSession.runInTx(new Runnable() {\n\n            @Override\n            public void run() {\n                txThread = Thread.currentThread();\n            }\n        });\n        assertWaitForCompletion1Sec();\n        assertSingleOperationCompleted(operation);\n        assertNotNull(txThread);\n        assertFalse(Thread.currentThread().equals(txThread));\n    }\n\n    public void testAsynCallInTx() {\n        AsyncOperation operation = asyncSession.callInTx(new Callable<String>() {\n\n            @Override\n            public String call() throws Exception {\n                txThread = Thread.currentThread();\n                return \"OK\";\n            }\n        });\n        assertEquals(\"OK\", operation.waitForCompletion());\n        assertNotNull(txThread);\n        assertFalse(Thread.currentThread().equals(txThread));\n    }\n\n    public void testListenerMainThread() throws InterruptedException {\n        AsyncOperationListener listener = new AsyncOperationListener() {\n            @Override\n            public synchronized void onAsyncOperationCompleted(AsyncOperation operation) {\n                assertEquals(Looper.getMainLooper(), Looper.myLooper());\n                testListenerMainThread_done = true;\n                notifyAll();\n            }\n        };\n        asyncSession.setListenerMainThread(listener);\n        asyncSession.insert(new SimpleEntity());\n        assertWaitForCompletion1Sec();\n        while (!testListenerMainThread_done) {\n            synchronized (listener) {\n                listener.wait(1000);\n            }\n        }\n    }\n\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/async/MergeTxAsyncTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.async;\n\nimport org.greenrobot.greendao.async.AsyncOperation;\nimport org.greenrobot.greendao.daotest.SimpleEntity;\n\npublic class MergeTxAsyncTest extends AbstractAsyncTest {\n\n    public void testMergeInsertAndUpdate() {\n        SimpleEntity entity = new SimpleEntity();\n        entity.setId(42l);\n        entity.setSimpleString(\"heho\");\n        \n        SimpleEntity entity2 = new SimpleEntity();\n        entity2.setId(42l);\n        entity2.setSimpleString(\"updated\");\n        \n        AsyncOperation op1 = asyncSession.insert(entity, AsyncOperation.FLAG_MERGE_TX);\n        AsyncOperation op2 = asyncSession.update(entity2, AsyncOperation.FLAG_MERGE_TX);\n        \n        assertWaitForCompletion1Sec();\n        daoSession.clear();\n        SimpleEntity entity3 = daoSession.load(SimpleEntity.class, 42l);\n        assertNotNull(entity3);\n        assertEquals(entity2.getSimpleString(), entity3.getSimpleString());\n        \n        assertEquals(2, op1.getMergedOperationsCount());\n        assertEquals(2, op2.getMergedOperationsCount());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/contentprovider/SimpleEntityContentProviderTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.contentprovider;\n\nimport android.database.Cursor;\nimport android.test.suitebuilder.annotation.Suppress;\n\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.daotest.SimpleEntity;\nimport org.greenrobot.greendao.daotest.SimpleEntityContentProvider;\nimport org.greenrobot.greendao.daotest.SimpleEntityDao;\n\n@Suppress\n// TODO Activate once the gradle build is fixed (AndroidManifest.xml is not used for instrumentTest)\npublic class SimpleEntityContentProviderTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n\n    public SimpleEntityContentProviderTest() {\n        super(DaoMaster.class);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        SimpleEntityContentProvider.daoSession = daoSession;\n    }\n\n    public void testQuery() {\n        SimpleEntity entity = new SimpleEntity();\n        entity.setSimpleString(\"hello\");\n        daoSession.insert(entity);\n        long id = entity.getId();\n\n        SimpleEntity entity2 = new SimpleEntity();\n        entity2.setSimpleString(\"content\");\n        daoSession.insert(entity2);\n        long id2 = entity2.getId();\n        Cursor cursor = getContext().getContentResolver().query(SimpleEntityContentProvider.CONTENT_URI, null,\n                null, null, \"_id\");\n        assertEquals(2, cursor.getCount());\n        int idxId = cursor.getColumnIndexOrThrow(SimpleEntityDao.Properties.Id.columnName);\n        int idxString = cursor.getColumnIndexOrThrow(SimpleEntityDao.Properties.SimpleString.columnName);\n\n        assertTrue(cursor.moveToFirst());\n        assertEquals(\"hello\", cursor.getString(idxString));\n        assertEquals(id, cursor.getLong(idxId));\n\n        assertTrue(cursor.moveToNext());\n        assertEquals(\"content\", cursor.getString(idxString));\n        assertEquals(id2, cursor.getLong(idxId));\n    }\n\n}"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/encrypted/EncryptedDataFileTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.encrypted;\n\nimport java.io.File;\nimport java.io.FileInputStream;\nimport java.io.IOException;\n\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.daotest.SimpleEntity;\n\npublic class EncryptedDataFileTest extends EncryptionSimpleEntityTest {\n\n    public static final String ENCRYPTED_DB_FILE = \"encrypted-db-file\";\n\n    @Override\n    protected Database createDatabase() {\n        getContext().deleteDatabase(ENCRYPTED_DB_FILE);\n        return EncryptedDbUtils.createDatabase(getContext(), ENCRYPTED_DB_FILE, \"password\");\n        // You can do a sanity check by disabling encryption and see the test fail:\n        // SQLiteDatabase sqLiteDatabase = getContext().openOrCreateDatabase(ENCRYPTED_DB_FILE, 0, null);\n        // return new StandardDatabase(sqLiteDatabase);\n    }\n\n    public void testFileisEncrypted() throws IOException {\n        EncryptedDbUtils.assertEncryptedDbUsed(db);\n\n        SimpleEntity simpleEntity = createEntityWithRandomPk();\n        String text = \"Catch me if you can\";\n        simpleEntity.setSimpleString(text);\n        dao.insert(simpleEntity);\n        File dbFile = getContext().getDatabasePath(ENCRYPTED_DB_FILE);\n        int length = (int) dbFile.length();\n        assertTrue(length > 0);\n        byte[] buffer = new byte[length];\n        // TODO readAll\n        int read = new FileInputStream(dbFile).read(buffer);\n        String contents = new String(buffer, 0, read, \"US-ASCII\");\n        assertFalse(contents, contents.startsWith(\"SQLite\"));\n        assertFalse(contents, contents.contains(\"CREATE TABLE\"));\n        assertFalse(contents, contents.contains(text));\n    }\n\n    public void testEncryptedDbUsed() {\n        EncryptedDbUtils.assertEncryptedDbUsed(db);\n    }\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/encrypted/EncryptedDatabaseOpenHelperTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.encrypted;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoMaster.DevOpenHelper;\nimport org.greenrobot.greendao.daotest.DaoMaster.OpenHelper;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.daotest.SimpleEntity;\nimport org.greenrobot.greendao.database.Database;\n\npublic class EncryptedDatabaseOpenHelperTest extends ApplicationTestCase {\n\n    public EncryptedDatabaseOpenHelperTest() {\n        super(Application.class);\n    }\n\n    public void testEncryptedDevOpenHelper() {\n        createApplication();\n        Database db = new DevOpenHelper(getApplication(), null).getEncryptedReadableDb(\"password\");\n        assertDbEncryptedAndFunctional(db);\n    }\n\n    public void testEncryptedOpenHelper() {\n        createApplication();\n        Database db = new OpenHelper(getApplication(), null) {\n            @Override\n            public void onUpgrade(Database db, int oldVersion, int newVersion) {\n\n            }\n        }.getEncryptedReadableDb(\"password\");\n        assertDbEncryptedAndFunctional(db);\n    }\n\n    private void assertDbEncryptedAndFunctional(Database db) {\n        EncryptedDbUtils.assertEncryptedDbUsed(db);\n        DaoSession daoSession = new DaoMaster(db).newSession();\n        daoSession.insert(new SimpleEntity());\n        assertEquals(1, daoSession.loadAll(SimpleEntity.class).size());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/encrypted/EncryptedDbUtils.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.encrypted;\n\nimport android.content.Context;\nimport android.database.Cursor;\n\nimport net.sqlcipher.database.SQLiteDatabase;\n\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.EncryptedDatabase;\n\nimport java.io.File;\n\nimport static junit.framework.Assert.assertEquals;\nimport static junit.framework.Assert.assertTrue;\n\n/**\n * Helper to create encrypted databases.\n */\npublic class EncryptedDbUtils {\n    private static boolean loadedLibs;\n\n    public static Database createDatabase(Context context, String dbName, String password) {\n        if (!loadedLibs) {\n            loadedLibs = true;\n            SQLiteDatabase.loadLibs(context);\n        }\n        SQLiteDatabase sqLiteDatabase;\n        if (dbName == null) {\n            sqLiteDatabase = SQLiteDatabase.create(null, password);\n        } else {\n            File dbFile = context.getDatabasePath(dbName);\n            dbFile.getParentFile().mkdir();\n            context.deleteDatabase(dbName);\n            sqLiteDatabase = SQLiteDatabase.openOrCreateDatabase(dbFile, password, null);\n        }\n        return new EncryptedDatabase(sqLiteDatabase);\n    }\n\n    public static String queryString(Database db, String sql) {\n        Cursor cursor = db.rawQuery(sql, null);\n        try {\n            assertTrue(cursor.moveToNext());\n            return cursor.getString(0);\n        } finally {\n            cursor.close();\n        }\n    }\n\n    public static void assertEncryptedDbUsed(Database db) {\n        assertEquals(\"3.15.2\", queryString(db, \"select sqlite_version()\"));\n        String cipherProvider = queryString(db, \"PRAGMA cipher_provider_version\");\n        assertTrue(cipherProvider, cipherProvider.contains(\"OpenSSL\"));\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/encrypted/EncryptionSimpleEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.encrypted;\n\nimport net.sqlcipher.database.SQLiteConstraintException;\n\nimport java.util.List;\n\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.daotest.SimpleEntity;\nimport org.greenrobot.greendao.daotest.SimpleEntityDao.Properties;\nimport org.greenrobot.greendao.daotest.entity.SimpleEntityTest;\n\npublic class EncryptionSimpleEntityTest extends SimpleEntityTest {\n    @Override\n    protected Database createDatabase() {\n        return EncryptedDbUtils.createDatabase(getContext(), null, \"password\");\n    }\n\n    @Override\n    public void testInsertTwice() {\n        try {\n            super.testInsertTwice();\n            fail(\"Expected SQLCipher exception\");\n        } catch (SQLiteConstraintException ex) {\n            // OK, expected\n        }\n    }\n\n    public void testEncryptedDbUsed() {\n        EncryptedDbUtils.assertEncryptedDbUsed(db);\n    }\n\n    public void testOrderAscString() {\n        // SQLCipher 3.5.0 does not understand \"COLLATE LOCALIZED ASC\" and crashed here initially\n        List<SimpleEntity> result = dao.queryBuilder().orderAsc(Properties.SimpleString).list();\n        assertEquals(0, result.size());\n    }\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/AbcdefEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\nimport org.greenrobot.greendao.daotest.AbcdefEntity;\nimport org.greenrobot.greendao.daotest.AbcdefEntityDao;\n\npublic class AbcdefEntityTest extends AbstractDaoTestLongPk<AbcdefEntityDao, AbcdefEntity> {\n\n    public AbcdefEntityTest() {\n        super(AbcdefEntityDao.class);\n    }\n\n    @Override\n    protected AbcdefEntity createEntity(Long key) {\n        AbcdefEntity entity = new AbcdefEntity();\n        entity.setId(key);\n        return entity;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/AnActiveEntityMultithreadingTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport java.lang.reflect.Field;\nimport java.util.concurrent.CountDownLatch;\nimport java.util.concurrent.TimeUnit;\n\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\nimport org.greenrobot.greendao.daotest.AnActiveEntity;\nimport org.greenrobot.greendao.daotest.AnActiveEntityDao;\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\n\npublic class AnActiveEntityMultithreadingTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n\n    /** Serious multithreading tests require this set to true. */\n    private static final boolean LONG_RUNNING = false;\n    private static final int ENTITIES_TO_CHECK = LONG_RUNNING ? 1000000 : 10000;\n\n    private AnActiveEntityDao dao;\n    private CountDownLatch latch = new CountDownLatch(2);\n    volatile boolean running = true;\n\n    public AnActiveEntityMultithreadingTest() {\n        super(DaoMaster.class);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        dao = daoSession.getAnActiveEntityDao();\n    }\n\n    public void testAlwaysAttachedWithInsertDelete() throws Exception {\n        doTestAlwaysAttached(new InsertDeleteThread());\n    }\n\n    public void testAlwaysAttachedWithDetach() throws Exception {\n        doTestAlwaysAttached(new DetachThread());\n    }\n\n    private void doTestAlwaysAttached(Thread thread) throws Exception {\n        thread.start();\n\n        Field daoSessionField = AnActiveEntity.class.getDeclaredField(\"daoSession\");\n        daoSessionField.setAccessible(true);\n\n        int countEntity = 0;\n        countDownAndAwaitLatch();\n\n        try {\n            assertTrue(latch.await(10, TimeUnit.SECONDS));\n            for (int i = 0;; i++) {\n                AnActiveEntity entity = dao.load(1l);\n                if (entity != null) {\n                    countEntity++;\n                    assertNotNull(daoSessionField.get(entity));\n                }\n                if (i == 1000000 && countEntity == 0) {\n                    fail(\"No entity available\");\n                }\n                if (countEntity % 10000 == 0) {\n                    DaoLog.d(\"Checked entities \" + countEntity + \" in \" + i + \" iterations\");\n                }\n                if (countEntity == ENTITIES_TO_CHECK) {\n                    break;\n                }\n            }\n        } finally {\n            running = false;\n            thread.join();\n        }\n    }\n\n    private void countDownAndAwaitLatch() {\n        latch.countDown();\n        try {\n            assertTrue(latch.await(10, TimeUnit.SECONDS));\n        } catch (InterruptedException e) {\n            throw new RuntimeException(e);\n        }\n    }\n\n    class InsertDeleteThread extends Thread {\n        @Override\n        public void run() {\n            countDownAndAwaitLatch();\n\n            while (running) {\n                AnActiveEntity entity = null;\n                entity = new AnActiveEntity(1l);\n                dao.insert(entity);\n                dao.delete(entity);\n            }\n        }\n    }\n\n    class DetachThread extends Thread {\n        @Override\n        public void run() {\n            countDownAndAwaitLatch();\n\n            AnActiveEntity entity = new AnActiveEntity(1l);\n            dao.insert(entity);\n            while (running) {\n                dao.detach(entity);\n                entity = dao.load(1l);\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/AnActiveEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\nimport org.greenrobot.greendao.daotest.AnActiveEntity;\nimport org.greenrobot.greendao.daotest.AnActiveEntityDao;\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\n\npublic class AnActiveEntityTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n\n    private AnActiveEntityDao dao;\n\n    public AnActiveEntityTest() {\n        super(DaoMaster.class);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        dao = daoSession.getAnActiveEntityDao();\n    }\n\n    public void testThrowWhenDetached() {\n        AnActiveEntity entity = new AnActiveEntity();\n        try {\n            entity.delete();\n            fail(\"Should fail for detached entity\");\n        } catch (DaoException e) {\n            // OK, expected\n        }\n        try {\n            entity.refresh();\n            fail(\"Should fail for detached entity\");\n        } catch (DaoException e) {\n            // OK, expected\n        }\n        try {\n            entity.update();\n            fail(\"Should fail for detached entity\");\n        } catch (DaoException e) {\n            // OK, expected\n        }\n    }\n\n    public void testActiveUpdate() {\n        AnActiveEntity entity = new AnActiveEntity(1l);\n        long rowId = dao.insert(entity);\n\n        entity.setText(\"NEW\");\n        entity.update();\n\n        daoSession.clear();\n        AnActiveEntity entity2 = dao.load(rowId);\n        assertNotSame(entity, entity2);\n        assertEquals(\"NEW\", entity2.getText());\n    }\n\n    public void testActiveRefresh() {\n        AnActiveEntity entity = new AnActiveEntity(1l);\n        dao.insert(entity);\n\n        AnActiveEntity entity2 = new AnActiveEntity(1l);\n        entity2.setText(\"NEW\");\n        dao.update(entity2);\n\n        entity.refresh();\n        assertEquals(\"NEW\", entity.getText());\n    }\n\n    public void testActiveDelete() {\n        AnActiveEntity entity = new AnActiveEntity(1l);\n        dao.insert(entity);\n\n        entity.delete();\n        assertNull(dao.load(1l));\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/AutoincrementEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\nimport org.greenrobot.greendao.daotest.AutoincrementEntity;\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.daotest.SimpleEntity;\n\npublic class AutoincrementEntityTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n\n    public AutoincrementEntityTest() {\n        super(DaoMaster.class);\n    }\n\n    public void testAutoincrement() {\n        AutoincrementEntity entity = new AutoincrementEntity();\n        daoSession.insert(entity);\n        Long id1 = entity.getId();\n        assertNotNull(id1);\n        daoSession.delete(entity);\n\n        AutoincrementEntity entity2 = new AutoincrementEntity();\n        daoSession.insert(entity2);\n        assertEquals(id1 + 1, (long) entity2.getId());\n    }\n\n    public void testNoAutoincrement() {\n        SimpleEntity entity = new SimpleEntity();\n        daoSession.insert(entity);\n        Long id1 = entity.getId();\n        assertNotNull(id1);\n        daoSession.delete(entity);\n\n        SimpleEntity entity2 = new SimpleEntity();\n        daoSession.insert(entity2);\n        assertEquals(id1, entity2.getId());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/CustomTypeEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.daotest.CustomTypeEntity;\nimport org.greenrobot.greendao.daotest.CustomTypeEntityDao;\nimport org.greenrobot.greendao.daotest.customtype.MyTimestamp;\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\n\nimport java.util.List;\n\npublic class CustomTypeEntityTest extends AbstractDaoTestLongPk<CustomTypeEntityDao, CustomTypeEntity> {\n\n    public CustomTypeEntityTest() {\n        super(CustomTypeEntityDao.class);\n    }\n\n    @Override\n    protected CustomTypeEntity createEntity(Long key) {\n        CustomTypeEntity entity = new CustomTypeEntity();\n        entity.setId(key);\n        MyTimestamp myCustomTimestamp = new MyTimestamp();\n        myCustomTimestamp.timestamp = System.currentTimeMillis();\n        entity.setMyCustomTimestamp(myCustomTimestamp);\n        return entity;\n    }\n\n    public void testCustomTypeValue() {\n        CustomTypeEntity entity = createEntityWithRandomPk();\n        long timestamp = entity.getMyCustomTimestamp().timestamp;\n        dao.insert(entity);\n\n        List<CustomTypeEntity> all = dao.loadAll();\n        assertEquals(1, all.size());\n        assertEquals(timestamp, all.get(0).getMyCustomTimestamp().timestamp);\n    }\n\n    public void testCustomTypeValueNull() {\n        CustomTypeEntity entity = createEntityWithRandomPk();\n        entity.setMyCustomTimestamp(null);\n        dao.insert(entity);\n\n        List<CustomTypeEntity> all = dao.loadAll();\n        assertEquals(1, all.size());\n        assertNull(all.get(0).getMyCustomTimestamp());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/DateEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport java.util.Date;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\nimport org.greenrobot.greendao.daotest.DateEntity;\nimport org.greenrobot.greendao.daotest.DateEntityDao;\n\npublic class DateEntityTest extends AbstractDaoTestLongPk<DateEntityDao, DateEntity> {\n\n    public DateEntityTest() {\n        super(DateEntityDao.class);\n    }\n\n    @Override\n    protected DateEntity createEntity(Long key) {\n        DateEntity entity = new DateEntity();\n        entity.setId(key);\n        entity.setDateNotNull(new Date());\n        return entity;\n    }\n    \n    public void testValues() {\n        DateEntity entity = createEntity(1l);\n        dao.insert(entity);\n        \n        DateEntity reloaded = dao.load(entity.getId());\n        assertNull(reloaded.getDate());\n        assertNotNull(reloaded.getDateNotNull());\n        assertEquals(entity.getDateNotNull(), reloaded.getDateNotNull());\n    }\n\n    public void testValues2() {\n        DateEntity entity = createEntity(1l);\n        long t1=32479875;\n        long t2=976345942443435235l;\n        entity.setDate(new Date(t1));\n        entity.setDateNotNull(new Date(t2));\n        dao.insert(entity);\n        \n        DateEntity reloaded = dao.load(entity.getId());\n        assertNotNull(reloaded.getDate());\n        assertNotNull(reloaded.getDateNotNull());\n        assertEquals(t1, reloaded.getDate().getTime());\n        assertEquals(t2, reloaded.getDateNotNull().getTime());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/ExtendsImplementsEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport java.io.Serializable;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\nimport org.greenrobot.greendao.daotest.ExtendsImplementsEntity;\nimport org.greenrobot.greendao.daotest.ExtendsImplementsEntityDao;\nimport org.greenrobot.greendao.daotest.TestInterface;\nimport org.greenrobot.greendao.daotest.TestSuperclass;\n\npublic class ExtendsImplementsEntityTest extends\n        AbstractDaoTestLongPk<ExtendsImplementsEntityDao, ExtendsImplementsEntity> {\n\n    public ExtendsImplementsEntityTest() {\n        super(ExtendsImplementsEntityDao.class);\n    }\n\n    @Override\n    protected ExtendsImplementsEntity createEntity(Long key) {\n        ExtendsImplementsEntity entity = new ExtendsImplementsEntity();\n        entity.setId(key);\n        return entity;\n    }\n\n    public void testInheritance() {\n        ExtendsImplementsEntity entity = createEntityWithRandomPk();\n        assertTrue(entity instanceof TestSuperclass);\n        assertTrue(entity instanceof TestInterface);\n        assertTrue(entity instanceof Serializable);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/IndexedStringEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\n\nimport org.greenrobot.greendao.daotest.IndexedStringEntity;\nimport org.greenrobot.greendao.daotest.IndexedStringEntityDao;\n\npublic class IndexedStringEntityTest extends AbstractDaoTestLongPk<IndexedStringEntityDao, IndexedStringEntity> {\n\n    public IndexedStringEntityTest() {\n        super(IndexedStringEntityDao.class);\n    }\n\n    @Override\n    protected IndexedStringEntity createEntity(Long key) {\n        IndexedStringEntity entity = new IndexedStringEntity();\n        entity.setId(key);\n        return entity;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/JoinManyToDateEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\n\nimport org.greenrobot.greendao.daotest.JoinManyToDateEntity;\nimport org.greenrobot.greendao.daotest.JoinManyToDateEntityDao;\n\npublic class JoinManyToDateEntityTest extends AbstractDaoTestLongPk<JoinManyToDateEntityDao, JoinManyToDateEntity> {\n\n    public JoinManyToDateEntityTest() {\n        super(JoinManyToDateEntityDao.class);\n    }\n\n    @Override\n    protected JoinManyToDateEntity createEntity(Long key) {\n        JoinManyToDateEntity entity = new JoinManyToDateEntity();\n        entity.setId(key);\n        return entity;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/RelationEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport java.util.List;\n\nimport org.greenrobot.greendao.identityscope.IdentityScopeType;\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.daotest.RelationEntity;\nimport org.greenrobot.greendao.daotest.RelationEntityDao;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao;\n\npublic class RelationEntityTest extends AbstractDaoTestLongPk<RelationEntityDao, RelationEntity> {\n\n    protected DaoMaster daoMaster;\n    protected DaoSession daoSession;\n    /** set before calling setUp of this class. */\n    protected IdentityScopeType identityScopeTypeForSession;\n\n    public RelationEntityTest() {\n        super(RelationEntityDao.class);\n        identityScopeTypeForSession = IdentityScopeType.None;\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        TestEntityDao.createTable(db, false);\n        daoMaster = new DaoMaster(db);\n        daoSession = daoMaster.newSession(identityScopeTypeForSession);\n        dao = daoSession.getRelationEntityDao();\n    }\n\n    @Override\n    protected RelationEntity createEntity(Long key) {\n        RelationEntity entity = new RelationEntity();\n        entity.setId(key);\n        return entity;\n    }\n\n    public void testToOne() {\n        RelationEntity entity = insertEntityWithRelations(42l);\n        entity = dao.load(entity.getId());\n        assertTestEntity(entity);\n    }\n\n    public void testToOneSelf() {\n        RelationEntity entity = createEntity(1l);\n        dao.insert(entity);\n\n        entity = dao.load(1l);\n        assertNull(entity.getParent());\n\n        entity.setParentId(entity.getId());\n        dao.update(entity);\n\n        entity = dao.load(1l);\n        RelationEntity parent = entity.getParent();\n        assertEquals(entity.getId(), parent.getId());\n    }\n\n    public void testToOneClearKey() {\n        RelationEntity entity = insertEntityWithRelations(42l);\n        assertNotNull(entity.getParent());\n        entity.setParentId(null);\n        assertNull(entity.getParent());\n    }\n\n    public void testToOneClearEntity() {\n        RelationEntity entity = insertEntityWithRelations(42l);\n        assertNotNull(entity.getParentId());\n        entity.setParent(null);\n        assertNull(entity.getParentId());\n    }\n\n    public void testToOneUpdateKey() {\n        RelationEntity entity = insertEntityWithRelations(42l);\n        TestEntity testEntity = entity.getTestEntity();\n        RelationEntity entity2 = insertEntityWithRelations(43l);\n        TestEntity testEntity2 = entity2.getTestEntity();\n\n        entity.setTestId(testEntity2.getId());\n        assertEquals(testEntity2.getId(), entity.getTestEntity().getId());\n\n        entity.setTestId(null);\n        assertNull(entity.getTestEntity());\n\n        entity.setTestId(testEntity.getId());\n        assertEquals(testEntity.getId(), entity.getTestEntity().getId());\n    }\n\n    public void testToOneUpdateEntity() {\n        RelationEntity entity = insertEntityWithRelations(42l);\n        TestEntity testEntity = entity.getTestEntity();\n        RelationEntity entity2 = insertEntityWithRelations(43l);\n        TestEntity testEntity2 = entity2.getTestEntity();\n\n        entity.setTestEntity(testEntity2);\n        assertEquals(testEntity2.getId(), entity.getTestId());\n\n        entity.setTestEntity(null);\n        assertNull(entity.getTestId());\n\n        entity.setTestEntity(testEntity);\n        assertEquals(testEntity.getId(), entity.getTestId());\n    }\n\n    public void testToOneLoadDeep() {\n        RelationEntity entity = insertEntityWithRelations(42l);\n        entity = dao.loadDeep(entity.getId());\n        assertTestEntity(entity);\n    }\n\n    public void testToOneNoMatch() {\n        RelationEntity entity = insertEntityWithRelations(42l);\n        assertNotNull(entity.getTestEntity());\n        entity.setTestId(23l);\n        entity.setTestIdNotNull(-78);\n        assertNull(entity.getTestEntity());\n        assertNull(entity.getTestNotNull());\n    }\n\n    public void testToOneNoMatchLoadDeep() {\n        RelationEntity entity = insertEntityWithRelations(42l);\n        assertNotNull(entity.getTestEntity());\n        entity.setTestId(23l);\n        entity.setTestIdNotNull(-78);\n        dao.update(entity);\n        entity = dao.loadDeep(entity.getId());\n        assertNull(entity.getTestEntity());\n        assertNull(entity.getTestNotNull());\n    }\n\n    public void testToOneLoadDeepNull() {\n        RelationEntity entity = insertEntityWithRelations(42l);\n        entity.setParentId(null);\n        entity.setTestId(null);\n        dao.update(entity);\n        entity = dao.loadDeep(entity.getId());\n        assertNull(entity.getParent());\n        assertNull(entity.getTestEntity());\n    }\n\n    public void testQueryDeep() {\n        insertEntityWithRelations(42l);\n        String columnName = RelationEntityDao.Properties.SimpleString.columnName;\n        List<RelationEntity> entityList = dao.queryDeep(\"WHERE T.\" + columnName + \"=?\", \"findMe\");\n        assertEquals(1, entityList.size());\n        assertTestEntity(entityList.get(0));\n    }\n\n    protected RelationEntity insertEntityWithRelations(Long testEntityId) {\n        TestEntity testEntity = daoSession.getTestEntityDao().load(testEntityId);\n        if (testEntity == null) {\n            testEntity = new TestEntity(testEntityId);\n            testEntity.setSimpleStringNotNull(\"mytest\");\n            daoSession.getTestEntityDao().insert(testEntity);\n        }\n\n        RelationEntity parentEntity = createEntity(null);\n        parentEntity.setSimpleString(\"I'm a parent\");\n        parentEntity.setTestNotNull(testEntity);\n        dao.insert(parentEntity);\n\n        RelationEntity entity = createEntity(null);\n        entity.setTestId(testEntityId);\n        entity.setParentId(parentEntity.getId());\n        entity.setSimpleString(\"findMe\");\n        entity.setTestNotNull(testEntity);\n        dao.insert(entity);\n\n        return entity;\n    }\n\n    protected void assertTestEntity(RelationEntity entity) {\n        TestEntity testEntity = entity.getTestEntity();\n        assertNotNull(testEntity);\n        assertEquals(42l, (long) testEntity.getId());\n        assertEquals(\"mytest\", testEntity.getSimpleStringNotNull());\n        assertEquals(\"I'm a parent\", entity.getParent().getSimpleString());\n        assertEquals(entity.getParentId(), entity.getParent().getId());\n        assertNotNull(entity.getTestNotNull());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/RelationEntityTestIdentityScope.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport java.util.List;\n\nimport org.greenrobot.greendao.identityscope.IdentityScopeType;\nimport org.greenrobot.greendao.daotest.RelationEntity;\nimport org.greenrobot.greendao.daotest.RelationEntityDao;\n\n/**\n * @author Markus\n */\npublic class RelationEntityTestIdentityScope extends RelationEntityTest {\n\n    @Override\n    protected void setUp() throws Exception {\n        identityScopeTypeForSession = IdentityScopeType.Session;\n        super.setUp();\n    }\n\n    public void testToOneLoadDeepIdentityScope() {\n        RelationEntity entity = insertEntityWithRelations(42l);\n        RelationEntity entity2 = insertEntityWithRelations(42l);\n        entity = dao.loadDeep(entity.getId());\n        entity2 = dao.loadDeep(entity2.getId());\n        assertFalse(entity.getId().equals(entity2.getId()));\n        assertTestEntity(entity);\n        assertTestEntity(entity2);\n        assertSame(entity.getTestEntity(), entity2.getTestEntity());\n    }\n\n    public void testToQueryDeepIdentityScope() {\n        insertEntityWithRelations(42l);\n        RelationEntity entity2 = insertEntityWithRelations(42l);\n        String columnName = RelationEntityDao.Properties.SimpleString.columnName;\n        List<RelationEntity> entityList = dao.queryDeep(\"WHERE T.\" + columnName + \"=?\", \"findMe\");\n        assertEquals(2, entityList.size());\n        RelationEntity entity = entityList.get(0);\n        assertTestEntity(entity);\n        entity2 = entityList.get(1);\n        assertTestEntity(entity2);\n        assertSame(entity.getTestEntity(), entity2.getTestEntity());\n    }\n\n    public void testLoadDeepIdentityScope() {\n        RelationEntity entity = insertEntityWithRelations(42l);\n        RelationEntity entity2 = dao.loadDeep(entity.getId());\n        RelationEntity entity3 = dao.loadDeep(entity.getId());\n        assertSame(entity, entity2);\n        assertSame(entity, entity3);\n        assertTestEntity(entity);\n    }\n\n    public void testQueryDeepIdentityScope() {\n        RelationEntity entity = insertEntityWithRelations(42l);\n\n        String columnName = RelationEntityDao.Properties.SimpleString.columnName;\n        List<RelationEntity> entityList = dao.queryDeep(\"WHERE T.\" + columnName + \"=?\", \"findMe\");\n        RelationEntity entity2 = entityList.get(0);\n        entityList = dao.queryDeep(\"WHERE T.\" + columnName + \"=?\", \"findMe\");\n        RelationEntity entity3 = entityList.get(0);\n\n        assertSame(entity, entity2);\n        assertSame(entity, entity3);\n        assertTestEntity(entity);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/SimpleEntityNotNullTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport java.util.Arrays;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\nimport org.greenrobot.greendao.daotest.SimpleEntityNotNull;\nimport org.greenrobot.greendao.daotest.SimpleEntityNotNullDao;\n\npublic class SimpleEntityNotNullTest extends AbstractDaoTestLongPk<SimpleEntityNotNullDao, SimpleEntityNotNull> {\n\n    public SimpleEntityNotNullTest() {\n        super(SimpleEntityNotNullDao.class);\n    }\n\n    @Override\n    protected SimpleEntityNotNull createEntity(Long key) {\n        return SimpleEntityNotNullHelper.createEntity(key);\n    }\n\n    public void testValues() {\n        SimpleEntityNotNull entity = createEntity(1l);\n        dao.insert(entity);\n        SimpleEntityNotNull reloaded = dao.load(1l);\n        assertEqualProperties(entity, reloaded);\n    }\n\n    protected static void assertEqualProperties(SimpleEntityNotNull entity, SimpleEntityNotNull reloaded) {\n        assertNotSame(entity, reloaded);\n\n        assertEquals(entity.getId(), reloaded.getId());\n        assertEquals(entity.getSimpleBoolean(), reloaded.getSimpleBoolean());\n        assertEquals(entity.getSimpleDouble(), reloaded.getSimpleDouble());\n        assertEquals(entity.getSimpleFloat(), reloaded.getSimpleFloat());\n        assertEquals(entity.getSimpleLong(), reloaded.getSimpleLong());\n        assertEquals(entity.getSimpleByte(), reloaded.getSimpleByte());\n        assertEquals(entity.getSimpleInt(), reloaded.getSimpleInt());\n        assertEquals(entity.getSimpleShort(), reloaded.getSimpleShort());\n        assertEquals(entity.getSimpleBoolean(), reloaded.getSimpleBoolean());\n        assertEquals(entity.getSimpleString(), reloaded.getSimpleString());\n        assertTrue(Arrays.equals(entity.getSimpleByteArray(), reloaded.getSimpleByteArray()));\n    }\n\n    public void testUpdateValues() {\n        SimpleEntityNotNull entity = createEntity(1l);\n        dao.insert(entity);\n        entity = dao.load(1l);\n\n        entity.setSimpleBoolean(false);\n        entity.setSimpleByte(Byte.MIN_VALUE);\n        entity.setSimpleShort(Short.MIN_VALUE);\n        entity.setSimpleInt(Integer.MIN_VALUE);\n        entity.setSimpleLong(Long.MIN_VALUE);\n        entity.setSimpleFloat(Float.MIN_VALUE);\n        entity.setSimpleDouble(Double.MIN_VALUE);\n        entity.setSimpleString(\"greenDAO\");\n        byte[] bytes = { -1, 0, 1 };\n        entity.setSimpleByteArray(bytes);\n        dao.update(entity);\n\n        SimpleEntityNotNull reloaded = dao.load(1l);\n        assertEqualProperties(entity, reloaded);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/SimpleEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport java.util.Arrays;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\nimport org.greenrobot.greendao.daotest.SimpleEntity;\nimport org.greenrobot.greendao.daotest.SimpleEntityDao;\n\npublic class SimpleEntityTest extends AbstractDaoTestLongPk<SimpleEntityDao, SimpleEntity> {\n\n    public SimpleEntityTest() {\n        super(SimpleEntityDao.class);\n    }\n\n    @Override\n    protected SimpleEntity createEntity(Long key) {\n        SimpleEntity entity = new SimpleEntity();\n        entity.setId(key);\n        return entity;\n    }\n\n    public void testValuesNull() {\n        SimpleEntity entity = createEntity(1l);\n        dao.insert(entity);\n        SimpleEntity reloaded = dao.load(1l);\n        assertNotSame(entity, reloaded);\n\n        assertEquals(entity.getId(), reloaded.getId());\n        assertValuesNull(reloaded);\n    }\n\n    public void testValues() {\n        SimpleEntity entity = createEntity(1l);\n        setValues(entity);\n        dao.insert(entity);\n        SimpleEntity reloaded = dao.load(1l);\n        assertNotSame(entity, reloaded);\n        assertValues(reloaded);\n    }\n\n    public void testUpdateValues() {\n        SimpleEntity entity = createEntity(1l);\n        dao.insert(entity);\n        entity = dao.load(1l);\n        setValues(entity);\n        dao.update(entity);\n        SimpleEntity reloaded = dao.load(1l);\n        assertNotSame(entity, reloaded);\n        assertValues(reloaded);\n    }\n\n    public void testUpdateValuesToNull() {\n        SimpleEntity entity = createEntity(1l);\n        setValues(entity);\n        dao.insert(entity);\n        entity = dao.load(1l);\n        assertValues(entity);\n        setValuesToNull(entity);\n        dao.update(entity);\n        SimpleEntity reloaded = dao.load(1l);\n        assertNotSame(entity, reloaded);\n        assertValuesNull(reloaded);\n    }\n\n    protected void assertValues(SimpleEntity reloaded) {\n        assertEquals(1l, (long) reloaded.getId());\n        assertEquals(true, (boolean) reloaded.getSimpleBoolean());\n        assertEquals(Double.MAX_VALUE, reloaded.getSimpleDouble());\n        assertEquals(Float.MAX_VALUE, reloaded.getSimpleFloat());\n        assertEquals(Long.MAX_VALUE, (long) reloaded.getSimpleLong());\n        assertEquals(Byte.MAX_VALUE, (byte) reloaded.getSimpleByte());\n        assertEquals(Integer.MAX_VALUE, (int) reloaded.getSimpleInt());\n        assertEquals(Short.MAX_VALUE, (short) reloaded.getSimpleShort());\n        assertEquals(\"greenrobot greenDAO\", reloaded.getSimpleString());\n        byte[] bytes = { 42, -17, 23, 0, 127, -128 };\n        assertTrue(Arrays.equals(bytes, reloaded.getSimpleByteArray()));\n    }\n\n    protected void setValues(SimpleEntity entity) {\n        entity.setSimpleBoolean(true);\n        entity.setSimpleByte(Byte.MAX_VALUE);\n        entity.setSimpleShort(Short.MAX_VALUE);\n        entity.setSimpleInt(Integer.MAX_VALUE);\n        entity.setSimpleLong(Long.MAX_VALUE);\n        entity.setSimpleFloat(Float.MAX_VALUE);\n        entity.setSimpleDouble(Double.MAX_VALUE);\n        entity.setSimpleString(\"greenrobot greenDAO\");\n        byte[] bytes = { 42, -17, 23, 0, 127, -128 };\n        entity.setSimpleByteArray(bytes);\n    }\n\n    protected void setValuesToNull(SimpleEntity entity) {\n        entity.setSimpleBoolean(null);\n        entity.setSimpleByte(null);\n        entity.setSimpleShort(null);\n        entity.setSimpleInt(null);\n        entity.setSimpleLong(null);\n        entity.setSimpleFloat(null);\n        entity.setSimpleDouble(null);\n        entity.setSimpleString(null);\n        entity.setSimpleByteArray(null);\n    }\n\n    protected void assertValuesNull(SimpleEntity reloaded) {\n        assertNull(reloaded.getSimpleBoolean());\n        assertNull(reloaded.getSimpleDouble());\n        assertNull(reloaded.getSimpleFloat());\n        assertNull(reloaded.getSimpleLong());\n        assertNull(reloaded.getSimpleByte());\n        assertNull(reloaded.getSimpleInt());\n        assertNull(reloaded.getSimpleShort());\n        assertNull(reloaded.getSimpleBoolean());\n        assertNull(reloaded.getSimpleString());\n        assertNull(reloaded.getSimpleByteArray());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/SpecialNamesEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\nimport org.greenrobot.greendao.daotest.SpecialNamesEntity;\nimport org.greenrobot.greendao.daotest.SpecialNamesEntityDao;\n\npublic class SpecialNamesEntityTest extends AbstractDaoTestLongPk<SpecialNamesEntityDao, SpecialNamesEntity> {\n\n    public SpecialNamesEntityTest() {\n        super(SpecialNamesEntityDao.class);\n    }\n\n    @Override\n    protected SpecialNamesEntity createEntity(Long key) {\n        SpecialNamesEntity entity = new SpecialNamesEntity();\n        entity.setId(key);\n        return entity;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/SqliteMasterTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport java.util.List;\n\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.test.AbstractDaoTest;\nimport org.greenrobot.greendao.daotest.SqliteMaster;\nimport org.greenrobot.greendao.daotest.SqliteMasterDao;\nimport org.greenrobot.greendao.daotest.SqliteMasterDao.Properties;\n\npublic class SqliteMasterTest extends AbstractDaoTest<SqliteMasterDao, SqliteMaster, Void> {\n\n    public SqliteMasterTest() {\n        super(SqliteMasterDao.class);\n    }\n\n    public void testLoadAll() {\n        List<SqliteMaster> all = dao.loadAll();\n        for (SqliteMaster meta : all) {\n            DaoLog.v(meta.toString());\n        }\n    }\n\n    public void testQueryRaw() {\n        List<SqliteMaster> tables = dao.queryRaw(\"WHERE \" + Properties.Type.columnName + \"=?\", \"table\");\n        for (SqliteMaster table : tables) {\n            DaoLog.v(table.toString());\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/StringKeyValueEntityIdentityScopeTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.identityscope.IdentityScopeObject;\nimport org.greenrobot.greendao.daotest.StringKeyValueEntity;\n\npublic class StringKeyValueEntityIdentityScopeTest extends StringKeyValueEntityTest {\n    @Override\n    protected void setUp() throws Exception {\n        setIdentityScopeBeforeSetUp(new IdentityScopeObject<String, StringKeyValueEntity>());\n        super.setUp();\n    }\n\n    public void testLoadIdScope() {\n        StringKeyValueEntity entity = createEntityWithRandomPk();\n        dao.insert(entity);\n        StringKeyValueEntity entity2 = dao.load(entity.getKey());\n        StringKeyValueEntity entity3 = dao.load(entity.getKey());\n\n        assertSame(entity, entity2);\n        assertSame(entity2, entity3);\n    }\n\n    public void testLoadIdScope_load() {\n        StringKeyValueEntity entity = createEntityWithRandomPk();\n        dao.insert(entity);\n        dao.detach(entity);\n        StringKeyValueEntity entity2 = dao.load(entity.getKey());\n        StringKeyValueEntity entity3 = dao.load(entity.getKey());\n\n        assertNotSame(entity, entity2);\n        assertSame(entity2, entity3);\n    }\n\n    public void testDetach() {\n        StringKeyValueEntity entity = createEntityWithRandomPk();\n        dao.insert(entity);\n        dao.detach(entity);\n        StringKeyValueEntity entity2 = dao.load(entity.getKey());\n        dao.detach(entity2);\n        StringKeyValueEntity entity3 = dao.load(entity.getKey());\n\n        assertNotSame(entity, entity2);\n        assertNotSame(entity2, entity3);\n        assertNotSame(entity, entity3);\n    }\n\n    public void testDetachOther() {\n        StringKeyValueEntity entity = createEntityWithRandomPk();\n        dao.insert(entity);\n        dao.detach(entity);\n        StringKeyValueEntity entity2 = dao.load(entity.getKey());\n        dao.detach(entity);\n        StringKeyValueEntity entity3 = dao.load(entity.getKey());\n\n        assertSame(entity2, entity3);\n    }\n\n    public void testLoadAllScope() {\n        StringKeyValueEntity entity = createEntityWithRandomPk();\n        dao.insert(entity);\n        StringKeyValueEntity entity2 = dao.loadAll().get(0);\n        StringKeyValueEntity entity3 = dao.loadAll().get(0);\n\n        assertSame(entity, entity2);\n        assertSame(entity2, entity3);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/StringKeyValueEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport junit.framework.Assert;\nimport org.greenrobot.greendao.test.AbstractDaoTestStringPk;\nimport org.greenrobot.greendao.daotest.StringKeyValueEntity;\nimport org.greenrobot.greendao.daotest.StringKeyValueEntityDao;\n\npublic class StringKeyValueEntityTest extends AbstractDaoTestStringPk<StringKeyValueEntityDao, StringKeyValueEntity> {\n\n    public StringKeyValueEntityTest() {\n        super(StringKeyValueEntityDao.class);\n    }\n\n    @Override\n    protected StringKeyValueEntity createEntity(String key) {\n        if(key == null) {\n            return null;\n        }\n        StringKeyValueEntity entity = new StringKeyValueEntity();\n        entity.setKey(key);\n        return entity;\n    }\n\n    public void testInsertWithoutPK() {\n        StringKeyValueEntity entity = createEntity(null);\n        try {\n            dao.insert(entity);\n            Assert.fail(\"Insert without pre-set PK succeeded\");\n        } catch (Exception e) {\n            // Expected\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/TestEntityIdentityScopeTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.identityscope.IdentityScopeLong;\nimport org.greenrobot.greendao.daotest.TestEntity;\n\npublic class TestEntityIdentityScopeTest extends TestEntityTest {\n    @Override\n    protected void setUp() throws Exception {\n        setIdentityScopeBeforeSetUp(new IdentityScopeLong<TestEntity>());\n        super.setUp();\n    }\n\n    public void testLoadIdScope() {\n        TestEntity entity = createEntity(null);\n        dao.insert(entity);\n        TestEntity entity2 = dao.load(entity.getId());\n        TestEntity entity3 = dao.load(entity.getId());\n\n        assertSame(entity, entity2);\n        assertSame(entity2, entity3);\n    }\n\n    public void testDetach() {\n        TestEntity entity = createEntity(null);\n        dao.insert(entity);\n        dao.detach(entity);\n        TestEntity entity2 = dao.load(entity.getId());\n        dao.detach(entity2);\n        TestEntity entity3 = dao.load(entity.getId());\n\n        assertNotSame(entity, entity2);\n        assertNotSame(entity2, entity3);\n        assertNotSame(entity, entity3);\n    }\n\n    public void testDetachAll() {\n        TestEntity entity1 = createEntity(null);\n        TestEntity entity2 = createEntity(null);\n        dao.insertInTx(entity1, entity2);\n        dao.detachAll();\n        TestEntity entity1a = dao.load(entity1.getId());\n        TestEntity entity2a = dao.load(entity2.getId());\n        assertNotSame(entity1, entity1a);\n        assertNotSame(entity2, entity2a);\n    }\n\n    public void testDetachOther() {\n        TestEntity entity = createEntity(null);\n        dao.insert(entity);\n        dao.detach(entity);\n        TestEntity entity2 = dao.load(entity.getId());\n        dao.detach(entity);\n        TestEntity entity3 = dao.load(entity.getId());\n\n        assertSame(entity2, entity3);\n    }\n\n    public void testLoadAllScope() {\n        TestEntity entity = createEntity(null);\n        dao.insert(entity);\n        TestEntity entity2 = dao.loadAll().get(0);\n        TestEntity entity3 = dao.loadAll().get(0);\n\n        assertSame(entity, entity2);\n        assertSame(entity2, entity3);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/TestEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao;\n\npublic class TestEntityTest extends AbstractDaoTestLongPk<TestEntityDao, TestEntity> {\n\n    public TestEntityTest() {\n        super(TestEntityDao.class);\n    }\n\n    @Override\n    protected TestEntity createEntity(Long key) {\n        TestEntity entity = new TestEntity();\n        entity.setId(key);\n        entity.setSimpleStringNotNull(\"green\");\n        return entity;\n    }\n\n    public void testRefresh() {\n        TestEntity entity = createEntity(1l);\n        entity.setSimpleInteger(42);\n        entity.setSimpleString(null);\n        dao.insert(entity);\n        entity.setSimpleInteger(null);\n        entity.setSimpleString(\"temp\");\n        dao.refresh(entity);\n        assertEquals(42, (int) entity.getSimpleInteger());\n        assertNull(entity.getSimpleString());\n    }\n\n    public void testRefreshIllegal() {\n        TestEntity entity = createEntity(1l);\n        try {\n            dao.refresh(entity);\n            fail(\"Exception expected\");\n        } catch (DaoException expected) {\n        }\n        dao.insert(entity);\n        dao.delete(entity);\n        try {\n            dao.refresh(entity);\n            fail(\"Exception expected\");\n        } catch (DaoException expected) {\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/TestEntityTestBase.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.greenrobot.greendao.test.AbstractDaoTest;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao;\n\npublic abstract class TestEntityTestBase extends AbstractDaoTest<TestEntityDao, TestEntity, Long> {\n\n    public TestEntityTestBase() {\n        super(TestEntityDao.class);\n    }\n\n    protected TestEntity createEntity(int simpleInteger, String simpleString) {\n        TestEntity entity = new TestEntity();\n        entity.setId(null);\n        entity.setSimpleStringNotNull(\"green\");\n        entity.setSimpleInteger(simpleInteger);\n        entity.setSimpleString(simpleString);\n        return entity;\n    }\n\n    protected ArrayList<TestEntity> insert(int count) {\n        ArrayList<TestEntity> list = new ArrayList<TestEntity>();\n        for (int i = 0; i < count; i++) {\n            TestEntity entity = createEntity(getSimpleInteger(i), getSimpleString(i));\n            list.add(entity);\n        }\n        dao.insertInTx(list);\n        return list;\n    }\n\n    protected String getSimpleString(int i) {\n        return \"String\" + (i + 100);\n    }\n\n    protected int getSimpleInteger(int i) {\n        return 100 + i;\n    }\n\n    protected void assertIds(List<TestEntity> list, List<TestEntity> list2) {\n        for (int i = 0; i < list.size(); i++) {\n            TestEntity entity = list.get(i);\n            TestEntity lazyEntity = list2.get(i);\n            assertIds(entity, lazyEntity);\n        }\n    }\n\n    protected void assertIds(TestEntity entity, TestEntity entity2) {\n        assertEquals(entity.getId(), entity2.getId());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/ToManyEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.daotest.DateEntity;\nimport org.greenrobot.greendao.daotest.DateEntityDao;\nimport org.greenrobot.greendao.daotest.JoinManyToDateEntity;\nimport org.greenrobot.greendao.daotest.ToManyEntity;\nimport org.greenrobot.greendao.daotest.ToManyEntityDao;\nimport org.greenrobot.greendao.daotest.ToManyTargetEntity;\nimport org.greenrobot.greendao.daotest.ToManyTargetEntityDao;\n\npublic class ToManyEntityTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n\n    private ToManyEntityDao toManyEntityDao;\n    private ToManyTargetEntityDao toManyTargetEntityDao;\n\n    public ToManyEntityTest() {\n        super(DaoMaster.class);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        toManyEntityDao = daoSession.getToManyEntityDao();\n        toManyTargetEntityDao = daoSession.getToManyTargetEntityDao();\n    }\n\n    public void testToManyBasics() {\n        int count = 0;\n        for (int i = 0; i < 16; i++) {\n            runTestToManyBasics(i + 1, i);\n            count += i;\n        }\n        assertEquals(count, toManyTargetEntityDao.count());\n    }\n\n    public void runTestToManyBasics(long id, int count) {\n        ToManyTargetEntity[] targetEntities = prepareToMany(id, count);\n\n        ToManyEntity testEntity = toManyEntityDao.load(id);\n        List<ToManyTargetEntity> resolvedToMany = testEntity.getToManyTargetEntityList();\n        assertSameEntities(targetEntities, resolvedToMany);\n    }\n\n    public void testGetToManyTwice() {\n        prepareToMany(1, 3);\n\n        ToManyEntity testEntity = toManyEntityDao.load(1L);\n        List<ToManyTargetEntity> resolvedToMany1 = testEntity.getToManyTargetEntityList();\n        List<ToManyTargetEntity> resolvedToMany2 = testEntity.getToManyTargetEntityList();\n        assertSame(resolvedToMany1, resolvedToMany2);\n    }\n\n    public void testResetToMany() {\n        ToManyTargetEntity[] targetEntities = prepareToMany(1, 3);\n\n        ToManyEntity testEntity = toManyEntityDao.load(1L);\n        List<ToManyTargetEntity> resolvedToMany1 = testEntity.getToManyTargetEntityList();\n        testEntity.resetToManyTargetEntityList();\n        List<ToManyTargetEntity> resolvedToMany2 = testEntity.getToManyTargetEntityList();\n        assertNotSame(resolvedToMany1, resolvedToMany2);\n        assertSameEntities(targetEntities, resolvedToMany2);\n    }\n\n    public void testChangeResetToMany() {\n        prepareToMany(1, 3);\n\n        ToManyEntity testEntity = toManyEntityDao.load(1L);\n        List<ToManyTargetEntity> resolvedToMany1 = testEntity.getToManyTargetEntityList();\n        testEntity.resetToManyTargetEntityList();\n\n        ToManyTargetEntity newEntity = new ToManyTargetEntity();\n        newEntity.setToManyId(1L);\n        daoSession.insert(newEntity);\n\n        List<ToManyTargetEntity> resolvedToMany2 = testEntity.getToManyTargetEntityList();\n        assertNotSame(resolvedToMany1, resolvedToMany2);\n        assertEquals(resolvedToMany1.size() + 1, resolvedToMany2.size());\n\n        testEntity.resetToManyTargetEntityList();\n        toManyTargetEntityDao.deleteAll();\n        List<ToManyTargetEntity> resolvedToMany3 = testEntity.getToManyTargetEntityList();\n        assertEquals(0, resolvedToMany3.size());\n    }\n\n    public void testToManyOrder() {\n        prepareToMany(1, 3);\n\n        ToManyEntity testEntity = toManyEntityDao.load(1L);\n        List<ToManyTargetEntity> resolvedToManyAsc = testEntity.getToManyTargetEntityList();\n        List<ToManyTargetEntity> resolvedToManyDesc = testEntity.getToManyDescList();\n        assertNotSame(resolvedToManyAsc, resolvedToManyDesc);\n        assertEquals(resolvedToManyAsc.get(0).getId(), resolvedToManyDesc.get(2).getId());\n        assertSame(resolvedToManyAsc.get(0), resolvedToManyDesc.get(2));\n        assertSame(resolvedToManyAsc.get(1), resolvedToManyDesc.get(1));\n        assertSame(resolvedToManyAsc.get(2), resolvedToManyDesc.get(0));\n    }\n\n    public void testJoinProperty() {\n        ToManyEntity entity = new ToManyEntity(1L);\n        entity.setSourceJoinProperty(\"JOIN ME\");\n        daoSession.insert(entity);\n        insertTargetEntities(null, 3, \"JOIN ME\");\n\n        ToManyEntity testEntity = toManyEntityDao.load(1L);\n        List<ToManyTargetEntity> targetEntities = testEntity.getToManyByJoinProperty();\n        assertEquals(3, targetEntities.size());\n\n        ToManyTargetEntity middleEntity = targetEntities.get(1);\n        middleEntity.setTargetJoinProperty(\"DON'T JOIN ME\");\n        toManyTargetEntityDao.update(middleEntity);\n\n        testEntity.resetToManyByJoinProperty();\n        targetEntities = testEntity.getToManyByJoinProperty();\n        assertEquals(2, targetEntities.size());\n\n        assertFalse(middleEntity.getId() == targetEntities.get(0).getId());\n        assertFalse(middleEntity.getId() == targetEntities.get(1).getId());\n    }\n\n    public void testTwoJoinProperty() {\n        ToManyEntity entity = new ToManyEntity(1L);\n        entity.setSourceJoinProperty(\"JOIN ME\");\n        daoSession.insert(entity);\n        insertTargetEntities(1L, 3, \"JOIN ME\");\n\n        ToManyEntity testEntity = toManyEntityDao.load(1L);\n        List<ToManyTargetEntity> targetEntities = testEntity.getToManyJoinTwo();\n        assertEquals(3, targetEntities.size());\n\n        ToManyTargetEntity middleEntity = targetEntities.get(1);\n        middleEntity.setTargetJoinProperty(\"DON'T JOIN ME\");\n        toManyTargetEntityDao.update(middleEntity);\n\n        testEntity.resetToManyJoinTwo();\n        targetEntities = testEntity.getToManyJoinTwo();\n        assertEquals(2, targetEntities.size());\n\n        assertFalse(middleEntity.getId() == targetEntities.get(0).getId());\n        assertFalse(middleEntity.getId() == targetEntities.get(1).getId());\n    }\n\n    public void testToManyWithJoin() {\n        ToManyEntity entity = new ToManyEntity(1L);\n        daoSession.insert(entity);\n        List<DateEntity> dateEntities = entity.getDateEntityList();\n        assertEquals(0, dateEntities.size());\n\n        DateEntityDao dateDao = daoSession.getDateEntityDao();\n        Date now = new Date();\n        DateEntity date1 = new DateEntity(1L, null, now);\n        DateEntity date2 = new DateEntity(2L, null, now);\n        DateEntity date3 = new DateEntity(3L, null, now);\n        DateEntity date4 = new DateEntity(4L, null, now);\n        dateDao.insertInTx(date1, date2, date3, date4);\n\n        daoSession.insert(new JoinManyToDateEntity(1L,2L,1L));\n        daoSession.insert(new JoinManyToDateEntity(2L,1L,3L));\n        entity.resetDateEntityList();\n        dateEntities = entity.getDateEntityList();\n        assertEquals(1, dateEntities.size());\n        assertEquals(3L, (long) dateEntities.get(0).getId());\n\n        daoSession.insert(new JoinManyToDateEntity(3L, 1L, 4L));\n        entity.resetDateEntityList();\n        dateEntities = entity.getDateEntityList();\n        assertEquals(2, dateEntities.size());\n    }\n\n    private void assertSameEntities(ToManyTargetEntity[] targetEntities, List<ToManyTargetEntity> resolvedToMany) {\n        int count = targetEntities.length;\n        assertEquals(count, resolvedToMany.size());\n\n        Map<Long, ToManyTargetEntity> resolvedMap = new HashMap<>();\n        for (ToManyTargetEntity resolvedEntity : resolvedToMany) {\n            resolvedMap.put(resolvedEntity.getId(), resolvedEntity);\n        }\n        for (int i = 0; i < count; i++) {\n            long entityId = targetEntities[i].getId();\n            assertTrue(\"ID=\" + entityId, resolvedMap.containsKey(entityId));\n            assertSame(targetEntities[i], resolvedMap.get(entityId));\n        }\n    }\n\n    private ToManyTargetEntity[] prepareToMany(long id, int count) {\n        ToManyEntity entity = new ToManyEntity(id);\n        daoSession.insert(entity);\n        return insertTargetEntities(id, count, null);\n    }\n\n    private ToManyTargetEntity[] insertTargetEntities(Long toManyId, int count, String joinProperty) {\n        ToManyTargetEntity[] targetEntities = new ToManyTargetEntity[count];\n        for (int i = 0; i < count; i++) {\n            ToManyTargetEntity target = new ToManyTargetEntity();\n            target.setToManyId(toManyId);\n            target.setToManyIdDesc(toManyId);\n            target.setTargetJoinProperty(joinProperty);\n            targetEntities[i] = target;\n        }\n        toManyTargetEntityDao.insertInTx(targetEntities);\n        return targetEntities;\n    }\n\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/ToManyTargetEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\nimport org.greenrobot.greendao.daotest.ToManyTargetEntity;\nimport org.greenrobot.greendao.daotest.ToManyTargetEntityDao;\n\npublic class ToManyTargetEntityTest extends AbstractDaoTestLongPk<ToManyTargetEntityDao, ToManyTargetEntity> {\n\n    public ToManyTargetEntityTest() {\n        super(ToManyTargetEntityDao.class);\n    }\n\n    @Override\n    protected ToManyTargetEntity createEntity(Long key) {\n        ToManyTargetEntity entity = new ToManyTargetEntity();\n        entity.setId(key);\n        return entity;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/TransactionTest.java",
    "content": "package org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\n\nimport java.util.ArrayList;\n\npublic class TransactionTest extends TestEntityTestBase {\n    public void testUpdateTxFailed() {\n        String sql = \"CREATE UNIQUE INDEX test_simple_string_unique ON \" + TestEntityDao.TABLENAME + \"(\" +\n                Properties.SimpleString.columnName + \")\";\n        dao.getDatabase().execSQL(sql);\n        ArrayList<TestEntity> entities = insert(2);\n        TestEntity entity1 = entities.get(0);\n        String valueBeforeUpdate = entity1.getSimpleString();\n\n        entity1.setSimpleString(\"unique\");\n        entities.get(1).setSimpleString(\"unique\");\n        try {\n            dao.updateInTx(entities);\n            fail(\"Should have thrown\");\n        } catch (RuntimeException e) {\n            // OK\n        }\n        dao.refresh(entity1);\n        assertEquals(valueBeforeUpdate, entity1.getSimpleString());\n    }\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/entity/TreeEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.daotest.TreeEntity;\nimport org.greenrobot.greendao.daotest.TreeEntityDao;\n\npublic class TreeEntityTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n\n    private TreeEntityDao treeEntityDao;\n\n    public TreeEntityTest() {\n        super(DaoMaster.class);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        treeEntityDao = daoSession.getTreeEntityDao();\n    }\n\n    public void testNavigateTreeFromLeaf() {\n        createTree();\n        daoSession.clear();\n\n        TreeEntity child1Child = treeEntityDao.load(101l);\n        assertEquals(0, child1Child.getChildren().size());\n\n        TreeEntity child1 = child1Child.getParent();\n        assertEquals(11l, child1.getId().longValue());\n        assertEquals(1, child1.getChildren().size());\n        assertSame(child1Child, child1.getChildren().get(0));\n\n        TreeEntity root = child1.getParent();\n        assertEquals(1l, root.getId().longValue());\n        assertEquals(2, root.getChildren().size());\n        assertNull(root.getParent());\n    }\n\n    public void testNavigateTreeFromMiddle() {\n        createTree();\n        daoSession.clear();\n\n        TreeEntity child1 = treeEntityDao.load(11l);\n        assertEquals(1, child1.getChildren().size());\n        TreeEntity child1Child = child1.getChildren().get(0);\n        assertEquals(101, child1Child.getId().longValue());\n        assertEquals(0, child1Child.getChildren().size());\n\n        TreeEntity root = child1.getParent();\n        assertEquals(1l, root.getId().longValue());\n        assertEquals(2, root.getChildren().size());\n        assertNull(root.getParent());\n    }\n\n    public void testNavigateTreeFromRoot() {\n        createTree();\n        daoSession.clear();\n\n        TreeEntity root = treeEntityDao.load(1l);\n        assertEquals(2, root.getChildren().size());\n        assertNull(root.getParent());\n\n        TreeEntity child1 = root.getChildren().get(0);\n        TreeEntity child2 = root.getChildren().get(1);\n        if (child1.getId() != 11l) {\n            child1 = child2;\n            child2 = root.getChildren().get(0);\n        }\n\n        assertSame(root, child1.getParent());\n        assertEquals(1, child1.getChildren().size());\n        TreeEntity child1Child = child1.getChildren().get(0);\n        assertEquals(101, child1Child.getId().longValue());\n        assertEquals(0, child1Child.getChildren().size());\n        \n        assertSame(root, child2.getParent());\n        assertEquals(0, child2.getChildren().size());\n    }\n\n    private void createTree() {\n        TreeEntity root = new TreeEntity(1l);\n        TreeEntity child1 = new TreeEntity(11l);\n        child1.setParent(root);\n        TreeEntity child2 = new TreeEntity(12l);\n        child2.setParent(root);\n        TreeEntity child1Child = new TreeEntity(101l);\n        child1Child.setParent(child1);\n        treeEntityDao.insertInTx(root, child1, child2, child1Child);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/CountQueryTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport java.util.ArrayList;\n\nimport org.greenrobot.greendao.daotest.entity.TestEntityTestBase;\nimport org.greenrobot.greendao.query.CountQuery;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\n\n// TODO more tests\npublic class CountQueryTest extends TestEntityTestBase {\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        QueryBuilder.LOG_SQL = true;\n        QueryBuilder.LOG_VALUES = true;\n    }\n\n    public void testCountQuerySimple() {\n        int value = getSimpleInteger(1);\n        CountQuery<TestEntity> query = dao.queryBuilder().where(Properties.SimpleInteger.eq(value)).buildCount();\n        assertEquals(0, query.count());\n\n        ArrayList<TestEntity> inserted = insert(3);\n        assertEquals(1, query.count());\n\n        inserted.get(2).setSimpleInteger(value);\n        dao.update(inserted.get(2));\n        assertEquals(2, query.count());\n\n        dao.deleteAll();\n        assertEquals(0, query.count());\n    }\n\n    public void testCountQueryTwoParameters() {\n        int value = getSimpleInteger(1);\n        String valueString = getSimpleString(1);\n        \n        QueryBuilder<TestEntity> queryBuilder = dao.queryBuilder();\n        queryBuilder.where(Properties.SimpleInteger.eq(value), Properties.SimpleString.eq(valueString));\n        CountQuery<TestEntity> query = queryBuilder.buildCount();\n        assertEquals(0, query.count());\n\n        ArrayList<TestEntity> inserted = insert(3);\n        assertEquals(1, query.count());\n\n        inserted.get(2).setSimpleInteger(value);\n        dao.update(inserted.get(2));\n        assertEquals(1, query.count());\n        \n        inserted.get(2).setSimpleString(valueString);\n        dao.update(inserted.get(2));\n        assertEquals(2, query.count());\n\n        dao.deleteAll();\n        assertEquals(0, query.count());\n    }\n\n    public void testCountQueryTwoParametersOr() {\n        int value = getSimpleInteger(1);\n        String valueString = getSimpleString(2);\n        \n        QueryBuilder<TestEntity> queryBuilder = dao.queryBuilder();\n        queryBuilder.whereOr(Properties.SimpleInteger.eq(value), Properties.SimpleString.eq(valueString));\n        CountQuery<TestEntity> query = queryBuilder.buildCount();\n        assertEquals(0, query.count());\n\n        ArrayList<TestEntity> inserted = insert(3);\n        assertEquals(2, query.count());\n\n        inserted.get(1).setSimpleInteger(getSimpleInteger(2));\n        dao.update(inserted.get(1));\n        assertEquals(1, query.count());\n        \n        inserted.get(2).setSimpleString(getSimpleString(3));\n        dao.update(inserted.get(2));\n        assertEquals(0, query.count());\n    }\n\n    public void testCountQueryChangeParameter() {\n        insert(3);\n\n        String value = \"not existing value\";\n        CountQuery<TestEntity> query = dao.queryBuilder().where(Properties.SimpleString.eq(value)).buildCount();\n        assertEquals(0, query.count());\n        query.setParameter(0, getSimpleString(1));\n        assertEquals(1, query.count());\n        query.setParameter(0, getSimpleString(2));\n        assertEquals(1, query.count());\n        query.setParameter(0, \"you won't find me either\");\n        assertEquals(0, query.count());\n    }\n\n    public void testBuildQueryAndCountQuery() {\n        insert(3);\n        int value = getSimpleInteger(1);\n\n        QueryBuilder<TestEntity> builder = dao.queryBuilder().where(Properties.SimpleInteger.eq(value));\n        Query<TestEntity> query = builder.build();\n        CountQuery<TestEntity> countQuery = builder.buildCount();\n\n        assertEquals(1, query.list().size());\n        assertEquals(1, countQuery.count());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/CountQueryThreadLocalTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.query.CountQuery;\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\nimport org.greenrobot.greendao.daotest.entity.TestEntityTestBase;\n\npublic class CountQueryThreadLocalTest extends TestEntityTestBase {\n    private CountQuery<TestEntity> queryFromOtherThread;\n\n    public void testGetForCurrentThread_SameInstance() {\n        CountQuery<TestEntity> query = dao.queryBuilder().buildCount();\n        assertSame(query, query.forCurrentThread());\n    }\n\n    public void testGetForCurrentThread_ParametersAreReset() {\n        insert(3);\n        int value = getSimpleInteger(1);\n        CountQuery<TestEntity> query = dao.queryBuilder().where(Properties.SimpleInteger.eq(value)).buildCount();\n        query.setParameter(0, value + 100);\n        assertEquals(0, query.count());\n        query = query.forCurrentThread();\n        assertEquals(1, query.count());\n    }\n\n    public void testGetForCurrentThread_TwoThreads() throws InterruptedException {\n        insert(3);\n        createQueryFromOtherThread();\n        CountQuery<TestEntity> query = queryFromOtherThread.forCurrentThread();\n        assertNotSame(queryFromOtherThread, query);\n        assertEquals(1, query.count());\n        query.setParameter(0, -10);\n        assertEquals(0, query.count());\n    }\n\n    public void testThrowOutsideOwnerThread() throws InterruptedException {\n        createQueryFromOtherThread();\n        try {\n            queryFromOtherThread.count();\n            fail(\"Did not throw\");\n        } catch (DaoException expected) {\n        }\n        try {\n            queryFromOtherThread.setParameter(0, 42);\n            fail(\"Did not throw\");\n        } catch (DaoException expected) {\n        }\n    }\n\n    private void createQueryFromOtherThread() throws InterruptedException {\n        Thread thread = new Thread() {\n\n            @Override\n            public void run() {\n                QueryBuilder<TestEntity> builder = dao.queryBuilder();\n                builder.where(Properties.SimpleInteger.eq(getSimpleInteger(1)));\n                queryFromOtherThread = builder.buildCount();\n            }\n        };\n        thread.start();\n        thread.join();\n        assertNotNull(queryFromOtherThread);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/CursorQueryTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport android.database.Cursor;\nimport org.greenrobot.greendao.query.CursorQuery;\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\nimport org.greenrobot.greendao.daotest.entity.TestEntityTestBase;\n\n// TODO more tests\npublic class CursorQueryTest extends TestEntityTestBase {\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        QueryBuilder.LOG_SQL = true;\n        QueryBuilder.LOG_VALUES = true;\n    }\n\n    public void testCursorQuerySimple() {\n        insert(3);\n        CursorQuery query = dao.queryBuilder().orderAsc(Properties.SimpleInteger).buildCursor();\n        Cursor cursor = query.query();\n        try {\n            assertEquals(3, cursor.getCount());\n            assertTrue(cursor.moveToNext());\n            int columnIndex = cursor.getColumnIndexOrThrow(Properties.SimpleInteger.columnName);\n            assertEquals(getSimpleInteger(0), cursor.getInt(columnIndex));\n            assertTrue(cursor.moveToNext());\n            assertEquals(getSimpleInteger(1), cursor.getInt(columnIndex));\n            assertTrue(cursor.moveToNext());\n            assertEquals(getSimpleInteger(2), cursor.getInt(columnIndex));\n            assertFalse(cursor.moveToNext());\n        } finally {\n            cursor.close();\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/DeleteQueryTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.greenrobot.greendao.query.DeleteQuery;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\nimport org.greenrobot.greendao.daotest.entity.TestEntityTestBase;\n\n// TODO more tests\npublic class DeleteQueryTest extends TestEntityTestBase {\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        QueryBuilder.LOG_SQL = true;\n        QueryBuilder.LOG_VALUES = true;\n    }\n\n    public void testDeleteQuerySimple() {\n        ArrayList<TestEntity> inserted = insert(3);\n        int value = getSimpleInteger(1);\n        inserted.get(2).setSimpleInteger(value);\n        dao.update(inserted.get(2));\n\n        DeleteQuery<TestEntity> deleteQuery = dao.queryBuilder().where(Properties.SimpleInteger.eq(value))\n                .buildDelete();\n\n        deleteQuery.executeDeleteWithoutDetachingEntities();\n\n        List<TestEntity> allAfterDelete = dao.loadAll();\n        assertEquals(1, allAfterDelete.size());\n        assertEquals(getSimpleInteger(0), (int) allAfterDelete.get(0).getSimpleInteger());\n    }\n\n    public void testDeleteQueryOr() {\n        ArrayList<TestEntity> inserted = insert(3);\n\n        QueryBuilder<TestEntity> queryBuilder = dao.queryBuilder();\n        Integer value1 = inserted.get(0).getSimpleInteger();\n        Integer value2 = inserted.get(2).getSimpleInteger();\n        queryBuilder.whereOr(Properties.SimpleInteger.eq(value1), Properties.SimpleInteger.eq(value2));\n        DeleteQuery<TestEntity> deleteQuery = queryBuilder.buildDelete();\n\n        deleteQuery.executeDeleteWithoutDetachingEntities();\n\n        List<TestEntity> allAfterDelete = dao.loadAll();\n        assertEquals(1, allAfterDelete.size());\n        assertEquals(inserted.get(1).getSimpleInteger(), allAfterDelete.get(0).getSimpleInteger());\n    }\n\n    public void testDeleteQueryExecutingMultipleTimes() {\n        insert(3);\n\n        String value = getSimpleString(1);\n        DeleteQuery<TestEntity> deleteQuery = dao.queryBuilder().where(Properties.SimpleString.eq(value)).buildDelete();\n        deleteQuery.executeDeleteWithoutDetachingEntities();\n        assertEquals(2, dao.count());\n\n        deleteQuery.executeDeleteWithoutDetachingEntities();\n        assertEquals(2, dao.count());\n\n        insert(3);\n        assertEquals(5, dao.count());\n\n        deleteQuery.executeDeleteWithoutDetachingEntities();\n        assertEquals(4, dao.count());\n    }\n\n    public void testDeleteQueryChangeParameter() {\n        insert(3);\n\n        String value = getSimpleString(1);\n        DeleteQuery<TestEntity> deleteQuery = dao.queryBuilder().where(Properties.SimpleString.eq(value)).buildDelete();\n        deleteQuery.executeDeleteWithoutDetachingEntities();\n        assertEquals(2, dao.count());\n\n        deleteQuery.setParameter(0, getSimpleString(0));\n        deleteQuery.executeDeleteWithoutDetachingEntities();\n        assertEquals(1, dao.count());\n\n        TestEntity remaining = dao.loadAll().get(0);\n        assertEquals(getSimpleString(2), remaining.getSimpleString());\n    }\n\n    public void testBuildQueryAndDeleteQuery() {\n        insert(3);\n        int value = getSimpleInteger(1);\n\n        QueryBuilder<TestEntity> builder = dao.queryBuilder().where(Properties.SimpleInteger.eq(value));\n        Query<TestEntity> query = builder.build();\n        DeleteQuery<TestEntity> deleteQuery = builder.buildDelete();\n\n        assertEquals(1, query.list().size());\n        deleteQuery.executeDeleteWithoutDetachingEntities();\n        assertEquals(0, query.list().size());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/DeleteQueryThreadLocalTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\nimport org.greenrobot.greendao.daotest.entity.TestEntityTestBase;\nimport org.greenrobot.greendao.query.DeleteQuery;\nimport org.greenrobot.greendao.query.QueryBuilder;\n\npublic class DeleteQueryThreadLocalTest extends TestEntityTestBase {\n    private DeleteQuery<TestEntity> queryFromOtherThread;\n\n    public void testGetForCurrentThread_SameInstance() {\n        DeleteQuery<TestEntity> query = dao.queryBuilder().buildDelete();\n        assertSame(query, query.forCurrentThread());\n    }\n\n    public void testGetForCurrentThread_ParametersAreReset() {\n        insert(3);\n        int value = getSimpleInteger(1);\n        DeleteQuery<TestEntity> query = dao.queryBuilder().where(Properties.SimpleInteger.eq(value)).buildDelete();\n        query.setParameter(0, value + 100);\n        query.executeDeleteWithoutDetachingEntities();\n        assertEquals(3, dao.count());\n        query = query.forCurrentThread();\n        query.executeDeleteWithoutDetachingEntities();\n        assertEquals(2, dao.count());\n    }\n\n    public void testGetForCurrentThread_TwoThreads() throws InterruptedException {\n        insert(3);\n        createQueryFromOtherThread();\n        DeleteQuery<TestEntity> query = queryFromOtherThread.forCurrentThread();\n        assertNotSame(queryFromOtherThread, query);\n        query.setParameter(0, getSimpleInteger(2));\n        query.executeDeleteWithoutDetachingEntities();\n        assertEquals(2, dao.count());\n    }\n\n    public void testThrowOutsideOwnerThread() throws InterruptedException {\n        createQueryFromOtherThread();\n        try {\n            queryFromOtherThread.executeDeleteWithoutDetachingEntities();\n            fail(\"Did not throw\");\n        } catch (DaoException expected) {\n        }\n        try {\n            queryFromOtherThread.setParameter(0, 42);\n            fail(\"Did not throw\");\n        } catch (DaoException expected) {\n        }\n    }\n\n    private void createQueryFromOtherThread() throws InterruptedException {\n        Thread thread = new Thread() {\n\n            @Override\n            public void run() {\n                QueryBuilder<TestEntity> builder = dao.queryBuilder();\n                builder.where(Properties.SimpleInteger.eq(getSimpleInteger(1)));\n                queryFromOtherThread = builder.buildDelete();\n            }\n        };\n        thread.start();\n        thread.join();\n        assertNotNull(queryFromOtherThread);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/JoinTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.query.Join;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.daotest.RelationEntity;\nimport org.greenrobot.greendao.daotest.RelationEntityDao;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\npublic class JoinTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n\n    private TestEntityDao testEntityDao;\n    private RelationEntityDao relationEntityDao;\n\n    public JoinTest() {\n        super(DaoMaster.class);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        QueryBuilder.LOG_SQL = true;\n        QueryBuilder.LOG_VALUES = true;\n        testEntityDao = daoSession.getTestEntityDao();\n        relationEntityDao = daoSession.getRelationEntityDao();\n    }\n\n    public void testJoinSimple() {\n        prepareData();\n        QueryBuilder<RelationEntity> queryBuilder = createQueryBuilder(5);\n        RelationEntity unique = queryBuilder.uniqueOrThrow();\n        assertEquals(\"entity-5\", unique.getSimpleString());\n    }\n\n    public void testJoinSimpleParameterValue() {\n        prepareData();\n        QueryBuilder<RelationEntity> queryBuilder = createQueryBuilder(-1);\n        Query<RelationEntity> query = queryBuilder.build();\n        for (int i = 0; i < 10; i++) {\n            query.setParameter(0, i + 1);\n            RelationEntity unique = query.uniqueOrThrow();\n            assertEquals(\"entity-\" + (i + 1), unique.getSimpleString());\n        }\n    }\n\n    public void testJoinMixedParameterValues() {\n        prepareData();\n        QueryBuilder<RelationEntity> queryBuilder = relationEntityDao.queryBuilder();\n        queryBuilder.where(RelationEntityDao.Properties.SimpleString.like(\"\"), RelationEntityDao.Properties.SimpleString.ge(\"\"));\n        Join<RelationEntity, TestEntity> join = queryBuilder.join(RelationEntityDao.Properties.TestIdNotNull,\n                TestEntity.class);\n        join.where(Properties.SimpleInt.le(0));\n        queryBuilder.offset(0).limit(0);\n        Query<RelationEntity> query = queryBuilder.build();\n        query.setParameter(0, \"entity-%\");\n        query.setParameter(1, \"entity-4\");\n        query.setParameter(2, 6);\n        query.setOffset(1);\n        query.setLimit(99);\n        List<RelationEntity> entities = query.list();\n        assertEquals(2, entities.size());\n        assertEquals(\"entity-5\", entities.get(0).getSimpleString());\n        assertEquals(\"entity-6\", entities.get(1).getSimpleString());\n    }\n\n    public void testJoinOfJoin() {\n        prepareData();\n        List<RelationEntity> relationEntities = relationEntityDao.loadAll();\n        relationEntities.get(2).setParent(relationEntities.get(4));\n        relationEntities.get(3).setParent(relationEntities.get(5));\n        relationEntities.get(7).setParent(relationEntities.get(5));\n        relationEntityDao.updateInTx(relationEntities);\n\n        QueryBuilder<RelationEntity> queryBuilder = relationEntityDao.queryBuilder();\n        Join<RelationEntity, RelationEntity> join1 =\n                queryBuilder.join(RelationEntityDao.Properties.ParentId, RelationEntity.class);\n        queryBuilder.join(join1, RelationEntityDao.Properties.TestIdNotNull, TestEntity.class, Properties.Id)\n                .where(Properties.SimpleInt.lt(6));\n\n        Query<RelationEntity> query = queryBuilder.build();\n        RelationEntity entity = query.uniqueOrThrow();\n        assertEquals(relationEntities.get(2).getSimpleString(), entity.getSimpleString());\n\n        query.setParameter(0, 99);\n        assertEquals(3, query.list().size());\n    }\n\n    public void testJoinDelete() {\n        prepareData();\n        QueryBuilder<RelationEntity> queryBuilder = createQueryBuilder(5);\n        try {\n            queryBuilder.buildDelete().executeDeleteWithoutDetachingEntities();\n        } catch (DaoException e) {\n            assertEquals(\"JOINs are not supported for DELETE queries\", e.getMessage());\n            return;\n        }\n        // Never executed, unsupported by SQLite\n        assertEquals(9, relationEntityDao.count());\n        assertEquals(10, testEntityDao.count());\n        assertNull(relationEntityDao.queryBuilder().where(Properties.SimpleString.eq(\"entity-5\")).unique());\n    }\n\n    public void testJoinCount() {\n        prepareData();\n        QueryBuilder<RelationEntity> queryBuilder = relationEntityDao.queryBuilder();\n        Join<RelationEntity, TestEntity> join = queryBuilder.join(RelationEntityDao.Properties.TestIdNotNull,\n                TestEntity.class);\n        join.where(Properties.SimpleInt.gt(6));\n        queryBuilder.count();\n        assertEquals(4, queryBuilder.count());\n    }\n\n    private void prepareData() {\n        List<TestEntity> targetEntities = new ArrayList<TestEntity>();\n        for (int i = 0; i < 10; i++) {\n            TestEntity testEntity = new TestEntity();\n            testEntity.setSimpleInt(i + 1);\n            testEntity.setSimpleStringNotNull(\"string-\" + (i + 1));\n            targetEntities.add(testEntity);\n        }\n        testEntityDao.insertInTx(targetEntities);\n\n        List<RelationEntity> entities = new ArrayList<RelationEntity>();\n        for (int i = 0; i < 10; i++) {\n            RelationEntity entity = new RelationEntity();\n            entity.setSimpleString(\"entity-\" + (i + 1));\n            entity.setTestNotNull(targetEntities.get(i));\n            entities.add(entity);\n        }\n        relationEntityDao.insertInTx(entities);\n    }\n\n    private QueryBuilder<RelationEntity> createQueryBuilder(int simpleIntWhereValue) {\n        QueryBuilder<RelationEntity> queryBuilder = relationEntityDao.queryBuilder();\n        Join<RelationEntity, TestEntity> join = queryBuilder.join(RelationEntityDao.Properties.TestIdNotNull,\n                TestEntity.class);\n        join.where(Properties.SimpleInt.eq(simpleIntWhereValue));\n        return queryBuilder;\n    }\n\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/LazyListTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport java.util.ArrayList;\nimport java.util.ListIterator;\nimport java.util.NoSuchElementException;\n\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.query.CloseableListIterator;\nimport org.greenrobot.greendao.query.LazyList;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\nimport org.greenrobot.greendao.daotest.entity.TestEntityTestBase;\n\npublic class LazyListTest extends TestEntityTestBase {\n\n    public void testSizeAndGetAndPeak() {\n        ArrayList<TestEntity> list = insert(2);\n\n        LazyList<TestEntity> listLazy = dao.queryBuilder().build().listLazy();\n        assertEquals(list.size(), listLazy.size());\n        assertNull(listLazy.peek(0));\n        assertNull(listLazy.peek(1));\n\n        assertNotNull(listLazy.get(1));\n        assertNull(listLazy.peek(0));\n        assertNotNull(listLazy.peek(1));\n\n        assertNotNull(listLazy.get(0));\n        assertNotNull(listLazy.peek(0));\n        assertNotNull(listLazy.peek(1));\n    }\n\n    public void testGetAll100() {\n        ArrayList<TestEntity> list = insert(100);\n        LazyList<TestEntity> listLazy = dao.queryBuilder().orderAsc(Properties.SimpleInteger).build().listLazy();\n        assertIds(list, listLazy);\n        assertTrue(listLazy.isClosed());\n    }\n\n    public void testGetAll100Uncached() {\n        ArrayList<TestEntity> list = insert(100);\n        LazyList<TestEntity> listLazy = dao.queryBuilder().orderAsc(Properties.SimpleInteger).build()\n                .listLazyUncached();\n        assertIds(list, listLazy);\n        assertFalse(listLazy.isClosed());\n        listLazy.close();\n    }\n\n    public void testSublist() {\n        ArrayList<TestEntity> list = insert(10);\n        LazyList<TestEntity> listLazy = dao.queryBuilder().orderAsc(Properties.SimpleInteger).build().listLazy();\n        assertIds(list.subList(2, 7), listLazy.subList(2, 7));\n    }\n\n    public void testSublistUncached() {\n        ArrayList<TestEntity> list = insert(10);\n        LazyList<TestEntity> listLazy = dao.queryBuilder().orderAsc(Properties.SimpleInteger).build().listLazyUncached();\n        try {\n            assertIds(list.subList(2,7), listLazy.subList(2,7));\n        } catch (DaoException e) {\n            assertEquals(\"This operation only works with cached lazy lists\", e.getMessage());\n        }\n\n    }\n\n    public void testIterator() {\n        ArrayList<TestEntity> list = insert(100);\n        LazyList<TestEntity> listLazy = dao.queryBuilder().orderAsc(Properties.SimpleInteger).build().listLazy();\n        testIterator(list, listLazy, false);\n        assertTrue(listLazy.isClosed());\n    }\n\n    public void testIteratorUncached() {\n        ArrayList<TestEntity> list = insert(100);\n        LazyList<TestEntity> listLazy = dao.queryBuilder().orderAsc(Properties.SimpleInteger).build()\n                .listLazyUncached();\n        testIterator(list, listLazy, true);\n        assertFalse(listLazy.isClosed());\n        listLazy.close();\n    }\n\n    protected void testIterator(ArrayList<TestEntity> list, LazyList<TestEntity> listLazy, boolean uncached) {\n        ListIterator<TestEntity> iterator = listLazy.listIterator();\n        try {\n            iterator.previous();\n            fail(\"previous should throw here\");\n        } catch (NoSuchElementException expected) {\n            // OK\n        }\n        int size = list.size();\n        for (int i = 0; i < size; i++) {\n            assertTrue(iterator.hasNext());\n            assertEquals(i > 0, iterator.hasPrevious());\n            assertEquals(i, iterator.nextIndex());\n            assertEquals(i - 1, iterator.previousIndex());\n\n            if (i > 0) {\n                TestEntity entityPrevious = list.get(i - 1);\n                assertEquals(entityPrevious.getId(), iterator.previous().getId());\n                iterator.next();\n            }\n\n            TestEntity entity = list.get(i);\n            assertNull(listLazy.peek(i));\n            TestEntity lazyEntity = iterator.next();\n            if (uncached) {\n                assertNull(listLazy.peek(i));\n            } else {\n                assertNotNull(listLazy.peek(i));\n            }\n            assertEquals(entity.getId(), lazyEntity.getId());\n        }\n        assertFalse(iterator.hasNext());\n        try {\n            iterator.next();\n            fail(\"next should throw here\");\n        } catch (NoSuchElementException expected) {\n            // OK\n        }\n    }\n\n    public void testEmpty() {\n        insert(1);\n\n        LazyList<TestEntity> listLazy = dao.queryBuilder().where(Properties.SimpleInteger.eq(-1)).build().listLazy();\n        assertTrue(listLazy.isEmpty());\n        assertTrue(listLazy.isClosed());\n        try {\n            listLazy.get(0);\n            fail(\"Not empty\");\n        } catch (RuntimeException e) {\n            // Expected, OK\n        }\n\n    }\n\n    public void testUncached() {\n        insert(1);\n\n        LazyList<TestEntity> listLazy = dao.queryBuilder().build().listLazyUncached();\n        assertFalse(listLazy.isEmpty());\n        assertFalse(listLazy.isClosed());\n        TestEntity entity1 = listLazy.get(0);\n        TestEntity entity2 = listLazy.get(0);\n        assertEquals(entity1.getId(), entity2.getId());\n        if (identityScopeForDao == null) {\n            assertNotSame(entity1, entity2);\n        } else {\n            assertSame(entity1, entity2);\n        }\n        assertFalse(listLazy.isClosed());\n        try {\n            listLazy.loadRemaining();\n            fail(\"Not empty\");\n        } catch (DaoException expected) {\n            // Expected, OK\n        }\n        listLazy.close();\n        assertTrue(listLazy.isClosed());\n    }\n\n    public void testClose() {\n        insert(1);\n\n        LazyList<TestEntity> listLazy = dao.queryBuilder().build().listLazy();\n        assertFalse(listLazy.isEmpty());\n        assertFalse(listLazy.isClosed());\n        listLazy.get(0);\n        assertTrue(listLazy.isClosed());\n\n        // Closing again should not harm\n        listLazy.close();\n        listLazy.close();\n    }\n\n    public void testAutoClose() {\n        insert(10);\n        LazyList<TestEntity> lazyList = dao.queryBuilder().build().listLazyUncached();\n        CloseableListIterator<TestEntity> iterator = lazyList.listIteratorAutoClose();\n        while (iterator.hasNext()) {\n            assertFalse(lazyList.isClosed());\n            iterator.next();\n        }\n        assertTrue(lazyList.isClosed());\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/QueryBuilderAndOrTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.test.AbstractDaoTest;\nimport org.greenrobot.greendao.daotest.AbcdefEntity;\nimport org.greenrobot.greendao.daotest.AbcdefEntityDao;\nimport org.greenrobot.greendao.daotest.AbcdefEntityDao.Properties;\n\npublic class QueryBuilderAndOrTest extends AbstractDaoTest<AbcdefEntityDao, AbcdefEntity, Long> {\n\n    public QueryBuilderAndOrTest() {\n        super(AbcdefEntityDao.class);\n        QueryBuilder.LOG_SQL = true;\n        QueryBuilder.LOG_VALUES = true;\n    }\n\n    protected ArrayList<AbcdefEntity> insert(int count) {\n        ArrayList<AbcdefEntity> list = new ArrayList<AbcdefEntity>();\n        for (int i = 0; i < count; i++) {\n            int base = i * 100;\n            AbcdefEntity entity = new AbcdefEntity(null, base + 1, base + 2, base + 3, base + 4, base + 5, base + 6,\n                    base + 7, base + 8, base + 9, base + 10, base + 11);\n            list.add(entity);\n        }\n        dao.insertInTx(list);\n        return list;\n    }\n\n    public void testSimpleQuery() {\n        insert(3);\n\n        QueryBuilder<AbcdefEntity> queryBuilder = dao.queryBuilder().where(Properties.A.eq(1)).orderAsc(Properties.A);\n        List<AbcdefEntity> result = queryBuilder.list();\n        assertEquals(1, result.size());\n        assertEquals(1, queryBuilder.count());\n\n        AbcdefEntity resultEntity = result.get(0);\n        assertEquals(1, (int) resultEntity.getA());\n\n        queryBuilder.buildDelete().executeDeleteWithoutDetachingEntities();\n    }\n\n    public void testOr() {\n        insert(3);\n\n        QueryBuilder<AbcdefEntity> queryBuilder = dao.queryBuilder();\n        queryBuilder.whereOr(Properties.A.eq(1), Properties.A.eq(101));\n        List<AbcdefEntity> result = queryBuilder.orderAsc(Properties.A).list();\n        assertEquals(2, result.size());\n        assertEquals(2, queryBuilder.count());\n\n        assertEquals(1, (int) result.get(0).getA());\n        assertEquals(101, (int) result.get(1).getA());\n\n        queryBuilder.buildDelete().executeDeleteWithoutDetachingEntities();\n    }\n\n    public void testOr3() {\n        insert(5);\n\n        QueryBuilder<AbcdefEntity> queryBuilder = dao.queryBuilder();\n        queryBuilder.whereOr(Properties.A.eq(1), Properties.A.eq(101), Properties.B.eq(302));\n        List<AbcdefEntity> result = queryBuilder.orderAsc(Properties.A).list();\n        assertEquals(3, result.size());\n        assertEquals(3, queryBuilder.count());\n\n        assertEquals(1, (int) result.get(0).getA());\n        assertEquals(101, (int) result.get(1).getA());\n        assertEquals(301, (int) result.get(2).getA());\n\n        queryBuilder.buildDelete().executeDeleteWithoutDetachingEntities();\n    }\n\n    public void testOrNested() {\n        insert(10);\n\n        QueryBuilder<AbcdefEntity> queryBuilder = dao.queryBuilder();\n        queryBuilder.whereOr(Properties.A.eq(101), //\n                Properties.B.eq(302), Properties.C.eq(603));\n        List<AbcdefEntity> result = queryBuilder.orderAsc(Properties.A).list();\n        assertEquals(3, result.size());\n        assertEquals(3, queryBuilder.count());\n\n        assertEquals(101, (int) result.get(0).getA());\n        assertEquals(301, (int) result.get(1).getA());\n        assertEquals(601, (int) result.get(2).getA());\n\n        queryBuilder.buildDelete().executeDeleteWithoutDetachingEntities();\n    }\n\n    public void testOrNestedNested() {\n        insert(10);\n\n        QueryBuilder<AbcdefEntity> queryBuilder = dao.queryBuilder();\n        queryBuilder.whereOr(Properties.A.eq(101), //\n                queryBuilder.or(Properties.B.eq(302), //\n                        queryBuilder.or(Properties.C.eq(503), Properties.D.eq(804))));\n        List<AbcdefEntity> result = queryBuilder.orderAsc(Properties.A).list();\n        assertEquals(4, result.size());\n        assertEquals(4, queryBuilder.count());\n\n        assertEquals(101, (int) result.get(0).getA());\n        assertEquals(301, (int) result.get(1).getA());\n        assertEquals(501, (int) result.get(2).getA());\n        assertEquals(801, (int) result.get(3).getA());\n\n        queryBuilder.buildDelete().executeDeleteWithoutDetachingEntities();\n    }\n\n    public void testAnd() {\n        insert(5);\n\n        QueryBuilder<AbcdefEntity> queryBuilder = dao.queryBuilder();\n        queryBuilder.where(Properties.A.eq(201), Properties.B.eq(202));\n        List<AbcdefEntity> result = queryBuilder.orderAsc(Properties.A).list();\n        assertEquals(1, result.size());\n        assertEquals(1, queryBuilder.count());\n\n        assertEquals(201, (int) result.get(0).getA());\n\n        queryBuilder.buildDelete().executeDeleteWithoutDetachingEntities();\n    }\n\n    public void testOrAnd() {\n        insert(10);\n\n        QueryBuilder<AbcdefEntity> queryBuilder = dao.queryBuilder();\n        queryBuilder.whereOr(Properties.A.eq(201), //\n                queryBuilder.and(Properties.B.gt(402), Properties.C.lt(703)));\n        List<AbcdefEntity> result = queryBuilder.orderAsc(Properties.A).list();\n        assertEquals(3, result.size());\n        assertEquals(3, queryBuilder.count());\n\n        assertEquals(201, (int) result.get(0).getA());\n        assertEquals(501, (int) result.get(1).getA());\n        assertEquals(601, (int) result.get(2).getA());\n\n        queryBuilder.buildDelete().executeDeleteWithoutDetachingEntities();\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/QueryBuilderOrderTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\nimport org.greenrobot.greendao.daotest.entity.TestEntityTestBase;\nimport org.greenrobot.greendao.query.QueryBuilder;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport java.util.List;\n\npublic class QueryBuilderOrderTest extends TestEntityTestBase {\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        QueryBuilder.LOG_SQL = true;\n        QueryBuilder.LOG_VALUES = true;\n    }\n\n    public void testOrderAsc() {\n        ArrayList<TestEntity> inserted = insert(2);\n        TestEntity entity = inserted.get(0);\n        List<TestEntity> result = dao.queryBuilder().orderAsc(Properties.SimpleInteger).list();\n        assertEquals(2, result.size());\n        assertEquals(entity.getId(), result.get(0).getId());\n        result = dao.queryBuilder().orderAsc(Properties.SimpleInteger, Properties.SimpleString).list();\n        assertEquals(2, result.size());\n        assertEquals(entity.getId(), result.get(0).getId());\n    }\n\n    public void testOrderDesc() {\n        ArrayList<TestEntity> inserted = insert(2);\n        TestEntity entity = inserted.get(1);\n        List<TestEntity> result = dao.queryBuilder().orderDesc(Properties.SimpleInteger).list();\n        assertEquals(2, result.size());\n        assertEquals(entity.getId(), result.get(0).getId());\n        result = dao.queryBuilder().orderDesc(Properties.SimpleInteger, Properties.SimpleString).list();\n        assertEquals(2, result.size());\n        assertEquals(entity.getId(), result.get(0).getId());\n    }\n\n    public void testOrderUpperLowercase() {\n        List<TestEntity> list = new ArrayList<TestEntity>();\n        TestEntity entityAA = addEntity(list, \"aa\");\n        TestEntity entityAB = addEntity(list, \"Ab\");\n        TestEntity entityAC = addEntity(list, \"ac\");\n        TestEntity entityZA = addEntity(list, \"ZA\");\n        TestEntity entityZB = addEntity(list, \"zB\");\n        TestEntity entityZC = addEntity(list, \"ZC\");\n        Collections.shuffle(list);\n        dao.insertInTx(list);\n\n        List<TestEntity> result = dao.queryBuilder().orderAsc(Properties.SimpleString).list();\n        assertEquals(list.size(), result.size());\n        assertEquals(entityAA.getId(), result.get(0).getId());\n        assertEquals(entityAB.getId(), result.get(1).getId());\n        assertEquals(entityAC.getId(), result.get(2).getId());\n        assertEquals(entityZA.getId(), result.get(3).getId());\n        assertEquals(entityZB.getId(), result.get(4).getId());\n        assertEquals(entityZC.getId(), result.get(5).getId());\n    }\n\n    public void testOrderUmlauts() {\n        List<TestEntity> list = new ArrayList<TestEntity>();\n        TestEntity entityV = addEntity(list, \"V\");\n        TestEntity entityB = addEntity(list, \"B\");\n        TestEntity entityUE = addEntity(list, \"Ü\");\n        TestEntity entityAE = addEntity(list, \"Ä\");\n        dao.insertInTx(list);\n\n        List<TestEntity> result = dao.queryBuilder().preferLocalizedStringOrder().orderAsc(Properties.SimpleString)\n                .list();\n        assertEquals(list.size(), result.size());\n        assertEquals(entityAE.getId(), result.get(0).getId());\n        assertEquals(entityB.getId(), result.get(1).getId());\n        assertEquals(entityUE.getId(), result.get(2).getId());\n        assertEquals(entityV.getId(), result.get(3).getId());\n    }\n\n    public void testOrderCustom() {\n        List<TestEntity> list = new ArrayList<TestEntity>();\n        TestEntity entityAA = addEntity(list, \"Aa\");\n        TestEntity entityAB = addEntity(list, \"ab\");\n        TestEntity entityAC = addEntity(list, \"Ac\");\n        dao.insertInTx(list);\n\n        List<TestEntity> result = dao.queryBuilder().orderCustom(Properties.SimpleString, \"ASC\").list();\n        assertEquals(list.size(), result.size());\n        assertEquals(entityAA.getId(), result.get(0).getId());\n        assertEquals(entityAC.getId(), result.get(1).getId());\n        assertEquals(entityAB.getId(), result.get(2).getId());\n    }\n\n    public void testOrderCustom_stringOrderCollation() {\n        List<TestEntity> list = new ArrayList<TestEntity>();\n        TestEntity entityAA = addEntity(list, \"Aa\");\n        TestEntity entityAB = addEntity(list, \"ab\");\n        TestEntity entityAC = addEntity(list, \"Ac\");\n        dao.insertInTx(list);\n\n        List<TestEntity> result = dao.queryBuilder().stringOrderCollation(null).orderAsc(Properties.SimpleString).list();\n        assertEquals(list.size(), result.size());\n        assertEquals(entityAA.getId(), result.get(0).getId());\n        assertEquals(entityAC.getId(), result.get(1).getId());\n        assertEquals(entityAB.getId(), result.get(2).getId());\n\n        result = dao.queryBuilder().stringOrderCollation(\"COLLATE BINARY\").orderAsc(Properties.SimpleString).list();\n        assertEquals(list.size(), result.size());\n        assertEquals(entityAA.getId(), result.get(0).getId());\n        assertEquals(entityAC.getId(), result.get(1).getId());\n        assertEquals(entityAB.getId(), result.get(2).getId());\n    }\n\n    public void testOrderRaw() {\n        ArrayList<TestEntity> inserted = insert(2);\n        List<TestEntity> result = dao.queryBuilder().orderRaw(Properties.SimpleInteger.columnName + \" ASC\").list();\n        assertEquals(2, result.size());\n        assertEquals(inserted.get(0).getId(), result.get(0).getId());\n\n        result = dao.queryBuilder().orderRaw(Properties.SimpleInteger.columnName + \" DESC\").list();\n        assertEquals(2, result.size());\n        assertEquals(inserted.get(1).getId(), result.get(0).getId());\n    }\n\n    private TestEntity addEntity(List<TestEntity> list, String simpleString) {\n        TestEntity entityAB = createEntity(42, simpleString);\n        list.add(entityAB);\n        return entityAB;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/QueryBuilderSimpleTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.List;\n\nimport org.greenrobot.greendao.daotest.entity.TestEntityTestBase;\nimport org.greenrobot.greendao.internal.SqlUtils;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.query.WhereCondition;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\n\npublic class QueryBuilderSimpleTest extends TestEntityTestBase {\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        QueryBuilder.LOG_SQL = true;\n        QueryBuilder.LOG_VALUES = true;\n    }\n\n    public void testEqInteger() {\n        ArrayList<TestEntity> inserted = insert(3);\n        int value = getSimpleInteger(1);\n\n        List<TestEntity> result = dao.queryBuilder().where(Properties.SimpleInteger.eq(value)).list();\n        assertEquals(1, result.size());\n\n        TestEntity resultEntity = result.get(0);\n        assertEquals(value, (int) resultEntity.getSimpleInteger());\n        assertEquals(inserted.get(1).getId(), resultEntity.getId());\n    }\n\n    public void testEqString() {\n        ArrayList<TestEntity> inserted = insert(3);\n        String value = getSimpleString(1);\n\n        List<TestEntity> result = dao.queryBuilder().where(Properties.SimpleString.eq(value)).list();\n        assertEquals(1, result.size());\n\n        TestEntity resultEntity = result.get(0);\n        assertEquals(value, resultEntity.getSimpleString());\n        assertEquals(inserted.get(1).getId(), resultEntity.getId());\n    }\n\n    public void testIn() {\n        ArrayList<TestEntity> inserted = insert(10);\n        String value1 = getSimpleString(2);\n        String value2 = getSimpleString(8);\n        String value3 = getSimpleString(9);\n\n        List<TestEntity> result = dao.queryBuilder().where(Properties.SimpleString.in(value1, value2, value3))\n                .orderAsc(Properties.SimpleString).list();\n        assertEquals(3, result.size());\n\n        TestEntity resultEntity1 = result.get(0);\n        assertEquals(value1, resultEntity1.getSimpleString());\n        assertEquals(inserted.get(2).getId(), resultEntity1.getId());\n\n        TestEntity resultEntity2 = result.get(1);\n        assertEquals(value2, resultEntity2.getSimpleString());\n        assertEquals(inserted.get(8).getId(), resultEntity2.getId());\n\n        TestEntity resultEntity3 = result.get(2);\n        assertEquals(value3, resultEntity3.getSimpleString());\n        assertEquals(inserted.get(9).getId(), resultEntity3.getId());\n    }\n\n    public void testNotIn() {\n        ArrayList<TestEntity> inserted = insert(5);\n        String value1 = getSimpleString(0);\n        String value2 = getSimpleString(2);\n        String value3 = getSimpleString(4);\n\n        List<TestEntity> result = dao.queryBuilder().where(Properties.SimpleString.notIn(value1, value2, value3))\n                .orderAsc(Properties.SimpleString).list();\n        assertEquals(2, result.size());\n\n        TestEntity resultEntity1 = result.get(0);\n        assertEquals(inserted.get(1).getId(), resultEntity1.getId());\n\n        TestEntity resultEntity2 = result.get(1);\n        assertEquals(inserted.get(3).getId(), resultEntity2.getId());\n    }\n\n    public void testEqStringAndInteger() {\n        ArrayList<TestEntity> inserted = insert(3);\n        String valueStr = getSimpleString(1);\n        int valueInt = getSimpleInteger(1);\n\n        List<TestEntity> result = dao.queryBuilder()\n                .where(Properties.SimpleString.eq(valueStr), Properties.SimpleInteger.eq(valueInt)).list();\n        assertEquals(1, result.size());\n\n        TestEntity resultEntity = result.get(0);\n        assertEquals(inserted.get(1).getId(), resultEntity.getId());\n    }\n\n    public void testNotEqString() {\n        ArrayList<TestEntity> inserted = insert(3);\n        String value = getSimpleString(1);\n\n        List<TestEntity> result = dao.queryBuilder().where(Properties.SimpleString.notEq(value)).list();\n        assertEquals(2, result.size());\n\n        TestEntity resultEntity1 = result.get(0);\n        TestEntity resultEntity2 = result.get(1);\n        long loId = Math.min(resultEntity1.getId(), resultEntity2.getId());\n        long hiId = Math.max(resultEntity1.getId(), resultEntity2.getId());\n        assertEquals((long) inserted.get(0).getId(), loId);\n        assertEquals((long) inserted.get(2).getId(), hiId);\n    }\n\n    public void testEqDate() {\n        ArrayList<TestEntity> inserted = insert(3);\n        TestEntity testEntity = inserted.get(1);\n\n        Date date = new Date();\n        testEntity.setSimpleDate(date);\n        dao.update(testEntity);\n\n        Query<TestEntity> queryDate = dao.queryBuilder().where(Properties.SimpleDate.eq(date)).build();\n        TestEntity testEntity2 = queryDate.uniqueOrThrow();\n        assertEquals(testEntity.getId(), testEntity2.getId());\n        queryDate.setParameter(0, date);\n        testEntity2 = queryDate.uniqueOrThrow();\n        assertEquals(testEntity.getId(), testEntity2.getId());\n\n        testEntity2 = dao.queryBuilder().where(Properties.SimpleDate.eq(date.getTime())).uniqueOrThrow();\n        assertEquals(testEntity.getId(), testEntity2.getId());\n    }\n\n    public void testEqBoolean() {\n        ArrayList<TestEntity> inserted = insert(3);\n        TestEntity testEntity = inserted.get(1);\n\n        testEntity.setSimpleBoolean(true);\n        dao.update(testEntity);\n\n        Query<TestEntity> queryBoolean = dao.queryBuilder().where(Properties.SimpleBoolean.eq(true)).build();\n        TestEntity testEntity2 = queryBoolean.uniqueOrThrow();\n        assertEquals(testEntity.getId(), testEntity2.getId());\n        queryBoolean.setParameter(0, true);\n        testEntity2 = queryBoolean.uniqueOrThrow();\n        assertEquals(testEntity.getId(), testEntity2.getId());\n\n        testEntity2 = dao.queryBuilder().where(Properties.SimpleBoolean.eq(Boolean.TRUE)).uniqueOrThrow();\n        assertEquals(testEntity.getId(), testEntity2.getId());\n\n        testEntity2 = dao.queryBuilder().where(Properties.SimpleBoolean.eq(\"TRUE\")).uniqueOrThrow();\n        assertEquals(testEntity.getId(), testEntity2.getId());\n\n        testEntity2 = dao.queryBuilder().where(Properties.SimpleBoolean.eq(\"truE\")).uniqueOrThrow();\n        assertEquals(testEntity.getId(), testEntity2.getId());\n    }\n\n    // TODO fix byte arrays? Android is doing String args everywhere\n    public void testEqByteArray() {\n        ArrayList<TestEntity> inserted = insert(3);\n        TestEntity testEntity = inserted.get(1);\n\n        byte[] byteArray = {96, 77, 37, -21};\n        testEntity.setSimpleByteArray(byteArray);\n        dao.update(testEntity);\n\n        // Unsupported: Query<TestEntity> query = dao.queryBuilder().where(Properties.SimpleByteArray.eq(byteArray)).build();\n\n        // Works, but probably voids any index on BLOBs (Note: there's no hex2blob function and X'?' is bad syntax):\n        // String conditionString = \"HEX(\" + Properties.SimpleByteArray.columnName + \")=?\";\n        // WhereCondition condition = new WhereCondition.StringCondition(conditionString, SqlUtils.toHex(byteArray));\n\n        String conditionString = Properties.SimpleByteArray.columnName + '=' + SqlUtils.escapeBlobArgument(byteArray);\n        WhereCondition condition = new WhereCondition.StringCondition(conditionString);\n        Query<TestEntity> query = dao.queryBuilder().where(condition).build();\n        TestEntity testEntity2 = query.uniqueOrThrow();\n        assertEquals(testEntity.getId(), testEntity2.getId());\n\n        // Unsupported: query.setParameter(0, new byte[]{96, 77, 37, -21, 99});\n        // Unsupported: assertNull(query.unique());\n    }\n\n    public void testIsNullIsNotNull() {\n        ArrayList<TestEntity> inserted = insert(2);\n        TestEntity testEntityNull = inserted.get(0);\n        TestEntity testEntityNotNull = inserted.get(1);\n\n        testEntityNull.setSimpleInteger(null);\n        testEntityNotNull.setSimpleInteger(42);\n        dao.update(testEntityNull);\n        dao.update(testEntityNotNull);\n\n        TestEntity testEntityNull2 = dao.queryBuilder().where(Properties.SimpleInteger.isNull()).uniqueOrThrow();\n        assertEquals(testEntityNull.getId(), testEntityNull2.getId());\n\n        TestEntity testEntityNotNull2 = dao.queryBuilder().where(Properties.SimpleInteger.isNotNull()).uniqueOrThrow();\n        assertEquals(testEntityNotNull.getId(), testEntityNotNull2.getId());\n    }\n\n    public void testBuildTwice() {\n        insert(3);\n        String value = getSimpleString(1);\n\n        QueryBuilder<TestEntity> builder = dao.queryBuilder().where(Properties.SimpleString.eq(value));\n        Query<TestEntity> query1 = builder.build();\n        Query<TestEntity> query2 = builder.build();\n        List<TestEntity> list1 = query1.list();\n        List<TestEntity> list2 = query2.list();\n        assertEquals(1, list1.size());\n        assertEquals(1, list2.size());\n        assertEquals(list1.get(0).getId(), list2.get(0).getId());\n    }\n\n    public void testLike() {\n        TestEntity entity = insert(3).get(1);\n        entity.setSimpleString(\"greenrobot\");\n        dao.update(entity);\n\n        Query<TestEntity> query = dao.queryBuilder().where(Properties.SimpleString.like(\"%robot\")).build();\n        TestEntity entity2 = query.uniqueOrThrow();\n        assertEquals(entity.getId(), entity2.getId());\n\n        query.setParameter(0, \"green%\");\n        entity2 = query.uniqueOrThrow();\n        assertEquals(entity.getId(), entity2.getId());\n\n        query.setParameter(0, \"%enrob%\");\n        entity2 = query.uniqueOrThrow();\n        assertEquals(entity.getId(), entity2.getId());\n\n        query.setParameter(0, \"%nothere%\");\n        entity2 = query.unique();\n        assertNull(entity2);\n    }\n\n    public void testDistinct() {\n        TestEntity entity = insert(3).get(1);\n\n        Query<TestEntity> query = dao.queryBuilder().distinct()\n                .where(Properties.SimpleString.eq(entity.getSimpleString())).build();\n        TestEntity entity2 = query.uniqueOrThrow();\n        assertEquals(entity.getId(), entity2.getId());\n        // TODO improve test to check functionality\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/QueryForThreadTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport android.os.Build.VERSION;\nimport android.os.Build.VERSION_CODES;\nimport android.util.SparseArray;\n\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\nimport org.greenrobot.greendao.daotest.entity.TestEntityTestBase;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\n\nimport java.lang.reflect.Field;\nimport java.lang.reflect.Method;\nimport java.util.Map;\n\npublic class QueryForThreadTest extends TestEntityTestBase {\n    /** Takes longer when activated */\n    private final static boolean DO_LEAK_TESTS = false;\n    private final static int LEAK_TEST_ITERATIONS = DO_LEAK_TESTS ? 100000 : 2500;\n\n    private Query<TestEntity> queryFromOtherThread;\n\n    public void testGetForCurrentThread_SameInstance() {\n        Query<TestEntity> query = dao.queryBuilder().build();\n        assertSame(query, query.forCurrentThread());\n    }\n\n    public void testGetForCurrentThread_ParametersAreReset() {\n        insert(3);\n        int value = getSimpleInteger(1);\n        Query<TestEntity> query = dao.queryBuilder().where(Properties.SimpleInteger.eq(value)).build();\n        query.setParameter(0, value + 1);\n        TestEntity entityFor2 = query.unique();\n        assertEquals(value + 1, (int) entityFor2.getSimpleInteger());\n        query = query.forCurrentThread();\n        assertNotNull(query.unique());\n    }\n\n    public void testGetForCurrentThread_ManyThreadsDontLeak() throws Exception {\n        if (VERSION.SDK_INT > VERSION_CODES.LOLLIPOP_MR1) {\n            DaoLog.i(\"testGetForCurrentThread_ManyThreadsDontLeak does not work on API level \" + VERSION.SDK_INT);\n            return;\n        }\n        QueryBuilder<TestEntity> builder = dao.queryBuilder().where(Properties.SimpleInteger.eq(\"dummy\"));\n        final Query<TestEntity> query = builder.build();\n        for (int i = 1; i <= LEAK_TEST_ITERATIONS; i++) {\n            Thread thread = new Thread() {\n                public void run() {\n                    query.forCurrentThread();\n                }\n            };\n            thread.start();\n            if (i % 10 == 0) {\n                thread.join();\n            }\n        }\n        Field queryDataField = Query.class.getDeclaredField(\"queryData\");\n        queryDataField.setAccessible(true);\n        Object queryData = queryDataField.get(query);\n        Class<?> dataSuperclass = queryData.getClass().getSuperclass();\n        Field mapField = dataSuperclass.getDeclaredField(\"queriesForThreads\");\n        mapField.setAccessible(true);\n\n        Method gcMethod = dataSuperclass.getDeclaredMethod(\"gc\");\n        gcMethod.setAccessible(true);\n        Map map = (Map) mapField.get(queryData);\n        for (int i = 0; map.size() > 1 && i < 1000; i++) {\n            DaoLog.d(\"Queries left after \" + i + \". GC: \" + map.size());\n            System.gc();\n            gcMethod.invoke(queryData);\n        }\n        assertEquals(1, map.size());\n    }\n\n    public void testBuildQueryDoesntLeak() {\n        QueryBuilder<TestEntity> builder = dao.queryBuilder().where(Properties.SimpleInteger.eq(\"dummy\"));\n        for (int i = 0; i < LEAK_TEST_ITERATIONS; i++) {\n            builder.build();\n        }\n    }\n\n    public void testGetForCurrentThread_TwoThreads() throws InterruptedException {\n        insert(3);\n        createQueryFromOtherThread();\n        Query<TestEntity> query = queryFromOtherThread.forCurrentThread();\n        assertNotSame(queryFromOtherThread, query);\n        query.setLimit(10);\n        query.setOffset(0);\n        assertEquals(getSimpleInteger(1), (int) query.uniqueOrThrow().getSimpleInteger());\n        int expected = getSimpleInteger(2);\n        query.setParameter(0, expected);\n        assertEquals(expected, (int) query.list().get(0).getSimpleInteger());\n        assertEquals(expected, (int) query.listLazy().get(0).getSimpleInteger());\n        assertEquals(expected, (int) query.listLazyUncached().get(0).getSimpleInteger());\n        assertEquals(expected, (int) query.unique().getSimpleInteger());\n        assertEquals(expected, (int) query.uniqueOrThrow().getSimpleInteger());\n    }\n\n    public void testThrowOutsideOwnerThread() throws InterruptedException {\n        createQueryFromOtherThread();\n        try {\n            queryFromOtherThread.list();\n            fail(\"Did not throw\");\n        } catch (DaoException expected) {\n            // OK\n        }\n        try {\n            queryFromOtherThread.listIterator();\n            fail(\"Did not throw\");\n        } catch (DaoException expected) {\n            // OK\n        }\n        try {\n            queryFromOtherThread.listLazyUncached();\n            fail(\"Did not throw\");\n        } catch (DaoException expected) {\n            // OK\n        }\n        try {\n            queryFromOtherThread.setLimit(2);\n            fail(\"Did not throw\");\n        } catch (DaoException expected) {\n            // OK\n        }\n        try {\n            queryFromOtherThread.setOffset(2);\n            fail(\"Did not throw\");\n        } catch (DaoException expected) {\n            // OK\n        }\n        try {\n            queryFromOtherThread.setParameter(0, 42);\n            fail(\"Did not throw\");\n        } catch (DaoException expected) {\n            // OK\n        }\n        try {\n            queryFromOtherThread.unique();\n            fail(\"Did not throw\");\n        } catch (DaoException expected) {\n            // OK\n        }\n        try {\n            queryFromOtherThread.uniqueOrThrow();\n            fail(\"Did not throw\");\n        } catch (DaoException expected) {\n            // OK\n        }\n    }\n\n    private void createQueryFromOtherThread() throws InterruptedException {\n        Thread thread = new Thread() {\n\n            @Override\n            public void run() {\n                QueryBuilder<TestEntity> builder = dao.queryBuilder();\n                builder.where(Properties.SimpleInteger.eq(getSimpleInteger(1)));\n                builder.limit(10).offset(20);\n                queryFromOtherThread = builder.build();\n            }\n        };\n        thread.start();\n        thread.join();\n        assertNotNull(queryFromOtherThread);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/QueryLimitOffsetTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport java.util.List;\n\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\nimport org.greenrobot.greendao.daotest.entity.TestEntityTestBase;\n\npublic class QueryLimitOffsetTest extends TestEntityTestBase {\n    \n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        QueryBuilder.LOG_SQL = true;\n        QueryBuilder.LOG_VALUES = true;\n    }\n\n    public void testQueryBuilderLimit() {\n        insert(10);\n        List<TestEntity> result = dao.queryBuilder().limit(3).orderAsc(Properties.SimpleInt).list();\n        assertEquals(3, result.size());\n\n        assertEquals(getSimpleInteger(0), result.get(0).getSimpleInteger().intValue());\n        assertEquals(getSimpleInteger(1), result.get(1).getSimpleInteger().intValue());\n        assertEquals(getSimpleInteger(2), result.get(2).getSimpleInteger().intValue());\n    }\n\n    public void testQueryBuilderOffsetAndLimit() {\n        insert(10);\n        List<TestEntity> result = dao.queryBuilder().offset(3).limit(3).orderAsc(Properties.SimpleInt).list();\n        assertEquals(3, result.size());\n\n        assertEquals(getSimpleInteger(3), result.get(0).getSimpleInteger().intValue());\n        assertEquals(getSimpleInteger(4), result.get(1).getSimpleInteger().intValue());\n        assertEquals(getSimpleInteger(5), result.get(2).getSimpleInteger().intValue());\n    }\n\n    public void testQueryBuilderOffsetAndLimitWithWhere() {\n        insert(10);\n        List<TestEntity> result = dao.queryBuilder().where(Properties.SimpleInteger.gt(getSimpleInteger(1))).offset(2)\n                .limit(3).orderAsc(Properties.SimpleInt).list();\n        assertEquals(3, result.size());\n\n        assertEquals(getSimpleInteger(4), result.get(0).getSimpleInteger().intValue());\n        assertEquals(getSimpleInteger(5), result.get(1).getSimpleInteger().intValue());\n        assertEquals(getSimpleInteger(6), result.get(2).getSimpleInteger().intValue());\n    }\n\n    public void testQueryOffsetAndLimit() {\n        insert(10);\n        Query<TestEntity> query = dao.queryBuilder().where(Properties.SimpleInteger.gt(getSimpleInteger(-1))).offset(-1)\n                .limit(-1).orderAsc(Properties.SimpleInt).build(); \n        query.setParameter(0, getSimpleInteger(1));\n        query.setLimit(3);\n        query.setOffset(2);\n        List<TestEntity> result = query.list();\n        assertEquals(3, result.size());\n\n        assertEquals(getSimpleInteger(4), result.get(0).getSimpleInteger().intValue());\n        assertEquals(getSimpleInteger(5), result.get(1).getSimpleInteger().intValue());\n        assertEquals(getSimpleInteger(6), result.get(2).getSimpleInteger().intValue());\n    }\n    \n    public void testQueryBuilderOffsetWithoutLimit() {\n        try{\n            dao.queryBuilder().offset(7).orderAsc(Properties.SimpleInt).build();\n            fail(\"Offset may not be set alone\");\n        } catch(RuntimeException expected) {\n            //OK\n        }\n    }\n    \n    public void testQueryLimitAndSetParameter() {\n        Query<TestEntity> query = dao.queryBuilder().limit(5).offset(1).build();\n        try{\n            query.setParameter(0, (Object) null);\n            fail(\"Offset/limit parameters must not interfere with user parameters\");\n        } catch(RuntimeException expected) {\n            //OK\n        }\n    }\n    \n    public void testQueryUnsetLimit() {\n        Query<TestEntity> query = dao.queryBuilder().build();\n        try{\n            query.setLimit(1);\n            fail(\"Limit must be defined in builder first\");\n        } catch(RuntimeException expected) {\n            //OK\n        }\n    } \n\n    public void testQueryUnsetOffset() {\n        Query<TestEntity> query = dao.queryBuilder().limit(1).build();\n        try{\n            query.setOffset(1);\n            fail(\"Offset must be defined in builder first\");\n        } catch(RuntimeException expected) {\n            //OK\n        }\n    } \n\n\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/QuerySpecialNamesTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.test.AbstractDaoTest;\nimport org.greenrobot.greendao.daotest.SpecialNamesEntity;\nimport org.greenrobot.greendao.daotest.SpecialNamesEntityDao;\nimport org.greenrobot.greendao.daotest.SpecialNamesEntityDao.Properties;\n\npublic class QuerySpecialNamesTest extends AbstractDaoTest<SpecialNamesEntityDao, SpecialNamesEntity, Long> {\n\n    public QuerySpecialNamesTest() {\n        super(SpecialNamesEntityDao.class);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        QueryBuilder.LOG_SQL = true;\n        QueryBuilder.LOG_VALUES = true;\n    }\n\n    public void testWhereWithSpecialNames() {\n        QueryBuilder<SpecialNamesEntity> queryBuilder = dao.queryBuilder();\n        queryBuilder.where(Properties.Avg.isNotNull());\n        queryBuilder.where(Properties.Count.isNotNull());\n        queryBuilder.where(Properties.Distinct.isNotNull());\n        queryBuilder.where(Properties.Index.isNotNull());\n        queryBuilder.where(Properties.Join.isNotNull());\n        queryBuilder.where(Properties.On.isNotNull());\n        queryBuilder.where(Properties.Select.isNotNull());\n        queryBuilder.where(Properties.Sum.isNotNull());\n        queryBuilder.where(Properties.Order.isNotNull());\n        queryBuilder.list();\n        queryBuilder.buildCount().count();\n        queryBuilder.buildDelete().executeDeleteWithoutDetachingEntities();\n    }\n\n    public void testWhereWithSpecialNamesWithValues() {\n        QueryBuilder<SpecialNamesEntity> queryBuilder = dao.queryBuilder();\n        queryBuilder.where(Properties.Avg.eq(\"test\"));\n        queryBuilder.where(Properties.Count.notIn(\"test\", \"test2\"));\n        queryBuilder.where(Properties.Distinct.ge(\"test\"));\n        queryBuilder.where(Properties.Index.le(\"test\"));\n        queryBuilder.where(Properties.Join.like(\"test\"));\n        queryBuilder.where(Properties.On.notEq(\"test\"));\n        queryBuilder.where(Properties.Select.in(\"test\", \"test2\"));\n        queryBuilder.where(Properties.Sum.lt(1));\n        queryBuilder.where(Properties.Order.gt(1));\n        queryBuilder.list();\n        queryBuilder.buildCount().count();\n        queryBuilder.buildDelete().executeDeleteWithoutDetachingEntities();\n    }\n\n    public void testOrderWithSpecialNames() {\n        QueryBuilder<SpecialNamesEntity> queryBuilder = dao.queryBuilder();\n        queryBuilder.orderAsc(Properties.Avg);\n        queryBuilder.orderAsc(Properties.Count);\n        queryBuilder.orderAsc(Properties.Distinct);\n        queryBuilder.orderAsc(Properties.Index);\n        queryBuilder.orderAsc(Properties.Join);\n        queryBuilder.orderAsc(Properties.On);\n        queryBuilder.orderAsc(Properties.Select);\n        queryBuilder.orderAsc(Properties.Sum);\n        queryBuilder.orderAsc(Properties.Order);\n        queryBuilder.list();\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/query/RawQueryTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.query;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport org.greenrobot.greendao.query.LazyList;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\nimport org.greenrobot.greendao.daotest.entity.TestEntityTestBase;\n\npublic class RawQueryTest extends TestEntityTestBase {\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        QueryBuilder.LOG_SQL = true;\n        QueryBuilder.LOG_VALUES = true;\n    }\n\n    public void testRawQueryEmptySql() {\n        insert(3);\n        Query<TestEntity> query = dao.queryRawCreate(\"\");\n        List<TestEntity> result = query.list();\n        assertEquals(3, result.size());\n    }\n\n    public void testRawQueryEqualsString() {\n        ArrayList<TestEntity> inserted = insert(3);\n        String value = getSimpleString(1);\n\n        String sql = \"WHERE \" + Properties.SimpleString.columnName + \"=?\";\n        List<TestEntity> result = dao.queryRawCreate(sql, value).list();\n        assertEquals(1, result.size());\n\n        TestEntity resultEntity = result.get(0);\n        assertEquals(value, resultEntity.getSimpleString());\n        assertEquals(inserted.get(1).getId(), resultEntity.getId());\n    }\n\n    public void testRawQueryCreate_setParameterInQuery() {\n        insert(3);\n        String value = getSimpleString(2);\n\n        String sql = \"WHERE \" + Properties.SimpleString.columnName + \"=?\";\n        Query<TestEntity> query = dao.queryRawCreate(sql, getSimpleString(1));\n        query.list();\n\n        query.setParameter(0, value);\n        List<TestEntity> result = query.list();\n\n        assertEquals(1, result.size());\n        assertEquals(value, result.get(0).getSimpleString());\n    }\n    \n    public void testRawQueryLazyList() {\n        ArrayList<TestEntity> list = insert(2);\n\n        LazyList<TestEntity> listLazy = dao.queryRawCreate(\"\").listLazy();\n        assertEquals(list.size(), listLazy.size());\n        assertNull(listLazy.peek(0));\n        assertNull(listLazy.peek(1));\n\n        assertNotNull(listLazy.get(1));\n        assertNull(listLazy.peek(0));\n        assertNotNull(listLazy.peek(1));\n\n        assertNotNull(listLazy.get(0));\n        assertNotNull(listLazy.peek(0));\n        assertNotNull(listLazy.peek(1));\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/rx/RxDaoTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.rx;\n\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao;\nimport org.greenrobot.greendao.rx.RxDao;\nimport org.greenrobot.greendao.test.AbstractDaoTest;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\nimport rx.Observable;\nimport rx.observers.TestSubscriber;\n\n@SuppressWarnings(\"unchecked\")\npublic class RxDaoTest extends AbstractDaoTest<TestEntityDao, TestEntity, Long> {\n\n    private RxDao rxDao;\n\n    public RxDaoTest() {\n        super(TestEntityDao.class);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        rxDao = dao.rx();\n    }\n\n    public void testScheduler() {\n        TestSubscriber<List<TestEntity>> testSubscriber = RxTestHelper.awaitTestSubscriber(rxDao.loadAll());\n        Thread lastSeenThread = testSubscriber.getLastSeenThread();\n        assertNotSame(lastSeenThread, Thread.currentThread());\n    }\n\n    public void testNoScheduler() {\n        RxDao<TestEntity, Long> rxDaoNoScheduler = dao.rxPlain();\n        TestSubscriber<List<TestEntity>> testSubscriber = RxTestHelper.awaitTestSubscriber(rxDaoNoScheduler.loadAll());\n        Thread lastSeenThread = testSubscriber.getLastSeenThread();\n        assertSame(lastSeenThread, Thread.currentThread());\n    }\n\n    public void testLoadAll() {\n        insertEntity(\"foo\");\n        insertEntity(\"bar\");\n\n        TestSubscriber<List<TestEntity>> testSubscriber = RxTestHelper.awaitTestSubscriber(rxDao.loadAll());\n        assertEquals(1, testSubscriber.getValueCount());\n        List<TestEntity> entities = testSubscriber.getOnNextEvents().get(0);\n\n        // Order of entities is unspecified\n        int foo = 0, bar = 0;\n        for (TestEntity entity : entities) {\n            String value = entity.getSimpleStringNotNull();\n            if (value.equals(\"foo\")) {\n                foo++;\n            } else if (value.equals(\"bar\")) {\n                bar++;\n            } else {\n                fail(value);\n            }\n        }\n        assertEquals(1, foo);\n        assertEquals(1, bar);\n    }\n\n    public void testLoad() {\n        TestEntity foo = insertEntity(\"foo\");\n        TestSubscriber<TestEntity> testSubscriber = RxTestHelper.awaitTestSubscriber(rxDao.load(foo.getId()));\n        assertEquals(1, testSubscriber.getValueCount());\n        TestEntity foo2 = testSubscriber.getOnNextEvents().get(0);\n        assertEquals(foo.getSimpleStringNotNull(), foo2.getSimpleStringNotNull());\n    }\n\n    public void testLoad_noResult() {\n        TestSubscriber<TestEntity> testSubscriber = RxTestHelper.awaitTestSubscriber(rxDao.load(42));\n        assertEquals(1, testSubscriber.getValueCount());\n        // Should we really propagate null through Rx?\n        assertNull(testSubscriber.getOnNextEvents().get(0));\n    }\n\n    public void testRefresh() {\n        TestEntity entity = insertEntity(\"foo\");\n        entity.setSimpleStringNotNull(\"temp\");\n        RxTestHelper.awaitTestSubscriber(rxDao.refresh(entity));\n        assertEquals(\"foo\", entity.getSimpleStringNotNull());\n    }\n\n    public void testInsert() {\n        TestEntity foo = RxTestHelper.createEntity(\"foo\");\n        TestSubscriber<TestEntity> testSubscriber = RxTestHelper.awaitTestSubscriber(rxDao.insert(foo));\n        assertEquals(1, testSubscriber.getValueCount());\n        TestEntity foo2 = testSubscriber.getOnNextEvents().get(0);\n        assertSame(foo, foo2);\n\n        List<TestEntity> all = dao.loadAll();\n        assertEquals(1, all.size());\n        assertEquals(foo.getSimpleStringNotNull(), all.get(0).getSimpleStringNotNull());\n    }\n\n    public void testInsertInTx() {\n        TestEntity foo = RxTestHelper.createEntity(\"foo\");\n        TestEntity bar = RxTestHelper.createEntity(\"bar\");\n        TestSubscriber<Object[]> testSubscriber = RxTestHelper.awaitTestSubscriber(rxDao.insertInTx(foo, bar));\n        assertEquals(1, testSubscriber.getValueCount());\n        Object[] array = testSubscriber.getOnNextEvents().get(0);\n        assertSame(foo, array[0]);\n        assertSame(bar, array[1]);\n\n        List<TestEntity> all = dao.loadAll();\n        assertEquals(2, all.size());\n        assertEquals(foo.getSimpleStringNotNull(), all.get(0).getSimpleStringNotNull());\n        assertEquals(bar.getSimpleStringNotNull(), all.get(1).getSimpleStringNotNull());\n    }\n\n    public void testInsertInTxList() {\n        TestEntity foo = RxTestHelper.createEntity(\"foo\");\n        TestEntity bar = RxTestHelper.createEntity(\"bar\");\n        List<TestEntity> list = new ArrayList<>();\n        list.add(foo);\n        list.add(bar);\n        TestSubscriber<List<TestEntity>> testSubscriber = RxTestHelper.awaitTestSubscriber(rxDao.insertInTx(list));\n        assertEquals(1, testSubscriber.getValueCount());\n        List<TestEntity> result = testSubscriber.getOnNextEvents().get(0);\n        assertSame(foo, result.get(0));\n        assertSame(bar, result.get(1));\n\n        List<TestEntity> all = dao.loadAll();\n        assertEquals(2, all.size());\n        assertEquals(foo.getSimpleStringNotNull(), all.get(0).getSimpleStringNotNull());\n        assertEquals(bar.getSimpleStringNotNull(), all.get(1).getSimpleStringNotNull());\n    }\n\n    public void testInsertOrReplace() {\n        TestEntity foo = insertEntity(\"foo\");\n\n        foo.setSimpleStringNotNull(\"bar\");\n\n        assertUpdatedEntity(foo, rxDao.insertOrReplace(foo));\n    }\n\n    public void testInsertOrReplaceInTx() {\n        TestEntity foo = insertEntity(\"foo\");\n        TestEntity bar = insertEntity(\"bar\");\n\n        foo.setSimpleStringNotNull(\"foo2\");\n\n        assertUpdatedEntities(foo, bar, rxDao.insertOrReplaceInTx(foo, bar));\n    }\n\n    public void testInsertOrReplaceInTxList() {\n        TestEntity foo = insertEntity(\"foo\");\n        TestEntity bar = insertEntity(\"bar\");\n\n        foo.setSimpleStringNotNull(\"foo2\");\n\n        List<TestEntity> list = new ArrayList<>();\n        list.add(foo);\n        list.add(bar);\n\n        assertUpdatedEntities(list, rxDao.insertOrReplaceInTx(list));\n    }\n\n    public void testSave() {\n        TestEntity foo = insertEntity(\"foo\");\n\n        foo.setSimpleStringNotNull(\"bar\");\n\n        assertUpdatedEntity(foo, rxDao.save(foo));\n    }\n\n    public void testSaveInTx() {\n        TestEntity foo = insertEntity(\"foo\");\n        TestEntity bar = insertEntity(\"bar\");\n\n        foo.setSimpleStringNotNull(\"foo2\");\n\n        assertUpdatedEntities(foo, bar, rxDao.saveInTx(foo, bar));\n    }\n\n    public void testSaveInTxList() {\n        TestEntity foo = insertEntity(\"foo\");\n        TestEntity bar = insertEntity(\"bar\");\n\n        foo.setSimpleStringNotNull(\"foo2\");\n\n        List<TestEntity> list = new ArrayList<>();\n        list.add(foo);\n        list.add(bar);\n\n        assertUpdatedEntities(list, rxDao.saveInTx(list));\n    }\n\n    public void testUpdate() {\n        TestEntity foo = insertEntity(\"foo\");\n        foo.setSimpleString(\"foofoo\");\n        TestSubscriber testSubscriber = RxTestHelper.awaitTestSubscriber(rxDao.update(foo));\n        assertEquals(1, testSubscriber.getValueCount());\n        assertSame(foo, testSubscriber.getOnNextEvents().get(0));\n        List<TestEntity> testEntities = dao.loadAll();\n        assertEquals(1, testEntities.size());\n        assertNotSame(foo, testEntities.get(0));\n        assertEquals(\"foofoo\", testEntities.get(0).getSimpleString());\n    }\n\n    public void testUpdateInTx() {\n        TestEntity foo = insertEntity(\"foo\");\n        TestEntity bar = insertEntity(\"bar\");\n\n        foo.setSimpleStringNotNull(\"foo2\");\n        bar.setSimpleStringNotNull(\"bar2\");\n\n        assertUpdatedEntities(foo, bar, rxDao.updateInTx(foo, bar));\n    }\n\n    public void testUpdateInTxList() {\n        TestEntity foo = insertEntity(\"foo\");\n        TestEntity bar = insertEntity(\"bar\");\n\n        foo.setSimpleStringNotNull(\"foo2\");\n        bar.setSimpleStringNotNull(\"bar2\");\n\n        List<TestEntity> list = new ArrayList<>();\n        list.add(foo);\n        list.add(bar);\n\n        assertUpdatedEntities(list, rxDao.updateInTx(list));\n    }\n\n    private void assertUpdatedEntity(TestEntity foo, Observable<TestEntity> observable) {\n        TestSubscriber<TestEntity> testSubscriber = RxTestHelper.awaitTestSubscriber(observable);\n        assertEquals(1, testSubscriber.getValueCount());\n        TestEntity bar = testSubscriber.getOnNextEvents().get(0);\n        assertSame(foo, bar);\n\n        List<TestEntity> all = dao.loadAll();\n        assertEquals(1, all.size());\n        assertEquals(foo.getSimpleStringNotNull(), all.get(0).getSimpleStringNotNull());\n    }\n\n    private void assertUpdatedEntities(TestEntity foo, TestEntity bar, Observable<Object[]> observable) {\n        TestSubscriber<Object[]> testSubscriber = RxTestHelper.awaitTestSubscriber(observable);\n        assertEquals(1, testSubscriber.getValueCount());\n        Object[] array = testSubscriber.getOnNextEvents().get(0);\n        assertSame(foo, array[0]);\n        assertSame(bar, array[1]);\n\n        List<TestEntity> all = dao.loadAll();\n        assertEquals(2, all.size());\n        assertEquals(foo.getSimpleStringNotNull(), all.get(0).getSimpleStringNotNull());\n        assertEquals(bar.getSimpleStringNotNull(), all.get(1).getSimpleStringNotNull());\n    }\n\n    private void assertUpdatedEntities(List<TestEntity> entities, Observable<List<TestEntity>> observable) {\n        TestEntity foo = entities.get(0);\n        TestEntity bar = entities.get(1);\n\n        TestSubscriber<List<TestEntity>> testSubscriber = RxTestHelper.awaitTestSubscriber(observable);\n        assertEquals(1, testSubscriber.getValueCount());\n        List<TestEntity> result = testSubscriber.getOnNextEvents().get(0);\n        assertSame(foo, result.get(0));\n        assertSame(bar, result.get(1));\n\n        List<TestEntity> all = dao.loadAll();\n        assertEquals(2, all.size());\n        assertEquals(foo.getSimpleStringNotNull(), all.get(0).getSimpleStringNotNull());\n        assertEquals(bar.getSimpleStringNotNull(), all.get(1).getSimpleStringNotNull());\n    }\n\n    public void testDelete() {\n        TestEntity foo = insertEntity(\"foo\");\n        assertDeleted(rxDao.delete(foo));\n    }\n\n    public void testDeleteByKey() {\n        TestEntity foo = insertEntity(\"foo\");\n        assertDeleted(rxDao.deleteByKey(foo.getId()));\n    }\n\n    public void testDeleteAll() {\n        insertEntity(\"foo\");\n        insertEntity(\"bar\");\n        assertDeleted(rxDao.deleteAll());\n    }\n\n    public void testDeleteInTx() {\n        TestEntity foo = insertEntity(\"foo\");\n        TestEntity bar = insertEntity(\"bar\");\n        assertDeleted(rxDao.deleteInTx(foo, bar));\n    }\n\n    public void testDeleteInTxList() {\n        TestEntity foo = insertEntity(\"foo\");\n        TestEntity bar = insertEntity(\"bar\");\n\n        List<TestEntity> list = new ArrayList<>();\n        list.add(foo);\n        list.add(bar);\n\n        assertDeleted(rxDao.deleteInTx(list));\n    }\n\n    public void testDeleteByKeyInTx() {\n        TestEntity foo = insertEntity(\"foo\");\n        TestEntity bar = insertEntity(\"bar\");\n        assertDeleted(rxDao.deleteByKeyInTx(foo.getId(), bar.getId()));\n    }\n\n    public void testDeleteByKeyInTxList() {\n        TestEntity foo = insertEntity(\"foo\");\n        TestEntity bar = insertEntity(\"bar\");\n\n        List<Long> list = new ArrayList<>();\n        list.add(foo.getId());\n        list.add(bar.getId());\n\n        assertDeleted(rxDao.deleteByKeyInTx(list));\n    }\n\n    private void assertDeleted(Observable<Void> observable) {\n        TestSubscriber testSubscriber = RxTestHelper.awaitTestSubscriber(observable);\n        assertEquals(1, testSubscriber.getValueCount());\n        assertNull(testSubscriber.getOnNextEvents().get(0));\n        assertEquals(0, dao.count());\n    }\n\n    public void testCount() {\n        insertEntity(\"foo\");\n        TestSubscriber<Long> testSubscriber = RxTestHelper.awaitTestSubscriber(rxDao.count());\n        assertEquals(1, testSubscriber.getValueCount());\n        Long count = testSubscriber.getOnNextEvents().get(0);\n        assertEquals(1L, (long) count);\n    }\n\n    protected TestEntity insertEntity(String simpleStringNotNull) {\n        return RxTestHelper.insertEntity(dao, simpleStringNotNull);\n    }\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/rx/RxQueryTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.rx;\n\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao.Properties;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.rx.RxQuery;\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\nimport rx.Observable;\nimport rx.Subscription;\nimport rx.observers.TestSubscriber;\n\npublic class RxQueryTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n\n    private Query<TestEntity> query;\n    private RxQuery<TestEntity> rxQuery;\n\n    public RxQueryTest() {\n        super(DaoMaster.class);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        query = daoSession.getTestEntityDao().queryBuilder().where(Properties.SimpleInt.lt(10)).build();\n        rxQuery = query.__InternalRx();\n    }\n\n    public void testList() {\n        insertEntities(15);\n        TestSubscriber<List<TestEntity>> testSubscriber = RxTestHelper.awaitTestSubscriber(rxQuery.list());\n        assertEquals(1, testSubscriber.getValueCount());\n        List<TestEntity> entitiesRead = testSubscriber.getOnNextEvents().get(0);\n        assertEquals(10, entitiesRead.size());\n    }\n\n    // TODO figure out how to pass params to rxQuery\n    public void _testListSetParameters() {\n        insertEntities(15);\n\n        // TODO how to pass those to rxQuery?\n        query.setParameter(0, 5);\n\n        TestSubscriber<List<TestEntity>> testSubscriber = RxTestHelper.awaitTestSubscriber(rxQuery.list());\n        assertEquals(1, testSubscriber.getValueCount());\n        List<TestEntity> entitiesRead = testSubscriber.getOnNextEvents().get(0);\n        assertEquals(5, entitiesRead.size());\n    }\n\n    public void testUnique() {\n        insertEntities(1);\n        TestSubscriber<TestEntity> testSubscriber = RxTestHelper.awaitTestSubscriber(rxQuery.unique());\n        assertEquals(1, testSubscriber.getValueCount());\n        TestEntity entityRead = testSubscriber.getOnNextEvents().get(0);\n        assertNotNull(entityRead);\n    }\n\n    public void testOneByOne() {\n        insertEntities(15);\n        TestSubscriber<TestEntity> testSubscriber = RxTestHelper.awaitTestSubscriber(rxQuery.oneByOne());\n        assertEquals(10, testSubscriber.getValueCount());\n        for (int i = 0; i < 10; i++) {\n            TestEntity entity = testSubscriber.getOnNextEvents().get(i);\n            assertEquals(i, entity.getSimpleInt());\n        }\n    }\n\n    public void testOneByOneUnsubscribe() {\n        insertEntities(1000);\n        RxQuery<TestEntity> bigQuery = daoSession.getTestEntityDao().queryBuilder().rx();\n        TestSubscriber<TestEntity> testSubscriber = new TestSubscriber<>();\n        Observable<TestEntity> observable = bigQuery.oneByOne();\n        Subscription subscription = observable.subscribe(testSubscriber);\n        subscription.unsubscribe();\n        testSubscriber.assertUnsubscribed();\n        int count = testSubscriber.getValueCount();\n        testSubscriber.awaitTerminalEvent(100, TimeUnit.MILLISECONDS);\n        int count2 = testSubscriber.getValueCount();\n        DaoLog.d(\"Count 1: \" + count + \" vs. count 2: \" + count2);\n        // Not strictly multi-threading correct, but anyway:\n        assertTrue(count2 < 1000);\n    }\n\n    protected List<TestEntity> insertEntities(int count) {\n        List<TestEntity> entities = new ArrayList<>(count);\n        for (int i = 0; i < count; i++) {\n            TestEntity entity = RxTestHelper.createEntity(\"My entity \");\n            entity.setSimpleInt(i);\n            entities.add(entity);\n        }\n\n        daoSession.getTestEntityDao().insertInTx(entities);\n        return entities;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/rx/RxTestHelper.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.rx;\n\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.TestEntityDao;\n\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\nimport rx.Observable;\nimport rx.observers.TestSubscriber;\n\npublic class RxTestHelper {\n    static <T> TestSubscriber<T> awaitTestSubscriber(Observable<T> observable) {\n        TestSubscriber<T> testSubscriber = new TestSubscriber<>();\n        observable.subscribe(testSubscriber);\n        testSubscriber.awaitTerminalEvent(3, TimeUnit.SECONDS);\n        testSubscriber.assertNoErrors();\n        testSubscriber.assertCompleted();\n        return testSubscriber;\n    }\n\n    static TestEntity insertEntity(TestEntityDao dao, String simpleStringNotNull) {\n        TestEntity entity = createEntity(simpleStringNotNull);\n        dao.insert(entity);\n        return entity;\n    }\n\n    static TestEntity createEntity(String simpleStringNotNull) {\n        TestEntity entity = new TestEntity();\n        entity.setSimpleStringNotNull(simpleStringNotNull);\n        return entity;\n    }\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest/rx/RxTransactionTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.rx;\n\nimport org.greenrobot.greendao.daotest.DaoMaster;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.rx.RxTransaction;\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\n\nimport java.util.List;\nimport java.util.concurrent.Callable;\n\nimport rx.Observable;\nimport rx.observers.TestSubscriber;\n\npublic class RxTransactionTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n\n    private RxTransaction rxTx;\n\n    public RxTransactionTest() {\n        super(DaoMaster.class);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n        rxTx = daoSession.rxTx();\n    }\n\n    public void testRun() {\n        Observable<Void> observable = rxTx.run(new Runnable() {\n            @Override\n            public void run() {\n                TestEntity entity = insertEntity(\"hello\");\n                entity.setSimpleString(\"world\");\n                daoSession.update(entity);\n            }\n        });\n        TestSubscriber<Void> testSubscriber = assertTxExecuted(observable);\n        assertNull(testSubscriber.getOnNextEvents().get(0));\n    }\n\n    public void testCall() {\n        testCall(rxTx);\n    }\n\n    public void testCallPlain() {\n        RxTransaction rxTxPlain = daoSession.rxTxPlain();\n        assertNotSame(rxTx, rxTxPlain);\n        testCall(rxTxPlain);\n    }\n\n    public void testCall(RxTransaction rxTx) {\n        Observable<String> observable = rxTx.call(new Callable<String>() {\n            @Override\n            public String call() {\n                TestEntity entity = insertEntity(\"hello\");\n                entity.setSimpleString(\"world\");\n                daoSession.update(entity);\n                return \"Just checking\";\n            }\n        });\n        TestSubscriber<String> testSubscriber = assertTxExecuted(observable);\n        assertEquals(\"Just checking\", testSubscriber.getOnNextEvents().get(0));\n    }\n\n    private <T> TestSubscriber<T> assertTxExecuted(Observable<T> observable) {\n        TestSubscriber<T> testSubscriber = RxTestHelper.awaitTestSubscriber(observable);\n        assertEquals(1, testSubscriber.getValueCount());\n\n        daoSession.clear();\n        List<TestEntity> all = daoSession.getTestEntityDao().loadAll();\n        assertEquals(1, all.size());\n        assertEquals(\"hello\", all.get(0).getSimpleStringNotNull());\n        assertEquals(\"world\", all.get(0).getSimpleString());\n        return testSubscriber;\n    }\n\n    protected TestEntity insertEntity(String simpleStringNotNull) {\n        return RxTestHelper.insertEntity(daoSession.getTestEntityDao(), simpleStringNotNull);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/androidTest/java/org/greenrobot/greendao/daotest2/entity/KeepEntityTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest2.entity;\n\nimport android.os.Build;\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\nimport org.greenrobot.greendao.daotest2.KeepEntity;\nimport org.greenrobot.greendao.daotest2.dao.KeepEntityDao;\n\npublic class KeepEntityTest extends AbstractDaoTestLongPk<KeepEntityDao, KeepEntity> {\n\n    public KeepEntityTest() {\n        super(KeepEntityDao.class);\n    }\n\n    @Override\n    protected KeepEntity createEntity(Long key) {\n        KeepEntity entity = new KeepEntity();\n        entity.setId(key);\n        return entity;\n    }\n\n    public void testKeepSectionAvailable() {\n        KeepEntity keepEntity = new KeepEntity(42l);\n        assertEquals(\"KeepEntity ID=42 (extra=\"+Build.VERSION.SDK+\")\", keepEntity.toString());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"org.greenrobot.greendao.daotest.dummyapp\"\n    android:versionCode=\"1\"\n    android:versionName=\"1.0\" >\n\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n\n    <application>\n        <uses-library android:name=\"android.test.runner\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "tests/DaoTest/src/main/assets/minimal-entity.sql",
    "content": "CREATE TABLE MINIMAL_ENTITY (_id INTEGER PRIMARY KEY);\nINSERT INTO MINIMAL_ENTITY VALUES (1);\nINSERT INTO MINIMAL_ENTITY \n\tVALUES (2);\nINSERT INTO MINIMAL_ENTITY VALUES (3)   ;\nINSERT INTO MINIMAL_ENTITY VALUES (4);  \nINSERT INTO MINIMAL_ENTITY VALUES (5) ;  \n"
  },
  {
    "path": "tests/DaoTest/src/test/java/org/greenrobot/greendao/unittest/DaoMaster.java",
    "content": "package org.greenrobot.greendao.unittest;\n\nimport android.content.Context;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.database.sqlite.SQLiteDatabase.CursorFactory;\nimport android.util.Log;\n\nimport org.greenrobot.greendao.AbstractDaoMaster;\nimport org.greenrobot.greendao.database.StandardDatabase;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseOpenHelper;\nimport org.greenrobot.greendao.identityscope.IdentityScopeType;\n\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/**\n * Master of DAO (schema version 1): knows all DAOs.\n */\npublic class DaoMaster extends AbstractDaoMaster {\n    public static final int SCHEMA_VERSION = 1;\n\n    /** Creates underlying database table using DAOs. */\n    public static void createAllTables(Database db, boolean ifNotExists) {\n        MinimalEntityDao.createTable(db, ifNotExists);\n    }\n\n    /** Drops underlying database table using DAOs. */\n    public static void dropAllTables(Database db, boolean ifExists) {\n        MinimalEntityDao.dropTable(db, ifExists);\n    }\n\n    /**\n     * WARNING: Drops all table on Upgrade! Use only during development.\n     * Convenience method using a {@link DevOpenHelper}.\n     */\n    public static DaoSession newDevSession(Context context, String name) {\n        Database db = new DevOpenHelper(context, name).getWritableDb();\n        DaoMaster daoMaster = new DaoMaster(db);\n        return daoMaster.newSession();\n    }\n\n    public DaoMaster(SQLiteDatabase db) {\n        this(new StandardDatabase(db));\n    }\n\n    public DaoMaster(Database db) {\n        super(db, SCHEMA_VERSION);\n        registerDaoClass(MinimalEntityDao.class);\n    }\n\n    public DaoSession newSession() {\n        return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);\n    }\n\n    public DaoSession newSession(IdentityScopeType type) {\n        return new DaoSession(db, type, daoConfigMap);\n    }\n\n    /**\n     * Calls {@link #createAllTables(Database, boolean)} in {@link #onCreate(Database)} -\n     */\n    public static abstract class OpenHelper extends DatabaseOpenHelper {\n        public OpenHelper(Context context, String name) {\n            super(context, name, SCHEMA_VERSION);\n        }\n\n        public OpenHelper(Context context, String name, CursorFactory factory) {\n            super(context, name, factory, SCHEMA_VERSION);\n        }\n\n        @Override\n        public void onCreate(Database db) {\n            Log.i(\"greenDAO\", \"Creating tables for schema version \" + SCHEMA_VERSION);\n            createAllTables(db, false);\n        }\n    }\n\n    /** WARNING: Drops all table on Upgrade! Use only during development. */\n    public static class DevOpenHelper extends OpenHelper {\n        public DevOpenHelper(Context context, String name) {\n            super(context, name);\n        }\n\n        public DevOpenHelper(Context context, String name, CursorFactory factory) {\n            super(context, name, factory);\n        }\n\n        @Override\n        public void onUpgrade(Database db, int oldVersion, int newVersion) {\n            Log.i(\"greenDAO\", \"Upgrading schema from version \" + oldVersion + \" to \" + newVersion + \" by dropping all tables\");\n            dropAllTables(db, true);\n            onCreate(db);\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/test/java/org/greenrobot/greendao/unittest/DaoSession.java",
    "content": "package org.greenrobot.greendao.unittest;\n\nimport java.util.Map;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.AbstractDaoSession;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.identityscope.IdentityScopeType;\nimport org.greenrobot.greendao.internal.DaoConfig;\n\nimport org.greenrobot.greendao.unittest.MinimalEntity;\n\nimport org.greenrobot.greendao.unittest.MinimalEntityDao;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n\n/**\n * {@inheritDoc}\n * \n * @see org.greenrobot.greendao.AbstractDaoSession\n */\npublic class DaoSession extends AbstractDaoSession {\n\n    private final DaoConfig minimalEntityDaoConfig;\n\n    private final MinimalEntityDao minimalEntityDao;\n\n    public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>\n            daoConfigMap) {\n        super(db);\n\n        minimalEntityDaoConfig = daoConfigMap.get(MinimalEntityDao.class).clone();\n        minimalEntityDaoConfig.initIdentityScope(type);\n\n        minimalEntityDao = new MinimalEntityDao(minimalEntityDaoConfig, this);\n\n        registerDao(MinimalEntity.class, minimalEntityDao);\n    }\n    \n    public void clear() {\n        minimalEntityDaoConfig.clearIdentityScope();\n    }\n\n    public MinimalEntityDao getMinimalEntityDao() {\n        return minimalEntityDao;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/test/java/org/greenrobot/greendao/unittest/MinimalEntity.java",
    "content": "package org.greenrobot.greendao.unittest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"MINIMAL_ENTITY\".\n */\n@Entity\npublic class MinimalEntity {\n\n    @Id\n    private Long id;\n\n    @Generated\n    public MinimalEntity() {\n    }\n\n    @Generated\n    public MinimalEntity(Long id) {\n        this.id = id;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/test/java/org/greenrobot/greendao/unittest/MinimalEntityDao.java",
    "content": "package org.greenrobot.greendao.unittest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"MINIMAL_ENTITY\".\n*/\npublic class MinimalEntityDao extends AbstractDao<MinimalEntity, Long> {\n\n    public static final String TABLENAME = \"MINIMAL_ENTITY\";\n\n    /**\n     * Properties of entity MinimalEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n    }\n\n\n    public MinimalEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public MinimalEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"MINIMAL_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY );\"); // 0: id\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"MINIMAL_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, MinimalEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, MinimalEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public MinimalEntity readEntity(Cursor cursor, int offset) {\n        MinimalEntity entity = new MinimalEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0) // id\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, MinimalEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(MinimalEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(MinimalEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(MinimalEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTest/src/test/java/org/greenrobot/greendao/unittest/MinimalEntityTest.java",
    "content": "package org.greenrobot.greendao.unittest;\n\nimport org.greenrobot.greendao.daotest.dummyapp.BuildConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.query.Query;\nimport org.junit.Before;\nimport org.junit.Test;\nimport org.junit.runner.RunWith;\nimport org.robolectric.RobolectricTestRunner;\nimport org.robolectric.RuntimeEnvironment;\nimport org.robolectric.annotation.Config;\n\nimport java.util.concurrent.CountDownLatch;\n\nimport static org.junit.Assert.assertEquals;\nimport static org.junit.Assert.assertNotNull;\nimport static org.junit.Assert.assertNull;\n\n@RunWith(RobolectricTestRunner.class)\n@Config(constants = BuildConfig.class, sdk = 16)\npublic class MinimalEntityTest {\n\n    private DaoSession daoSession;\n    private MinimalEntityDao minimalEntityDao;\n\n    @Before\n    public void setUp() {\n        DaoMaster.DevOpenHelper openHelper = new DaoMaster.DevOpenHelper(RuntimeEnvironment.application, null);\n        Database db = openHelper.getWritableDb();\n        daoSession = new DaoMaster(db).newSession();\n        minimalEntityDao = daoSession.getMinimalEntityDao();\n    }\n\n    @Test\n    public void testBasics() {\n        MinimalEntity entity = new MinimalEntity();\n        daoSession.insert(entity);\n        assertNotNull(entity.getId());\n        assertNotNull(minimalEntityDao.load(entity.getId()));\n        assertEquals(1, minimalEntityDao.count());\n        assertEquals(1, daoSession.loadAll(MinimalEntity.class).size());\n\n        daoSession.update(entity);\n        daoSession.delete(entity);\n        assertNull(minimalEntityDao.load(entity.getId()));\n    }\n\n    @Test\n    // Testing the work around for Process.myTid() being always 0 in Robolectric\n    public void testQueryForCurrentThread() throws InterruptedException {\n        final CountDownLatch latch = new CountDownLatch(1);\n        final Query<MinimalEntity>[] queryHolder = new Query[1];\n        new Thread() {\n            @Override\n            public void run() {\n                try {\n                    queryHolder[0] = minimalEntityDao.queryBuilder().build();\n                    queryHolder[0].list();\n                } finally {\n                    latch.countDown();\n                }\n            }\n        }.start();\n        latch.await();\n        Query<MinimalEntity> query = queryHolder[0].forCurrentThread();\n        query.list();\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTest/src/test/java/org/greenrobot/greendao/unittest/OptionalDepedenciesTest.java",
    "content": "package org.greenrobot.greendao.unittest;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\nimport org.greenrobot.greendao.database.EncryptedDatabase;\nimport org.greenrobot.greendao.identityscope.IdentityScope;\nimport org.greenrobot.greendao.query.CountQuery;\nimport org.greenrobot.greendao.query.DeleteQuery;\nimport org.greenrobot.greendao.query.Join;\nimport org.greenrobot.greendao.query.LazyList;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\nimport org.greenrobot.greendao.query.WhereCondition;\nimport org.greenrobot.greendao.rx.RxDao;\nimport org.junit.Ignore;\nimport org.junit.Test;\n\n\nimport static org.mockito.Mockito.mock;\n\n/**\n * We should not expose any optional library classes in signatures of greenDAO's primary classes and interfaces.\n * Reflection utils like Mockito should not fail with NoClassDefFoundError or the likes.\n */\npublic class OptionalDepedenciesTest {\n    @Test(expected = ClassNotFoundException.class)\n    public void testOptionalDependenciesAbsentRx() throws Exception {\n        Class.forName(\"rx.Observable\");\n    }\n\n    @Test(expected = ClassNotFoundException.class)\n    @Ignore(\"Why is it still on classpath??\")\n    public void testOptionalDependenciesAbsentSQLCipher() throws Exception {\n        Class.forName(\"net.sqlcipher.database.SQLiteDatabase\");\n    }\n\n    @Test\n    public void testMockitoMocks() {\n        mock(DaoMaster.class).newSession();\n        mock(DaoSession.class).getDatabase();\n        mock(Database.class).getRawDatabase();\n        mock(DatabaseStatement.class).execute();\n        mock(IdentityScope.class).clear();\n        mock(AbstractDao.class).queryBuilder();\n        mock(MinimalEntityDao.class).queryBuilder();\n        mock(MinimalEntity.class).getId();\n        mock(Query.class).forCurrentThread();\n        mock(QueryBuilder.class).build();\n        mock(CountQuery.class).forCurrentThread();\n        mock(DeleteQuery.class).forCurrentThread();\n        mock(Join.class).getTablePrefix();\n        mock(LazyList.class).getLoadedCount();\n        mock(WhereCondition.class).appendValuesTo(null);\n        mock(Property.class).isNull();\n        mock(DaoException.class).getMessage();\n    }\n\n    @Test(expected = NoClassDefFoundError.class)\n    public void testMockitoMocksFailForRx() {\n        mock(RxDao.class);\n    }\n\n    @Test(expected = NoClassDefFoundError.class)\n    @Ignore(\"Why is it still on classpath??\")\n    public void testMockitoMocksFailForSQLCipher() {\n        mock(EncryptedDatabase.class);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/build.gradle",
    "content": "apply plugin: 'java'\n\nsourceCompatibility = 1.7\ntargetCompatibility = 1.7\n\ndependencies {\n    compile project(':DaoCore')\n    compileOnly 'com.google.android:android:4.1.1.4'\n}\n\nuploadArchives.enabled = false"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/AbcdefEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"ABCDEF_ENTITY\".\n */\n@Entity\npublic class AbcdefEntity {\n\n    @Id\n    private Long id;\n    private Integer a;\n    private Integer b;\n    private Integer c;\n    private Integer d;\n    private Integer e;\n    private Integer f;\n    private Integer g;\n    private Integer h;\n    private Integer j;\n    private Integer i;\n    private Integer k;\n\n    @Generated\n    public AbcdefEntity() {\n    }\n\n    public AbcdefEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public AbcdefEntity(Long id, Integer a, Integer b, Integer c, Integer d, Integer e, Integer f, Integer g, Integer h, Integer j, Integer i, Integer k) {\n        this.id = id;\n        this.a = a;\n        this.b = b;\n        this.c = c;\n        this.d = d;\n        this.e = e;\n        this.f = f;\n        this.g = g;\n        this.h = h;\n        this.j = j;\n        this.i = i;\n        this.k = k;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public Integer getA() {\n        return a;\n    }\n\n    public void setA(Integer a) {\n        this.a = a;\n    }\n\n    public Integer getB() {\n        return b;\n    }\n\n    public void setB(Integer b) {\n        this.b = b;\n    }\n\n    public Integer getC() {\n        return c;\n    }\n\n    public void setC(Integer c) {\n        this.c = c;\n    }\n\n    public Integer getD() {\n        return d;\n    }\n\n    public void setD(Integer d) {\n        this.d = d;\n    }\n\n    public Integer getE() {\n        return e;\n    }\n\n    public void setE(Integer e) {\n        this.e = e;\n    }\n\n    public Integer getF() {\n        return f;\n    }\n\n    public void setF(Integer f) {\n        this.f = f;\n    }\n\n    public Integer getG() {\n        return g;\n    }\n\n    public void setG(Integer g) {\n        this.g = g;\n    }\n\n    public Integer getH() {\n        return h;\n    }\n\n    public void setH(Integer h) {\n        this.h = h;\n    }\n\n    public Integer getJ() {\n        return j;\n    }\n\n    public void setJ(Integer j) {\n        this.j = j;\n    }\n\n    public Integer getI() {\n        return i;\n    }\n\n    public void setI(Integer i) {\n        this.i = i;\n    }\n\n    public Integer getK() {\n        return k;\n    }\n\n    public void setK(Integer k) {\n        this.k = k;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/AbcdefEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"ABCDEF_ENTITY\".\n*/\npublic class AbcdefEntityDao extends AbstractDao<AbcdefEntity, Long> {\n\n    public static final String TABLENAME = \"ABCDEF_ENTITY\";\n\n    /**\n     * Properties of entity AbcdefEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property A = new Property(1, Integer.class, \"a\", false, \"A\");\n        public final static Property B = new Property(2, Integer.class, \"b\", false, \"B\");\n        public final static Property C = new Property(3, Integer.class, \"c\", false, \"C\");\n        public final static Property D = new Property(4, Integer.class, \"d\", false, \"D\");\n        public final static Property E = new Property(5, Integer.class, \"e\", false, \"E\");\n        public final static Property F = new Property(6, Integer.class, \"f\", false, \"F\");\n        public final static Property G = new Property(7, Integer.class, \"g\", false, \"G\");\n        public final static Property H = new Property(8, Integer.class, \"h\", false, \"H\");\n        public final static Property J = new Property(9, Integer.class, \"j\", false, \"J\");\n        public final static Property I = new Property(10, Integer.class, \"i\", false, \"I\");\n        public final static Property K = new Property(11, Integer.class, \"k\", false, \"K\");\n    }\n\n\n    public AbcdefEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public AbcdefEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"ABCDEF_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"A\\\" INTEGER,\" + // 1: a\n                \"\\\"B\\\" INTEGER,\" + // 2: b\n                \"\\\"C\\\" INTEGER,\" + // 3: c\n                \"\\\"D\\\" INTEGER,\" + // 4: d\n                \"\\\"E\\\" INTEGER,\" + // 5: e\n                \"\\\"F\\\" INTEGER,\" + // 6: f\n                \"\\\"G\\\" INTEGER,\" + // 7: g\n                \"\\\"H\\\" INTEGER,\" + // 8: h\n                \"\\\"J\\\" INTEGER,\" + // 9: j\n                \"\\\"I\\\" INTEGER,\" + // 10: i\n                \"\\\"K\\\" INTEGER);\"); // 11: k\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"ABCDEF_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, AbcdefEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Integer a = entity.getA();\n        if (a != null) {\n            stmt.bindLong(2, a);\n        }\n \n        Integer b = entity.getB();\n        if (b != null) {\n            stmt.bindLong(3, b);\n        }\n \n        Integer c = entity.getC();\n        if (c != null) {\n            stmt.bindLong(4, c);\n        }\n \n        Integer d = entity.getD();\n        if (d != null) {\n            stmt.bindLong(5, d);\n        }\n \n        Integer e = entity.getE();\n        if (e != null) {\n            stmt.bindLong(6, e);\n        }\n \n        Integer f = entity.getF();\n        if (f != null) {\n            stmt.bindLong(7, f);\n        }\n \n        Integer g = entity.getG();\n        if (g != null) {\n            stmt.bindLong(8, g);\n        }\n \n        Integer h = entity.getH();\n        if (h != null) {\n            stmt.bindLong(9, h);\n        }\n \n        Integer j = entity.getJ();\n        if (j != null) {\n            stmt.bindLong(10, j);\n        }\n \n        Integer i = entity.getI();\n        if (i != null) {\n            stmt.bindLong(11, i);\n        }\n \n        Integer k = entity.getK();\n        if (k != null) {\n            stmt.bindLong(12, k);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, AbcdefEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Integer a = entity.getA();\n        if (a != null) {\n            stmt.bindLong(2, a);\n        }\n \n        Integer b = entity.getB();\n        if (b != null) {\n            stmt.bindLong(3, b);\n        }\n \n        Integer c = entity.getC();\n        if (c != null) {\n            stmt.bindLong(4, c);\n        }\n \n        Integer d = entity.getD();\n        if (d != null) {\n            stmt.bindLong(5, d);\n        }\n \n        Integer e = entity.getE();\n        if (e != null) {\n            stmt.bindLong(6, e);\n        }\n \n        Integer f = entity.getF();\n        if (f != null) {\n            stmt.bindLong(7, f);\n        }\n \n        Integer g = entity.getG();\n        if (g != null) {\n            stmt.bindLong(8, g);\n        }\n \n        Integer h = entity.getH();\n        if (h != null) {\n            stmt.bindLong(9, h);\n        }\n \n        Integer j = entity.getJ();\n        if (j != null) {\n            stmt.bindLong(10, j);\n        }\n \n        Integer i = entity.getI();\n        if (i != null) {\n            stmt.bindLong(11, i);\n        }\n \n        Integer k = entity.getK();\n        if (k != null) {\n            stmt.bindLong(12, k);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public AbcdefEntity readEntity(Cursor cursor, int offset) {\n        AbcdefEntity entity = new AbcdefEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : cursor.getInt(offset + 1), // a\n            cursor.isNull(offset + 2) ? null : cursor.getInt(offset + 2), // b\n            cursor.isNull(offset + 3) ? null : cursor.getInt(offset + 3), // c\n            cursor.isNull(offset + 4) ? null : cursor.getInt(offset + 4), // d\n            cursor.isNull(offset + 5) ? null : cursor.getInt(offset + 5), // e\n            cursor.isNull(offset + 6) ? null : cursor.getInt(offset + 6), // f\n            cursor.isNull(offset + 7) ? null : cursor.getInt(offset + 7), // g\n            cursor.isNull(offset + 8) ? null : cursor.getInt(offset + 8), // h\n            cursor.isNull(offset + 9) ? null : cursor.getInt(offset + 9), // j\n            cursor.isNull(offset + 10) ? null : cursor.getInt(offset + 10), // i\n            cursor.isNull(offset + 11) ? null : cursor.getInt(offset + 11) // k\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, AbcdefEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setA(cursor.isNull(offset + 1) ? null : cursor.getInt(offset + 1));\n        entity.setB(cursor.isNull(offset + 2) ? null : cursor.getInt(offset + 2));\n        entity.setC(cursor.isNull(offset + 3) ? null : cursor.getInt(offset + 3));\n        entity.setD(cursor.isNull(offset + 4) ? null : cursor.getInt(offset + 4));\n        entity.setE(cursor.isNull(offset + 5) ? null : cursor.getInt(offset + 5));\n        entity.setF(cursor.isNull(offset + 6) ? null : cursor.getInt(offset + 6));\n        entity.setG(cursor.isNull(offset + 7) ? null : cursor.getInt(offset + 7));\n        entity.setH(cursor.isNull(offset + 8) ? null : cursor.getInt(offset + 8));\n        entity.setJ(cursor.isNull(offset + 9) ? null : cursor.getInt(offset + 9));\n        entity.setI(cursor.isNull(offset + 10) ? null : cursor.getInt(offset + 10));\n        entity.setK(cursor.isNull(offset + 11) ? null : cursor.getInt(offset + 11));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(AbcdefEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(AbcdefEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(AbcdefEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/AnActiveEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.DaoException;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"AN_ACTIVE_ENTITY\".\n */\n@Entity(active = true)\npublic class AnActiveEntity {\n\n    @Id\n    private Long id;\n    private String text;\n\n    /** Used to resolve relations */\n    @Generated\n    private transient DaoSession daoSession;\n\n    /** Used for active entity operations. */\n    @Generated\n    private transient AnActiveEntityDao myDao;\n\n    @Generated\n    public AnActiveEntity() {\n    }\n\n    public AnActiveEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public AnActiveEntity(Long id, String text) {\n        this.id = id;\n        this.text = text;\n    }\n\n    /** called by internal mechanisms, do not call yourself. */\n    @Generated\n    public void __setDaoSession(DaoSession daoSession) {\n        this.daoSession = daoSession;\n        myDao = daoSession != null ? daoSession.getAnActiveEntityDao() : null;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public String getText() {\n        return text;\n    }\n\n    public void setText(String text) {\n        this.text = text;\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void delete() {\n        __throwIfDetached();\n        myDao.delete(this);\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void update() {\n        __throwIfDetached();\n        myDao.update(this);\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void refresh() {\n        __throwIfDetached();\n        myDao.refresh(this);\n    }\n\n    @Generated\n    private void __throwIfDetached() {\n        if (myDao == null) {\n            throw new DaoException(\"Entity is detached from DAO context\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/AnActiveEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"AN_ACTIVE_ENTITY\".\n*/\npublic class AnActiveEntityDao extends AbstractDao<AnActiveEntity, Long> {\n\n    public static final String TABLENAME = \"AN_ACTIVE_ENTITY\";\n\n    /**\n     * Properties of entity AnActiveEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property Text = new Property(1, String.class, \"text\", false, \"TEXT\");\n    }\n\n    private DaoSession daoSession;\n\n\n    public AnActiveEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public AnActiveEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n        this.daoSession = daoSession;\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"AN_ACTIVE_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"TEXT\\\" TEXT);\"); // 1: text\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"AN_ACTIVE_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, AnActiveEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        String text = entity.getText();\n        if (text != null) {\n            stmt.bindString(2, text);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, AnActiveEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        String text = entity.getText();\n        if (text != null) {\n            stmt.bindString(2, text);\n        }\n    }\n\n    @Override\n    protected final void attachEntity(AnActiveEntity entity) {\n        super.attachEntity(entity);\n        entity.__setDaoSession(daoSession);\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public AnActiveEntity readEntity(Cursor cursor, int offset) {\n        AnActiveEntity entity = new AnActiveEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1) // text\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, AnActiveEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setText(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(AnActiveEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(AnActiveEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(AnActiveEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/AutoincrementEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"AUTOINCREMENT_ENTITY\".\n */\n@Entity\npublic class AutoincrementEntity {\n\n    @Id(autoincrement = true)\n    private Long id;\n\n    @Generated\n    public AutoincrementEntity() {\n    }\n\n    @Generated\n    public AutoincrementEntity(Long id) {\n        this.id = id;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/AutoincrementEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"AUTOINCREMENT_ENTITY\".\n*/\npublic class AutoincrementEntityDao extends AbstractDao<AutoincrementEntity, Long> {\n\n    public static final String TABLENAME = \"AUTOINCREMENT_ENTITY\";\n\n    /**\n     * Properties of entity AutoincrementEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n    }\n\n\n    public AutoincrementEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public AutoincrementEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"AUTOINCREMENT_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY AUTOINCREMENT );\"); // 0: id\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"AUTOINCREMENT_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, AutoincrementEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, AutoincrementEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public AutoincrementEntity readEntity(Cursor cursor, int offset) {\n        AutoincrementEntity entity = new AutoincrementEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0) // id\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, AutoincrementEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(AutoincrementEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(AutoincrementEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(AutoincrementEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/CustomTypeEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\nimport org.greenrobot.greendao.daotest.customtype.MyTimestamp;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"CUSTOM_TYPE_ENTITY\".\n */\n@Entity\npublic class CustomTypeEntity {\n\n    @Id\n    private Long id;\n\n    @Convert(converter = org.greenrobot.greendao.daotest.customtype.MyTimestampConverter.class, columnType = Long.class)\n    private MyTimestamp myCustomTimestamp;\n\n    @Generated\n    public CustomTypeEntity() {\n    }\n\n    public CustomTypeEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public CustomTypeEntity(Long id, MyTimestamp myCustomTimestamp) {\n        this.id = id;\n        this.myCustomTimestamp = myCustomTimestamp;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public MyTimestamp getMyCustomTimestamp() {\n        return myCustomTimestamp;\n    }\n\n    public void setMyCustomTimestamp(MyTimestamp myCustomTimestamp) {\n        this.myCustomTimestamp = myCustomTimestamp;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/CustomTypeEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\nimport org.greenrobot.greendao.daotest.customtype.MyTimestamp;\nimport org.greenrobot.greendao.daotest.customtype.MyTimestampConverter;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"CUSTOM_TYPE_ENTITY\".\n*/\npublic class CustomTypeEntityDao extends AbstractDao<CustomTypeEntity, Long> {\n\n    public static final String TABLENAME = \"CUSTOM_TYPE_ENTITY\";\n\n    /**\n     * Properties of entity CustomTypeEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property MyCustomTimestamp = new Property(1, Long.class, \"myCustomTimestamp\", false, \"MY_CUSTOM_TIMESTAMP\");\n    }\n\n    private final MyTimestampConverter myCustomTimestampConverter = new MyTimestampConverter();\n\n    public CustomTypeEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public CustomTypeEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"CUSTOM_TYPE_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"MY_CUSTOM_TIMESTAMP\\\" INTEGER);\"); // 1: myCustomTimestamp\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"CUSTOM_TYPE_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, CustomTypeEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        MyTimestamp myCustomTimestamp = entity.getMyCustomTimestamp();\n        if (myCustomTimestamp != null) {\n            stmt.bindLong(2, myCustomTimestampConverter.convertToDatabaseValue(myCustomTimestamp));\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, CustomTypeEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        MyTimestamp myCustomTimestamp = entity.getMyCustomTimestamp();\n        if (myCustomTimestamp != null) {\n            stmt.bindLong(2, myCustomTimestampConverter.convertToDatabaseValue(myCustomTimestamp));\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public CustomTypeEntity readEntity(Cursor cursor, int offset) {\n        CustomTypeEntity entity = new CustomTypeEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : myCustomTimestampConverter.convertToEntityProperty(cursor.getLong(offset + 1)) // myCustomTimestamp\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, CustomTypeEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setMyCustomTimestamp(cursor.isNull(offset + 1) ? null : myCustomTimestampConverter.convertToEntityProperty(cursor.getLong(offset + 1)));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(CustomTypeEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(CustomTypeEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(CustomTypeEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/DaoMaster.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.content.Context;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.database.sqlite.SQLiteDatabase.CursorFactory;\nimport android.util.Log;\n\nimport org.greenrobot.greendao.AbstractDaoMaster;\nimport org.greenrobot.greendao.database.StandardDatabase;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseOpenHelper;\nimport org.greenrobot.greendao.identityscope.IdentityScopeType;\n\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/**\n * Master of DAO (schema version 1): knows all DAOs.\n */\npublic class DaoMaster extends AbstractDaoMaster {\n    public static final int SCHEMA_VERSION = 1;\n\n    /** Creates underlying database table using DAOs. */\n    public static void createAllTables(Database db, boolean ifNotExists) {\n        SimpleEntityDao.createTable(db, ifNotExists);\n        SimpleEntityNotNullDao.createTable(db, ifNotExists);\n        TestEntityDao.createTable(db, ifNotExists);\n        RelationEntityDao.createTable(db, ifNotExists);\n        DateEntityDao.createTable(db, ifNotExists);\n        SpecialNamesEntityDao.createTable(db, ifNotExists);\n        AbcdefEntityDao.createTable(db, ifNotExists);\n        ToManyTargetEntityDao.createTable(db, ifNotExists);\n        ToManyEntityDao.createTable(db, ifNotExists);\n        JoinManyToDateEntityDao.createTable(db, ifNotExists);\n        TreeEntityDao.createTable(db, ifNotExists);\n        AnActiveEntityDao.createTable(db, ifNotExists);\n        ExtendsImplementsEntityDao.createTable(db, ifNotExists);\n        StringKeyValueEntityDao.createTable(db, ifNotExists);\n        AutoincrementEntityDao.createTable(db, ifNotExists);\n        CustomTypeEntityDao.createTable(db, ifNotExists);\n        IndexedStringEntityDao.createTable(db, ifNotExists);\n    }\n\n    /** Drops underlying database table using DAOs. */\n    public static void dropAllTables(Database db, boolean ifExists) {\n        SimpleEntityDao.dropTable(db, ifExists);\n        SimpleEntityNotNullDao.dropTable(db, ifExists);\n        TestEntityDao.dropTable(db, ifExists);\n        RelationEntityDao.dropTable(db, ifExists);\n        DateEntityDao.dropTable(db, ifExists);\n        SpecialNamesEntityDao.dropTable(db, ifExists);\n        AbcdefEntityDao.dropTable(db, ifExists);\n        ToManyTargetEntityDao.dropTable(db, ifExists);\n        ToManyEntityDao.dropTable(db, ifExists);\n        JoinManyToDateEntityDao.dropTable(db, ifExists);\n        TreeEntityDao.dropTable(db, ifExists);\n        AnActiveEntityDao.dropTable(db, ifExists);\n        ExtendsImplementsEntityDao.dropTable(db, ifExists);\n        StringKeyValueEntityDao.dropTable(db, ifExists);\n        AutoincrementEntityDao.dropTable(db, ifExists);\n        CustomTypeEntityDao.dropTable(db, ifExists);\n        IndexedStringEntityDao.dropTable(db, ifExists);\n    }\n\n    /**\n     * WARNING: Drops all table on Upgrade! Use only during development.\n     * Convenience method using a {@link DevOpenHelper}.\n     */\n    public static DaoSession newDevSession(Context context, String name) {\n        Database db = new DevOpenHelper(context, name).getWritableDb();\n        DaoMaster daoMaster = new DaoMaster(db);\n        return daoMaster.newSession();\n    }\n\n    public DaoMaster(SQLiteDatabase db) {\n        this(new StandardDatabase(db));\n    }\n\n    public DaoMaster(Database db) {\n        super(db, SCHEMA_VERSION);\n        registerDaoClass(SimpleEntityDao.class);\n        registerDaoClass(SimpleEntityNotNullDao.class);\n        registerDaoClass(TestEntityDao.class);\n        registerDaoClass(RelationEntityDao.class);\n        registerDaoClass(DateEntityDao.class);\n        registerDaoClass(SpecialNamesEntityDao.class);\n        registerDaoClass(AbcdefEntityDao.class);\n        registerDaoClass(ToManyTargetEntityDao.class);\n        registerDaoClass(ToManyEntityDao.class);\n        registerDaoClass(JoinManyToDateEntityDao.class);\n        registerDaoClass(TreeEntityDao.class);\n        registerDaoClass(AnActiveEntityDao.class);\n        registerDaoClass(ExtendsImplementsEntityDao.class);\n        registerDaoClass(StringKeyValueEntityDao.class);\n        registerDaoClass(AutoincrementEntityDao.class);\n        registerDaoClass(SqliteMasterDao.class);\n        registerDaoClass(CustomTypeEntityDao.class);\n        registerDaoClass(IndexedStringEntityDao.class);\n    }\n\n    public DaoSession newSession() {\n        return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);\n    }\n\n    public DaoSession newSession(IdentityScopeType type) {\n        return new DaoSession(db, type, daoConfigMap);\n    }\n\n    /**\n     * Calls {@link #createAllTables(Database, boolean)} in {@link #onCreate(Database)} -\n     */\n    public static abstract class OpenHelper extends DatabaseOpenHelper {\n        public OpenHelper(Context context, String name) {\n            super(context, name, SCHEMA_VERSION);\n        }\n\n        public OpenHelper(Context context, String name, CursorFactory factory) {\n            super(context, name, factory, SCHEMA_VERSION);\n        }\n\n        @Override\n        public void onCreate(Database db) {\n            Log.i(\"greenDAO\", \"Creating tables for schema version \" + SCHEMA_VERSION);\n            createAllTables(db, false);\n        }\n    }\n\n    /** WARNING: Drops all table on Upgrade! Use only during development. */\n    public static class DevOpenHelper extends OpenHelper {\n        public DevOpenHelper(Context context, String name) {\n            super(context, name);\n        }\n\n        public DevOpenHelper(Context context, String name, CursorFactory factory) {\n            super(context, name, factory);\n        }\n\n        @Override\n        public void onUpgrade(Database db, int oldVersion, int newVersion) {\n            Log.i(\"greenDAO\", \"Upgrading schema from version \" + oldVersion + \" to \" + newVersion + \" by dropping all tables\");\n            dropAllTables(db, true);\n            onCreate(db);\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/DaoSession.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport java.util.Map;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.AbstractDaoSession;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.identityscope.IdentityScopeType;\nimport org.greenrobot.greendao.internal.DaoConfig;\n\nimport org.greenrobot.greendao.daotest.SimpleEntity;\nimport org.greenrobot.greendao.daotest.SimpleEntityNotNull;\nimport org.greenrobot.greendao.daotest.TestEntity;\nimport org.greenrobot.greendao.daotest.RelationEntity;\nimport org.greenrobot.greendao.daotest.DateEntity;\nimport org.greenrobot.greendao.daotest.SpecialNamesEntity;\nimport org.greenrobot.greendao.daotest.AbcdefEntity;\nimport org.greenrobot.greendao.daotest.ToManyTargetEntity;\nimport org.greenrobot.greendao.daotest.ToManyEntity;\nimport org.greenrobot.greendao.daotest.JoinManyToDateEntity;\nimport org.greenrobot.greendao.daotest.TreeEntity;\nimport org.greenrobot.greendao.daotest.AnActiveEntity;\nimport org.greenrobot.greendao.daotest.ExtendsImplementsEntity;\nimport org.greenrobot.greendao.daotest.StringKeyValueEntity;\nimport org.greenrobot.greendao.daotest.AutoincrementEntity;\nimport org.greenrobot.greendao.daotest.SqliteMaster;\nimport org.greenrobot.greendao.daotest.CustomTypeEntity;\nimport org.greenrobot.greendao.daotest.IndexedStringEntity;\n\nimport org.greenrobot.greendao.daotest.SimpleEntityDao;\nimport org.greenrobot.greendao.daotest.SimpleEntityNotNullDao;\nimport org.greenrobot.greendao.daotest.TestEntityDao;\nimport org.greenrobot.greendao.daotest.RelationEntityDao;\nimport org.greenrobot.greendao.daotest.DateEntityDao;\nimport org.greenrobot.greendao.daotest.SpecialNamesEntityDao;\nimport org.greenrobot.greendao.daotest.AbcdefEntityDao;\nimport org.greenrobot.greendao.daotest.ToManyTargetEntityDao;\nimport org.greenrobot.greendao.daotest.ToManyEntityDao;\nimport org.greenrobot.greendao.daotest.JoinManyToDateEntityDao;\nimport org.greenrobot.greendao.daotest.TreeEntityDao;\nimport org.greenrobot.greendao.daotest.AnActiveEntityDao;\nimport org.greenrobot.greendao.daotest.ExtendsImplementsEntityDao;\nimport org.greenrobot.greendao.daotest.StringKeyValueEntityDao;\nimport org.greenrobot.greendao.daotest.AutoincrementEntityDao;\nimport org.greenrobot.greendao.daotest.SqliteMasterDao;\nimport org.greenrobot.greendao.daotest.CustomTypeEntityDao;\nimport org.greenrobot.greendao.daotest.IndexedStringEntityDao;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n\n/**\n * {@inheritDoc}\n * \n * @see org.greenrobot.greendao.AbstractDaoSession\n */\npublic class DaoSession extends AbstractDaoSession {\n\n    private final DaoConfig simpleEntityDaoConfig;\n    private final DaoConfig simpleEntityNotNullDaoConfig;\n    private final DaoConfig testEntityDaoConfig;\n    private final DaoConfig relationEntityDaoConfig;\n    private final DaoConfig dateEntityDaoConfig;\n    private final DaoConfig specialNamesEntityDaoConfig;\n    private final DaoConfig abcdefEntityDaoConfig;\n    private final DaoConfig toManyTargetEntityDaoConfig;\n    private final DaoConfig toManyEntityDaoConfig;\n    private final DaoConfig joinManyToDateEntityDaoConfig;\n    private final DaoConfig treeEntityDaoConfig;\n    private final DaoConfig anActiveEntityDaoConfig;\n    private final DaoConfig extendsImplementsEntityDaoConfig;\n    private final DaoConfig stringKeyValueEntityDaoConfig;\n    private final DaoConfig autoincrementEntityDaoConfig;\n    private final DaoConfig sqliteMasterDaoConfig;\n    private final DaoConfig customTypeEntityDaoConfig;\n    private final DaoConfig indexedStringEntityDaoConfig;\n\n    private final SimpleEntityDao simpleEntityDao;\n    private final SimpleEntityNotNullDao simpleEntityNotNullDao;\n    private final TestEntityDao testEntityDao;\n    private final RelationEntityDao relationEntityDao;\n    private final DateEntityDao dateEntityDao;\n    private final SpecialNamesEntityDao specialNamesEntityDao;\n    private final AbcdefEntityDao abcdefEntityDao;\n    private final ToManyTargetEntityDao toManyTargetEntityDao;\n    private final ToManyEntityDao toManyEntityDao;\n    private final JoinManyToDateEntityDao joinManyToDateEntityDao;\n    private final TreeEntityDao treeEntityDao;\n    private final AnActiveEntityDao anActiveEntityDao;\n    private final ExtendsImplementsEntityDao extendsImplementsEntityDao;\n    private final StringKeyValueEntityDao stringKeyValueEntityDao;\n    private final AutoincrementEntityDao autoincrementEntityDao;\n    private final SqliteMasterDao sqliteMasterDao;\n    private final CustomTypeEntityDao customTypeEntityDao;\n    private final IndexedStringEntityDao indexedStringEntityDao;\n\n    public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>\n            daoConfigMap) {\n        super(db);\n\n        simpleEntityDaoConfig = daoConfigMap.get(SimpleEntityDao.class).clone();\n        simpleEntityDaoConfig.initIdentityScope(type);\n\n        simpleEntityNotNullDaoConfig = daoConfigMap.get(SimpleEntityNotNullDao.class).clone();\n        simpleEntityNotNullDaoConfig.initIdentityScope(type);\n\n        testEntityDaoConfig = daoConfigMap.get(TestEntityDao.class).clone();\n        testEntityDaoConfig.initIdentityScope(type);\n\n        relationEntityDaoConfig = daoConfigMap.get(RelationEntityDao.class).clone();\n        relationEntityDaoConfig.initIdentityScope(type);\n\n        dateEntityDaoConfig = daoConfigMap.get(DateEntityDao.class).clone();\n        dateEntityDaoConfig.initIdentityScope(type);\n\n        specialNamesEntityDaoConfig = daoConfigMap.get(SpecialNamesEntityDao.class).clone();\n        specialNamesEntityDaoConfig.initIdentityScope(type);\n\n        abcdefEntityDaoConfig = daoConfigMap.get(AbcdefEntityDao.class).clone();\n        abcdefEntityDaoConfig.initIdentityScope(type);\n\n        toManyTargetEntityDaoConfig = daoConfigMap.get(ToManyTargetEntityDao.class).clone();\n        toManyTargetEntityDaoConfig.initIdentityScope(type);\n\n        toManyEntityDaoConfig = daoConfigMap.get(ToManyEntityDao.class).clone();\n        toManyEntityDaoConfig.initIdentityScope(type);\n\n        joinManyToDateEntityDaoConfig = daoConfigMap.get(JoinManyToDateEntityDao.class).clone();\n        joinManyToDateEntityDaoConfig.initIdentityScope(type);\n\n        treeEntityDaoConfig = daoConfigMap.get(TreeEntityDao.class).clone();\n        treeEntityDaoConfig.initIdentityScope(type);\n\n        anActiveEntityDaoConfig = daoConfigMap.get(AnActiveEntityDao.class).clone();\n        anActiveEntityDaoConfig.initIdentityScope(type);\n\n        extendsImplementsEntityDaoConfig = daoConfigMap.get(ExtendsImplementsEntityDao.class).clone();\n        extendsImplementsEntityDaoConfig.initIdentityScope(type);\n\n        stringKeyValueEntityDaoConfig = daoConfigMap.get(StringKeyValueEntityDao.class).clone();\n        stringKeyValueEntityDaoConfig.initIdentityScope(type);\n\n        autoincrementEntityDaoConfig = daoConfigMap.get(AutoincrementEntityDao.class).clone();\n        autoincrementEntityDaoConfig.initIdentityScope(type);\n\n        sqliteMasterDaoConfig = daoConfigMap.get(SqliteMasterDao.class).clone();\n        sqliteMasterDaoConfig.initIdentityScope(type);\n\n        customTypeEntityDaoConfig = daoConfigMap.get(CustomTypeEntityDao.class).clone();\n        customTypeEntityDaoConfig.initIdentityScope(type);\n\n        indexedStringEntityDaoConfig = daoConfigMap.get(IndexedStringEntityDao.class).clone();\n        indexedStringEntityDaoConfig.initIdentityScope(type);\n\n        simpleEntityDao = new SimpleEntityDao(simpleEntityDaoConfig, this);\n        simpleEntityNotNullDao = new SimpleEntityNotNullDao(simpleEntityNotNullDaoConfig, this);\n        testEntityDao = new TestEntityDao(testEntityDaoConfig, this);\n        relationEntityDao = new RelationEntityDao(relationEntityDaoConfig, this);\n        dateEntityDao = new DateEntityDao(dateEntityDaoConfig, this);\n        specialNamesEntityDao = new SpecialNamesEntityDao(specialNamesEntityDaoConfig, this);\n        abcdefEntityDao = new AbcdefEntityDao(abcdefEntityDaoConfig, this);\n        toManyTargetEntityDao = new ToManyTargetEntityDao(toManyTargetEntityDaoConfig, this);\n        toManyEntityDao = new ToManyEntityDao(toManyEntityDaoConfig, this);\n        joinManyToDateEntityDao = new JoinManyToDateEntityDao(joinManyToDateEntityDaoConfig, this);\n        treeEntityDao = new TreeEntityDao(treeEntityDaoConfig, this);\n        anActiveEntityDao = new AnActiveEntityDao(anActiveEntityDaoConfig, this);\n        extendsImplementsEntityDao = new ExtendsImplementsEntityDao(extendsImplementsEntityDaoConfig, this);\n        stringKeyValueEntityDao = new StringKeyValueEntityDao(stringKeyValueEntityDaoConfig, this);\n        autoincrementEntityDao = new AutoincrementEntityDao(autoincrementEntityDaoConfig, this);\n        sqliteMasterDao = new SqliteMasterDao(sqliteMasterDaoConfig, this);\n        customTypeEntityDao = new CustomTypeEntityDao(customTypeEntityDaoConfig, this);\n        indexedStringEntityDao = new IndexedStringEntityDao(indexedStringEntityDaoConfig, this);\n\n        registerDao(SimpleEntity.class, simpleEntityDao);\n        registerDao(SimpleEntityNotNull.class, simpleEntityNotNullDao);\n        registerDao(TestEntity.class, testEntityDao);\n        registerDao(RelationEntity.class, relationEntityDao);\n        registerDao(DateEntity.class, dateEntityDao);\n        registerDao(SpecialNamesEntity.class, specialNamesEntityDao);\n        registerDao(AbcdefEntity.class, abcdefEntityDao);\n        registerDao(ToManyTargetEntity.class, toManyTargetEntityDao);\n        registerDao(ToManyEntity.class, toManyEntityDao);\n        registerDao(JoinManyToDateEntity.class, joinManyToDateEntityDao);\n        registerDao(TreeEntity.class, treeEntityDao);\n        registerDao(AnActiveEntity.class, anActiveEntityDao);\n        registerDao(ExtendsImplementsEntity.class, extendsImplementsEntityDao);\n        registerDao(StringKeyValueEntity.class, stringKeyValueEntityDao);\n        registerDao(AutoincrementEntity.class, autoincrementEntityDao);\n        registerDao(SqliteMaster.class, sqliteMasterDao);\n        registerDao(CustomTypeEntity.class, customTypeEntityDao);\n        registerDao(IndexedStringEntity.class, indexedStringEntityDao);\n    }\n    \n    public void clear() {\n        simpleEntityDaoConfig.clearIdentityScope();\n        simpleEntityNotNullDaoConfig.clearIdentityScope();\n        testEntityDaoConfig.clearIdentityScope();\n        relationEntityDaoConfig.clearIdentityScope();\n        dateEntityDaoConfig.clearIdentityScope();\n        specialNamesEntityDaoConfig.clearIdentityScope();\n        abcdefEntityDaoConfig.clearIdentityScope();\n        toManyTargetEntityDaoConfig.clearIdentityScope();\n        toManyEntityDaoConfig.clearIdentityScope();\n        joinManyToDateEntityDaoConfig.clearIdentityScope();\n        treeEntityDaoConfig.clearIdentityScope();\n        anActiveEntityDaoConfig.clearIdentityScope();\n        extendsImplementsEntityDaoConfig.clearIdentityScope();\n        stringKeyValueEntityDaoConfig.clearIdentityScope();\n        autoincrementEntityDaoConfig.clearIdentityScope();\n        sqliteMasterDaoConfig.clearIdentityScope();\n        customTypeEntityDaoConfig.clearIdentityScope();\n        indexedStringEntityDaoConfig.clearIdentityScope();\n    }\n\n    public SimpleEntityDao getSimpleEntityDao() {\n        return simpleEntityDao;\n    }\n\n    public SimpleEntityNotNullDao getSimpleEntityNotNullDao() {\n        return simpleEntityNotNullDao;\n    }\n\n    public TestEntityDao getTestEntityDao() {\n        return testEntityDao;\n    }\n\n    public RelationEntityDao getRelationEntityDao() {\n        return relationEntityDao;\n    }\n\n    public DateEntityDao getDateEntityDao() {\n        return dateEntityDao;\n    }\n\n    public SpecialNamesEntityDao getSpecialNamesEntityDao() {\n        return specialNamesEntityDao;\n    }\n\n    public AbcdefEntityDao getAbcdefEntityDao() {\n        return abcdefEntityDao;\n    }\n\n    public ToManyTargetEntityDao getToManyTargetEntityDao() {\n        return toManyTargetEntityDao;\n    }\n\n    public ToManyEntityDao getToManyEntityDao() {\n        return toManyEntityDao;\n    }\n\n    public JoinManyToDateEntityDao getJoinManyToDateEntityDao() {\n        return joinManyToDateEntityDao;\n    }\n\n    public TreeEntityDao getTreeEntityDao() {\n        return treeEntityDao;\n    }\n\n    public AnActiveEntityDao getAnActiveEntityDao() {\n        return anActiveEntityDao;\n    }\n\n    public ExtendsImplementsEntityDao getExtendsImplementsEntityDao() {\n        return extendsImplementsEntityDao;\n    }\n\n    public StringKeyValueEntityDao getStringKeyValueEntityDao() {\n        return stringKeyValueEntityDao;\n    }\n\n    public AutoincrementEntityDao getAutoincrementEntityDao() {\n        return autoincrementEntityDao;\n    }\n\n    public SqliteMasterDao getSqliteMasterDao() {\n        return sqliteMasterDao;\n    }\n\n    public CustomTypeEntityDao getCustomTypeEntityDao() {\n        return customTypeEntityDao;\n    }\n\n    public IndexedStringEntityDao getIndexedStringEntityDao() {\n        return indexedStringEntityDao;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/DateEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\nimport java.lang.String;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"DATE_ENTITY\".\n */\n@Entity\npublic class DateEntity {\n\n    @Id\n    private Long id;\n    // Test code for\n    // field\n    private java.util.Date date;\n\n    @NotNull\n    private java.util.Date dateNotNull;\n\n    @Generated\n    public DateEntity() {\n    }\n\n    public DateEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public DateEntity(Long id, java.util.Date date, java.util.Date dateNotNull) {\n        this.id = id;\n        this.date = date;\n        this.dateNotNull = dateNotNull;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    // Test code for\n    // getter\n    public java.util.Date getDate() {\n        return date;\n    }\n\n    // Test code for\n    // setter\n    public void setDate(java.util.Date date) {\n        this.date = date;\n    }\n\n    @NotNull\n    public java.util.Date getDateNotNull() {\n        return dateNotNull;\n    }\n\n    /** Not-null value; ensure this value is available before it is saved to the database. */\n    public void setDateNotNull(@NotNull java.util.Date dateNotNull) {\n        this.dateNotNull = dateNotNull;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/DateEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport java.util.List;\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"DATE_ENTITY\".\n*/\npublic class DateEntityDao extends AbstractDao<DateEntity, Long> {\n\n    public static final String TABLENAME = \"DATE_ENTITY\";\n\n    /**\n     * Properties of entity DateEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property Date = new Property(1, java.util.Date.class, \"date\", false, \"DATE\");\n        public final static Property DateNotNull = new Property(2, java.util.Date.class, \"dateNotNull\", false, \"DATE_NOT_NULL\");\n    }\n\n    private Query<DateEntity> toManyEntity_DateEntityListQuery;\n\n    public DateEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public DateEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"DATE_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"DATE\\\" INTEGER,\" + // 1: date\n                \"\\\"DATE_NOT_NULL\\\" INTEGER NOT NULL );\"); // 2: dateNotNull\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"DATE_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, DateEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        java.util.Date date = entity.getDate();\n        if (date != null) {\n            stmt.bindLong(2, date.getTime());\n        }\n        stmt.bindLong(3, entity.getDateNotNull().getTime());\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, DateEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        java.util.Date date = entity.getDate();\n        if (date != null) {\n            stmt.bindLong(2, date.getTime());\n        }\n        stmt.bindLong(3, entity.getDateNotNull().getTime());\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public DateEntity readEntity(Cursor cursor, int offset) {\n        DateEntity entity = new DateEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : new java.util.Date(cursor.getLong(offset + 1)), // date\n            new java.util.Date(cursor.getLong(offset + 2)) // dateNotNull\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, DateEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setDate(cursor.isNull(offset + 1) ? null : new java.util.Date(cursor.getLong(offset + 1)));\n        entity.setDateNotNull(new java.util.Date(cursor.getLong(offset + 2)));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(DateEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(DateEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(DateEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n    /** Internal query to resolve the \"dateEntityList\" to-many relationship of ToManyEntity. */\n    public List<DateEntity> _queryToManyEntity_DateEntityList(Long idToMany) {\n        synchronized (this) {\n            if (toManyEntity_DateEntityListQuery == null) {\n                QueryBuilder<DateEntity> queryBuilder = queryBuilder();\n                queryBuilder.join(JoinManyToDateEntity.class, JoinManyToDateEntityDao.Properties.IdDate)\n                    .where(JoinManyToDateEntityDao.Properties.IdToMany.eq(idToMany));\n                toManyEntity_DateEntityListQuery = queryBuilder.build();\n            }\n        }\n        Query<DateEntity> query = toManyEntity_DateEntityListQuery.forCurrentThread();\n        query.setParameter(0, idToMany);\n        return query.list();\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/ExtendsImplementsEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"EXTENDS_IMPLEMENTS_ENTITY\".\n */\n@Entity\npublic class ExtendsImplementsEntity extends TestSuperclass  implements TestInterface, java.io.Serializable {\n\n    @Id\n    private Long id;\n    private String text;\n\n    @Generated\n    public ExtendsImplementsEntity() {\n    }\n\n    public ExtendsImplementsEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public ExtendsImplementsEntity(Long id, String text) {\n        this.id = id;\n        this.text = text;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public String getText() {\n        return text;\n    }\n\n    public void setText(String text) {\n        this.text = text;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/ExtendsImplementsEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"EXTENDS_IMPLEMENTS_ENTITY\".\n*/\npublic class ExtendsImplementsEntityDao extends AbstractDao<ExtendsImplementsEntity, Long> {\n\n    public static final String TABLENAME = \"EXTENDS_IMPLEMENTS_ENTITY\";\n\n    /**\n     * Properties of entity ExtendsImplementsEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property Text = new Property(1, String.class, \"text\", false, \"TEXT\");\n    }\n\n\n    public ExtendsImplementsEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public ExtendsImplementsEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"EXTENDS_IMPLEMENTS_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"TEXT\\\" TEXT);\"); // 1: text\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"EXTENDS_IMPLEMENTS_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, ExtendsImplementsEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        String text = entity.getText();\n        if (text != null) {\n            stmt.bindString(2, text);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, ExtendsImplementsEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        String text = entity.getText();\n        if (text != null) {\n            stmt.bindString(2, text);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public ExtendsImplementsEntity readEntity(Cursor cursor, int offset) {\n        ExtendsImplementsEntity entity = new ExtendsImplementsEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1) // text\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, ExtendsImplementsEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setText(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(ExtendsImplementsEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(ExtendsImplementsEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(ExtendsImplementsEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/IndexedStringEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"INDEXED_STRING_ENTITY\".\n */\n@Entity\npublic class IndexedStringEntity {\n\n    @Id\n    private Long id;\n\n    @Index\n    private String indexedString;\n\n    @Generated\n    public IndexedStringEntity() {\n    }\n\n    public IndexedStringEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public IndexedStringEntity(Long id, String indexedString) {\n        this.id = id;\n        this.indexedString = indexedString;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public String getIndexedString() {\n        return indexedString;\n    }\n\n    public void setIndexedString(String indexedString) {\n        this.indexedString = indexedString;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/IndexedStringEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"INDEXED_STRING_ENTITY\".\n*/\npublic class IndexedStringEntityDao extends AbstractDao<IndexedStringEntity, Long> {\n\n    public static final String TABLENAME = \"INDEXED_STRING_ENTITY\";\n\n    /**\n     * Properties of entity IndexedStringEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property IndexedString = new Property(1, String.class, \"indexedString\", false, \"INDEXED_STRING\");\n    }\n\n\n    public IndexedStringEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public IndexedStringEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"INDEXED_STRING_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"INDEXED_STRING\\\" TEXT);\"); // 1: indexedString\n        // Add Indexes\n        db.execSQL(\"CREATE INDEX \" + constraint + \"IDX_INDEXED_STRING_ENTITY_INDEXED_STRING ON INDEXED_STRING_ENTITY\" +\n                \" (\\\"INDEXED_STRING\\\");\");\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"INDEXED_STRING_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, IndexedStringEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        String indexedString = entity.getIndexedString();\n        if (indexedString != null) {\n            stmt.bindString(2, indexedString);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, IndexedStringEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        String indexedString = entity.getIndexedString();\n        if (indexedString != null) {\n            stmt.bindString(2, indexedString);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public IndexedStringEntity readEntity(Cursor cursor, int offset) {\n        IndexedStringEntity entity = new IndexedStringEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1) // indexedString\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, IndexedStringEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setIndexedString(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(IndexedStringEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(IndexedStringEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(IndexedStringEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/JoinManyToDateEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"JOIN_MANY_TO_DATE_ENTITY\".\n */\n@Entity\npublic class JoinManyToDateEntity {\n\n    @Id\n    private Long id;\n    private Long idToMany;\n    private Long idDate;\n\n    @Generated\n    public JoinManyToDateEntity() {\n    }\n\n    public JoinManyToDateEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public JoinManyToDateEntity(Long id, Long idToMany, Long idDate) {\n        this.id = id;\n        this.idToMany = idToMany;\n        this.idDate = idDate;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public Long getIdToMany() {\n        return idToMany;\n    }\n\n    public void setIdToMany(Long idToMany) {\n        this.idToMany = idToMany;\n    }\n\n    public Long getIdDate() {\n        return idDate;\n    }\n\n    public void setIdDate(Long idDate) {\n        this.idDate = idDate;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/JoinManyToDateEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"JOIN_MANY_TO_DATE_ENTITY\".\n*/\npublic class JoinManyToDateEntityDao extends AbstractDao<JoinManyToDateEntity, Long> {\n\n    public static final String TABLENAME = \"JOIN_MANY_TO_DATE_ENTITY\";\n\n    /**\n     * Properties of entity JoinManyToDateEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property IdToMany = new Property(1, Long.class, \"idToMany\", false, \"ID_TO_MANY\");\n        public final static Property IdDate = new Property(2, Long.class, \"idDate\", false, \"ID_DATE\");\n    }\n\n\n    public JoinManyToDateEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public JoinManyToDateEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"JOIN_MANY_TO_DATE_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"ID_TO_MANY\\\" INTEGER,\" + // 1: idToMany\n                \"\\\"ID_DATE\\\" INTEGER);\"); // 2: idDate\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"JOIN_MANY_TO_DATE_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, JoinManyToDateEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Long idToMany = entity.getIdToMany();\n        if (idToMany != null) {\n            stmt.bindLong(2, idToMany);\n        }\n \n        Long idDate = entity.getIdDate();\n        if (idDate != null) {\n            stmt.bindLong(3, idDate);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, JoinManyToDateEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Long idToMany = entity.getIdToMany();\n        if (idToMany != null) {\n            stmt.bindLong(2, idToMany);\n        }\n \n        Long idDate = entity.getIdDate();\n        if (idDate != null) {\n            stmt.bindLong(3, idDate);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public JoinManyToDateEntity readEntity(Cursor cursor, int offset) {\n        JoinManyToDateEntity entity = new JoinManyToDateEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1), // idToMany\n            cursor.isNull(offset + 2) ? null : cursor.getLong(offset + 2) // idDate\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, JoinManyToDateEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setIdToMany(cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1));\n        entity.setIdDate(cursor.isNull(offset + 2) ? null : cursor.getLong(offset + 2));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(JoinManyToDateEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(JoinManyToDateEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(JoinManyToDateEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/RelationEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.DaoException;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"RELATION_ENTITY\".\n */\n@Entity(active = true)\npublic class RelationEntity {\n\n    @Id\n    private Long id;\n    private Long parentId;\n    private Long testId;\n    private long testIdNotNull;\n    private String simpleString;\n\n    /** Used to resolve relations */\n    @Generated\n    private transient DaoSession daoSession;\n\n    /** Used for active entity operations. */\n    @Generated\n    private transient RelationEntityDao myDao;\n\n    @ToOne(joinProperty = \"parentId\")\n    private RelationEntity parent;\n\n    @Generated\n    private transient Long parent__resolvedKey;\n\n    @ToOne(joinProperty = \"testId\")\n    private TestEntity testEntity;\n\n    @Generated\n    private transient Long testEntity__resolvedKey;\n\n    @ToOne(joinProperty = \"testIdNotNull\")\n    private TestEntity testNotNull;\n\n    @Generated\n    private transient Long testNotNull__resolvedKey;\n\n    @ToOne\n    @Property(nameInDb = \"WITHOUT_PROPERTY_TEST_ID\")\n    private TestEntity testWithoutProperty;\n\n    @Generated\n    private transient boolean testWithoutProperty__refreshed;\n\n    @Generated\n    public RelationEntity() {\n    }\n\n    public RelationEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public RelationEntity(Long id, Long parentId, Long testId, long testIdNotNull, String simpleString) {\n        this.id = id;\n        this.parentId = parentId;\n        this.testId = testId;\n        this.testIdNotNull = testIdNotNull;\n        this.simpleString = simpleString;\n    }\n\n    /** called by internal mechanisms, do not call yourself. */\n    @Generated\n    public void __setDaoSession(DaoSession daoSession) {\n        this.daoSession = daoSession;\n        myDao = daoSession != null ? daoSession.getRelationEntityDao() : null;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public Long getParentId() {\n        return parentId;\n    }\n\n    public void setParentId(Long parentId) {\n        this.parentId = parentId;\n    }\n\n    public Long getTestId() {\n        return testId;\n    }\n\n    public void setTestId(Long testId) {\n        this.testId = testId;\n    }\n\n    public long getTestIdNotNull() {\n        return testIdNotNull;\n    }\n\n    public void setTestIdNotNull(long testIdNotNull) {\n        this.testIdNotNull = testIdNotNull;\n    }\n\n    public String getSimpleString() {\n        return simpleString;\n    }\n\n    public void setSimpleString(String simpleString) {\n        this.simpleString = simpleString;\n    }\n\n    /** To-one relationship, resolved on first access. */\n    @Generated\n    public RelationEntity getParent() {\n        Long __key = this.parentId;\n        if (parent__resolvedKey == null || !parent__resolvedKey.equals(__key)) {\n            __throwIfDetached();\n            RelationEntityDao targetDao = daoSession.getRelationEntityDao();\n            RelationEntity parentNew = targetDao.load(__key);\n            synchronized (this) {\n                parent = parentNew;\n            \tparent__resolvedKey = __key;\n            }\n        }\n        return parent;\n    }\n\n    @Generated\n    public void setParent(RelationEntity parent) {\n        synchronized (this) {\n            this.parent = parent;\n            parentId = parent == null ? null : parent.getId();\n            parent__resolvedKey = parentId;\n        }\n    }\n\n    /** To-one relationship, resolved on first access. */\n    @Generated\n    public TestEntity getTestEntity() {\n        Long __key = this.testId;\n        if (testEntity__resolvedKey == null || !testEntity__resolvedKey.equals(__key)) {\n            __throwIfDetached();\n            TestEntityDao targetDao = daoSession.getTestEntityDao();\n            TestEntity testEntityNew = targetDao.load(__key);\n            synchronized (this) {\n                testEntity = testEntityNew;\n            \ttestEntity__resolvedKey = __key;\n            }\n        }\n        return testEntity;\n    }\n\n    @Generated\n    public void setTestEntity(TestEntity testEntity) {\n        synchronized (this) {\n            this.testEntity = testEntity;\n            testId = testEntity == null ? null : testEntity.getId();\n            testEntity__resolvedKey = testId;\n        }\n    }\n\n    /** To-one relationship, resolved on first access. */\n    @Generated\n    public TestEntity getTestNotNull() {\n        long __key = this.testIdNotNull;\n        if (testNotNull__resolvedKey == null || !testNotNull__resolvedKey.equals(__key)) {\n            __throwIfDetached();\n            TestEntityDao targetDao = daoSession.getTestEntityDao();\n            TestEntity testNotNullNew = targetDao.load(__key);\n            synchronized (this) {\n                testNotNull = testNotNullNew;\n            \ttestNotNull__resolvedKey = __key;\n            }\n        }\n        return testNotNull;\n    }\n\n    @Generated\n    public void setTestNotNull(TestEntity testNotNull) {\n        if (testNotNull == null) {\n            throw new DaoException(\"To-one property 'testIdNotNull' has not-null constraint; cannot set to-one to null\");\n        }\n        synchronized (this) {\n            this.testNotNull = testNotNull;\n            testIdNotNull = testNotNull.getId();\n            testNotNull__resolvedKey = testIdNotNull;\n        }\n    }\n\n    /** To-one relationship, resolved on first access. */\n    @Generated\n    public TestEntity getTestWithoutProperty() {\n        if (testWithoutProperty != null || !testWithoutProperty__refreshed) {\n            __throwIfDetached();\n            TestEntityDao targetDao = daoSession.getTestEntityDao();\n            targetDao.refresh(testWithoutProperty);\n            testWithoutProperty__refreshed = true;\n        }\n        return testWithoutProperty;\n    }\n\n    /** To-one relationship, returned entity is not refreshed and may carry only the PK property. */\n    @Generated\n    public TestEntity peakTestWithoutProperty() {\n        return testWithoutProperty;\n    }\n\n    @Generated\n    public void setTestWithoutProperty(TestEntity testWithoutProperty) {\n        synchronized (this) {\n            this.testWithoutProperty = testWithoutProperty;\n            testWithoutProperty__refreshed = true;\n        }\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void delete() {\n        __throwIfDetached();\n        myDao.delete(this);\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void update() {\n        __throwIfDetached();\n        myDao.update(this);\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void refresh() {\n        __throwIfDetached();\n        myDao.refresh(this);\n    }\n\n    @Generated\n    private void __throwIfDetached() {\n        if (myDao == null) {\n            throw new DaoException(\"Entity is detached from DAO context\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/RelationEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport java.util.List;\nimport java.util.ArrayList;\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.SqlUtils;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"RELATION_ENTITY\".\n*/\npublic class RelationEntityDao extends AbstractDao<RelationEntity, Long> {\n\n    public static final String TABLENAME = \"RELATION_ENTITY\";\n\n    /**\n     * Properties of entity RelationEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property ParentId = new Property(1, Long.class, \"parentId\", false, \"PARENT_ID\");\n        public final static Property TestId = new Property(2, Long.class, \"testId\", false, \"TEST_ID\");\n        public final static Property TestIdNotNull = new Property(3, long.class, \"testIdNotNull\", false, \"TEST_ID_NOT_NULL\");\n        public final static Property SimpleString = new Property(4, String.class, \"simpleString\", false, \"SIMPLE_STRING\");\n        public final static Property TestWithoutProperty = new Property(5, Long.class, \"testWithoutProperty\", false, \"WITHOUT_PROPERTY_TEST_ID\");\n    }\n\n    private DaoSession daoSession;\n\n\n    public RelationEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public RelationEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n        this.daoSession = daoSession;\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"RELATION_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"PARENT_ID\\\" INTEGER,\" + // 1: parentId\n                \"\\\"TEST_ID\\\" INTEGER,\" + // 2: testId\n                \"\\\"TEST_ID_NOT_NULL\\\" INTEGER NOT NULL ,\" + // 3: testIdNotNull\n                \"\\\"SIMPLE_STRING\\\" TEXT,\" + // 4: simpleString\n                \"\\\"WITHOUT_PROPERTY_TEST_ID\\\" INTEGER);\"); // 5: testWithoutProperty\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"RELATION_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, RelationEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Long parentId = entity.getParentId();\n        if (parentId != null) {\n            stmt.bindLong(2, parentId);\n        }\n \n        Long testId = entity.getTestId();\n        if (testId != null) {\n            stmt.bindLong(3, testId);\n        }\n        stmt.bindLong(4, entity.getTestIdNotNull());\n \n        String simpleString = entity.getSimpleString();\n        if (simpleString != null) {\n            stmt.bindString(5, simpleString);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, RelationEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Long parentId = entity.getParentId();\n        if (parentId != null) {\n            stmt.bindLong(2, parentId);\n        }\n \n        Long testId = entity.getTestId();\n        if (testId != null) {\n            stmt.bindLong(3, testId);\n        }\n        stmt.bindLong(4, entity.getTestIdNotNull());\n \n        String simpleString = entity.getSimpleString();\n        if (simpleString != null) {\n            stmt.bindString(5, simpleString);\n        }\n    }\n\n    @Override\n    protected final void attachEntity(RelationEntity entity) {\n        super.attachEntity(entity);\n        entity.__setDaoSession(daoSession);\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public RelationEntity readEntity(Cursor cursor, int offset) {\n        RelationEntity entity = new RelationEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1), // parentId\n            cursor.isNull(offset + 2) ? null : cursor.getLong(offset + 2), // testId\n            cursor.getLong(offset + 3), // testIdNotNull\n            cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4) // simpleString\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, RelationEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setParentId(cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1));\n        entity.setTestId(cursor.isNull(offset + 2) ? null : cursor.getLong(offset + 2));\n        entity.setTestIdNotNull(cursor.getLong(offset + 3));\n        entity.setSimpleString(cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(RelationEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(RelationEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(RelationEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n    private String selectDeep;\n\n    protected String getSelectDeep() {\n        if (selectDeep == null) {\n            StringBuilder builder = new StringBuilder(\"SELECT \");\n            SqlUtils.appendColumns(builder, \"T\", getAllColumns());\n            builder.append(',');\n            SqlUtils.appendColumns(builder, \"T0\", daoSession.getRelationEntityDao().getAllColumns());\n            builder.append(',');\n            SqlUtils.appendColumns(builder, \"T1\", daoSession.getTestEntityDao().getAllColumns());\n            builder.append(',');\n            SqlUtils.appendColumns(builder, \"T2\", daoSession.getTestEntityDao().getAllColumns());\n            builder.append(',');\n            SqlUtils.appendColumns(builder, \"T3\", daoSession.getTestEntityDao().getAllColumns());\n            builder.append(\" FROM RELATION_ENTITY T\");\n            builder.append(\" LEFT JOIN RELATION_ENTITY T0 ON T.\\\"PARENT_ID\\\"=T0.\\\"_id\\\"\");\n            builder.append(\" LEFT JOIN TEST_ENTITY T1 ON T.\\\"TEST_ID\\\"=T1.\\\"_id\\\"\");\n            builder.append(\" LEFT JOIN TEST_ENTITY T2 ON T.\\\"TEST_ID_NOT_NULL\\\"=T2.\\\"_id\\\"\");\n            builder.append(\" LEFT JOIN TEST_ENTITY T3 ON T.\\\"WITHOUT_PROPERTY_TEST_ID\\\"=T3.\\\"_id\\\"\");\n            builder.append(' ');\n            selectDeep = builder.toString();\n        }\n        return selectDeep;\n    }\n    \n    protected RelationEntity loadCurrentDeep(Cursor cursor, boolean lock) {\n        RelationEntity entity = loadCurrent(cursor, 0, lock);\n        int offset = getAllColumns().length;\n\n        RelationEntity parent = loadCurrentOther(daoSession.getRelationEntityDao(), cursor, offset);\n        entity.setParent(parent);\n        offset += daoSession.getRelationEntityDao().getAllColumns().length;\n\n        TestEntity testEntity = loadCurrentOther(daoSession.getTestEntityDao(), cursor, offset);\n        entity.setTestEntity(testEntity);\n        offset += daoSession.getTestEntityDao().getAllColumns().length;\n\n        TestEntity testNotNull = loadCurrentOther(daoSession.getTestEntityDao(), cursor, offset);\n         if(testNotNull != null) {\n            entity.setTestNotNull(testNotNull);\n        }\n        offset += daoSession.getTestEntityDao().getAllColumns().length;\n\n        TestEntity testWithoutProperty = loadCurrentOther(daoSession.getTestEntityDao(), cursor, offset);\n        entity.setTestWithoutProperty(testWithoutProperty);\n\n        return entity;    \n    }\n\n    public RelationEntity loadDeep(Long key) {\n        assertSinglePk();\n        if (key == null) {\n            return null;\n        }\n\n        StringBuilder builder = new StringBuilder(getSelectDeep());\n        builder.append(\"WHERE \");\n        SqlUtils.appendColumnsEqValue(builder, \"T\", getPkColumns());\n        String sql = builder.toString();\n        \n        String[] keyArray = new String[] { key.toString() };\n        Cursor cursor = db.rawQuery(sql, keyArray);\n        \n        try {\n            boolean available = cursor.moveToFirst();\n            if (!available) {\n                return null;\n            } else if (!cursor.isLast()) {\n                throw new IllegalStateException(\"Expected unique result, but count was \" + cursor.getCount());\n            }\n            return loadCurrentDeep(cursor, true);\n        } finally {\n            cursor.close();\n        }\n    }\n    \n    /** Reads all available rows from the given cursor and returns a list of new ImageTO objects. */\n    public List<RelationEntity> loadAllDeepFromCursor(Cursor cursor) {\n        int count = cursor.getCount();\n        List<RelationEntity> list = new ArrayList<RelationEntity>(count);\n        \n        if (cursor.moveToFirst()) {\n            if (identityScope != null) {\n                identityScope.lock();\n                identityScope.reserveRoom(count);\n            }\n            try {\n                do {\n                    list.add(loadCurrentDeep(cursor, false));\n                } while (cursor.moveToNext());\n            } finally {\n                if (identityScope != null) {\n                    identityScope.unlock();\n                }\n            }\n        }\n        return list;\n    }\n    \n    protected List<RelationEntity> loadDeepAllAndCloseCursor(Cursor cursor) {\n        try {\n            return loadAllDeepFromCursor(cursor);\n        } finally {\n            cursor.close();\n        }\n    }\n    \n\n    /** A raw-style query where you can pass any WHERE clause and arguments. */\n    public List<RelationEntity> queryDeep(String where, String... selectionArg) {\n        Cursor cursor = db.rawQuery(getSelectDeep() + where, selectionArg);\n        return loadDeepAllAndCloseCursor(cursor);\n    }\n \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/SimpleEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"SIMPLE_ENTITY\".\n */\n@Entity\npublic class SimpleEntity {\n\n    @Id\n    private Long id;\n    private Boolean simpleBoolean;\n    private Byte simpleByte;\n    private Short simpleShort;\n    private Integer simpleInt;\n    private Long simpleLong;\n    private Float simpleFloat;\n    private Double simpleDouble;\n    private String simpleString;\n    private byte[] simpleByteArray;\n\n    @Generated\n    public SimpleEntity() {\n    }\n\n    public SimpleEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public SimpleEntity(Long id, Boolean simpleBoolean, Byte simpleByte, Short simpleShort, Integer simpleInt, Long simpleLong, Float simpleFloat, Double simpleDouble, String simpleString, byte[] simpleByteArray) {\n        this.id = id;\n        this.simpleBoolean = simpleBoolean;\n        this.simpleByte = simpleByte;\n        this.simpleShort = simpleShort;\n        this.simpleInt = simpleInt;\n        this.simpleLong = simpleLong;\n        this.simpleFloat = simpleFloat;\n        this.simpleDouble = simpleDouble;\n        this.simpleString = simpleString;\n        this.simpleByteArray = simpleByteArray;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public Boolean getSimpleBoolean() {\n        return simpleBoolean;\n    }\n\n    public void setSimpleBoolean(Boolean simpleBoolean) {\n        this.simpleBoolean = simpleBoolean;\n    }\n\n    public Byte getSimpleByte() {\n        return simpleByte;\n    }\n\n    public void setSimpleByte(Byte simpleByte) {\n        this.simpleByte = simpleByte;\n    }\n\n    public Short getSimpleShort() {\n        return simpleShort;\n    }\n\n    public void setSimpleShort(Short simpleShort) {\n        this.simpleShort = simpleShort;\n    }\n\n    public Integer getSimpleInt() {\n        return simpleInt;\n    }\n\n    public void setSimpleInt(Integer simpleInt) {\n        this.simpleInt = simpleInt;\n    }\n\n    public Long getSimpleLong() {\n        return simpleLong;\n    }\n\n    public void setSimpleLong(Long simpleLong) {\n        this.simpleLong = simpleLong;\n    }\n\n    public Float getSimpleFloat() {\n        return simpleFloat;\n    }\n\n    public void setSimpleFloat(Float simpleFloat) {\n        this.simpleFloat = simpleFloat;\n    }\n\n    public Double getSimpleDouble() {\n        return simpleDouble;\n    }\n\n    public void setSimpleDouble(Double simpleDouble) {\n        this.simpleDouble = simpleDouble;\n    }\n\n    public String getSimpleString() {\n        return simpleString;\n    }\n\n    public void setSimpleString(String simpleString) {\n        this.simpleString = simpleString;\n    }\n\n    public byte[] getSimpleByteArray() {\n        return simpleByteArray;\n    }\n\n    public void setSimpleByteArray(byte[] simpleByteArray) {\n        this.simpleByteArray = simpleByteArray;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/SimpleEntityContentProvider.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.content.ContentProvider;\nimport android.content.ContentResolver;\nimport android.content.ContentValues;\nimport android.content.UriMatcher;\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteQueryBuilder;\nimport android.net.Uri;\n\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.database.StandardDatabase;\nimport org.greenrobot.greendao.database.Database;\n\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.daotest.SimpleEntityDao;\n\n/* Copy this code snippet into your AndroidManifest.xml inside the <application> element:\n\n    <provider\n        android:name=\"org.greenrobot.greendao.daotest.SimpleEntityContentProvider\"\n        android:authorities=\"org.greenrobot.greendao.daotest.provider\" />\n*/\n\npublic class SimpleEntityContentProvider extends ContentProvider {\n\n    public static final String AUTHORITY = \"org.greenrobot.greendao.daotest.provider\";\n    public static final String BASE_PATH = \"\";\n    public static final Uri CONTENT_URI = Uri.parse(\"content://\" + AUTHORITY + \"/\" + BASE_PATH);\n    public static final String CONTENT_TYPE = ContentResolver.CURSOR_DIR_BASE_TYPE\n            + \"/\" + BASE_PATH;\n    public static final String CONTENT_ITEM_TYPE = ContentResolver.CURSOR_ITEM_BASE_TYPE\n            + \"/\" + BASE_PATH;\n\n    private static final String TABLENAME = SimpleEntityDao.TABLENAME;\n    private static final String PK = SimpleEntityDao.Properties.Id.columnName;\n\n    private static final int SIMPLEENTITY_DIR = 0;\n    private static final int SIMPLEENTITY_ID = 1;\n\n    private static final UriMatcher sURIMatcher;\n\n    static {\n        sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);\n        sURIMatcher.addURI(AUTHORITY, BASE_PATH, SIMPLEENTITY_DIR);\n        sURIMatcher.addURI(AUTHORITY, BASE_PATH + \"/#\", SIMPLEENTITY_ID);\n    }\n\n    /**\n    * This must be set from outside, it's recommended to do this inside your Application object.\n    * Subject to change (static isn't nice).\n    */\n    public static DaoSession daoSession;\n\n    @Override\n    public boolean onCreate() {\n        // if(daoSession == null) {\n        //     throw new IllegalStateException(\"DaoSession must be set before content provider is created\");\n        // }\n        DaoLog.d(\"Content Provider started: \" + CONTENT_URI);\n        return true;\n    }\n\n    protected Database getDatabase() {\n        if(daoSession == null) {\n            throw new IllegalStateException(\"DaoSession must be set during content provider is active\");\n        }\n        return daoSession.getDatabase();\n    }\n\n    @Override\n    public Uri insert(Uri uri, ContentValues values) {\n        throw new UnsupportedOperationException(\"This content provider is readonly\");\n    }\n\n    @Override\n    public int delete(Uri uri, String selection, String[] selectionArgs) {\n        throw new UnsupportedOperationException(\"This content provider is readonly\");\n    }\n\n    @Override\n    public int update(Uri uri, ContentValues values, String selection,\n            String[] selectionArgs) {\n        throw new UnsupportedOperationException(\"This content provider is readonly\");\n    }\n\n    @Override\n    public Cursor query(Uri uri, String[] projection, String selection,\n            String[] selectionArgs, String sortOrder) {\n\n        SQLiteQueryBuilder queryBuilder = new SQLiteQueryBuilder();\n        int uriType = sURIMatcher.match(uri);\n        switch (uriType) {\n        case SIMPLEENTITY_DIR:\n            queryBuilder.setTables(TABLENAME);\n            break;\n        case SIMPLEENTITY_ID:\n            queryBuilder.setTables(TABLENAME);\n            queryBuilder.appendWhere(PK + \"=\"\n                    + uri.getLastPathSegment());\n            break;\n        default:\n            throw new IllegalArgumentException(\"Unknown URI: \" + uri);\n        }\n\n        Database db = getDatabase();\n        Cursor cursor = queryBuilder.query(((StandardDatabase) db).getSQLiteDatabase(), projection, selection,\n                selectionArgs, null, null, sortOrder);\n        cursor.setNotificationUri(getContext().getContentResolver(), uri);\n\n        return cursor;\n    }\n\n    @Override\n    public final String getType(Uri uri) {\n        switch (sURIMatcher.match(uri)) {\n        case SIMPLEENTITY_DIR:\n            return CONTENT_TYPE;\n        case SIMPLEENTITY_ID:\n            return CONTENT_ITEM_TYPE;\n        default :\n            throw new IllegalArgumentException(\"Unsupported URI: \" + uri);\n        }\n    }\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/SimpleEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"SIMPLE_ENTITY\".\n*/\npublic class SimpleEntityDao extends AbstractDao<SimpleEntity, Long> {\n\n    public static final String TABLENAME = \"SIMPLE_ENTITY\";\n\n    /**\n     * Properties of entity SimpleEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property SimpleBoolean = new Property(1, Boolean.class, \"simpleBoolean\", false, \"SIMPLE_BOOLEAN\");\n        public final static Property SimpleByte = new Property(2, Byte.class, \"simpleByte\", false, \"SIMPLE_BYTE\");\n        public final static Property SimpleShort = new Property(3, Short.class, \"simpleShort\", false, \"SIMPLE_SHORT\");\n        public final static Property SimpleInt = new Property(4, Integer.class, \"simpleInt\", false, \"SIMPLE_INT\");\n        public final static Property SimpleLong = new Property(5, Long.class, \"simpleLong\", false, \"SIMPLE_LONG\");\n        public final static Property SimpleFloat = new Property(6, Float.class, \"simpleFloat\", false, \"SIMPLE_FLOAT\");\n        public final static Property SimpleDouble = new Property(7, Double.class, \"simpleDouble\", false, \"SIMPLE_DOUBLE\");\n        public final static Property SimpleString = new Property(8, String.class, \"simpleString\", false, \"SIMPLE_STRING\");\n        public final static Property SimpleByteArray = new Property(9, byte[].class, \"simpleByteArray\", false, \"SIMPLE_BYTE_ARRAY\");\n    }\n\n\n    public SimpleEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public SimpleEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"SIMPLE_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"SIMPLE_BOOLEAN\\\" INTEGER,\" + // 1: simpleBoolean\n                \"\\\"SIMPLE_BYTE\\\" INTEGER,\" + // 2: simpleByte\n                \"\\\"SIMPLE_SHORT\\\" INTEGER,\" + // 3: simpleShort\n                \"\\\"SIMPLE_INT\\\" INTEGER,\" + // 4: simpleInt\n                \"\\\"SIMPLE_LONG\\\" INTEGER,\" + // 5: simpleLong\n                \"\\\"SIMPLE_FLOAT\\\" REAL,\" + // 6: simpleFloat\n                \"\\\"SIMPLE_DOUBLE\\\" REAL,\" + // 7: simpleDouble\n                \"\\\"SIMPLE_STRING\\\" TEXT,\" + // 8: simpleString\n                \"\\\"SIMPLE_BYTE_ARRAY\\\" BLOB);\"); // 9: simpleByteArray\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"SIMPLE_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, SimpleEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Boolean simpleBoolean = entity.getSimpleBoolean();\n        if (simpleBoolean != null) {\n            stmt.bindLong(2, simpleBoolean ? 1L: 0L);\n        }\n \n        Byte simpleByte = entity.getSimpleByte();\n        if (simpleByte != null) {\n            stmt.bindLong(3, simpleByte);\n        }\n \n        Short simpleShort = entity.getSimpleShort();\n        if (simpleShort != null) {\n            stmt.bindLong(4, simpleShort);\n        }\n \n        Integer simpleInt = entity.getSimpleInt();\n        if (simpleInt != null) {\n            stmt.bindLong(5, simpleInt);\n        }\n \n        Long simpleLong = entity.getSimpleLong();\n        if (simpleLong != null) {\n            stmt.bindLong(6, simpleLong);\n        }\n \n        Float simpleFloat = entity.getSimpleFloat();\n        if (simpleFloat != null) {\n            stmt.bindDouble(7, simpleFloat);\n        }\n \n        Double simpleDouble = entity.getSimpleDouble();\n        if (simpleDouble != null) {\n            stmt.bindDouble(8, simpleDouble);\n        }\n \n        String simpleString = entity.getSimpleString();\n        if (simpleString != null) {\n            stmt.bindString(9, simpleString);\n        }\n \n        byte[] simpleByteArray = entity.getSimpleByteArray();\n        if (simpleByteArray != null) {\n            stmt.bindBlob(10, simpleByteArray);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, SimpleEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Boolean simpleBoolean = entity.getSimpleBoolean();\n        if (simpleBoolean != null) {\n            stmt.bindLong(2, simpleBoolean ? 1L: 0L);\n        }\n \n        Byte simpleByte = entity.getSimpleByte();\n        if (simpleByte != null) {\n            stmt.bindLong(3, simpleByte);\n        }\n \n        Short simpleShort = entity.getSimpleShort();\n        if (simpleShort != null) {\n            stmt.bindLong(4, simpleShort);\n        }\n \n        Integer simpleInt = entity.getSimpleInt();\n        if (simpleInt != null) {\n            stmt.bindLong(5, simpleInt);\n        }\n \n        Long simpleLong = entity.getSimpleLong();\n        if (simpleLong != null) {\n            stmt.bindLong(6, simpleLong);\n        }\n \n        Float simpleFloat = entity.getSimpleFloat();\n        if (simpleFloat != null) {\n            stmt.bindDouble(7, simpleFloat);\n        }\n \n        Double simpleDouble = entity.getSimpleDouble();\n        if (simpleDouble != null) {\n            stmt.bindDouble(8, simpleDouble);\n        }\n \n        String simpleString = entity.getSimpleString();\n        if (simpleString != null) {\n            stmt.bindString(9, simpleString);\n        }\n \n        byte[] simpleByteArray = entity.getSimpleByteArray();\n        if (simpleByteArray != null) {\n            stmt.bindBlob(10, simpleByteArray);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public SimpleEntity readEntity(Cursor cursor, int offset) {\n        SimpleEntity entity = new SimpleEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : cursor.getShort(offset + 1) != 0, // simpleBoolean\n            cursor.isNull(offset + 2) ? null : (byte) cursor.getShort(offset + 2), // simpleByte\n            cursor.isNull(offset + 3) ? null : cursor.getShort(offset + 3), // simpleShort\n            cursor.isNull(offset + 4) ? null : cursor.getInt(offset + 4), // simpleInt\n            cursor.isNull(offset + 5) ? null : cursor.getLong(offset + 5), // simpleLong\n            cursor.isNull(offset + 6) ? null : cursor.getFloat(offset + 6), // simpleFloat\n            cursor.isNull(offset + 7) ? null : cursor.getDouble(offset + 7), // simpleDouble\n            cursor.isNull(offset + 8) ? null : cursor.getString(offset + 8), // simpleString\n            cursor.isNull(offset + 9) ? null : cursor.getBlob(offset + 9) // simpleByteArray\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, SimpleEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setSimpleBoolean(cursor.isNull(offset + 1) ? null : cursor.getShort(offset + 1) != 0);\n        entity.setSimpleByte(cursor.isNull(offset + 2) ? null : (byte) cursor.getShort(offset + 2));\n        entity.setSimpleShort(cursor.isNull(offset + 3) ? null : cursor.getShort(offset + 3));\n        entity.setSimpleInt(cursor.isNull(offset + 4) ? null : cursor.getInt(offset + 4));\n        entity.setSimpleLong(cursor.isNull(offset + 5) ? null : cursor.getLong(offset + 5));\n        entity.setSimpleFloat(cursor.isNull(offset + 6) ? null : cursor.getFloat(offset + 6));\n        entity.setSimpleDouble(cursor.isNull(offset + 7) ? null : cursor.getDouble(offset + 7));\n        entity.setSimpleString(cursor.isNull(offset + 8) ? null : cursor.getString(offset + 8));\n        entity.setSimpleByteArray(cursor.isNull(offset + 9) ? null : cursor.getBlob(offset + 9));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(SimpleEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(SimpleEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(SimpleEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/SimpleEntityNotNull.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"SIMPLE_ENTITY_NOT_NULL\".\n */\n@Entity\npublic class SimpleEntityNotNull {\n\n    @Id\n    private long id;\n    private boolean simpleBoolean;\n    private byte simpleByte;\n    private short simpleShort;\n    private int simpleInt;\n    private long simpleLong;\n    private float simpleFloat;\n    private double simpleDouble;\n\n    @NotNull\n    private String simpleString;\n\n    @NotNull\n    private byte[] simpleByteArray;\n\n    @Generated\n    public SimpleEntityNotNull() {\n    }\n\n    public SimpleEntityNotNull(long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public SimpleEntityNotNull(long id, boolean simpleBoolean, byte simpleByte, short simpleShort, int simpleInt, long simpleLong, float simpleFloat, double simpleDouble, String simpleString, byte[] simpleByteArray) {\n        this.id = id;\n        this.simpleBoolean = simpleBoolean;\n        this.simpleByte = simpleByte;\n        this.simpleShort = simpleShort;\n        this.simpleInt = simpleInt;\n        this.simpleLong = simpleLong;\n        this.simpleFloat = simpleFloat;\n        this.simpleDouble = simpleDouble;\n        this.simpleString = simpleString;\n        this.simpleByteArray = simpleByteArray;\n    }\n\n    public long getId() {\n        return id;\n    }\n\n    public void setId(long id) {\n        this.id = id;\n    }\n\n    public boolean getSimpleBoolean() {\n        return simpleBoolean;\n    }\n\n    public void setSimpleBoolean(boolean simpleBoolean) {\n        this.simpleBoolean = simpleBoolean;\n    }\n\n    public byte getSimpleByte() {\n        return simpleByte;\n    }\n\n    public void setSimpleByte(byte simpleByte) {\n        this.simpleByte = simpleByte;\n    }\n\n    public short getSimpleShort() {\n        return simpleShort;\n    }\n\n    public void setSimpleShort(short simpleShort) {\n        this.simpleShort = simpleShort;\n    }\n\n    public int getSimpleInt() {\n        return simpleInt;\n    }\n\n    public void setSimpleInt(int simpleInt) {\n        this.simpleInt = simpleInt;\n    }\n\n    public long getSimpleLong() {\n        return simpleLong;\n    }\n\n    public void setSimpleLong(long simpleLong) {\n        this.simpleLong = simpleLong;\n    }\n\n    public float getSimpleFloat() {\n        return simpleFloat;\n    }\n\n    public void setSimpleFloat(float simpleFloat) {\n        this.simpleFloat = simpleFloat;\n    }\n\n    public double getSimpleDouble() {\n        return simpleDouble;\n    }\n\n    public void setSimpleDouble(double simpleDouble) {\n        this.simpleDouble = simpleDouble;\n    }\n\n    @NotNull\n    public String getSimpleString() {\n        return simpleString;\n    }\n\n    /** Not-null value; ensure this value is available before it is saved to the database. */\n    public void setSimpleString(@NotNull String simpleString) {\n        this.simpleString = simpleString;\n    }\n\n    @NotNull\n    public byte[] getSimpleByteArray() {\n        return simpleByteArray;\n    }\n\n    /** Not-null value; ensure this value is available before it is saved to the database. */\n    public void setSimpleByteArray(@NotNull byte[] simpleByteArray) {\n        this.simpleByteArray = simpleByteArray;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/SimpleEntityNotNullDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"SIMPLE_ENTITY_NOT_NULL\".\n*/\npublic class SimpleEntityNotNullDao extends AbstractDao<SimpleEntityNotNull, Long> {\n\n    public static final String TABLENAME = \"SIMPLE_ENTITY_NOT_NULL\";\n\n    /**\n     * Properties of entity SimpleEntityNotNull.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, long.class, \"id\", true, \"_id\");\n        public final static Property SimpleBoolean = new Property(1, boolean.class, \"simpleBoolean\", false, \"SIMPLE_BOOLEAN\");\n        public final static Property SimpleByte = new Property(2, byte.class, \"simpleByte\", false, \"SIMPLE_BYTE\");\n        public final static Property SimpleShort = new Property(3, short.class, \"simpleShort\", false, \"SIMPLE_SHORT\");\n        public final static Property SimpleInt = new Property(4, int.class, \"simpleInt\", false, \"SIMPLE_INT\");\n        public final static Property SimpleLong = new Property(5, long.class, \"simpleLong\", false, \"SIMPLE_LONG\");\n        public final static Property SimpleFloat = new Property(6, float.class, \"simpleFloat\", false, \"SIMPLE_FLOAT\");\n        public final static Property SimpleDouble = new Property(7, double.class, \"simpleDouble\", false, \"SIMPLE_DOUBLE\");\n        public final static Property SimpleString = new Property(8, String.class, \"simpleString\", false, \"SIMPLE_STRING\");\n        public final static Property SimpleByteArray = new Property(9, byte[].class, \"simpleByteArray\", false, \"SIMPLE_BYTE_ARRAY\");\n    }\n\n\n    public SimpleEntityNotNullDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public SimpleEntityNotNullDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"SIMPLE_ENTITY_NOT_NULL\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY NOT NULL ,\" + // 0: id\n                \"\\\"SIMPLE_BOOLEAN\\\" INTEGER NOT NULL ,\" + // 1: simpleBoolean\n                \"\\\"SIMPLE_BYTE\\\" INTEGER NOT NULL ,\" + // 2: simpleByte\n                \"\\\"SIMPLE_SHORT\\\" INTEGER NOT NULL ,\" + // 3: simpleShort\n                \"\\\"SIMPLE_INT\\\" INTEGER NOT NULL ,\" + // 4: simpleInt\n                \"\\\"SIMPLE_LONG\\\" INTEGER NOT NULL ,\" + // 5: simpleLong\n                \"\\\"SIMPLE_FLOAT\\\" REAL NOT NULL ,\" + // 6: simpleFloat\n                \"\\\"SIMPLE_DOUBLE\\\" REAL NOT NULL ,\" + // 7: simpleDouble\n                \"\\\"SIMPLE_STRING\\\" TEXT NOT NULL ,\" + // 8: simpleString\n                \"\\\"SIMPLE_BYTE_ARRAY\\\" BLOB NOT NULL );\"); // 9: simpleByteArray\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"SIMPLE_ENTITY_NOT_NULL\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, SimpleEntityNotNull entity) {\n        stmt.clearBindings();\n        stmt.bindLong(1, entity.getId());\n        stmt.bindLong(2, entity.getSimpleBoolean() ? 1L: 0L);\n        stmt.bindLong(3, entity.getSimpleByte());\n        stmt.bindLong(4, entity.getSimpleShort());\n        stmt.bindLong(5, entity.getSimpleInt());\n        stmt.bindLong(6, entity.getSimpleLong());\n        stmt.bindDouble(7, entity.getSimpleFloat());\n        stmt.bindDouble(8, entity.getSimpleDouble());\n        stmt.bindString(9, entity.getSimpleString());\n        stmt.bindBlob(10, entity.getSimpleByteArray());\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, SimpleEntityNotNull entity) {\n        stmt.clearBindings();\n        stmt.bindLong(1, entity.getId());\n        stmt.bindLong(2, entity.getSimpleBoolean() ? 1L: 0L);\n        stmt.bindLong(3, entity.getSimpleByte());\n        stmt.bindLong(4, entity.getSimpleShort());\n        stmt.bindLong(5, entity.getSimpleInt());\n        stmt.bindLong(6, entity.getSimpleLong());\n        stmt.bindDouble(7, entity.getSimpleFloat());\n        stmt.bindDouble(8, entity.getSimpleDouble());\n        stmt.bindString(9, entity.getSimpleString());\n        stmt.bindBlob(10, entity.getSimpleByteArray());\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public SimpleEntityNotNull readEntity(Cursor cursor, int offset) {\n        SimpleEntityNotNull entity = new SimpleEntityNotNull( //\n            cursor.getLong(offset + 0), // id\n            cursor.getShort(offset + 1) != 0, // simpleBoolean\n            (byte) cursor.getShort(offset + 2), // simpleByte\n            cursor.getShort(offset + 3), // simpleShort\n            cursor.getInt(offset + 4), // simpleInt\n            cursor.getLong(offset + 5), // simpleLong\n            cursor.getFloat(offset + 6), // simpleFloat\n            cursor.getDouble(offset + 7), // simpleDouble\n            cursor.getString(offset + 8), // simpleString\n            cursor.getBlob(offset + 9) // simpleByteArray\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, SimpleEntityNotNull entity, int offset) {\n        entity.setId(cursor.getLong(offset + 0));\n        entity.setSimpleBoolean(cursor.getShort(offset + 1) != 0);\n        entity.setSimpleByte((byte) cursor.getShort(offset + 2));\n        entity.setSimpleShort(cursor.getShort(offset + 3));\n        entity.setSimpleInt(cursor.getInt(offset + 4));\n        entity.setSimpleLong(cursor.getLong(offset + 5));\n        entity.setSimpleFloat(cursor.getFloat(offset + 6));\n        entity.setSimpleDouble(cursor.getDouble(offset + 7));\n        entity.setSimpleString(cursor.getString(offset + 8));\n        entity.setSimpleByteArray(cursor.getBlob(offset + 9));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(SimpleEntityNotNull entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(SimpleEntityNotNull entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(SimpleEntityNotNull entity) {\n        throw new UnsupportedOperationException(\"Unsupported for entities with a non-null key\");\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/SpecialNamesEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"ORDER TRANSACTION GROUP BY\".\n */\n@Entity(nameInDb = \"ORDER TRANSACTION GROUP BY\")\npublic class SpecialNamesEntity {\n\n    @Id\n    private Long id;\n    private String count;\n    private String select;\n    private String sum;\n    private String avg;\n    private String join;\n    private String distinct;\n    private String on;\n    private String index;\n    private Integer order;\n\n    @Generated\n    public SpecialNamesEntity() {\n    }\n\n    public SpecialNamesEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public SpecialNamesEntity(Long id, String count, String select, String sum, String avg, String join, String distinct, String on, String index, Integer order) {\n        this.id = id;\n        this.count = count;\n        this.select = select;\n        this.sum = sum;\n        this.avg = avg;\n        this.join = join;\n        this.distinct = distinct;\n        this.on = on;\n        this.index = index;\n        this.order = order;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public String getCount() {\n        return count;\n    }\n\n    public void setCount(String count) {\n        this.count = count;\n    }\n\n    public String getSelect() {\n        return select;\n    }\n\n    public void setSelect(String select) {\n        this.select = select;\n    }\n\n    public String getSum() {\n        return sum;\n    }\n\n    public void setSum(String sum) {\n        this.sum = sum;\n    }\n\n    public String getAvg() {\n        return avg;\n    }\n\n    public void setAvg(String avg) {\n        this.avg = avg;\n    }\n\n    public String getJoin() {\n        return join;\n    }\n\n    public void setJoin(String join) {\n        this.join = join;\n    }\n\n    public String getDistinct() {\n        return distinct;\n    }\n\n    public void setDistinct(String distinct) {\n        this.distinct = distinct;\n    }\n\n    public String getOn() {\n        return on;\n    }\n\n    public void setOn(String on) {\n        this.on = on;\n    }\n\n    public String getIndex() {\n        return index;\n    }\n\n    public void setIndex(String index) {\n        this.index = index;\n    }\n\n    public Integer getOrder() {\n        return order;\n    }\n\n    public void setOrder(Integer order) {\n        this.order = order;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/SpecialNamesEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"ORDER TRANSACTION GROUP BY\".\n*/\npublic class SpecialNamesEntityDao extends AbstractDao<SpecialNamesEntity, Long> {\n\n    public static final String TABLENAME = \"ORDER TRANSACTION GROUP BY\";\n\n    /**\n     * Properties of entity SpecialNamesEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property Count = new Property(1, String.class, \"count\", false, \"COUNT\");\n        public final static Property Select = new Property(2, String.class, \"select\", false, \"SELECT\");\n        public final static Property Sum = new Property(3, String.class, \"sum\", false, \"SUM\");\n        public final static Property Avg = new Property(4, String.class, \"avg\", false, \"AVG\");\n        public final static Property Join = new Property(5, String.class, \"join\", false, \"JOIN\");\n        public final static Property Distinct = new Property(6, String.class, \"distinct\", false, \"DISTINCT\");\n        public final static Property On = new Property(7, String.class, \"on\", false, \"ON\");\n        public final static Property Index = new Property(8, String.class, \"index\", false, \"INDEX\");\n        public final static Property Order = new Property(9, Integer.class, \"order\", false, \"ORDER\");\n    }\n\n\n    public SpecialNamesEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public SpecialNamesEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"ORDER TRANSACTION GROUP BY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"COUNT\\\" TEXT,\" + // 1: count\n                \"\\\"SELECT\\\" TEXT,\" + // 2: select\n                \"\\\"SUM\\\" TEXT,\" + // 3: sum\n                \"\\\"AVG\\\" TEXT,\" + // 4: avg\n                \"\\\"JOIN\\\" TEXT,\" + // 5: join\n                \"\\\"DISTINCT\\\" TEXT,\" + // 6: distinct\n                \"\\\"ON\\\" TEXT,\" + // 7: on\n                \"\\\"INDEX\\\" TEXT,\" + // 8: index\n                \"\\\"ORDER\\\" INTEGER);\"); // 9: order\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"ORDER TRANSACTION GROUP BY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, SpecialNamesEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        String count = entity.getCount();\n        if (count != null) {\n            stmt.bindString(2, count);\n        }\n \n        String select = entity.getSelect();\n        if (select != null) {\n            stmt.bindString(3, select);\n        }\n \n        String sum = entity.getSum();\n        if (sum != null) {\n            stmt.bindString(4, sum);\n        }\n \n        String avg = entity.getAvg();\n        if (avg != null) {\n            stmt.bindString(5, avg);\n        }\n \n        String join = entity.getJoin();\n        if (join != null) {\n            stmt.bindString(6, join);\n        }\n \n        String distinct = entity.getDistinct();\n        if (distinct != null) {\n            stmt.bindString(7, distinct);\n        }\n \n        String on = entity.getOn();\n        if (on != null) {\n            stmt.bindString(8, on);\n        }\n \n        String index = entity.getIndex();\n        if (index != null) {\n            stmt.bindString(9, index);\n        }\n \n        Integer order = entity.getOrder();\n        if (order != null) {\n            stmt.bindLong(10, order);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, SpecialNamesEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        String count = entity.getCount();\n        if (count != null) {\n            stmt.bindString(2, count);\n        }\n \n        String select = entity.getSelect();\n        if (select != null) {\n            stmt.bindString(3, select);\n        }\n \n        String sum = entity.getSum();\n        if (sum != null) {\n            stmt.bindString(4, sum);\n        }\n \n        String avg = entity.getAvg();\n        if (avg != null) {\n            stmt.bindString(5, avg);\n        }\n \n        String join = entity.getJoin();\n        if (join != null) {\n            stmt.bindString(6, join);\n        }\n \n        String distinct = entity.getDistinct();\n        if (distinct != null) {\n            stmt.bindString(7, distinct);\n        }\n \n        String on = entity.getOn();\n        if (on != null) {\n            stmt.bindString(8, on);\n        }\n \n        String index = entity.getIndex();\n        if (index != null) {\n            stmt.bindString(9, index);\n        }\n \n        Integer order = entity.getOrder();\n        if (order != null) {\n            stmt.bindLong(10, order);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public SpecialNamesEntity readEntity(Cursor cursor, int offset) {\n        SpecialNamesEntity entity = new SpecialNamesEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1), // count\n            cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2), // select\n            cursor.isNull(offset + 3) ? null : cursor.getString(offset + 3), // sum\n            cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4), // avg\n            cursor.isNull(offset + 5) ? null : cursor.getString(offset + 5), // join\n            cursor.isNull(offset + 6) ? null : cursor.getString(offset + 6), // distinct\n            cursor.isNull(offset + 7) ? null : cursor.getString(offset + 7), // on\n            cursor.isNull(offset + 8) ? null : cursor.getString(offset + 8), // index\n            cursor.isNull(offset + 9) ? null : cursor.getInt(offset + 9) // order\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, SpecialNamesEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setCount(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));\n        entity.setSelect(cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2));\n        entity.setSum(cursor.isNull(offset + 3) ? null : cursor.getString(offset + 3));\n        entity.setAvg(cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4));\n        entity.setJoin(cursor.isNull(offset + 5) ? null : cursor.getString(offset + 5));\n        entity.setDistinct(cursor.isNull(offset + 6) ? null : cursor.getString(offset + 6));\n        entity.setOn(cursor.isNull(offset + 7) ? null : cursor.getString(offset + 7));\n        entity.setIndex(cursor.isNull(offset + 8) ? null : cursor.getString(offset + 8));\n        entity.setOrder(cursor.isNull(offset + 9) ? null : cursor.getInt(offset + 9));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(SpecialNamesEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(SpecialNamesEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(SpecialNamesEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/SqliteMaster.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, EDIT ONLY INSIDE THE \"KEEP\"-SECTIONS\n\n// KEEP INCLUDES - put your custom includes here\n// KEEP INCLUDES END\n\n/**\n * Entity mapped to table \"SQLITE_MASTER\".\n */\n@Entity(createInDb = false)\npublic class SqliteMaster {\n    private String type;\n    private String name;\n\n    @Property(nameInDb = \"tbl_name\")\n    private String tableName;\n    private Long rootpage;\n    private String sql;\n\n    // KEEP FIELDS - put your custom fields here\n    // KEEP FIELDS END\n\n    @Generated\n    public SqliteMaster() {\n    }\n\n    @Generated\n    public SqliteMaster(String type, String name, String tableName, Long rootpage, String sql) {\n        this.type = type;\n        this.name = name;\n        this.tableName = tableName;\n        this.rootpage = rootpage;\n        this.sql = sql;\n    }\n\n    public String getType() {\n        return type;\n    }\n\n    public void setType(String type) {\n        this.type = type;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getTableName() {\n        return tableName;\n    }\n\n    public void setTableName(String tableName) {\n        this.tableName = tableName;\n    }\n\n    public Long getRootpage() {\n        return rootpage;\n    }\n\n    public void setRootpage(Long rootpage) {\n        this.rootpage = rootpage;\n    }\n\n    public String getSql() {\n        return sql;\n    }\n\n    public void setSql(String sql) {\n        this.sql = sql;\n    }\n\n    // KEEP METHODS - put your custom methods here\n    @Override\n    public String toString() {\n        return \"Type: \" + type + \", name: \" + name + \", table: \" + tableName + \", SQL: \" + sql;\n    }\n    // KEEP METHODS END\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/SqliteMasterDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"SQLITE_MASTER\".\n*/\npublic class SqliteMasterDao extends AbstractDao<SqliteMaster, Void> {\n\n    public static final String TABLENAME = \"SQLITE_MASTER\";\n\n    /**\n     * Properties of entity SqliteMaster.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Type = new Property(0, String.class, \"type\", false, \"TYPE\");\n        public final static Property Name = new Property(1, String.class, \"name\", false, \"NAME\");\n        public final static Property TableName = new Property(2, String.class, \"tableName\", false, \"tbl_name\");\n        public final static Property Rootpage = new Property(3, Long.class, \"rootpage\", false, \"ROOTPAGE\");\n        public final static Property Sql = new Property(4, String.class, \"sql\", false, \"SQL\");\n    }\n\n\n    public SqliteMasterDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public SqliteMasterDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, SqliteMaster entity) {\n        stmt.clearBindings();\n \n        String type = entity.getType();\n        if (type != null) {\n            stmt.bindString(1, type);\n        }\n \n        String name = entity.getName();\n        if (name != null) {\n            stmt.bindString(2, name);\n        }\n \n        String tableName = entity.getTableName();\n        if (tableName != null) {\n            stmt.bindString(3, tableName);\n        }\n \n        Long rootpage = entity.getRootpage();\n        if (rootpage != null) {\n            stmt.bindLong(4, rootpage);\n        }\n \n        String sql = entity.getSql();\n        if (sql != null) {\n            stmt.bindString(5, sql);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, SqliteMaster entity) {\n        stmt.clearBindings();\n \n        String type = entity.getType();\n        if (type != null) {\n            stmt.bindString(1, type);\n        }\n \n        String name = entity.getName();\n        if (name != null) {\n            stmt.bindString(2, name);\n        }\n \n        String tableName = entity.getTableName();\n        if (tableName != null) {\n            stmt.bindString(3, tableName);\n        }\n \n        Long rootpage = entity.getRootpage();\n        if (rootpage != null) {\n            stmt.bindLong(4, rootpage);\n        }\n \n        String sql = entity.getSql();\n        if (sql != null) {\n            stmt.bindString(5, sql);\n        }\n    }\n\n    @Override\n    public Void readKey(Cursor cursor, int offset) {\n        return null;\n    }    \n\n    @Override\n    public SqliteMaster readEntity(Cursor cursor, int offset) {\n        SqliteMaster entity = new SqliteMaster( //\n            cursor.isNull(offset + 0) ? null : cursor.getString(offset + 0), // type\n            cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1), // name\n            cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2), // tableName\n            cursor.isNull(offset + 3) ? null : cursor.getLong(offset + 3), // rootpage\n            cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4) // sql\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, SqliteMaster entity, int offset) {\n        entity.setType(cursor.isNull(offset + 0) ? null : cursor.getString(offset + 0));\n        entity.setName(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));\n        entity.setTableName(cursor.isNull(offset + 2) ? null : cursor.getString(offset + 2));\n        entity.setRootpage(cursor.isNull(offset + 3) ? null : cursor.getLong(offset + 3));\n        entity.setSql(cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4));\n     }\n    \n    @Override\n    protected final Void updateKeyAfterInsert(SqliteMaster entity, long rowId) {\n        // Unsupported or missing PK type\n        return null;\n    }\n    \n    @Override\n    public Void getKey(SqliteMaster entity) {\n        return null;\n    }\n\n    @Override\n    public boolean hasKey(SqliteMaster entity) {\n        // TODO\n        return false;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/StringKeyValueEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"STRING_KEY_VALUE_ENTITY\".\n */\n@Entity\npublic class StringKeyValueEntity {\n\n    @Id\n    private String key;\n    private String value;\n\n    @Generated\n    public StringKeyValueEntity() {\n    }\n\n    public StringKeyValueEntity(String key) {\n        this.key = key;\n    }\n\n    @Generated\n    public StringKeyValueEntity(String key, String value) {\n        this.key = key;\n        this.value = value;\n    }\n\n    public String getKey() {\n        return key;\n    }\n\n    public void setKey(String key) {\n        this.key = key;\n    }\n\n    public String getValue() {\n        return value;\n    }\n\n    public void setValue(String value) {\n        this.value = value;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/StringKeyValueEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"STRING_KEY_VALUE_ENTITY\".\n*/\npublic class StringKeyValueEntityDao extends AbstractDao<StringKeyValueEntity, String> {\n\n    public static final String TABLENAME = \"STRING_KEY_VALUE_ENTITY\";\n\n    /**\n     * Properties of entity StringKeyValueEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Key = new Property(0, String.class, \"key\", true, \"KEY\");\n        public final static Property Value = new Property(1, String.class, \"value\", false, \"VALUE\");\n    }\n\n\n    public StringKeyValueEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public StringKeyValueEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"STRING_KEY_VALUE_ENTITY\\\" (\" + //\n                \"\\\"KEY\\\" TEXT PRIMARY KEY NOT NULL ,\" + // 0: key\n                \"\\\"VALUE\\\" TEXT);\"); // 1: value\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"STRING_KEY_VALUE_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, StringKeyValueEntity entity) {\n        stmt.clearBindings();\n \n        String key = entity.getKey();\n        if (key != null) {\n            stmt.bindString(1, key);\n        }\n \n        String value = entity.getValue();\n        if (value != null) {\n            stmt.bindString(2, value);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, StringKeyValueEntity entity) {\n        stmt.clearBindings();\n \n        String key = entity.getKey();\n        if (key != null) {\n            stmt.bindString(1, key);\n        }\n \n        String value = entity.getValue();\n        if (value != null) {\n            stmt.bindString(2, value);\n        }\n    }\n\n    @Override\n    public String readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getString(offset + 0);\n    }    \n\n    @Override\n    public StringKeyValueEntity readEntity(Cursor cursor, int offset) {\n        StringKeyValueEntity entity = new StringKeyValueEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getString(offset + 0), // key\n            cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1) // value\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, StringKeyValueEntity entity, int offset) {\n        entity.setKey(cursor.isNull(offset + 0) ? null : cursor.getString(offset + 0));\n        entity.setValue(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));\n     }\n    \n    @Override\n    protected final String updateKeyAfterInsert(StringKeyValueEntity entity, long rowId) {\n        return entity.getKey();\n    }\n    \n    @Override\n    public String getKey(StringKeyValueEntity entity) {\n        if(entity != null) {\n            return entity.getKey();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(StringKeyValueEntity entity) {\n        return entity.getKey() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/TestEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * This entity is used by internal tests of greenDAO.\n * (This JavaDoc is defined in the generator project.)\n */\n// This is another test comment, you could also apply annotations like this\n@Entity\npublic class TestEntity {\n\n    /**\n     * JavaDoc test field\n     */\n    @Id\n    private Long id;\n    private int simpleInt;\n    private Integer simpleInteger;\n\n    @NotNull\n    private String simpleStringNotNull;\n    private String simpleString;\n\n    @Index\n    private String indexedString;\n\n    @Index(unique = true)\n    private String indexedStringAscUnique;\n    private java.util.Date simpleDate;\n    private Boolean simpleBoolean;\n    private byte[] simpleByteArray;\n\n    @Generated\n    public TestEntity() {\n    }\n\n    public TestEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public TestEntity(Long id, int simpleInt, Integer simpleInteger, String simpleStringNotNull, String simpleString, String indexedString, String indexedStringAscUnique, java.util.Date simpleDate, Boolean simpleBoolean, byte[] simpleByteArray) {\n        this.id = id;\n        this.simpleInt = simpleInt;\n        this.simpleInteger = simpleInteger;\n        this.simpleStringNotNull = simpleStringNotNull;\n        this.simpleString = simpleString;\n        this.indexedString = indexedString;\n        this.indexedStringAscUnique = indexedStringAscUnique;\n        this.simpleDate = simpleDate;\n        this.simpleBoolean = simpleBoolean;\n        this.simpleByteArray = simpleByteArray;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    /**\n     * JavaDoc test getter\n     */\n    public int getSimpleInt() {\n        return simpleInt;\n    }\n\n    public void setSimpleInt(int simpleInt) {\n        this.simpleInt = simpleInt;\n    }\n\n    public Integer getSimpleInteger() {\n        return simpleInteger;\n    }\n\n    /**\n     * JavaDoc test setter\n     */\n    public void setSimpleInteger(Integer simpleInteger) {\n        this.simpleInteger = simpleInteger;\n    }\n\n    /**\n     * JavaDoc test getter and setter\n     */\n    @NotNull\n    public String getSimpleStringNotNull() {\n        return simpleStringNotNull;\n    }\n\n    /** Not-null value; ensure this value is available before it is saved to the database. */\n    /**\n     * JavaDoc test getter and setter\n     */\n    public void setSimpleStringNotNull(@NotNull String simpleStringNotNull) {\n        this.simpleStringNotNull = simpleStringNotNull;\n    }\n\n    public String getSimpleString() {\n        return simpleString;\n    }\n\n    public void setSimpleString(String simpleString) {\n        this.simpleString = simpleString;\n    }\n\n    public String getIndexedString() {\n        return indexedString;\n    }\n\n    public void setIndexedString(String indexedString) {\n        this.indexedString = indexedString;\n    }\n\n    public String getIndexedStringAscUnique() {\n        return indexedStringAscUnique;\n    }\n\n    public void setIndexedStringAscUnique(String indexedStringAscUnique) {\n        this.indexedStringAscUnique = indexedStringAscUnique;\n    }\n\n    public java.util.Date getSimpleDate() {\n        return simpleDate;\n    }\n\n    public void setSimpleDate(java.util.Date simpleDate) {\n        this.simpleDate = simpleDate;\n    }\n\n    public Boolean getSimpleBoolean() {\n        return simpleBoolean;\n    }\n\n    public void setSimpleBoolean(Boolean simpleBoolean) {\n        this.simpleBoolean = simpleBoolean;\n    }\n\n    public byte[] getSimpleByteArray() {\n        return simpleByteArray;\n    }\n\n    public void setSimpleByteArray(byte[] simpleByteArray) {\n        this.simpleByteArray = simpleByteArray;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/TestEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"TEST_ENTITY\".\n*/\npublic class TestEntityDao extends AbstractDao<TestEntity, Long> {\n\n    public static final String TABLENAME = \"TEST_ENTITY\";\n\n    /**\n     * Properties of entity TestEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property SimpleInt = new Property(1, int.class, \"simpleInt\", false, \"SIMPLE_INT\");\n        public final static Property SimpleInteger = new Property(2, Integer.class, \"simpleInteger\", false, \"SIMPLE_INTEGER\");\n        public final static Property SimpleStringNotNull = new Property(3, String.class, \"simpleStringNotNull\", false, \"SIMPLE_STRING_NOT_NULL\");\n        public final static Property SimpleString = new Property(4, String.class, \"simpleString\", false, \"SIMPLE_STRING\");\n        public final static Property IndexedString = new Property(5, String.class, \"indexedString\", false, \"INDEXED_STRING\");\n        public final static Property IndexedStringAscUnique = new Property(6, String.class, \"indexedStringAscUnique\", false, \"INDEXED_STRING_ASC_UNIQUE\");\n        public final static Property SimpleDate = new Property(7, java.util.Date.class, \"simpleDate\", false, \"SIMPLE_DATE\");\n        public final static Property SimpleBoolean = new Property(8, Boolean.class, \"simpleBoolean\", false, \"SIMPLE_BOOLEAN\");\n        public final static Property SimpleByteArray = new Property(9, byte[].class, \"simpleByteArray\", false, \"SIMPLE_BYTE_ARRAY\");\n    }\n\n\n    public TestEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public TestEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"TEST_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"SIMPLE_INT\\\" INTEGER NOT NULL ,\" + // 1: simpleInt\n                \"\\\"SIMPLE_INTEGER\\\" INTEGER,\" + // 2: simpleInteger\n                \"\\\"SIMPLE_STRING_NOT_NULL\\\" TEXT NOT NULL ,\" + // 3: simpleStringNotNull\n                \"\\\"SIMPLE_STRING\\\" TEXT,\" + // 4: simpleString\n                \"\\\"INDEXED_STRING\\\" TEXT,\" + // 5: indexedString\n                \"\\\"INDEXED_STRING_ASC_UNIQUE\\\" TEXT,\" + // 6: indexedStringAscUnique\n                \"\\\"SIMPLE_DATE\\\" INTEGER,\" + // 7: simpleDate\n                \"\\\"SIMPLE_BOOLEAN\\\" INTEGER,\" + // 8: simpleBoolean\n                \"\\\"SIMPLE_BYTE_ARRAY\\\" BLOB);\"); // 9: simpleByteArray\n        // Add Indexes\n        db.execSQL(\"CREATE INDEX \" + constraint + \"IDX_TEST_ENTITY_INDEXED_STRING ON TEST_ENTITY\" +\n                \" (\\\"INDEXED_STRING\\\");\");\n        db.execSQL(\"CREATE UNIQUE INDEX \" + constraint + \"IDX_TEST_ENTITY_INDEXED_STRING_ASC_UNIQUE ON TEST_ENTITY\" +\n                \" (\\\"INDEXED_STRING_ASC_UNIQUE\\\" ASC);\");\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"TEST_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, TestEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n        stmt.bindLong(2, entity.getSimpleInt());\n \n        Integer simpleInteger = entity.getSimpleInteger();\n        if (simpleInteger != null) {\n            stmt.bindLong(3, simpleInteger);\n        }\n        stmt.bindString(4, entity.getSimpleStringNotNull());\n \n        String simpleString = entity.getSimpleString();\n        if (simpleString != null) {\n            stmt.bindString(5, simpleString);\n        }\n \n        String indexedString = entity.getIndexedString();\n        if (indexedString != null) {\n            stmt.bindString(6, indexedString);\n        }\n \n        String indexedStringAscUnique = entity.getIndexedStringAscUnique();\n        if (indexedStringAscUnique != null) {\n            stmt.bindString(7, indexedStringAscUnique);\n        }\n \n        java.util.Date simpleDate = entity.getSimpleDate();\n        if (simpleDate != null) {\n            stmt.bindLong(8, simpleDate.getTime());\n        }\n \n        Boolean simpleBoolean = entity.getSimpleBoolean();\n        if (simpleBoolean != null) {\n            stmt.bindLong(9, simpleBoolean ? 1L: 0L);\n        }\n \n        byte[] simpleByteArray = entity.getSimpleByteArray();\n        if (simpleByteArray != null) {\n            stmt.bindBlob(10, simpleByteArray);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, TestEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n        stmt.bindLong(2, entity.getSimpleInt());\n \n        Integer simpleInteger = entity.getSimpleInteger();\n        if (simpleInteger != null) {\n            stmt.bindLong(3, simpleInteger);\n        }\n        stmt.bindString(4, entity.getSimpleStringNotNull());\n \n        String simpleString = entity.getSimpleString();\n        if (simpleString != null) {\n            stmt.bindString(5, simpleString);\n        }\n \n        String indexedString = entity.getIndexedString();\n        if (indexedString != null) {\n            stmt.bindString(6, indexedString);\n        }\n \n        String indexedStringAscUnique = entity.getIndexedStringAscUnique();\n        if (indexedStringAscUnique != null) {\n            stmt.bindString(7, indexedStringAscUnique);\n        }\n \n        java.util.Date simpleDate = entity.getSimpleDate();\n        if (simpleDate != null) {\n            stmt.bindLong(8, simpleDate.getTime());\n        }\n \n        Boolean simpleBoolean = entity.getSimpleBoolean();\n        if (simpleBoolean != null) {\n            stmt.bindLong(9, simpleBoolean ? 1L: 0L);\n        }\n \n        byte[] simpleByteArray = entity.getSimpleByteArray();\n        if (simpleByteArray != null) {\n            stmt.bindBlob(10, simpleByteArray);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public TestEntity readEntity(Cursor cursor, int offset) {\n        TestEntity entity = new TestEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.getInt(offset + 1), // simpleInt\n            cursor.isNull(offset + 2) ? null : cursor.getInt(offset + 2), // simpleInteger\n            cursor.getString(offset + 3), // simpleStringNotNull\n            cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4), // simpleString\n            cursor.isNull(offset + 5) ? null : cursor.getString(offset + 5), // indexedString\n            cursor.isNull(offset + 6) ? null : cursor.getString(offset + 6), // indexedStringAscUnique\n            cursor.isNull(offset + 7) ? null : new java.util.Date(cursor.getLong(offset + 7)), // simpleDate\n            cursor.isNull(offset + 8) ? null : cursor.getShort(offset + 8) != 0, // simpleBoolean\n            cursor.isNull(offset + 9) ? null : cursor.getBlob(offset + 9) // simpleByteArray\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, TestEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setSimpleInt(cursor.getInt(offset + 1));\n        entity.setSimpleInteger(cursor.isNull(offset + 2) ? null : cursor.getInt(offset + 2));\n        entity.setSimpleStringNotNull(cursor.getString(offset + 3));\n        entity.setSimpleString(cursor.isNull(offset + 4) ? null : cursor.getString(offset + 4));\n        entity.setIndexedString(cursor.isNull(offset + 5) ? null : cursor.getString(offset + 5));\n        entity.setIndexedStringAscUnique(cursor.isNull(offset + 6) ? null : cursor.getString(offset + 6));\n        entity.setSimpleDate(cursor.isNull(offset + 7) ? null : new java.util.Date(cursor.getLong(offset + 7)));\n        entity.setSimpleBoolean(cursor.isNull(offset + 8) ? null : cursor.getShort(offset + 8) != 0);\n        entity.setSimpleByteArray(cursor.isNull(offset + 9) ? null : cursor.getBlob(offset + 9));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(TestEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(TestEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(TestEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/TestInterface.java",
    "content": "package org.greenrobot.greendao.daotest;\n\npublic interface TestInterface {\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/TestSuperclass.java",
    "content": "package org.greenrobot.greendao.daotest;\n\npublic class TestSuperclass {\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/ToManyEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\nimport java.util.List;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.DaoException;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"TO_MANY_ENTITY\".\n */\n@Entity(active = true)\npublic class ToManyEntity {\n\n    @Id\n    private Long id;\n    private String sourceJoinProperty;\n\n    /** Used to resolve relations */\n    @Generated\n    private transient DaoSession daoSession;\n\n    /** Used for active entity operations. */\n    @Generated\n    private transient ToManyEntityDao myDao;\n\n    @ToMany(joinProperties = {\n        @JoinProperty(name = \"id\", referencedName = \"toManyId\")\n    })\n    @OrderBy(\"id ASC\")\n    private List<ToManyTargetEntity> toManyTargetEntityList;\n\n    @ToMany(joinProperties = {\n        @JoinProperty(name = \"id\", referencedName = \"toManyIdDesc\")\n    })\n    @OrderBy(\"id DESC\")\n    private List<ToManyTargetEntity> toManyDescList;\n\n    @ToMany(joinProperties = {\n        @JoinProperty(name = \"sourceJoinProperty\", referencedName = \"targetJoinProperty\")\n    })\n    @OrderBy(\"id ASC\")\n    private List<ToManyTargetEntity> toManyByJoinProperty;\n\n    @ToMany(joinProperties = {\n        @JoinProperty(name = \"id\", referencedName = \"toManyId\"),\n        @JoinProperty(name = \"sourceJoinProperty\", referencedName = \"targetJoinProperty\")\n    })\n    @OrderBy(\"targetJoinProperty DESC, id DESC\")\n    private List<ToManyTargetEntity> toManyJoinTwo;\n\n    @ToMany\n    @JoinEntity(entity = JoinManyToDateEntity.class, sourceProperty = \"idToMany\", targetProperty = \"idDate\")\n    private List<DateEntity> dateEntityList;\n\n    @Generated\n    public ToManyEntity() {\n    }\n\n    public ToManyEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public ToManyEntity(Long id, String sourceJoinProperty) {\n        this.id = id;\n        this.sourceJoinProperty = sourceJoinProperty;\n    }\n\n    /** called by internal mechanisms, do not call yourself. */\n    @Generated\n    public void __setDaoSession(DaoSession daoSession) {\n        this.daoSession = daoSession;\n        myDao = daoSession != null ? daoSession.getToManyEntityDao() : null;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public String getSourceJoinProperty() {\n        return sourceJoinProperty;\n    }\n\n    public void setSourceJoinProperty(String sourceJoinProperty) {\n        this.sourceJoinProperty = sourceJoinProperty;\n    }\n\n    /** To-many relationship, resolved on first access (and after reset). Changes to to-many relations are not persisted, make changes to the target entity. */\n    @Generated\n    public List<ToManyTargetEntity> getToManyTargetEntityList() {\n        if (toManyTargetEntityList == null) {\n            __throwIfDetached();\n            ToManyTargetEntityDao targetDao = daoSession.getToManyTargetEntityDao();\n            List<ToManyTargetEntity> toManyTargetEntityListNew = targetDao._queryToManyEntity_ToManyTargetEntityList(id);\n            synchronized (this) {\n                if(toManyTargetEntityList == null) {\n                    toManyTargetEntityList = toManyTargetEntityListNew;\n                }\n            }\n        }\n        return toManyTargetEntityList;\n    }\n\n    /** Resets a to-many relationship, making the next get call to query for a fresh result. */\n    @Generated\n    public synchronized void resetToManyTargetEntityList() {\n        toManyTargetEntityList = null;\n    }\n\n    /** To-many relationship, resolved on first access (and after reset). Changes to to-many relations are not persisted, make changes to the target entity. */\n    @Generated\n    public List<ToManyTargetEntity> getToManyDescList() {\n        if (toManyDescList == null) {\n            __throwIfDetached();\n            ToManyTargetEntityDao targetDao = daoSession.getToManyTargetEntityDao();\n            List<ToManyTargetEntity> toManyDescListNew = targetDao._queryToManyEntity_ToManyDescList(id);\n            synchronized (this) {\n                if(toManyDescList == null) {\n                    toManyDescList = toManyDescListNew;\n                }\n            }\n        }\n        return toManyDescList;\n    }\n\n    /** Resets a to-many relationship, making the next get call to query for a fresh result. */\n    @Generated\n    public synchronized void resetToManyDescList() {\n        toManyDescList = null;\n    }\n\n    /** To-many relationship, resolved on first access (and after reset). Changes to to-many relations are not persisted, make changes to the target entity. */\n    @Generated\n    public List<ToManyTargetEntity> getToManyByJoinProperty() {\n        if (toManyByJoinProperty == null) {\n            __throwIfDetached();\n            ToManyTargetEntityDao targetDao = daoSession.getToManyTargetEntityDao();\n            List<ToManyTargetEntity> toManyByJoinPropertyNew = targetDao._queryToManyEntity_ToManyByJoinProperty(sourceJoinProperty);\n            synchronized (this) {\n                if(toManyByJoinProperty == null) {\n                    toManyByJoinProperty = toManyByJoinPropertyNew;\n                }\n            }\n        }\n        return toManyByJoinProperty;\n    }\n\n    /** Resets a to-many relationship, making the next get call to query for a fresh result. */\n    @Generated\n    public synchronized void resetToManyByJoinProperty() {\n        toManyByJoinProperty = null;\n    }\n\n    /** To-many relationship, resolved on first access (and after reset). Changes to to-many relations are not persisted, make changes to the target entity. */\n    @Generated\n    public List<ToManyTargetEntity> getToManyJoinTwo() {\n        if (toManyJoinTwo == null) {\n            __throwIfDetached();\n            ToManyTargetEntityDao targetDao = daoSession.getToManyTargetEntityDao();\n            List<ToManyTargetEntity> toManyJoinTwoNew = targetDao._queryToManyEntity_ToManyJoinTwo(id, sourceJoinProperty);\n            synchronized (this) {\n                if(toManyJoinTwo == null) {\n                    toManyJoinTwo = toManyJoinTwoNew;\n                }\n            }\n        }\n        return toManyJoinTwo;\n    }\n\n    /** Resets a to-many relationship, making the next get call to query for a fresh result. */\n    @Generated\n    public synchronized void resetToManyJoinTwo() {\n        toManyJoinTwo = null;\n    }\n\n    /** To-many relationship, resolved on first access (and after reset). Changes to to-many relations are not persisted, make changes to the target entity. */\n    @Generated\n    public List<DateEntity> getDateEntityList() {\n        if (dateEntityList == null) {\n            __throwIfDetached();\n            DateEntityDao targetDao = daoSession.getDateEntityDao();\n            List<DateEntity> dateEntityListNew = targetDao._queryToManyEntity_DateEntityList(id);\n            synchronized (this) {\n                if(dateEntityList == null) {\n                    dateEntityList = dateEntityListNew;\n                }\n            }\n        }\n        return dateEntityList;\n    }\n\n    /** Resets a to-many relationship, making the next get call to query for a fresh result. */\n    @Generated\n    public synchronized void resetDateEntityList() {\n        dateEntityList = null;\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void delete() {\n        __throwIfDetached();\n        myDao.delete(this);\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void update() {\n        __throwIfDetached();\n        myDao.update(this);\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void refresh() {\n        __throwIfDetached();\n        myDao.refresh(this);\n    }\n\n    @Generated\n    private void __throwIfDetached() {\n        if (myDao == null) {\n            throw new DaoException(\"Entity is detached from DAO context\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/ToManyEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"TO_MANY_ENTITY\".\n*/\npublic class ToManyEntityDao extends AbstractDao<ToManyEntity, Long> {\n\n    public static final String TABLENAME = \"TO_MANY_ENTITY\";\n\n    /**\n     * Properties of entity ToManyEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property SourceJoinProperty = new Property(1, String.class, \"sourceJoinProperty\", false, \"SOURCE_JOIN_PROPERTY\");\n    }\n\n    private DaoSession daoSession;\n\n\n    public ToManyEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public ToManyEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n        this.daoSession = daoSession;\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"TO_MANY_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"SOURCE_JOIN_PROPERTY\\\" TEXT);\"); // 1: sourceJoinProperty\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"TO_MANY_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, ToManyEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        String sourceJoinProperty = entity.getSourceJoinProperty();\n        if (sourceJoinProperty != null) {\n            stmt.bindString(2, sourceJoinProperty);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, ToManyEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        String sourceJoinProperty = entity.getSourceJoinProperty();\n        if (sourceJoinProperty != null) {\n            stmt.bindString(2, sourceJoinProperty);\n        }\n    }\n\n    @Override\n    protected final void attachEntity(ToManyEntity entity) {\n        super.attachEntity(entity);\n        entity.__setDaoSession(daoSession);\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public ToManyEntity readEntity(Cursor cursor, int offset) {\n        ToManyEntity entity = new ToManyEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1) // sourceJoinProperty\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, ToManyEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setSourceJoinProperty(cursor.isNull(offset + 1) ? null : cursor.getString(offset + 1));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(ToManyEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(ToManyEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(ToManyEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/ToManyTargetEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"TO_MANY_TARGET_ENTITY\".\n */\n@Entity\npublic class ToManyTargetEntity {\n    private Long toManyId;\n    private Long toManyIdDesc;\n\n    @Id\n    private Long id;\n    private String targetJoinProperty;\n\n    @Generated\n    public ToManyTargetEntity() {\n    }\n\n    public ToManyTargetEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public ToManyTargetEntity(Long toManyId, Long toManyIdDesc, Long id, String targetJoinProperty) {\n        this.toManyId = toManyId;\n        this.toManyIdDesc = toManyIdDesc;\n        this.id = id;\n        this.targetJoinProperty = targetJoinProperty;\n    }\n\n    public Long getToManyId() {\n        return toManyId;\n    }\n\n    public void setToManyId(Long toManyId) {\n        this.toManyId = toManyId;\n    }\n\n    public Long getToManyIdDesc() {\n        return toManyIdDesc;\n    }\n\n    public void setToManyIdDesc(Long toManyIdDesc) {\n        this.toManyIdDesc = toManyIdDesc;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public String getTargetJoinProperty() {\n        return targetJoinProperty;\n    }\n\n    public void setTargetJoinProperty(String targetJoinProperty) {\n        this.targetJoinProperty = targetJoinProperty;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/ToManyTargetEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport java.util.List;\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"TO_MANY_TARGET_ENTITY\".\n*/\npublic class ToManyTargetEntityDao extends AbstractDao<ToManyTargetEntity, Long> {\n\n    public static final String TABLENAME = \"TO_MANY_TARGET_ENTITY\";\n\n    /**\n     * Properties of entity ToManyTargetEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property ToManyId = new Property(0, Long.class, \"toManyId\", false, \"TO_MANY_ID\");\n        public final static Property ToManyIdDesc = new Property(1, Long.class, \"toManyIdDesc\", false, \"TO_MANY_ID_DESC\");\n        public final static Property Id = new Property(2, Long.class, \"id\", true, \"_id\");\n        public final static Property TargetJoinProperty = new Property(3, String.class, \"targetJoinProperty\", false, \"TARGET_JOIN_PROPERTY\");\n    }\n\n    private Query<ToManyTargetEntity> toManyEntity_ToManyTargetEntityListQuery;\n    private Query<ToManyTargetEntity> toManyEntity_ToManyDescListQuery;\n    private Query<ToManyTargetEntity> toManyEntity_ToManyByJoinPropertyQuery;\n    private Query<ToManyTargetEntity> toManyEntity_ToManyJoinTwoQuery;\n\n    public ToManyTargetEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public ToManyTargetEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"TO_MANY_TARGET_ENTITY\\\" (\" + //\n                \"\\\"TO_MANY_ID\\\" INTEGER,\" + // 0: toManyId\n                \"\\\"TO_MANY_ID_DESC\\\" INTEGER,\" + // 1: toManyIdDesc\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 2: id\n                \"\\\"TARGET_JOIN_PROPERTY\\\" TEXT);\"); // 3: targetJoinProperty\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"TO_MANY_TARGET_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, ToManyTargetEntity entity) {\n        stmt.clearBindings();\n \n        Long toManyId = entity.getToManyId();\n        if (toManyId != null) {\n            stmt.bindLong(1, toManyId);\n        }\n \n        Long toManyIdDesc = entity.getToManyIdDesc();\n        if (toManyIdDesc != null) {\n            stmt.bindLong(2, toManyIdDesc);\n        }\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(3, id);\n        }\n \n        String targetJoinProperty = entity.getTargetJoinProperty();\n        if (targetJoinProperty != null) {\n            stmt.bindString(4, targetJoinProperty);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, ToManyTargetEntity entity) {\n        stmt.clearBindings();\n \n        Long toManyId = entity.getToManyId();\n        if (toManyId != null) {\n            stmt.bindLong(1, toManyId);\n        }\n \n        Long toManyIdDesc = entity.getToManyIdDesc();\n        if (toManyIdDesc != null) {\n            stmt.bindLong(2, toManyIdDesc);\n        }\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(3, id);\n        }\n \n        String targetJoinProperty = entity.getTargetJoinProperty();\n        if (targetJoinProperty != null) {\n            stmt.bindString(4, targetJoinProperty);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 2) ? null : cursor.getLong(offset + 2);\n    }    \n\n    @Override\n    public ToManyTargetEntity readEntity(Cursor cursor, int offset) {\n        ToManyTargetEntity entity = new ToManyTargetEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // toManyId\n            cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1), // toManyIdDesc\n            cursor.isNull(offset + 2) ? null : cursor.getLong(offset + 2), // id\n            cursor.isNull(offset + 3) ? null : cursor.getString(offset + 3) // targetJoinProperty\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, ToManyTargetEntity entity, int offset) {\n        entity.setToManyId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setToManyIdDesc(cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1));\n        entity.setId(cursor.isNull(offset + 2) ? null : cursor.getLong(offset + 2));\n        entity.setTargetJoinProperty(cursor.isNull(offset + 3) ? null : cursor.getString(offset + 3));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(ToManyTargetEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(ToManyTargetEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(ToManyTargetEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n    /** Internal query to resolve the \"toManyTargetEntityList\" to-many relationship of ToManyEntity. */\n    public List<ToManyTargetEntity> _queryToManyEntity_ToManyTargetEntityList(Long toManyId) {\n        synchronized (this) {\n            if (toManyEntity_ToManyTargetEntityListQuery == null) {\n                QueryBuilder<ToManyTargetEntity> queryBuilder = queryBuilder();\n                queryBuilder.where(Properties.ToManyId.eq(null));\n                queryBuilder.orderRaw(\"T.'_id' ASC\");\n                toManyEntity_ToManyTargetEntityListQuery = queryBuilder.build();\n            }\n        }\n        Query<ToManyTargetEntity> query = toManyEntity_ToManyTargetEntityListQuery.forCurrentThread();\n        query.setParameter(0, toManyId);\n        return query.list();\n    }\n\n    /** Internal query to resolve the \"toManyDescList\" to-many relationship of ToManyEntity. */\n    public List<ToManyTargetEntity> _queryToManyEntity_ToManyDescList(Long toManyIdDesc) {\n        synchronized (this) {\n            if (toManyEntity_ToManyDescListQuery == null) {\n                QueryBuilder<ToManyTargetEntity> queryBuilder = queryBuilder();\n                queryBuilder.where(Properties.ToManyIdDesc.eq(null));\n                queryBuilder.orderRaw(\"T.'_id' DESC\");\n                toManyEntity_ToManyDescListQuery = queryBuilder.build();\n            }\n        }\n        Query<ToManyTargetEntity> query = toManyEntity_ToManyDescListQuery.forCurrentThread();\n        query.setParameter(0, toManyIdDesc);\n        return query.list();\n    }\n\n    /** Internal query to resolve the \"toManyByJoinProperty\" to-many relationship of ToManyEntity. */\n    public List<ToManyTargetEntity> _queryToManyEntity_ToManyByJoinProperty(String targetJoinProperty) {\n        synchronized (this) {\n            if (toManyEntity_ToManyByJoinPropertyQuery == null) {\n                QueryBuilder<ToManyTargetEntity> queryBuilder = queryBuilder();\n                queryBuilder.where(Properties.TargetJoinProperty.eq(null));\n                queryBuilder.orderRaw(\"T.'_id' ASC\");\n                toManyEntity_ToManyByJoinPropertyQuery = queryBuilder.build();\n            }\n        }\n        Query<ToManyTargetEntity> query = toManyEntity_ToManyByJoinPropertyQuery.forCurrentThread();\n        query.setParameter(0, targetJoinProperty);\n        return query.list();\n    }\n\n    /** Internal query to resolve the \"toManyJoinTwo\" to-many relationship of ToManyEntity. */\n    public List<ToManyTargetEntity> _queryToManyEntity_ToManyJoinTwo(Long toManyId, String targetJoinProperty) {\n        synchronized (this) {\n            if (toManyEntity_ToManyJoinTwoQuery == null) {\n                QueryBuilder<ToManyTargetEntity> queryBuilder = queryBuilder();\n                queryBuilder.where(Properties.ToManyId.eq(null));\n                queryBuilder.where(Properties.TargetJoinProperty.eq(null));\n                queryBuilder.orderRaw(\"T.'TARGET_JOIN_PROPERTY' DESC,T.'_id' DESC\");\n                toManyEntity_ToManyJoinTwoQuery = queryBuilder.build();\n            }\n        }\n        Query<ToManyTargetEntity> query = toManyEntity_ToManyJoinTwoQuery.forCurrentThread();\n        query.setParameter(0, toManyId);\n        query.setParameter(1, targetJoinProperty);\n        return query.list();\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/TreeEntity.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport org.greenrobot.greendao.annotation.*;\n\nimport java.util.List;\nimport org.greenrobot.greendao.daotest.DaoSession;\nimport org.greenrobot.greendao.DaoException;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT. Enable \"keep\" sections if you want to edit.\n\n/**\n * Entity mapped to table \"TREE_ENTITY\".\n */\n@Entity(active = true)\npublic class TreeEntity {\n\n    @Id\n    private Long id;\n    private Long parentId;\n\n    /** Used to resolve relations */\n    @Generated\n    private transient DaoSession daoSession;\n\n    /** Used for active entity operations. */\n    @Generated\n    private transient TreeEntityDao myDao;\n\n    @ToOne(joinProperty = \"parentId\")\n    private TreeEntity parent;\n\n    @Generated\n    private transient Long parent__resolvedKey;\n\n    @ToMany(joinProperties = {\n        @JoinProperty(name = \"id\", referencedName = \"parentId\")\n    })\n    private List<TreeEntity> children;\n\n    @Generated\n    public TreeEntity() {\n    }\n\n    public TreeEntity(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public TreeEntity(Long id, Long parentId) {\n        this.id = id;\n        this.parentId = parentId;\n    }\n\n    /** called by internal mechanisms, do not call yourself. */\n    @Generated\n    public void __setDaoSession(DaoSession daoSession) {\n        this.daoSession = daoSession;\n        myDao = daoSession != null ? daoSession.getTreeEntityDao() : null;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public Long getParentId() {\n        return parentId;\n    }\n\n    public void setParentId(Long parentId) {\n        this.parentId = parentId;\n    }\n\n    /** To-one relationship, resolved on first access. */\n    @Generated\n    public TreeEntity getParent() {\n        Long __key = this.parentId;\n        if (parent__resolvedKey == null || !parent__resolvedKey.equals(__key)) {\n            __throwIfDetached();\n            TreeEntityDao targetDao = daoSession.getTreeEntityDao();\n            TreeEntity parentNew = targetDao.load(__key);\n            synchronized (this) {\n                parent = parentNew;\n            \tparent__resolvedKey = __key;\n            }\n        }\n        return parent;\n    }\n\n    @Generated\n    public void setParent(TreeEntity parent) {\n        synchronized (this) {\n            this.parent = parent;\n            parentId = parent == null ? null : parent.getId();\n            parent__resolvedKey = parentId;\n        }\n    }\n\n    /** To-many relationship, resolved on first access (and after reset). Changes to to-many relations are not persisted, make changes to the target entity. */\n    @Generated\n    public List<TreeEntity> getChildren() {\n        if (children == null) {\n            __throwIfDetached();\n            TreeEntityDao targetDao = daoSession.getTreeEntityDao();\n            List<TreeEntity> childrenNew = targetDao._queryTreeEntity_Children(id);\n            synchronized (this) {\n                if(children == null) {\n                    children = childrenNew;\n                }\n            }\n        }\n        return children;\n    }\n\n    /** Resets a to-many relationship, making the next get call to query for a fresh result. */\n    @Generated\n    public synchronized void resetChildren() {\n        children = null;\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void delete() {\n        __throwIfDetached();\n        myDao.delete(this);\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void update() {\n        __throwIfDetached();\n        myDao.update(this);\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void refresh() {\n        __throwIfDetached();\n        myDao.refresh(this);\n    }\n\n    @Generated\n    private void __throwIfDetached() {\n        if (myDao == null) {\n            throw new DaoException(\"Entity is detached from DAO context\");\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/TreeEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest;\n\nimport java.util.List;\nimport java.util.ArrayList;\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.SqlUtils;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"TREE_ENTITY\".\n*/\npublic class TreeEntityDao extends AbstractDao<TreeEntity, Long> {\n\n    public static final String TABLENAME = \"TREE_ENTITY\";\n\n    /**\n     * Properties of entity TreeEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property ParentId = new Property(1, Long.class, \"parentId\", false, \"PARENT_ID\");\n    }\n\n    private DaoSession daoSession;\n\n    private Query<TreeEntity> treeEntity_ChildrenQuery;\n\n    public TreeEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public TreeEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n        this.daoSession = daoSession;\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"TREE_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"PARENT_ID\\\" INTEGER);\"); // 1: parentId\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"TREE_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, TreeEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Long parentId = entity.getParentId();\n        if (parentId != null) {\n            stmt.bindLong(2, parentId);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, TreeEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Long parentId = entity.getParentId();\n        if (parentId != null) {\n            stmt.bindLong(2, parentId);\n        }\n    }\n\n    @Override\n    protected final void attachEntity(TreeEntity entity) {\n        super.attachEntity(entity);\n        entity.__setDaoSession(daoSession);\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public TreeEntity readEntity(Cursor cursor, int offset) {\n        TreeEntity entity = new TreeEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1) // parentId\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, TreeEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setParentId(cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(TreeEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(TreeEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(TreeEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n    /** Internal query to resolve the \"children\" to-many relationship of TreeEntity. */\n    public List<TreeEntity> _queryTreeEntity_Children(Long parentId) {\n        synchronized (this) {\n            if (treeEntity_ChildrenQuery == null) {\n                QueryBuilder<TreeEntity> queryBuilder = queryBuilder();\n                queryBuilder.where(Properties.ParentId.eq(null));\n                treeEntity_ChildrenQuery = queryBuilder.build();\n            }\n        }\n        Query<TreeEntity> query = treeEntity_ChildrenQuery.forCurrentThread();\n        query.setParameter(0, parentId);\n        return query.list();\n    }\n\n    private String selectDeep;\n\n    protected String getSelectDeep() {\n        if (selectDeep == null) {\n            StringBuilder builder = new StringBuilder(\"SELECT \");\n            SqlUtils.appendColumns(builder, \"T\", getAllColumns());\n            builder.append(',');\n            SqlUtils.appendColumns(builder, \"T0\", daoSession.getTreeEntityDao().getAllColumns());\n            builder.append(\" FROM TREE_ENTITY T\");\n            builder.append(\" LEFT JOIN TREE_ENTITY T0 ON T.\\\"PARENT_ID\\\"=T0.\\\"_id\\\"\");\n            builder.append(' ');\n            selectDeep = builder.toString();\n        }\n        return selectDeep;\n    }\n    \n    protected TreeEntity loadCurrentDeep(Cursor cursor, boolean lock) {\n        TreeEntity entity = loadCurrent(cursor, 0, lock);\n        int offset = getAllColumns().length;\n\n        TreeEntity parent = loadCurrentOther(daoSession.getTreeEntityDao(), cursor, offset);\n        entity.setParent(parent);\n\n        return entity;    \n    }\n\n    public TreeEntity loadDeep(Long key) {\n        assertSinglePk();\n        if (key == null) {\n            return null;\n        }\n\n        StringBuilder builder = new StringBuilder(getSelectDeep());\n        builder.append(\"WHERE \");\n        SqlUtils.appendColumnsEqValue(builder, \"T\", getPkColumns());\n        String sql = builder.toString();\n        \n        String[] keyArray = new String[] { key.toString() };\n        Cursor cursor = db.rawQuery(sql, keyArray);\n        \n        try {\n            boolean available = cursor.moveToFirst();\n            if (!available) {\n                return null;\n            } else if (!cursor.isLast()) {\n                throw new IllegalStateException(\"Expected unique result, but count was \" + cursor.getCount());\n            }\n            return loadCurrentDeep(cursor, true);\n        } finally {\n            cursor.close();\n        }\n    }\n    \n    /** Reads all available rows from the given cursor and returns a list of new ImageTO objects. */\n    public List<TreeEntity> loadAllDeepFromCursor(Cursor cursor) {\n        int count = cursor.getCount();\n        List<TreeEntity> list = new ArrayList<TreeEntity>(count);\n        \n        if (cursor.moveToFirst()) {\n            if (identityScope != null) {\n                identityScope.lock();\n                identityScope.reserveRoom(count);\n            }\n            try {\n                do {\n                    list.add(loadCurrentDeep(cursor, false));\n                } while (cursor.moveToNext());\n            } finally {\n                if (identityScope != null) {\n                    identityScope.unlock();\n                }\n            }\n        }\n        return list;\n    }\n    \n    protected List<TreeEntity> loadDeepAllAndCloseCursor(Cursor cursor) {\n        try {\n            return loadAllDeepFromCursor(cursor);\n        } finally {\n            cursor.close();\n        }\n    }\n    \n\n    /** A raw-style query where you can pass any WHERE clause and arguments. */\n    public List<TreeEntity> queryDeep(String where, String... selectionArg) {\n        Cursor cursor = db.rawQuery(getSelectDeep() + where, selectionArg);\n        return loadDeepAllAndCloseCursor(cursor);\n    }\n \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/customtype/IntegerListConverter.java",
    "content": "/*\n * Copyright (C) 2011-2015 Markus Junginger, greenrobot (http://greenrobot.de)\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n *      http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\npackage org.greenrobot.greendao.daotest.customtype;\n\nimport org.greenrobot.greendao.converter.PropertyConverter;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Just a sketch how an embedded List could be done using PropertyConverter. Usually, doing a separate table is\n * preferred because the values can be indexed and queried for.\n */\npublic class IntegerListConverter implements PropertyConverter<List<Integer>, byte[]> {\n    @Override\n    public List<Integer> convertToEntityProperty(byte[] databaseValue) {\n        if (databaseValue == null) {\n            return null;\n        }\n        if (databaseValue.length % 4 != 0) {\n            throw new RuntimeException(\"Length must be dividable by 4, but is \" + databaseValue.length);\n        }\n        ArrayList<Integer> list = new ArrayList<Integer>(databaseValue.length / 4);\n        for (int i = 0; i < databaseValue.length; i += 4) {\n            int intValue = getIntBE(databaseValue, i);\n            list.add(intValue);\n        }\n\n        return list;\n    }\n\n    @Override\n    public byte[] convertToDatabaseValue(List<Integer> entityProperty) {\n        if (entityProperty == null) {\n            return null;\n        }\n        byte[] bytes = new byte[entityProperty.size() * 4];\n        for (Integer integer : entityProperty) {\n            // TODO\n        }\n        return bytes;\n\n    }\n\n    public int getIntBE(byte[] bytes, int index) {\n        return (bytes[index + 3] & 0xff) | ((bytes[index + 2] & 0xff) << 8) |\n                ((bytes[index + 1] & 0xff) << 16) | (bytes[index] << 24);\n    }\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/customtype/MyTimestamp.java",
    "content": "package org.greenrobot.greendao.daotest.customtype;\n\npublic class MyTimestamp {\n    public long timestamp;\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/customtype/MyTimestampConverter.java",
    "content": "package org.greenrobot.greendao.daotest.customtype;\n\nimport org.greenrobot.greendao.converter.PropertyConverter;\n\npublic class MyTimestampConverter implements PropertyConverter<MyTimestamp, Long> {\n    @Override\n    public MyTimestamp convertToEntityProperty(Long databaseValue) {\n        MyTimestamp myTimestamp = new MyTimestamp();\n        myTimestamp.timestamp=databaseValue;\n        return myTimestamp;\n    }\n\n    @Override\n    public Long convertToDatabaseValue(MyTimestamp entityProperty) {\n        return entityProperty.timestamp;\n    }\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest/entity/SimpleEntityNotNullHelper.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.daotest.entity;\n\nimport org.greenrobot.greendao.daotest.SimpleEntityNotNull;\n\n\npublic class SimpleEntityNotNullHelper {\n    public static SimpleEntityNotNull createEntity(Long key) {\n        if (key == null) {\n            return null;\n        }\n        SimpleEntityNotNull entity = new SimpleEntityNotNull();\n        entity.setId(key);\n        entity.setSimpleBoolean(true);\n        entity.setSimpleByte(Byte.MAX_VALUE);\n        entity.setSimpleShort(Short.MAX_VALUE);\n        entity.setSimpleInt(Integer.MAX_VALUE);\n        entity.setSimpleLong(Long.MAX_VALUE);\n        entity.setSimpleFloat(Float.MAX_VALUE);\n        entity.setSimpleDouble(Double.MAX_VALUE);\n        entity.setSimpleString(\"greenrobot greenDAO\");\n        byte[] bytes = { 42, -17, 23, 0, 127, -128 };\n        entity.setSimpleByteArray(bytes);\n        return entity;\n    }\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest2/KeepEntity.java",
    "content": "package org.greenrobot.greendao.daotest2;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, EDIT ONLY INSIDE THE \"KEEP\"-SECTIONS\n\n// KEEP INCLUDES - put your custom includes here\nimport android.os.Build;\n// KEEP INCLUDES END\n\n/**\n * Entity mapped to table \"KEEP_ENTITY\".\n */\n@Entity\npublic class KeepEntity {\n\n    @Id\n    private Long id;\n\n    // KEEP FIELDS - put your custom fields here\n    String extra = Build.VERSION.SDK;\n    // KEEP FIELDS END\n\n    @Generated\n    public KeepEntity() {\n    }\n\n    @Generated\n    public KeepEntity(Long id) {\n        this.id = id;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    // KEEP METHODS - put your custom methods here\n    @Override\n    public String toString() {\n        return \"KeepEntity ID=42 (extra=\" + extra + \")\";\n    }\n    // KEEP METHODS END\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest2/ToManyTarget2.java",
    "content": "package org.greenrobot.greendao.daotest2;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, EDIT ONLY INSIDE THE \"KEEP\"-SECTIONS\n\n// KEEP INCLUDES - put your custom includes here\n// KEEP INCLUDES END\n\n/**\n * Entity mapped to table \"TO_MANY_TARGET2\".\n */\n@Entity\npublic class ToManyTarget2 {\n\n    @Id\n    private Long id;\n    private Long fkId;\n\n    // KEEP FIELDS - put your custom fields here\n    // KEEP FIELDS END\n\n    @Generated\n    public ToManyTarget2() {\n    }\n\n    public ToManyTarget2(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public ToManyTarget2(Long id, Long fkId) {\n        this.id = id;\n        this.fkId = fkId;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public Long getFkId() {\n        return fkId;\n    }\n\n    public void setFkId(Long fkId) {\n        this.fkId = fkId;\n    }\n\n    // KEEP METHODS - put your custom methods here\n    // KEEP METHODS END\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest2/dao/DaoMaster.java",
    "content": "package org.greenrobot.greendao.daotest2.dao;\n\nimport android.content.Context;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.database.sqlite.SQLiteDatabase.CursorFactory;\nimport android.util.Log;\n\nimport org.greenrobot.greendao.AbstractDaoMaster;\nimport org.greenrobot.greendao.database.StandardDatabase;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseOpenHelper;\nimport org.greenrobot.greendao.identityscope.IdentityScopeType;\n\nimport org.greenrobot.greendao.daotest2.to1_specialdao.ToOneTarget2Dao;\nimport org.greenrobot.greendao.daotest2.specialdao.RelationSource2Dao;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/**\n * Master of DAO (schema version 1): knows all DAOs.\n */\npublic class DaoMaster extends AbstractDaoMaster {\n    public static final int SCHEMA_VERSION = 1;\n\n    /** Creates underlying database table using DAOs. */\n    public static void createAllTables(Database db, boolean ifNotExists) {\n        KeepEntityDao.createTable(db, ifNotExists);\n        ToManyTarget2Dao.createTable(db, ifNotExists);\n        ToOneTarget2Dao.createTable(db, ifNotExists);\n        RelationSource2Dao.createTable(db, ifNotExists);\n    }\n\n    /** Drops underlying database table using DAOs. */\n    public static void dropAllTables(Database db, boolean ifExists) {\n        KeepEntityDao.dropTable(db, ifExists);\n        ToManyTarget2Dao.dropTable(db, ifExists);\n        ToOneTarget2Dao.dropTable(db, ifExists);\n        RelationSource2Dao.dropTable(db, ifExists);\n    }\n\n    /**\n     * WARNING: Drops all table on Upgrade! Use only during development.\n     * Convenience method using a {@link DevOpenHelper}.\n     */\n    public static DaoSession newDevSession(Context context, String name) {\n        Database db = new DevOpenHelper(context, name).getWritableDb();\n        DaoMaster daoMaster = new DaoMaster(db);\n        return daoMaster.newSession();\n    }\n\n    public DaoMaster(SQLiteDatabase db) {\n        this(new StandardDatabase(db));\n    }\n\n    public DaoMaster(Database db) {\n        super(db, SCHEMA_VERSION);\n        registerDaoClass(KeepEntityDao.class);\n        registerDaoClass(ToManyTarget2Dao.class);\n        registerDaoClass(ToOneTarget2Dao.class);\n        registerDaoClass(RelationSource2Dao.class);\n    }\n\n    public DaoSession newSession() {\n        return new DaoSession(db, IdentityScopeType.Session, daoConfigMap);\n    }\n\n    public DaoSession newSession(IdentityScopeType type) {\n        return new DaoSession(db, type, daoConfigMap);\n    }\n\n    /**\n     * Calls {@link #createAllTables(Database, boolean)} in {@link #onCreate(Database)} -\n     */\n    public static abstract class OpenHelper extends DatabaseOpenHelper {\n        public OpenHelper(Context context, String name) {\n            super(context, name, SCHEMA_VERSION);\n        }\n\n        public OpenHelper(Context context, String name, CursorFactory factory) {\n            super(context, name, factory, SCHEMA_VERSION);\n        }\n\n        @Override\n        public void onCreate(Database db) {\n            Log.i(\"greenDAO\", \"Creating tables for schema version \" + SCHEMA_VERSION);\n            createAllTables(db, false);\n        }\n    }\n\n    /** WARNING: Drops all table on Upgrade! Use only during development. */\n    public static class DevOpenHelper extends OpenHelper {\n        public DevOpenHelper(Context context, String name) {\n            super(context, name);\n        }\n\n        public DevOpenHelper(Context context, String name, CursorFactory factory) {\n            super(context, name, factory);\n        }\n\n        @Override\n        public void onUpgrade(Database db, int oldVersion, int newVersion) {\n            Log.i(\"greenDAO\", \"Upgrading schema from version \" + oldVersion + \" to \" + newVersion + \" by dropping all tables\");\n            dropAllTables(db, true);\n            onCreate(db);\n        }\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest2/dao/DaoSession.java",
    "content": "package org.greenrobot.greendao.daotest2.dao;\n\nimport java.util.Map;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.AbstractDaoSession;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.identityscope.IdentityScopeType;\nimport org.greenrobot.greendao.internal.DaoConfig;\n\nimport org.greenrobot.greendao.daotest2.KeepEntity;\nimport org.greenrobot.greendao.daotest2.ToManyTarget2;\nimport org.greenrobot.greendao.daotest2.to1_specialentity.ToOneTarget2;\nimport org.greenrobot.greendao.daotest2.specialentity.RelationSource2;\n\nimport org.greenrobot.greendao.daotest2.dao.KeepEntityDao;\nimport org.greenrobot.greendao.daotest2.dao.ToManyTarget2Dao;\nimport org.greenrobot.greendao.daotest2.to1_specialdao.ToOneTarget2Dao;\nimport org.greenrobot.greendao.daotest2.specialdao.RelationSource2Dao;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n\n/**\n * {@inheritDoc}\n * \n * @see org.greenrobot.greendao.AbstractDaoSession\n */\npublic class DaoSession extends AbstractDaoSession {\n\n    private final DaoConfig keepEntityDaoConfig;\n    private final DaoConfig toManyTarget2DaoConfig;\n    private final DaoConfig toOneTarget2DaoConfig;\n    private final DaoConfig relationSource2DaoConfig;\n\n    private final KeepEntityDao keepEntityDao;\n    private final ToManyTarget2Dao toManyTarget2Dao;\n    private final ToOneTarget2Dao toOneTarget2Dao;\n    private final RelationSource2Dao relationSource2Dao;\n\n    public DaoSession(Database db, IdentityScopeType type, Map<Class<? extends AbstractDao<?, ?>>, DaoConfig>\n            daoConfigMap) {\n        super(db);\n\n        keepEntityDaoConfig = daoConfigMap.get(KeepEntityDao.class).clone();\n        keepEntityDaoConfig.initIdentityScope(type);\n\n        toManyTarget2DaoConfig = daoConfigMap.get(ToManyTarget2Dao.class).clone();\n        toManyTarget2DaoConfig.initIdentityScope(type);\n\n        toOneTarget2DaoConfig = daoConfigMap.get(ToOneTarget2Dao.class).clone();\n        toOneTarget2DaoConfig.initIdentityScope(type);\n\n        relationSource2DaoConfig = daoConfigMap.get(RelationSource2Dao.class).clone();\n        relationSource2DaoConfig.initIdentityScope(type);\n\n        keepEntityDao = new KeepEntityDao(keepEntityDaoConfig, this);\n        toManyTarget2Dao = new ToManyTarget2Dao(toManyTarget2DaoConfig, this);\n        toOneTarget2Dao = new ToOneTarget2Dao(toOneTarget2DaoConfig, this);\n        relationSource2Dao = new RelationSource2Dao(relationSource2DaoConfig, this);\n\n        registerDao(KeepEntity.class, keepEntityDao);\n        registerDao(ToManyTarget2.class, toManyTarget2Dao);\n        registerDao(ToOneTarget2.class, toOneTarget2Dao);\n        registerDao(RelationSource2.class, relationSource2Dao);\n    }\n    \n    public void clear() {\n        keepEntityDaoConfig.clearIdentityScope();\n        toManyTarget2DaoConfig.clearIdentityScope();\n        toOneTarget2DaoConfig.clearIdentityScope();\n        relationSource2DaoConfig.clearIdentityScope();\n    }\n\n    public KeepEntityDao getKeepEntityDao() {\n        return keepEntityDao;\n    }\n\n    public ToManyTarget2Dao getToManyTarget2Dao() {\n        return toManyTarget2Dao;\n    }\n\n    public ToOneTarget2Dao getToOneTarget2Dao() {\n        return toOneTarget2Dao;\n    }\n\n    public RelationSource2Dao getRelationSource2Dao() {\n        return relationSource2Dao;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest2/dao/KeepEntityDao.java",
    "content": "package org.greenrobot.greendao.daotest2.dao;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\nimport org.greenrobot.greendao.daotest2.KeepEntity;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"KEEP_ENTITY\".\n*/\npublic class KeepEntityDao extends AbstractDao<KeepEntity, Long> {\n\n    public static final String TABLENAME = \"KEEP_ENTITY\";\n\n    /**\n     * Properties of entity KeepEntity.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n    }\n\n\n    public KeepEntityDao(DaoConfig config) {\n        super(config);\n    }\n    \n    public KeepEntityDao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"KEEP_ENTITY\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY );\"); // 0: id\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"KEEP_ENTITY\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, KeepEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, KeepEntity entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public KeepEntity readEntity(Cursor cursor, int offset) {\n        KeepEntity entity = new KeepEntity( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0) // id\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, KeepEntity entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(KeepEntity entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(KeepEntity entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(KeepEntity entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest2/dao/ToManyTarget2Dao.java",
    "content": "package org.greenrobot.greendao.daotest2.dao;\n\nimport java.util.List;\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\nimport org.greenrobot.greendao.query.Query;\nimport org.greenrobot.greendao.query.QueryBuilder;\n\nimport org.greenrobot.greendao.daotest2.ToManyTarget2;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"TO_MANY_TARGET2\".\n*/\npublic class ToManyTarget2Dao extends AbstractDao<ToManyTarget2, Long> {\n\n    public static final String TABLENAME = \"TO_MANY_TARGET2\";\n\n    /**\n     * Properties of entity ToManyTarget2.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property FkId = new Property(1, Long.class, \"fkId\", false, \"FK_ID\");\n    }\n\n    private Query<ToManyTarget2> relationSource2_ToManyTarget2ListQuery;\n\n    public ToManyTarget2Dao(DaoConfig config) {\n        super(config);\n    }\n    \n    public ToManyTarget2Dao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"TO_MANY_TARGET2\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"FK_ID\\\" INTEGER);\"); // 1: fkId\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"TO_MANY_TARGET2\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, ToManyTarget2 entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Long fkId = entity.getFkId();\n        if (fkId != null) {\n            stmt.bindLong(2, fkId);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, ToManyTarget2 entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Long fkId = entity.getFkId();\n        if (fkId != null) {\n            stmt.bindLong(2, fkId);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public ToManyTarget2 readEntity(Cursor cursor, int offset) {\n        ToManyTarget2 entity = new ToManyTarget2( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1) // fkId\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, ToManyTarget2 entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setFkId(cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(ToManyTarget2 entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(ToManyTarget2 entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(ToManyTarget2 entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n    /** Internal query to resolve the \"toManyTarget2List\" to-many relationship of RelationSource2. */\n    public List<ToManyTarget2> _queryRelationSource2_ToManyTarget2List(Long fkId) {\n        synchronized (this) {\n            if (relationSource2_ToManyTarget2ListQuery == null) {\n                QueryBuilder<ToManyTarget2> queryBuilder = queryBuilder();\n                queryBuilder.where(Properties.FkId.eq(null));\n                relationSource2_ToManyTarget2ListQuery = queryBuilder.build();\n            }\n        }\n        Query<ToManyTarget2> query = relationSource2_ToManyTarget2ListQuery.forCurrentThread();\n        query.setParameter(0, fkId);\n        return query.list();\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest2/specialdao/RelationSource2Dao.java",
    "content": "package org.greenrobot.greendao.daotest2.specialdao;\n\nimport java.util.List;\nimport java.util.ArrayList;\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.SqlUtils;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\nimport org.greenrobot.greendao.daotest2.dao.DaoSession;\n\nimport org.greenrobot.greendao.daotest2.to1_specialentity.ToOneTarget2;\n\nimport org.greenrobot.greendao.daotest2.specialentity.RelationSource2;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"RELATION_SOURCE2\".\n*/\npublic class RelationSource2Dao extends AbstractDao<RelationSource2, Long> {\n\n    public static final String TABLENAME = \"RELATION_SOURCE2\";\n\n    /**\n     * Properties of entity RelationSource2.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n        public final static Property ToOneId = new Property(1, Long.class, \"toOneId\", false, \"TO_ONE_ID\");\n    }\n\n    private DaoSession daoSession;\n\n\n    public RelationSource2Dao(DaoConfig config) {\n        super(config);\n    }\n    \n    public RelationSource2Dao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n        this.daoSession = daoSession;\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"RELATION_SOURCE2\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY ,\" + // 0: id\n                \"\\\"TO_ONE_ID\\\" INTEGER);\"); // 1: toOneId\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"RELATION_SOURCE2\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, RelationSource2 entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Long toOneId = entity.getToOneId();\n        if (toOneId != null) {\n            stmt.bindLong(2, toOneId);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, RelationSource2 entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n \n        Long toOneId = entity.getToOneId();\n        if (toOneId != null) {\n            stmt.bindLong(2, toOneId);\n        }\n    }\n\n    @Override\n    protected final void attachEntity(RelationSource2 entity) {\n        super.attachEntity(entity);\n        entity.__setDaoSession(daoSession);\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public RelationSource2 readEntity(Cursor cursor, int offset) {\n        RelationSource2 entity = new RelationSource2( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0), // id\n            cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1) // toOneId\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, RelationSource2 entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n        entity.setToOneId(cursor.isNull(offset + 1) ? null : cursor.getLong(offset + 1));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(RelationSource2 entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(RelationSource2 entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(RelationSource2 entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n    private String selectDeep;\n\n    protected String getSelectDeep() {\n        if (selectDeep == null) {\n            StringBuilder builder = new StringBuilder(\"SELECT \");\n            SqlUtils.appendColumns(builder, \"T\", getAllColumns());\n            builder.append(',');\n            SqlUtils.appendColumns(builder, \"T0\", daoSession.getToOneTarget2Dao().getAllColumns());\n            builder.append(\" FROM RELATION_SOURCE2 T\");\n            builder.append(\" LEFT JOIN TO_ONE_TARGET2 T0 ON T.\\\"TO_ONE_ID\\\"=T0.\\\"_id\\\"\");\n            builder.append(' ');\n            selectDeep = builder.toString();\n        }\n        return selectDeep;\n    }\n    \n    protected RelationSource2 loadCurrentDeep(Cursor cursor, boolean lock) {\n        RelationSource2 entity = loadCurrent(cursor, 0, lock);\n        int offset = getAllColumns().length;\n\n        ToOneTarget2 toOneTarget2 = loadCurrentOther(daoSession.getToOneTarget2Dao(), cursor, offset);\n        entity.setToOneTarget2(toOneTarget2);\n\n        return entity;    \n    }\n\n    public RelationSource2 loadDeep(Long key) {\n        assertSinglePk();\n        if (key == null) {\n            return null;\n        }\n\n        StringBuilder builder = new StringBuilder(getSelectDeep());\n        builder.append(\"WHERE \");\n        SqlUtils.appendColumnsEqValue(builder, \"T\", getPkColumns());\n        String sql = builder.toString();\n        \n        String[] keyArray = new String[] { key.toString() };\n        Cursor cursor = db.rawQuery(sql, keyArray);\n        \n        try {\n            boolean available = cursor.moveToFirst();\n            if (!available) {\n                return null;\n            } else if (!cursor.isLast()) {\n                throw new IllegalStateException(\"Expected unique result, but count was \" + cursor.getCount());\n            }\n            return loadCurrentDeep(cursor, true);\n        } finally {\n            cursor.close();\n        }\n    }\n    \n    /** Reads all available rows from the given cursor and returns a list of new ImageTO objects. */\n    public List<RelationSource2> loadAllDeepFromCursor(Cursor cursor) {\n        int count = cursor.getCount();\n        List<RelationSource2> list = new ArrayList<RelationSource2>(count);\n        \n        if (cursor.moveToFirst()) {\n            if (identityScope != null) {\n                identityScope.lock();\n                identityScope.reserveRoom(count);\n            }\n            try {\n                do {\n                    list.add(loadCurrentDeep(cursor, false));\n                } while (cursor.moveToNext());\n            } finally {\n                if (identityScope != null) {\n                    identityScope.unlock();\n                }\n            }\n        }\n        return list;\n    }\n    \n    protected List<RelationSource2> loadDeepAllAndCloseCursor(Cursor cursor) {\n        try {\n            return loadAllDeepFromCursor(cursor);\n        } finally {\n            cursor.close();\n        }\n    }\n    \n\n    /** A raw-style query where you can pass any WHERE clause and arguments. */\n    public List<RelationSource2> queryDeep(String where, String... selectionArg) {\n        Cursor cursor = db.rawQuery(getSelectDeep() + where, selectionArg);\n        return loadDeepAllAndCloseCursor(cursor);\n    }\n \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest2/specialentity/RelationSource2.java",
    "content": "package org.greenrobot.greendao.daotest2.specialentity;\n\nimport org.greenrobot.greendao.annotation.*;\n\nimport java.util.List;\nimport org.greenrobot.greendao.daotest2.dao.DaoSession;\nimport org.greenrobot.greendao.DaoException;\n\nimport org.greenrobot.greendao.daotest2.ToManyTarget2;\nimport org.greenrobot.greendao.daotest2.dao.ToManyTarget2Dao;\nimport org.greenrobot.greendao.daotest2.specialdao.RelationSource2Dao;\nimport org.greenrobot.greendao.daotest2.to1_specialdao.ToOneTarget2Dao;\nimport org.greenrobot.greendao.daotest2.to1_specialentity.ToOneTarget2;\n\n// THIS CODE IS GENERATED BY greenDAO, EDIT ONLY INSIDE THE \"KEEP\"-SECTIONS\n\n// KEEP INCLUDES - put your custom includes here\n// KEEP INCLUDES END\n\n/**\n * Entity mapped to table \"RELATION_SOURCE2\".\n */\n@Entity(active = true)\npublic class RelationSource2 {\n\n    @Id\n    private Long id;\n    private Long toOneId;\n\n    /** Used to resolve relations */\n    @Generated\n    private transient DaoSession daoSession;\n\n    /** Used for active entity operations. */\n    @Generated\n    private transient RelationSource2Dao myDao;\n\n    @ToOne(joinProperty = \"toOneId\")\n    private ToOneTarget2 toOneTarget2;\n\n    @Generated\n    private transient Long toOneTarget2__resolvedKey;\n\n    @ToMany(joinProperties = {\n        @JoinProperty(name = \"id\", referencedName = \"fkId\")\n    })\n    private List<ToManyTarget2> toManyTarget2List;\n\n    // KEEP FIELDS - put your custom fields here\n    // KEEP FIELDS END\n\n    @Generated\n    public RelationSource2() {\n    }\n\n    public RelationSource2(Long id) {\n        this.id = id;\n    }\n\n    @Generated\n    public RelationSource2(Long id, Long toOneId) {\n        this.id = id;\n        this.toOneId = toOneId;\n    }\n\n    /** called by internal mechanisms, do not call yourself. */\n    @Generated\n    public void __setDaoSession(DaoSession daoSession) {\n        this.daoSession = daoSession;\n        myDao = daoSession != null ? daoSession.getRelationSource2Dao() : null;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public Long getToOneId() {\n        return toOneId;\n    }\n\n    public void setToOneId(Long toOneId) {\n        this.toOneId = toOneId;\n    }\n\n    /** To-one relationship, resolved on first access. */\n    @Generated\n    public ToOneTarget2 getToOneTarget2() {\n        Long __key = this.toOneId;\n        if (toOneTarget2__resolvedKey == null || !toOneTarget2__resolvedKey.equals(__key)) {\n            __throwIfDetached();\n            ToOneTarget2Dao targetDao = daoSession.getToOneTarget2Dao();\n            ToOneTarget2 toOneTarget2New = targetDao.load(__key);\n            synchronized (this) {\n                toOneTarget2 = toOneTarget2New;\n            \ttoOneTarget2__resolvedKey = __key;\n            }\n        }\n        return toOneTarget2;\n    }\n\n    @Generated\n    public void setToOneTarget2(ToOneTarget2 toOneTarget2) {\n        synchronized (this) {\n            this.toOneTarget2 = toOneTarget2;\n            toOneId = toOneTarget2 == null ? null : toOneTarget2.getId();\n            toOneTarget2__resolvedKey = toOneId;\n        }\n    }\n\n    /** To-many relationship, resolved on first access (and after reset). Changes to to-many relations are not persisted, make changes to the target entity. */\n    @Generated\n    public List<ToManyTarget2> getToManyTarget2List() {\n        if (toManyTarget2List == null) {\n            __throwIfDetached();\n            ToManyTarget2Dao targetDao = daoSession.getToManyTarget2Dao();\n            List<ToManyTarget2> toManyTarget2ListNew = targetDao._queryRelationSource2_ToManyTarget2List(id);\n            synchronized (this) {\n                if(toManyTarget2List == null) {\n                    toManyTarget2List = toManyTarget2ListNew;\n                }\n            }\n        }\n        return toManyTarget2List;\n    }\n\n    /** Resets a to-many relationship, making the next get call to query for a fresh result. */\n    @Generated\n    public synchronized void resetToManyTarget2List() {\n        toManyTarget2List = null;\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void delete() {\n        __throwIfDetached();\n        myDao.delete(this);\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void update() {\n        __throwIfDetached();\n        myDao.update(this);\n    }\n\n    /**\n    * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.\n    * Entity must attached to an entity context.\n    */\n    @Generated\n    public void refresh() {\n        __throwIfDetached();\n        myDao.refresh(this);\n    }\n\n    @Generated\n    private void __throwIfDetached() {\n        if (myDao == null) {\n            throw new DaoException(\"Entity is detached from DAO context\");\n        }\n    }\n\n    // KEEP METHODS - put your custom methods here\n    // KEEP METHODS END\n\n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest2/to1_specialdao/ToOneTarget2Dao.java",
    "content": "package org.greenrobot.greendao.daotest2.to1_specialdao;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQLiteStatement;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.Property;\nimport org.greenrobot.greendao.internal.DaoConfig;\nimport org.greenrobot.greendao.database.Database;\nimport org.greenrobot.greendao.database.DatabaseStatement;\n\nimport org.greenrobot.greendao.daotest2.dao.DaoSession;\n\nimport org.greenrobot.greendao.daotest2.to1_specialentity.ToOneTarget2;\n\n// THIS CODE IS GENERATED BY greenDAO, DO NOT EDIT.\n/** \n * DAO for table \"TO_ONE_TARGET2\".\n*/\npublic class ToOneTarget2Dao extends AbstractDao<ToOneTarget2, Long> {\n\n    public static final String TABLENAME = \"TO_ONE_TARGET2\";\n\n    /**\n     * Properties of entity ToOneTarget2.<br/>\n     * Can be used for QueryBuilder and for referencing column names.\n     */\n    public static class Properties {\n        public final static Property Id = new Property(0, Long.class, \"id\", true, \"_id\");\n    }\n\n\n    public ToOneTarget2Dao(DaoConfig config) {\n        super(config);\n    }\n    \n    public ToOneTarget2Dao(DaoConfig config, DaoSession daoSession) {\n        super(config, daoSession);\n    }\n\n    /** Creates the underlying database table. */\n    public static void createTable(Database db, boolean ifNotExists) {\n        String constraint = ifNotExists? \"IF NOT EXISTS \": \"\";\n        db.execSQL(\"CREATE TABLE \" + constraint + \"\\\"TO_ONE_TARGET2\\\" (\" + //\n                \"\\\"_id\\\" INTEGER PRIMARY KEY );\"); // 0: id\n    }\n\n    /** Drops the underlying database table. */\n    public static void dropTable(Database db, boolean ifExists) {\n        String sql = \"DROP TABLE \" + (ifExists ? \"IF EXISTS \" : \"\") + \"\\\"TO_ONE_TARGET2\\\"\";\n        db.execSQL(sql);\n    }\n\n    @Override\n    protected final void bindValues(DatabaseStatement stmt, ToOneTarget2 entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n    }\n\n    @Override\n    protected final void bindValues(SQLiteStatement stmt, ToOneTarget2 entity) {\n        stmt.clearBindings();\n \n        Long id = entity.getId();\n        if (id != null) {\n            stmt.bindLong(1, id);\n        }\n    }\n\n    @Override\n    public Long readKey(Cursor cursor, int offset) {\n        return cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0);\n    }    \n\n    @Override\n    public ToOneTarget2 readEntity(Cursor cursor, int offset) {\n        ToOneTarget2 entity = new ToOneTarget2( //\n            cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0) // id\n        );\n        return entity;\n    }\n     \n    @Override\n    public void readEntity(Cursor cursor, ToOneTarget2 entity, int offset) {\n        entity.setId(cursor.isNull(offset + 0) ? null : cursor.getLong(offset + 0));\n     }\n    \n    @Override\n    protected final Long updateKeyAfterInsert(ToOneTarget2 entity, long rowId) {\n        entity.setId(rowId);\n        return rowId;\n    }\n    \n    @Override\n    public Long getKey(ToOneTarget2 entity) {\n        if(entity != null) {\n            return entity.getId();\n        } else {\n            return null;\n        }\n    }\n\n    @Override\n    public boolean hasKey(ToOneTarget2 entity) {\n        return entity.getId() != null;\n    }\n\n    @Override\n    protected final boolean isEntityUpdateable() {\n        return true;\n    }\n    \n}\n"
  },
  {
    "path": "tests/DaoTestBase/src/main/java/org/greenrobot/greendao/daotest2/to1_specialentity/ToOneTarget2.java",
    "content": "package org.greenrobot.greendao.daotest2.to1_specialentity;\n\nimport org.greenrobot.greendao.annotation.*;\n\n// THIS CODE IS GENERATED BY greenDAO, EDIT ONLY INSIDE THE \"KEEP\"-SECTIONS\n\n// KEEP INCLUDES - put your custom includes here\n// KEEP INCLUDES END\n\n/**\n * Entity mapped to table \"TO_ONE_TARGET2\".\n */\n@Entity\npublic class ToOneTarget2 {\n\n    @Id\n    private Long id;\n\n    // KEEP FIELDS - put your custom fields here\n    // KEEP FIELDS END\n\n    @Generated\n    public ToOneTarget2() {\n    }\n\n    @Generated\n    public ToOneTarget2(Long id) {\n        this.id = id;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    // KEEP METHODS - put your custom methods here\n    // KEEP METHODS END\n\n}\n"
  },
  {
    "path": "tests/DaoTestEntityAnnotation/build.gradle",
    "content": "buildscript {\n    repositories {\n        jcenter()\n        google()\n        mavenCentral()\n    }\n\n    dependencies {\n        classpath dep.androidPlugin\n        classpath dep.greendaoPlugin\n    }\n}\n\napply plugin: 'org.greenrobot.greendao'\napply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n\n    // To use deprecated test classes on SDK 28+. https://developer.android.com/training/testing/set-up-project\n    useLibrary 'android.test.runner'\n    useLibrary 'android.test.base'\n\n    defaultConfig {\n        applicationId \"org.greenrobot.greendao.test.entityannotation\"\n        minSdkVersion rootProject.ext.minSdkVersion\n        targetSdkVersion rootProject.ext.targetSdkVersion\n        versionCode 1\n        versionName \"1.0.0\"\n\n        testInstrumentationRunner \"android.test.InstrumentationTestRunner\"\n    }\n\n    compileOptions {\n        encoding = \"UTF-8\"\n        sourceCompatibility JavaVersion.VERSION_1_6\n        targetCompatibility JavaVersion.VERSION_1_6\n    }\n}\n\ngreendao {\n    schemaVersion 1000\n    generateTests true\n}\n\ndependencies {\n    implementation project(':DaoCore')\n}\n\nuploadArchives.enabled = false"
  },
  {
    "path": "tests/DaoTestEntityAnnotation/src/androidTest/java/org/greenrobot/greendao/test/entityannotation/CustomerOrderTest.java",
    "content": "package org.greenrobot.greendao.test.entityannotation;\n\nimport org.greenrobot.greendao.test.AbstractDaoSessionTest;\n\nimport java.util.Date;\nimport java.util.List;\n\npublic class CustomerOrderTest extends AbstractDaoSessionTest<DaoMaster, DaoSession> {\n\n    public CustomerOrderTest() {\n        super(DaoMaster.class);\n    }\n\n    public void testCustomerToOrders() {\n        Customer customer = new Customer(null, \"greenrobot\");\n        daoSession.insert(customer);\n\n        addOrderToCustomer(customer);\n        addOrderToCustomer(customer);\n\n        List<Order> orders = customer.getOrders();\n        assertEquals(2, orders.size());\n    }\n\n    public void testOrderToCustomer() {\n        Customer customer = new Customer(null, \"greenrobot\");\n        daoSession.insert(customer);\n\n        Order order = addOrderToCustomer(customer);\n        Customer customer2 = order.getCustomer();\n        \n        assertSame(customer, customer2);\n    }\n\n    public void testUpdateBirectional() {\n        Customer customer = new Customer(null, \"greenrobot\");\n        daoSession.insert(customer);\n\n        addOrderToCustomer(customer);\n        List<Order> orders = customer.getOrders();\n        \n        Order newOrder = new Order();\n        newOrder.setCustomer(customer);\n        daoSession.insert(newOrder);\n        orders.add(newOrder);\n        assertEquals(2, orders.size());\n        \n        customer.resetOrders();\n        List<Order> orders2 = customer.getOrders();\n        assertEquals(orders.size(), orders2.size());\n    }\n\n    private Order addOrderToCustomer(Customer customer) {\n        Date date = new Date(System.currentTimeMillis() - ((long) (Math.random() * 1000 * 60 * 60 * 24 * 365)));\n        Order order = new Order(null, date, customer.getId());\n        daoSession.insert(order);\n        return order;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestEntityAnnotation/src/androidTest/java/org/greenrobot/greendao/test/entityannotation/CustomerTest.java",
    "content": "package org.greenrobot.greendao.test.entityannotation;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\n\nimport java.util.concurrent.atomic.AtomicLong;\n\npublic class CustomerTest extends AbstractDaoTestLongPk<CustomerDao, Customer> {\n    private AtomicLong nameNumber = new AtomicLong();\n\n    public CustomerTest() {\n        super(CustomerDao.class);\n    }\n\n    @Override\n    protected Customer createEntity(Long key) {\n        Customer entity = new Customer();\n        entity.setId(key);\n        entity.setName(\"Ho \" + nameNumber.incrementAndGet());\n        return entity;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestEntityAnnotation/src/androidTest/java/org/greenrobot/greendao/test/entityannotation/NotNullThingTest.java",
    "content": "package org.greenrobot.greendao.test.entityannotation;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\n\npublic class NotNullThingTest extends AbstractDaoTestLongPk<NotNullThingDao, NotNullThing> {\n\n    public NotNullThingTest() {\n        super(NotNullThingDao.class);\n    }\n\n    @Override\n    protected NotNullThing createEntity(Long key) {\n        NotNullThing thing = new NotNullThing();\n        thing.setId(key);\n        thing.setNotNullBoolean(true);\n        thing.setNotNullInteger(42);\n        thing.setNotNullWrappedBoolean(true);\n        thing.setNotNullWrappedInteger(42);\n        thing.setNullableBoolean(true);\n        thing.setNullableInteger(42);\n        thing.setNullableWrappedBoolean(true);\n        thing.setNullableWrappedInteger(42);\n        return thing;\n    }\n\n    public void testInsertNotNullProperties() {\n        NotNullThing thing = createEntity(1L);\n        thing.setNotNullWrappedBoolean(null);\n        thing.setNotNullWrappedInteger(null);\n        try {\n            dao.insert(thing);\n            fail();\n        } catch (NullPointerException ignored) {\n        }\n    }\n\n    public void testInsertNullableProperties() {\n        NotNullThing thing = createEntity(1L);\n        thing.setNullableWrappedBoolean(null);\n        thing.setNullableWrappedInteger(null);\n        dao.insert(thing);\n\n        loadAndAssertNullableProperties(thing);\n    }\n\n    public void testUpdateNotNullProperties() {\n        NotNullThing thing = insertEntity();\n\n        thing.setNotNullWrappedBoolean(null);\n        thing.setNotNullWrappedInteger(null);\n        try {\n            dao.update(thing);\n            fail();\n        } catch (NullPointerException ignored) {\n        }\n    }\n\n    public void testUpdateNullableProperties() {\n        NotNullThing thing = insertEntity();\n\n        thing.setNullableWrappedBoolean(null);\n        thing.setNullableWrappedInteger(null);\n        dao.update(thing);\n\n        loadAndAssertNullableProperties(thing);\n    }\n\n    private NotNullThing insertEntity() {\n        NotNullThing thing = createEntity(1L);\n        dao.insert(thing);\n        return thing;\n    }\n\n    private void loadAndAssertNullableProperties(NotNullThing thing) {\n        NotNullThing loaded = dao.load(thing.getId());\n        assertTrue(loaded.getNullableBoolean());\n        assertEquals(42, loaded.getNullableInteger());\n        assertTrue(loaded.getNotNullBoolean());\n        assertEquals(42, loaded.getNotNullInteger());\n\n        assertNull(loaded.getNullableWrappedBoolean());\n        assertNull(loaded.getNullableWrappedInteger());\n\n        assertNotNull(loaded.getNotNullWrappedBoolean());\n        assertNotNull(loaded.getNotNullWrappedInteger());\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestEntityAnnotation/src/androidTest/java/org/greenrobot/greendao/test/entityannotation/OrderTest.java",
    "content": "package org.greenrobot.greendao.test.entityannotation;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\n\npublic class OrderTest extends AbstractDaoTestLongPk<OrderDao, Order> {\n\n    public OrderTest() {\n        super(OrderDao.class);\n    }\n\n    @Override\n    protected Order createEntity(Long key) {\n        Order entity = new Order();\n        entity.setId(key);\n        entity.setCustomerId(1);\n        return entity;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestEntityAnnotation/src/androidTest/java/org/greenrobot/greendao/test/entityannotation/TypesInInnerClassTest.java",
    "content": "package org.greenrobot.greendao.test.entityannotation;\n\nimport org.greenrobot.greendao.test.AbstractDaoTestLongPk;\nimport org.greenrobot.greendao.test.entityannotation.TypesInInnerClass.MyInnerType;\n\npublic class TypesInInnerClassTest extends AbstractDaoTestLongPk<TypesInInnerClassDao, TypesInInnerClass> {\n\n    public TypesInInnerClassTest() {\n        super(TypesInInnerClassDao.class);\n    }\n\n    @Override\n    protected TypesInInnerClass createEntity(Long key) {\n        TypesInInnerClass entity = new TypesInInnerClass();\n        entity.setId(key);\n        entity.setType(new MyInnerType(\"cafe\"));\n        return entity;\n    }\n\n    public void testType() {\n        TypesInInnerClass entity = createEntity(1L);\n        dao.insert(entity);\n        TypesInInnerClass entity2 = dao.load(1L);\n        assertNotSame(entity, entity2);\n        assertEquals(\"cafe\", entity2.getType().value);\n    }\n}\n"
  },
  {
    "path": "tests/DaoTestEntityAnnotation/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"org.greenrobot.greendao.test.entityannotation\">\n\n    <application\n        android:label=\"greenDAO @Entity Test\"\n        android:allowBackup=\"true\">\n    </application>\n\n</manifest>"
  },
  {
    "path": "tests/DaoTestEntityAnnotation/src/main/java/org/greenrobot/greendao/test/entityannotation/Customer.java",
    "content": "package org.greenrobot.greendao.test.entityannotation;\n\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.annotation.Entity;\nimport org.greenrobot.greendao.annotation.Generated;\nimport org.greenrobot.greendao.annotation.Id;\nimport org.greenrobot.greendao.annotation.JoinProperty;\nimport org.greenrobot.greendao.annotation.NotNull;\nimport org.greenrobot.greendao.annotation.OrderBy;\nimport org.greenrobot.greendao.annotation.ToMany;\nimport org.greenrobot.greendao.annotation.Unique;\n\nimport java.util.List;\n\n/**\n * Entity mapped to table \"CUSTOMER\".\n */\n@Entity(active = true)\npublic class Customer {\n\n    @Id(autoincrement = true)\n    private Long id;\n\n    @NotNull\n    @Unique\n    private String name;\n\n    /** Used to resolve relations */\n    @Generated(hash = 2040040024)\n    private transient DaoSession daoSession;\n\n    /** Used for active entity operations. */\n    @Generated(hash = 1697251196)\n    private transient CustomerDao myDao;\n\n    @ToMany(joinProperties = {\n            @JoinProperty(name = \"id\", referencedName = \"customerId\")\n    })\n    @OrderBy(\"date ASC\")\n    private List<Order> orders;\n\n    @Generated(hash = 60841032)\n    public Customer() {\n    }\n\n    public Customer(Long id) {\n        this.id = id;\n    }\n\n    @Generated(hash = 969486800)\n    public Customer(Long id, @NotNull String name) {\n        this.id = id;\n        this.name = name;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    @NotNull\n    public String getName() {\n        return name;\n    }\n\n    /** Not-null value; ensure this value is available before it is saved to the database. */\n    public void setName(@NotNull String name) {\n        this.name = name;\n    }\n\n    /**\n     * To-many relationship, resolved on first access (and after reset).\n     * Changes to to-many relations are not persisted, make changes to the target entity.\n     */\n    @Generated(hash = 1084217201)\n    public List<Order> getOrders() {\n        if (orders == null) {\n            final DaoSession daoSession = this.daoSession;\n            if (daoSession == null) {\n                throw new DaoException(\"Entity is detached from DAO context\");\n            }\n            OrderDao targetDao = daoSession.getOrderDao();\n            List<Order> ordersNew = targetDao._queryCustomer_Orders(id);\n            synchronized (this) {\n                if (orders == null) {\n                    orders = ordersNew;\n                }\n            }\n        }\n        return orders;\n    }\n\n    /** Resets a to-many relationship, making the next get call to query for a fresh result. */\n    @Generated(hash = 1446109810)\n    public synchronized void resetOrders() {\n        orders = null;\n    }\n\n    /**\n     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.\n     * Entity must attached to an entity context.\n     */\n    @Generated(hash = 128553479)\n    public void delete() {\n        if (myDao == null) {\n            throw new DaoException(\"Entity is detached from DAO context\");\n        }\n        myDao.delete(this);\n    }\n\n    /**\n     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.\n     * Entity must attached to an entity context.\n     */\n    @Generated(hash = 713229351)\n    public void update() {\n        if (myDao == null) {\n            throw new DaoException(\"Entity is detached from DAO context\");\n        }\n        myDao.update(this);\n    }\n\n    /**\n     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.\n     * Entity must attached to an entity context.\n     */\n    @Generated(hash = 1942392019)\n    public void refresh() {\n        if (myDao == null) {\n            throw new DaoException(\"Entity is detached from DAO context\");\n        }\n        myDao.refresh(this);\n    }\n\n    /** called by internal mechanisms, do not call yourself. */\n    @Generated(hash = 462117449)\n    public void __setDaoSession(DaoSession daoSession) {\n        this.daoSession = daoSession;\n        myDao = daoSession != null ? daoSession.getCustomerDao() : null;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestEntityAnnotation/src/main/java/org/greenrobot/greendao/test/entityannotation/NotNullThing.java",
    "content": "package org.greenrobot.greendao.test.entityannotation;\n\nimport org.greenrobot.greendao.annotation.Entity;\nimport org.greenrobot.greendao.annotation.Generated;\nimport org.greenrobot.greendao.annotation.Id;\nimport org.greenrobot.greendao.annotation.NotNull;\n\n@Entity\npublic class NotNullThing {\n\n    @Id\n    private Long id;\n\n    boolean nullableBoolean;\n    int nullableInteger;\n    Boolean nullableWrappedBoolean;\n    Integer nullableWrappedInteger;\n\n    @NotNull\n    boolean notNullBoolean;\n    @NotNull\n    int notNullInteger;\n    @NotNull\n    Boolean notNullWrappedBoolean;\n    @NotNull\n    Integer notNullWrappedInteger;\n\n    @Generated(hash = 1109392169)\n    public NotNullThing(Long id, boolean nullableBoolean, int nullableInteger,\n                        Boolean nullableWrappedBoolean, Integer nullableWrappedInteger,\n                        boolean notNullBoolean, int notNullInteger,\n                        @NotNull Boolean notNullWrappedBoolean,\n                        @NotNull Integer notNullWrappedInteger) {\n        this.id = id;\n        this.nullableBoolean = nullableBoolean;\n        this.nullableInteger = nullableInteger;\n        this.nullableWrappedBoolean = nullableWrappedBoolean;\n        this.nullableWrappedInteger = nullableWrappedInteger;\n        this.notNullBoolean = notNullBoolean;\n        this.notNullInteger = notNullInteger;\n        this.notNullWrappedBoolean = notNullWrappedBoolean;\n        this.notNullWrappedInteger = notNullWrappedInteger;\n    }\n\n    @Generated(hash = 521031743)\n    public NotNullThing() {\n    }\n\n    public Long getId() {\n        return this.id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public boolean getNullableBoolean() {\n        return this.nullableBoolean;\n    }\n\n    public void setNullableBoolean(boolean nullableBoolean) {\n        this.nullableBoolean = nullableBoolean;\n    }\n\n    public int getNullableInteger() {\n        return this.nullableInteger;\n    }\n\n    public void setNullableInteger(int nullableInteger) {\n        this.nullableInteger = nullableInteger;\n    }\n\n    public Boolean getNullableWrappedBoolean() {\n        return this.nullableWrappedBoolean;\n    }\n\n    public void setNullableWrappedBoolean(Boolean nullableWrappedBoolean) {\n        this.nullableWrappedBoolean = nullableWrappedBoolean;\n    }\n\n    public Integer getNullableWrappedInteger() {\n        return this.nullableWrappedInteger;\n    }\n\n    public void setNullableWrappedInteger(Integer nullableWrappedInteger) {\n        this.nullableWrappedInteger = nullableWrappedInteger;\n    }\n\n    public boolean getNotNullBoolean() {\n        return this.notNullBoolean;\n    }\n\n    public void setNotNullBoolean(boolean notNullBoolean) {\n        this.notNullBoolean = notNullBoolean;\n    }\n\n    public int getNotNullInteger() {\n        return this.notNullInteger;\n    }\n\n    public void setNotNullInteger(int notNullInteger) {\n        this.notNullInteger = notNullInteger;\n    }\n\n    public Boolean getNotNullWrappedBoolean() {\n        return this.notNullWrappedBoolean;\n    }\n\n    public void setNotNullWrappedBoolean(Boolean notNullWrappedBoolean) {\n        this.notNullWrappedBoolean = notNullWrappedBoolean;\n    }\n\n    public Integer getNotNullWrappedInteger() {\n        return this.notNullWrappedInteger;\n    }\n\n    public void setNotNullWrappedInteger(Integer notNullWrappedInteger) {\n        this.notNullWrappedInteger = notNullWrappedInteger;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestEntityAnnotation/src/main/java/org/greenrobot/greendao/test/entityannotation/Order.java",
    "content": "package org.greenrobot.greendao.test.entityannotation;\n\nimport org.greenrobot.greendao.DaoException;\nimport org.greenrobot.greendao.annotation.Entity;\nimport org.greenrobot.greendao.annotation.Generated;\nimport org.greenrobot.greendao.annotation.Id;\nimport org.greenrobot.greendao.annotation.NotNull;\nimport org.greenrobot.greendao.annotation.ToOne;\n\n/**\n * Entity mapped to table \"ORDERS\".\n */\n@Entity(active = true, nameInDb = \"ORDERS\")\npublic class Order {\n\n    @Id\n    private Long id;\n    private java.util.Date date;\n    private long customerId;\n\n    /** Used to resolve relations */\n    @Generated(hash = 2040040024)\n    private transient DaoSession daoSession;\n\n    /** Used for active entity operations. */\n    @Generated(hash = 949219203)\n    private transient OrderDao myDao;\n\n    @ToOne(joinProperty = \"customerId\")\n    private Customer customer;\n\n    @Generated(hash = 8592637)\n    private transient Long customer__resolvedKey;\n\n    @Generated(hash = 1105174599)\n    public Order() {\n    }\n\n    public Order(Long id) {\n        this.id = id;\n    }\n\n    @Generated(hash = 767587610)\n    public Order(Long id, java.util.Date date, long customerId) {\n        this.id = id;\n        this.date = date;\n        this.customerId = customerId;\n    }\n\n    public Long getId() {\n        return id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    public java.util.Date getDate() {\n        return date;\n    }\n\n    public void setDate(java.util.Date date) {\n        this.date = date;\n    }\n\n    public long getCustomerId() {\n        return customerId;\n    }\n\n    public void setCustomerId(long customerId) {\n        this.customerId = customerId;\n    }\n\n    /** To-one relationship, resolved on first access. */\n    @Generated(hash = 941511332)\n    public Customer getCustomer() {\n        long __key = this.customerId;\n        if (customer__resolvedKey == null || !customer__resolvedKey.equals(__key)) {\n            final DaoSession daoSession = this.daoSession;\n            if (daoSession == null) {\n                throw new DaoException(\"Entity is detached from DAO context\");\n            }\n            CustomerDao targetDao = daoSession.getCustomerDao();\n            Customer customerNew = targetDao.load(__key);\n            synchronized (this) {\n                customer = customerNew;\n                customer__resolvedKey = __key;\n            }\n        }\n        return customer;\n    }\n\n    /** called by internal mechanisms, do not call yourself. */\n    @Generated(hash = 625323961)\n    public void setCustomer(@NotNull Customer customer) {\n        if (customer == null) {\n            throw new DaoException(\n                    \"To-one property 'customerId' has not-null constraint; cannot set to-one to null\");\n        }\n        synchronized (this) {\n            this.customer = customer;\n            customerId = customer.getId();\n            customer__resolvedKey = customerId;\n        }\n    }\n\n    /**\n     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#delete(Object)}.\n     * Entity must attached to an entity context.\n     */\n    @Generated(hash = 128553479)\n    public void delete() {\n        if (myDao == null) {\n            throw new DaoException(\"Entity is detached from DAO context\");\n        }\n        myDao.delete(this);\n    }\n\n    /**\n     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#update(Object)}.\n     * Entity must attached to an entity context.\n     */\n    @Generated(hash = 713229351)\n    public void update() {\n        if (myDao == null) {\n            throw new DaoException(\"Entity is detached from DAO context\");\n        }\n        myDao.update(this);\n    }\n\n\n\n    /**\n     * Convenient call for {@link org.greenrobot.greendao.AbstractDao#refresh(Object)}.\n     * Entity must attached to an entity context.\n     */\n    @Generated(hash = 1942392019)\n    public void refresh() {\n        if (myDao == null) {\n            throw new DaoException(\"Entity is detached from DAO context\");\n        }\n        myDao.refresh(this);\n    }\n\n    /** called by internal mechanisms, do not call yourself. */\n    @Generated(hash = 965731666)\n    public void __setDaoSession(DaoSession daoSession) {\n        this.daoSession = daoSession;\n        myDao = daoSession != null ? daoSession.getOrderDao() : null;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestEntityAnnotation/src/main/java/org/greenrobot/greendao/test/entityannotation/TypesInInnerClass.java",
    "content": "package org.greenrobot.greendao.test.entityannotation;\n\nimport org.greenrobot.greendao.annotation.Convert;\nimport org.greenrobot.greendao.annotation.Entity;\nimport org.greenrobot.greendao.annotation.Generated;\nimport org.greenrobot.greendao.annotation.Id;\nimport org.greenrobot.greendao.converter.PropertyConverter;\n\n@Entity\npublic class TypesInInnerClass {\n    static class MyInnerType {\n\n        public MyInnerType(String value) {\n            this.value = value;\n        }\n\n        String value;\n    }\n\n    static class MyInnerTypeConverter implements PropertyConverter<MyInnerType, Long> {\n\n        @Override\n        public MyInnerType convertToEntityProperty(Long databaseValue) {\n            return databaseValue != null ? new MyInnerType(Long.toHexString(databaseValue)) : null;\n        }\n\n        @Override\n        public Long convertToDatabaseValue(MyInnerType entityProperty) {\n            return entityProperty != null ? Long.parseLong(entityProperty.value, 16) : null;\n        }\n    }\n\n    @Id\n    Long id;\n\n    @Convert(converter = MyInnerTypeConverter.class, columnType = Long.class)\n    TypesInInnerClass.MyInnerType type;\n\n    public MyInnerType getType() {\n        return this.type;\n    }\n\n    public void setType(MyInnerType type) {\n        this.type = type;\n    }\n\n    public Long getId() {\n        return this.id;\n    }\n\n    public void setId(Long id) {\n        this.id = id;\n    }\n\n    @Generated(hash = 582873426)\n    public TypesInInnerClass(Long id, TypesInInnerClass.MyInnerType type) {\n        this.id = id;\n        this.type = type;\n    }\n\n    @Generated(hash = 1754325029)\n    public TypesInInnerClass() {\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestGenerator/build.gradle",
    "content": "apply plugin: 'java'\napply plugin: 'application'\n\n// If your IDE fails to run generation (NoClassDefFoundError), run it using gradle\nmainClassName = \"org.greenrobot.greendao.generator.gentest.TestDaoGenerator\"\n\nsourceSets {\n    main {\n        java {\n            srcDir 'src'\n        }\n    }\n}\n\ndependencies {\n    compile project(':DaoGenerator')\n}\n\nuploadArchives.enabled = false"
  },
  {
    "path": "tests/DaoTestGenerator/src/org/greenrobot/greendao/generator/gentest/TestDaoGenerator.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.generator.gentest;\n\nimport org.greenrobot.greendao.generator.DaoGenerator;\nimport org.greenrobot.greendao.generator.Entity;\nimport org.greenrobot.greendao.generator.Property;\nimport org.greenrobot.greendao.generator.Schema;\nimport org.greenrobot.greendao.generator.ToMany;\n\n/**\n * Generates test entities for test project DaoTest.\n *\n * @author Markus\n */\npublic class TestDaoGenerator {\n\n    public static void main(String[] args) throws Exception {\n        TestDaoGenerator testDaoGenerator = new TestDaoGenerator();\n        testDaoGenerator.generate();\n    }\n\n    private final Schema schema;\n    private final Entity testEntity;\n    private final Entity dateEntity;\n    private final Schema schema2;\n    private final Schema schemaUnitTest;\n\n    public TestDaoGenerator() {\n        schema = new Schema(1, \"org.greenrobot.greendao.daotest\");\n        schema.setDefaultJavaPackageTest(\"org.greenrobot.greendao.daotest.entity\");\n\n        createSimple();\n        createSimpleNotNull();\n        testEntity = createTest();\n        createRelation();\n        dateEntity = createDate();\n        createSpecialNames();\n        createAbcdef();\n        createToMany();\n        createTreeEntity();\n        createActive();\n        createExtendsImplements();\n        createStringKeyValue();\n        createAutoincrement();\n        createSqliteMaster();\n        createCustomType();\n        createIndexedString();\n\n        schema2 = createSchema2();\n        schemaUnitTest = createSchemaUnitTest();\n    }\n\n    public void generate() throws Exception {\n        DaoGenerator daoGenerator = new DaoGenerator();\n        daoGenerator.generateAll(schema, \"../DaoTestBase/src/main/java\");\n        daoGenerator.generateAll(schema2, \"../DaoTestBase/src/main/java\");\n        daoGenerator.generateAll(schemaUnitTest, \"../DaoTest/src/test/java\");\n    }\n\n    protected void createSimple() {\n        Entity simple = schema.addEntity(\"SimpleEntity\");\n        simple.addIdProperty();\n        simple.addBooleanProperty(\"simpleBoolean\");\n        simple.addByteProperty(\"simpleByte\");\n        simple.addShortProperty(\"simpleShort\");\n        simple.addIntProperty(\"simpleInt\");\n        simple.addLongProperty(\"simpleLong\");\n        simple.addFloatProperty(\"simpleFloat\");\n        simple.addDoubleProperty(\"simpleDouble\");\n        simple.addStringProperty(\"simpleString\");\n        simple.addByteArrayProperty(\"simpleByteArray\");\n\n        simple.addContentProvider().readOnly();\n    }\n\n    protected void createSimpleNotNull() {\n        Entity notNull = schema.addEntity(\"SimpleEntityNotNull\");\n        notNull.addIdProperty().notNull();\n        notNull.addBooleanProperty(\"simpleBoolean\").notNull();\n        notNull.addByteProperty(\"simpleByte\").notNull();\n        notNull.addShortProperty(\"simpleShort\").notNull();\n        notNull.addIntProperty(\"simpleInt\").notNull();\n        notNull.addLongProperty(\"simpleLong\").notNull();\n        notNull.addFloatProperty(\"simpleFloat\").notNull();\n        notNull.addDoubleProperty(\"simpleDouble\").notNull();\n        notNull.addStringProperty(\"simpleString\").notNull();\n        notNull.addByteArrayProperty(\"simpleByteArray\").notNull();\n    }\n\n    protected Entity createTest() {\n        Entity testEntity = schema.addEntity(\"TestEntity\");\n        testEntity.setJavaDoc(\"This entity is used by internal tests of greenDAO.\\n\" +\n                \"(This JavaDoc is defined in the generator project.)\");\n        testEntity.setCodeBeforeClass(\"// This is another test comment, you could also apply annotations like this\");\n        testEntity.addIdProperty().javaDocField(\"JavaDoc test field\");\n        testEntity.addIntProperty(\"simpleInt\").notNull().javaDocGetter(\"JavaDoc test getter\");\n        testEntity.addIntProperty(\"simpleInteger\").javaDocSetter(\"JavaDoc test setter\");\n        testEntity.addStringProperty(\"simpleStringNotNull\").notNull().javaDocGetterAndSetter(\"JavaDoc test getter and setter\");\n        testEntity.addStringProperty(\"simpleString\");\n        testEntity.addStringProperty(\"indexedString\").index();\n        testEntity.addStringProperty(\"indexedStringAscUnique\").indexAsc(null, true);\n        testEntity.addDateProperty(\"simpleDate\");\n        testEntity.addBooleanProperty(\"simpleBoolean\");\n        testEntity.addByteArrayProperty(\"simpleByteArray\");\n        return testEntity;\n    }\n\n    protected void createRelation() {\n        Entity relationEntity = schema.addEntity(\"RelationEntity\");\n        relationEntity.addIdProperty();\n        Property parentIdProperty = relationEntity.addLongProperty(\"parentId\").getProperty();\n        relationEntity.addToOne(relationEntity, parentIdProperty).setName(\"parent\");\n        Property testIdProperty = relationEntity.addLongProperty(\"testId\").getProperty();\n        relationEntity.addToOne(testEntity, testIdProperty);\n        Property testIdNotNullProperty = relationEntity.addLongProperty(\"testIdNotNull\").notNull().getProperty();\n        relationEntity.addToOne(testEntity, testIdNotNullProperty).setName(\"testNotNull\");\n        relationEntity.addStringProperty(\"simpleString\");\n        relationEntity.addToOneWithoutProperty(\"testWithoutProperty\", testEntity, \"WITHOUT_PROPERTY_TEST_ID\");\n    }\n\n    protected void createToMany() {\n        Entity toManyTargetEntity = schema.addEntity(\"ToManyTargetEntity\");\n        Property toManyIdProperty = toManyTargetEntity.addLongProperty(\"toManyId\").getProperty();\n        Property toManyIdDescProperty = toManyTargetEntity.addLongProperty(\"toManyIdDesc\").getProperty();\n        Property targetIdProperty = toManyTargetEntity.addIdProperty().getProperty();\n        Property targetJoinProperty = toManyTargetEntity.addStringProperty(\"targetJoinProperty\").getProperty();\n\n        Entity toManyEntity = schema.addEntity(\"ToManyEntity\");\n        Property sourceIdProperty = toManyEntity.addIdProperty().getProperty();\n        Property sourceJoinProperty = toManyEntity.addStringProperty(\"sourceJoinProperty\").getProperty();\n\n        ToMany toMany = toManyEntity.addToMany(toManyTargetEntity, toManyIdProperty);\n        toMany.orderAsc(targetIdProperty);\n\n        ToMany toManyDesc = toManyEntity.addToMany(toManyTargetEntity, toManyIdDescProperty);\n        toManyDesc.setName(\"toManyDescList\");\n        toManyDesc.orderDesc(targetIdProperty);\n\n        ToMany toManyByJoinProperty = toManyEntity\n                .addToMany(sourceJoinProperty, toManyTargetEntity, targetJoinProperty);\n        toManyByJoinProperty.setName(\"toManyByJoinProperty\");\n        toManyByJoinProperty.orderAsc(targetIdProperty);\n\n        Property[] sourceProperties = {sourceIdProperty, sourceJoinProperty};\n        Property[] targetProperties = {toManyIdProperty, targetJoinProperty};\n        ToMany toManyJoinTwo = toManyEntity.addToMany(sourceProperties, toManyTargetEntity, targetProperties);\n        toManyJoinTwo.setName(\"toManyJoinTwo\");\n        toManyJoinTwo.orderDesc(targetJoinProperty);\n        toManyJoinTwo.orderDesc(targetIdProperty);\n\n        Entity toManyJoinEntity = schema.addEntity(\"JoinManyToDateEntity\");\n        toManyJoinEntity.addIdProperty();\n        Property id1 = toManyJoinEntity.addLongProperty(\"idToMany\").getProperty();\n        Property id2 = toManyJoinEntity.addLongProperty(\"idDate\").getProperty();\n\n        toManyEntity.addToMany(dateEntity, toManyJoinEntity, id1, id2);\n    }\n\n    protected void createTreeEntity() {\n        Entity treeEntity = schema.addEntity(\"TreeEntity\");\n        treeEntity.addIdProperty();\n        Property parentIdProperty = treeEntity.addLongProperty(\"parentId\").getProperty();\n        treeEntity.addToOne(treeEntity, parentIdProperty).setName(\"parent\");\n        treeEntity.addToMany(treeEntity, parentIdProperty).setName(\"children\");\n    }\n\n    protected Entity createDate() {\n        Entity dateEntity = schema.addEntity(\"DateEntity\");\n        dateEntity.addIdProperty();\n        dateEntity.addDateProperty(\"date\").codeBeforeField(\"// Test code for\\n    // field\")\n        .codeBeforeGetter(\"// Test code for\\n    // getter\").codeBeforeSetter(\"// Test code for\\n    // setter\");\n        dateEntity.addImport(\"java.lang.String\");\n        dateEntity.addDateProperty(\"dateNotNull\").notNull();\n        return dateEntity;\n    }\n\n    protected void createSpecialNames() {\n        Entity specialNamesEntity = schema.addEntity(\"SpecialNamesEntity\");\n        specialNamesEntity.setDbName(\"ORDER TRANSACTION GROUP BY\");\n        specialNamesEntity.addIdProperty();\n        specialNamesEntity.addStringProperty(\"count\");\n        specialNamesEntity.addStringProperty(\"select\");\n        specialNamesEntity.addStringProperty(\"sum\");\n        specialNamesEntity.addStringProperty(\"avg\");\n        specialNamesEntity.addStringProperty(\"join\");\n        specialNamesEntity.addStringProperty(\"distinct\");\n        specialNamesEntity.addStringProperty(\"on\");\n        specialNamesEntity.addStringProperty(\"index\");\n        specialNamesEntity.addIntProperty(\"order\");\n    }\n\n    private void createAbcdef() {\n        Entity entity = schema.addEntity(\"AbcdefEntity\");\n        entity.addIdProperty();\n        entity.addIntProperty(\"a\");\n        entity.addIntProperty(\"b\");\n        entity.addIntProperty(\"c\");\n        entity.addIntProperty(\"d\");\n        entity.addIntProperty(\"e\");\n        entity.addIntProperty(\"f\");\n        entity.addIntProperty(\"g\");\n        entity.addIntProperty(\"h\");\n        entity.addIntProperty(\"j\");\n        entity.addIntProperty(\"i\");\n        entity.addIntProperty(\"k\");\n    }\n\n    protected void createActive() {\n        Entity activeEntity = schema.addEntity(\"AnActiveEntity\");\n        activeEntity.addIdProperty();\n        activeEntity.addStringProperty(\"text\");\n        activeEntity.setActive(true);\n    }\n\n    protected void createExtendsImplements() {\n        Entity entity = schema.addEntity(\"ExtendsImplementsEntity\");\n        entity.addIdProperty();\n        entity.addStringProperty(\"text\");\n        entity.setSuperclass(\"TestSuperclass\");\n        entity.implementsInterface(\"TestInterface\");\n        entity.implementsSerializable();\n    }\n\n    protected void createStringKeyValue() {\n        Entity entity = schema.addEntity(\"StringKeyValueEntity\");\n        entity.addStringProperty(\"key\").primaryKey();\n        entity.addStringProperty(\"value\");\n    }\n\n    protected void createAutoincrement() {\n        Entity entity = schema.addEntity(\"AutoincrementEntity\");\n        entity.addIdProperty().autoincrement();\n    }\n\n    protected void createSqliteMaster() {\n        Entity entity = schema.addEntity(\"SqliteMaster\");\n        entity.setSkipCreationInDb(true);\n        entity.setHasKeepSections(true);\n        entity.addStringProperty(\"type\");\n        entity.addStringProperty(\"name\");\n        entity.addStringProperty(\"tableName\").dbName(\"tbl_name\");\n        entity.addLongProperty(\"rootpage\");\n        entity.addStringProperty(\"sql\");\n    }\n\n    protected void createCustomType() {\n        Entity entity = schema.addEntity(\"CustomTypeEntity\");\n        entity.addIdProperty();\n        entity.addLongProperty(\"myCustomTimestamp\").customType(\"org.greenrobot.greendao.daotest.customtype.MyTimestamp\",\n                \"org.greenrobot.greendao.daotest.customtype.MyTimestampConverter\");\n    }\n\n    protected void createIndexedString() {\n        Entity entity = schema.addEntity(\"IndexedStringEntity\");\n        entity.addIdProperty();\n        entity.addStringProperty(\"indexedString\").index();\n    }\n\n    private Schema createSchema2() {\n        Schema schema2 = new Schema(1, \"org.greenrobot.greendao.daotest2\");\n        schema2.setDefaultJavaPackageTest(\"org.greenrobot.greendao.daotest2.entity\");\n        schema2.setDefaultJavaPackageDao(\"org.greenrobot.greendao.daotest2.dao\");\n        schema2.enableKeepSectionsByDefault();\n\n        Entity keepEntity = schema2.addEntity(\"KeepEntity\");\n        keepEntity.addIdProperty();\n\n        Entity toManyTarget2 = schema2.addEntity(\"ToManyTarget2\");\n        toManyTarget2.addIdProperty();\n        Property toManyTarget2FkId = toManyTarget2.addLongProperty(\"fkId\").getProperty();\n        toManyTarget2.setSkipGenerationTest(true);\n\n        Entity toOneTarget2 = schema2.addEntity(\"ToOneTarget2\");\n        toOneTarget2.addIdProperty();\n        toOneTarget2.setJavaPackage(\"org.greenrobot.greendao.daotest2.to1_specialentity\");\n        toOneTarget2.setJavaPackageDao(\"org.greenrobot.greendao.daotest2.to1_specialdao\");\n        toOneTarget2.setJavaPackageTest(\"org.greenrobot.greendao.daotest2.to1_specialtest\");\n        toOneTarget2.setSkipGenerationTest(true);\n\n        Entity relationSource2 = schema2.addEntity(\"RelationSource2\");\n        relationSource2.addIdProperty();\n        relationSource2.addToMany(toManyTarget2, toManyTarget2FkId);\n        Property toOneId = relationSource2.addLongProperty(\"toOneId\").getProperty();\n        relationSource2.addToOne(toOneTarget2, toOneId);\n        relationSource2.setJavaPackage(\"org.greenrobot.greendao.daotest2.specialentity\");\n        relationSource2.setJavaPackageDao(\"org.greenrobot.greendao.daotest2.specialdao\");\n        relationSource2.setJavaPackageTest(\"org.greenrobot.greendao.daotest2.specialtest\");\n        relationSource2.setSkipGenerationTest(true);\n        return schema2;\n    }\n\n    private Schema createSchemaUnitTest() {\n        Schema schema = new Schema(1, \"org.greenrobot.greendao.unittest\");\n\n        Entity entity = schema.addEntity(\"MinimalEntity\");\n        entity.addIdProperty();\n        return schema;\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestPerformance/build.gradle",
    "content": "buildscript {\n    repositories {\n        jcenter()\n        google()\n        mavenCentral()\n    }\n\n    dependencies {\n        classpath dep.androidPlugin\n    }\n}\n\napply plugin: 'com.android.application'\n\nrepositories {\n    maven {\n        url 'https://oss.sonatype.org/content/repositories/snapshots'\n    }\n}\n\ndependencies {\n    implementation project(':tests:DaoTestBase')\n    androidTestImplementation 'org.greenrobot:essentials:3.0.0-SNAPSHOT'\n}\n\nandroid {\n    compileSdkVersion rootProject.ext.compileSdkVersion\n\n    // To use deprecated test classes on SDK 28+. https://developer.android.com/training/testing/set-up-project\n    useLibrary 'android.test.runner'\n    useLibrary 'android.test.base'\n\n    defaultConfig {\n        minSdkVersion 5\n        testApplicationId \"org.greenrobot.greendao.perftest\"\n        testInstrumentationRunner \"android.test.InstrumentationTestRunner\"\n    }\n}\n\nuploadArchives.enabled = false\n"
  },
  {
    "path": "tests/DaoTestPerformance/src/androidTest/java/org/greenrobot/greendao/performance/Benchmark.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.performance;\n\nimport android.os.Build;\nimport android.os.SystemClock;\nimport android.util.Log;\nimport android.util.Pair;\n\nimport org.greenrobot.essentials.StringUtils;\nimport org.greenrobot.essentials.io.FileUtils;\n\nimport java.io.File;\nimport java.io.FileNotFoundException;\nimport java.io.IOException;\nimport java.text.SimpleDateFormat;\nimport java.util.ArrayList;\nimport java.util.Arrays;\nimport java.util.Date;\nimport java.util.List;\n\npublic class Benchmark {\n    public static final String TAG = \"Benchmark\";\n\n    private final List<Pair<String, String>> fixedColumns = new ArrayList<>();\n    private final List<Pair<String, String>> values = new ArrayList<>();\n    private final File file;\n    private final SimpleDateFormat dateFormat;\n    private final char separator = '\\t';\n\n    private String[] headers;\n    private boolean storeThreadTime;\n\n    private boolean started;\n    private long threadTimeMillis;\n    private long timeMillis;\n    private String name;\n    private int runs;\n    private int warmUpRuns;\n\n    public Benchmark(File file) {\n        this.file = file;\n        dateFormat = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\n        checkForLastHeader(file);\n    }\n\n    private void checkForLastHeader(File file) {\n        String contents = null;\n        try {\n            contents = FileUtils.readUtf8(file);\n        } catch (FileNotFoundException e) {\n            // OK\n        } catch (IOException e) {\n            throw new RuntimeException(e);\n        }\n        if (contents == null) {\n            return;\n        }\n\n        String[] lines = StringUtils.split(contents, '\\n');\n        for (int i = lines.length - 1; i >= 0; i--) {\n            String[] columnValues = StringUtils.split(lines[i], separator);\n            if (columnValues.length > 1) {\n                boolean longValueFound = false;\n                for (String value : columnValues) {\n                    try {\n                        Long.parseLong(value);\n                        longValueFound = true;\n                        break;\n                    } catch (NumberFormatException e) {\n                        // OK, header candidate\n                    }\n                }\n                if (!longValueFound) {\n                    headers = columnValues;\n                    break;\n                }\n            }\n        }\n    }\n\n    public Benchmark warmUpRuns(int warmUpRuns) {\n        this.warmUpRuns = warmUpRuns;\n        return this;\n    }\n\n    public Benchmark enableThreadTime() {\n        this.storeThreadTime = true;\n        return this;\n    }\n\n    public Benchmark disableThreadTime() {\n        this.storeThreadTime = false;\n        return this;\n    }\n\n    public Benchmark addFixedColumn(String key, String value) {\n        fixedColumns.add(new Pair<String, String>(key, value));\n        return this;\n    }\n\n    public Benchmark addFixedColumnDevice() {\n        addFixedColumn(\"device\", Build.MODEL);\n        return this;\n    }\n\n    public void start(String name) {\n        if (started) {\n            throw new RuntimeException(\"Already started\");\n        }\n        started = true;\n        prepareForNextRun();\n        if (values.isEmpty()) {\n            values.addAll(fixedColumns);\n            String startTime = dateFormat.format(new Date());\n            values.add(new Pair<>(\"time\", startTime));\n        }\n        this.name = name;\n        threadTimeMillis = SystemClock.currentThreadTimeMillis();\n        timeMillis = SystemClock.elapsedRealtime();\n    }\n\n    /**\n     * Try to give GC some time to settle down.\n     */\n    public void prepareForNextRun() {\n        for (int i = 0; i < 5; i++) {\n            System.gc();\n            try {\n                Thread.sleep(20);\n            } catch (InterruptedException e) {\n                e.printStackTrace();\n            }\n        }\n    }\n\n    public void stop() {\n        long time = SystemClock.elapsedRealtime() - timeMillis;\n        long timeThread = SystemClock.currentThreadTimeMillis() - threadTimeMillis;\n        if (!started) {\n            throw new RuntimeException(\"Not started\");\n        }\n        started = false;\n\n        Log.d(TAG, name + \": \" + time + \" ms (thread: \" + timeThread + \" ms)\");\n        values.add(new Pair<>(name, Long.toString(time)));\n        if (storeThreadTime) {\n            values.add(new Pair<>(name + \"-thread\", Long.toString(timeThread)));\n        }\n        name = null;\n    }\n\n    public void commit() {\n        runs++;\n        if (runs > warmUpRuns) {\n            Log.d(TAG, \"Writing results for run \" + runs);\n            String[] collectedHeaders = getAllFirsts(values);\n            if (!Arrays.equals(collectedHeaders, headers)) {\n                headers = collectedHeaders;\n                String line = StringUtils.join(headers, \"\" + separator) + '\\n';\n                try {\n                    FileUtils.appendUtf8(file, line);\n                } catch (IOException e) {\n                    throw new RuntimeException(\"Could not write header in benchmark file\", e);\n                }\n            }\n\n            StringBuilder line = new StringBuilder();\n            for (Pair<String, String> pair : values) {\n                line.append(pair.second).append(separator);\n            }\n            line.append('\\n');\n            try {\n                FileUtils.appendUtf8(file, line);\n            } catch (IOException e) {\n                throw new RuntimeException(\"Could not write header in benchmark file\", e);\n            }\n        } else {\n            Log.d(TAG, \"Ignoring results for run \" + runs + \" (warm up)\");\n        }\n        values.clear();\n    }\n\n    private String[] getAllFirsts(List<Pair<String, String>> columns) {\n        String[] firsts = new String[columns.size()];\n        for (int i = 0; i < firsts.length; i++) {\n            firsts[i] = columns.get(i).first;\n        }\n        return firsts;\n    }\n}\n"
  },
  {
    "path": "tests/DaoTestPerformance/src/androidTest/java/org/greenrobot/greendao/performance/IndexedStringPerformanceTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.performance;\n\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.daotest.IndexedStringEntity;\nimport org.greenrobot.greendao.daotest.IndexedStringEntityDao;\nimport org.greenrobot.greendao.test.AbstractDaoTest;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Stores entities with an indexed string property and measures the duration to query them by this\n * string. The generated strings are in a fixed random sequence. The strings to query for are also\n * in a fixed random sequence.\n */\npublic class IndexedStringPerformanceTest\n        extends AbstractDaoTest<IndexedStringEntityDao, IndexedStringEntity, Long> {\n\n    private static final int BATCH_SIZE = 10000;\n    private static final int QUERY_COUNT = 1000;\n    private static final int RUNS = 8;\n\n    public IndexedStringPerformanceTest() {\n        super(IndexedStringEntityDao.class, false);\n    }\n\n    public void testIndexedStringEntityQuery() {\n        // disabled for regular builds\n//        DaoLog.d(\"--------Indexed Queries: Start\");\n//        for (int i = 0; i < RUNS; i++) {\n//            DaoLog.d(\"----Run \" + (i + 1) + \" of \" + RUNS);\n//            doIndexedStringEntityQuery();\n//        }\n//        DaoLog.d(\"--------Indexed Queries: End\");\n    }\n\n    private void doIndexedStringEntityQuery() {\n        // create entities\n        List<IndexedStringEntity> entities = new ArrayList<>(BATCH_SIZE);\n        String[] fixedRandomStrings = StringGenerator.createFixedRandomStrings(BATCH_SIZE);\n        for (int i = 0; i < BATCH_SIZE; i++) {\n            IndexedStringEntity entity = new IndexedStringEntity();\n            entity.setId((long) i);\n            entity.setIndexedString(fixedRandomStrings[i]);\n            entities.add(entity);\n        }\n        DaoLog.d(\"Built entities.\");\n\n        // insert entities\n        dao.insertInTx(entities);\n        DaoLog.d(\"Inserted entities.\");\n\n        // query for entities by indexed string at random\n        int[] randomIndices = StringGenerator.getFixedRandomIndices(QUERY_COUNT, BATCH_SIZE - 1);\n\n        long start = System.currentTimeMillis();\n        for (int i = 0; i < QUERY_COUNT; i++) {\n            int nextIndex = randomIndices[i];\n            //noinspection unused\n            List<IndexedStringEntity> query = dao.queryBuilder()\n                    .where(IndexedStringEntityDao.Properties.IndexedString.eq(\n                            fixedRandomStrings[nextIndex]))\n                    .list();\n        }\n        long time = System.currentTimeMillis() - start;\n        DaoLog.d(\"Queried for \" + QUERY_COUNT + \" of \" + BATCH_SIZE + \" indexed entities in \" + time\n                + \" ms.\");\n\n        // delete all entities\n        dao.deleteAll();\n        DaoLog.d(\"Deleted all entities.\");\n    }\n}\n"
  },
  {
    "path": "tests/DaoTestPerformance/src/androidTest/java/org/greenrobot/greendao/performance/LoockupPerformanceTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.performance;\n\nimport junit.framework.TestCase;\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.internal.LongHashMap;\nimport org.greenrobot.greendao.performance.target.LongHashMapAmarena2DZechner;\nimport org.greenrobot.greendao.performance.target.LongHashMapJDBM;\nimport org.greenrobot.greendao.performance.target.LongSparseArray;\n\nimport java.util.Date;\nimport java.util.HashMap;\nimport java.util.Map;\nimport java.util.Random;\n\npublic class LoockupPerformanceTest extends TestCase {\n\n    Random random;\n    private String traceName;\n    private long start;\n\n    public LoockupPerformanceTest() {\n        this.random = new Random();\n    }\n\n    public void testHashMapPerformance() {\n        // runTests(100);\n        // runTests(1000);\n        // runTests(10000);\n        // runTests(100000); // hash: 1485/420ms; sparse: 148196/196ms\n        DaoLog.d(\"testHashMapPerformance DONE\");\n    }\n\n    private void runTests(int count) {\n        runTests(count, false);\n        runTests(count, true);\n    }\n\n    private void runTests(int count, boolean randomKeys) {\n        DaoLog.d(\"-----------------------------------\");\n        DaoLog.d(\"Look up \" + count + (randomKeys ? \" random\" : \" linear\") + \" keys on \" + new Date());\n        DaoLog.d(\"-----------------------------------\");\n        long[] keys = new long[count];\n        for (int i = 0; i < count; i++) {\n            if (randomKeys) {\n                keys[i] = random.nextLong();\n            } else {\n                keys[i] = i;\n            }\n        }\n        for (int i = 0; i < 3; i++) {\n            runMapTest(new HashMap<Long, Object>(count), keys, \"hashmap\");\n            // runMapTest(new WeakHashMap<Long, Object>(count), keys, \"weakhashmap\");\n            // runMapTest(new ConcurrentHashMap<Long, Object>(count), keys, \"concurrent-hashmap\");\n            // runLongSparseArrayTest(keys);\n            runLongHashMap(keys);\n            runLongHashMapAmarena2DZechnerTest(keys);\n            // runLongHashMapJDBMTest(keys);\n            DaoLog.d(\"-----------------------------------\");\n        }\n    }\n\n    protected void runMapTest(Map<Long, Object> map, long[] keys, String name) {\n        startClock(\"put-\" + name + \"-\" + keys.length);\n        for (long key : keys) {\n            map.put(key, this);\n        }\n        stopClock();\n\n        startClock(\"get-\" + name + \"-\" + keys.length);\n        int lossCount = 0;\n        for (long key : keys) {\n            Object object = map.get(key);\n            if (object != this) {\n                lossCount++;\n            }\n        }\n        if (lossCount > 0) {\n            stopClock(\"losses: \" + lossCount);\n        } else {\n            stopClock();\n        }\n    }\n\n    private void runLongSparseArrayTest(long[] keys) {\n        if (keys.length > 10000) {\n            DaoLog.d(\"Skipping runLongSparseArrayTest for \" + keys.length);\n            return;\n        }\n        LongSparseArray<Object> array = new LongSparseArray<Object>(keys.length);\n\n        startClock(\"put-sparsearray-\" + keys.length);\n        for (long key : keys) {\n            array.put(key, this);\n        }\n        stopClock();\n\n        startClock(\"get-sparsearray-\" + keys.length);\n        for (long key : keys) {\n            Object object = array.get(key);\n            if (object != this) {\n                fail(\"Ups: \" + object);\n            }\n        }\n        stopClock();\n    }\n\n    private void runLongHashMapJDBMTest(long[] keys) {\n        LongHashMapJDBM<Object> map = new LongHashMapJDBM<Object>(keys.length);\n\n        startClock(\"put-jdbm-\" + keys.length);\n        for (long key : keys) {\n            map.put(key, this);\n        }\n        stopClock();\n\n        startClock(\"get-jdbm-\" + keys.length);\n        for (long key : keys) {\n            Object object = map.get(key);\n            if (object != this) {\n                fail(\"Ups: \" + object);\n            }\n        }\n        stopClock();\n    }\n\n    private void runLongHashMap(long[] keys) {\n        LongHashMap<Object> map = new LongHashMap<Object>(keys.length);\n        map.reserveRoom(keys.length);\n\n        startClock(\"put-my-\" + keys.length);\n        for (long key : keys) {\n            map.put(key, this);\n        }\n        stopClock();\n\n        startClock(\"get-my-\" + keys.length);\n        for (long key : keys) {\n            Object object = map.get(key);\n            if (object != this) {\n                fail(\"Ups: \" + object);\n            }\n        }\n        stopClock();\n        map.logStats();\n    }\n\n    private void runLongHashMapAmarena2DZechnerTest(long[] keys) {\n        LongHashMapAmarena2DZechner<Object> map = new LongHashMapAmarena2DZechner<Object>(keys.length);\n\n        startClock(\"put-amarena-\" + keys.length);\n        for (long key : keys) {\n            map.put(key, this);\n        }\n        stopClock();\n\n        startClock(\"get-amarena-\" + keys.length);\n        for (long key : keys) {\n            Object object = map.get(key);\n            if (object != this) {\n                fail(\"Ups: \" + object);\n            }\n        }\n        stopClock();\n        map.logStats();\n    }\n\n    protected void startClock(String traceName) {\n        this.traceName = traceName;\n        start = System.currentTimeMillis();\n    }\n\n    protected void stopClock() {\n        stopClock(null);\n    }\n\n    protected void stopClock(String extraInfoOrNull) {\n        long time = System.currentTimeMillis() - start;\n        String extraLog = extraInfoOrNull != null ? \" (\" + extraInfoOrNull + \")\" : \"\";\n        DaoLog.d(traceName + \" completed in \" + time + \"ms\" + extraLog);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestPerformance/src/androidTest/java/org/greenrobot/greendao/performance/PerformanceTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.performance;\n\nimport android.app.Application;\nimport android.os.Debug;\nimport android.os.Environment;\n\nimport org.greenrobot.greendao.AbstractDao;\nimport org.greenrobot.greendao.DaoLog;\nimport org.greenrobot.greendao.test.AbstractDaoTest;\n\nimport java.io.File;\nimport java.util.ArrayList;\nimport java.util.Date;\nimport java.util.List;\n\npublic abstract class PerformanceTest<D extends AbstractDao<T, K>, T, K>\n        extends AbstractDaoTest<D, T, K> {\n\n    private static final int BATCH_SIZE = 10000;\n    private static final int RUNS = 10;\n\n    boolean useTraceView = false;\n    private Benchmark benchmark;\n    private ArrayList<T> entities;\n\n    public PerformanceTest(Class<D> daoClass) {\n        super(daoClass, false);\n    }\n\n    @Override\n    protected void setUp() throws Exception {\n        super.setUp();\n\n        DaoLog.d(\"####################\");\n        DaoLog.d(getClass().getSimpleName() + \": \" + BATCH_SIZE + \" entities on \" + new Date());\n        DaoLog.d(\"####################\");\n        clearIdentityScopeIfAny();\n\n        entities = new ArrayList(BATCH_SIZE);\n        for (int i = 0; i < BATCH_SIZE; i++) {\n            entities.add(createEntity());\n        }\n\n        dao.deleteAll();\n    }\n\n    // disable for regular builds\n    public void _testPerformanceOneByOne() throws Exception {\n        int count = BATCH_SIZE / 10;\n        File benchFile = getBenchFile(\"greendao-1by1-\" + count + \".tsv\");\n        benchmark = new Benchmark(benchFile);\n        benchmark.addFixedColumnDevice().warmUpRuns(2);\n        for (int i = 0; i < RUNS; i++) {\n            runOneByOneTests(entities, count, count);\n\n            startClock(\"delete-all\");\n            dao.deleteAll();\n            stopClock();\n\n            benchmark.commit();\n        }\n    }\n\n    private File getBenchFile(String name) {\n        File dir = Environment.getExternalStorageDirectory();\n        File file = new File(dir, name);\n        if (dir == null || !dir.canWrite()) {\n            Application app = createApplication(Application.class);\n            File appFile = new File(app.getFilesDir(), name);\n            DaoLog.d(\"Using file \" + appFile.getAbsolutePath() + \", (cannot write to \" + file.getAbsolutePath() + \")\");\n            file = appFile;\n        }\n        return file;\n    }\n\n    // disable for regular builds\n    public void testPerformanceBatch() throws Exception {\n        File benchFile = getBenchFile(\"greendao-batch-\" + BATCH_SIZE + \".tsv\");\n        benchmark = new Benchmark(benchFile);\n        benchmark.addFixedColumnDevice().warmUpRuns(2);\n\n        for (int i = 0; i < RUNS; i++) {\n            runBatchTests(entities);\n\n            startClock(\"delete-all\");\n            dao.deleteAll();\n            stopClock();\n\n            benchmark.commit();\n        }\n    }\n\n    protected void runOneByOneTests(List<T> list, int loadCount, int modifyCount) {\n        dao.insertInTx(list);\n        List<K> keys = new ArrayList<K>(loadCount);\n        for (int i = 0; i < loadCount; i++) {\n            keys.add(daoAccess.getKey(list.get(i)));\n        }\n        clearIdentityScopeIfAny();\n\n        list = runLoadOneByOne(keys, \"load-one-by-one-1\");\n        list = runLoadOneByOne(keys, \"load-one-by-one-2\");\n        Debug.stopMethodTracing();\n\n        dao.deleteAll();\n\n        startClock(\"insert-one-by-one\");\n        for (int i = 0; i < modifyCount; i++) {\n            dao.insert(list.get(i));\n        }\n        stopClock();\n\n        startClock(\"update-one-by-one\");\n        for (int i = 0; i < modifyCount; i++) {\n            dao.update(list.get(i));\n        }\n        stopClock();\n\n        startClock(\"delete-one-by-one\");\n        for (int i = 0; i < modifyCount; i++) {\n            dao.delete(list.get(i));\n        }\n        stopClock();\n    }\n\n    protected List<T> runLoadOneByOne(List<K> keys, String traceName) {\n        List<T> list = new ArrayList<T>(keys.size());\n        startClock(traceName);\n        for (K key : keys) {\n            list.add(dao.load(key));\n        }\n        stopClock();\n        return list;\n    }\n\n    protected void runBatchTests(List<T> list) {\n        startClock(\"insert\");\n        dao.insertInTx(list);\n        stopClock();\n\n        list = null;\n        System.gc();\n\n        clearIdentityScopeIfAny();\n        list = runLoadAll(\"load-all-1\");\n        accessAll(list, \"access-all-1\");\n        list = runLoadAll(\"load-all-2\");\n        accessAll(list, \"access-all-2\");\n\n        startClock(\"update\");\n        dao.updateInTx(list);\n        stopClock();\n    }\n\n    protected List<T> runLoadAll(String traceName) {\n        startClock(traceName);\n        List<T> list = dao.loadAll();\n        stopClock();\n        return list;\n    }\n\n    protected void startClock(String name) {\n        benchmark.start(name);\n        if (useTraceView) {\n            Debug.startMethodTracing(name);\n        }\n    }\n\n    protected void stopClock() {\n        benchmark.stop();\n        if (useTraceView) {\n            Debug.stopMethodTracing();\n        }\n    }\n\n    protected abstract T createEntity();\n\n    /**\n     * Access every property of the entity under test and record execution time with {@link\n     * #startClock(String)} and {@link #stopClock()}.\n     */\n    protected abstract void accessAll(List<T> list, String traceName);\n}\n"
  },
  {
    "path": "tests/DaoTestPerformance/src/androidTest/java/org/greenrobot/greendao/performance/PerformanceTestNotNull.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.performance;\n\nimport org.greenrobot.greendao.daotest.SimpleEntityNotNull;\nimport org.greenrobot.greendao.daotest.SimpleEntityNotNullDao;\nimport org.greenrobot.greendao.daotest.entity.SimpleEntityNotNullHelper;\n\nimport java.util.List;\n\npublic class PerformanceTestNotNull extends PerformanceTest<SimpleEntityNotNullDao, SimpleEntityNotNull, Long> {\n\n    static long sequence;\n\n    public PerformanceTestNotNull() {\n        super(SimpleEntityNotNullDao.class);\n    }\n\n    @Override\n    protected SimpleEntityNotNull createEntity() {\n        return SimpleEntityNotNullHelper.createEntity(sequence++);\n    }\n\n    @Override\n    protected void accessAll(List<SimpleEntityNotNull> list, String traceName) {\n        startClock(traceName);\n        for (int i = 0; i < list.size(); i++) {\n            SimpleEntityNotNull entity = list.get(i);\n            entity.getId();\n            entity.getSimpleBoolean();\n            entity.getSimpleByte();\n            entity.getSimpleShort();\n            entity.getSimpleInt();\n            entity.getSimpleLong();\n            entity.getSimpleFloat();\n            entity.getSimpleDouble();\n            entity.getSimpleString();\n            entity.getSimpleByteArray();\n        }\n        stopClock();\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestPerformance/src/androidTest/java/org/greenrobot/greendao/performance/PerformanceTestNotNullIdentityScope.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.performance;\n\nimport org.greenrobot.greendao.daotest.SimpleEntityNotNull;\nimport org.greenrobot.greendao.identityscope.IdentityScopeLong;\n\npublic class PerformanceTestNotNullIdentityScope extends PerformanceTestNotNull {\n\n    @Override\n    protected void setUp() throws Exception {\n        IdentityScopeLong<SimpleEntityNotNull> identityScope = new IdentityScopeLong< SimpleEntityNotNull>();\n        setIdentityScopeBeforeSetUp(identityScope);\n        super.setUp();\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestPerformance/src/androidTest/java/org/greenrobot/greendao/performance/ReflectionPerformanceTest.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.performance;\n\nimport org.greenrobot.greendao.DaoLog;\n\nimport java.lang.reflect.InvocationTargetException;\nimport java.lang.reflect.Method;\n\npublic class ReflectionPerformanceTest // extends TestCase\n{\n\n    int intValue;\n    String stringValue;\n\n    public int getIntValue() {\n        return intValue;\n    }\n\n    public void setIntValue(int inValue) {\n        this.intValue = inValue;\n    }\n\n    public String getStringValue() {\n        return stringValue;\n    }\n\n    public void setStringValue(String stringValue) {\n        this.stringValue = stringValue;\n    }\n\n    public void testSetIntPerf() throws SecurityException, NoSuchMethodException, IllegalArgumentException,\n            IllegalAccessException, InvocationTargetException {\n        int count = 100000;\n\n        long start = System.currentTimeMillis();\n        for (int i = 0; i < count; i++) {\n            setIntValue(i);\n        }\n        long time = System.currentTimeMillis() - start;\n\n        Method method = getClass().getMethod(\"setIntValue\", int.class);\n        long start2 = System.currentTimeMillis();\n        for (int i = 0; i < count; i++) {\n            method.invoke(this, i);\n        }\n        long time2 = System.currentTimeMillis() - start2;\n        DaoLog.d(\"set int: normal=\" + time + \"ms, reflected=\" + time2 + \"ms, \" + 1000 * count / time2\n                + \" refelected ops/s, slower=\" + ((float) time2) / time);\n\n    }\n\n    public void testGetIntPerf() throws SecurityException, NoSuchMethodException, IllegalArgumentException,\n            IllegalAccessException, InvocationTargetException {\n        int count = 100000;\n\n        long start = System.currentTimeMillis();\n        for (int i = 0; i < count; i++) {\n            int x = getIntValue();\n        }\n        long time = System.currentTimeMillis() - start;\n\n        Method method = getClass().getMethod(\"getIntValue\");\n        long start2 = System.currentTimeMillis();\n        for (int i = 0; i < count; i++) {\n            int x = (Integer) method.invoke(this);\n        }\n        long time2 = System.currentTimeMillis() - start2;\n        DaoLog.d(\"get int: normal=\" + time + \"ms, reflected=\" + time2 + \"ms, \" + 1000 * count / time2\n                + \" refelected ops/s, slower=\" + ((float) time2) / time);\n    }\n\n    public void testSetStringPerf() throws SecurityException, NoSuchMethodException, IllegalArgumentException,\n            IllegalAccessException, InvocationTargetException {\n        int count = 100000;\n\n        long start = System.currentTimeMillis();\n        for (int i = 0; i < count; i++) {\n            setStringValue(\"the quick brown fox\");\n        }\n        long time = System.currentTimeMillis() - start;\n\n        Method method = getClass().getMethod(\"setStringValue\", String.class);\n        long start2 = System.currentTimeMillis();\n        for (int i = 0; i < count; i++) {\n            method.invoke(this, \"the quick brown fox\");\n        }\n        long time2 = System.currentTimeMillis() - start2;\n        DaoLog.d(\"set String: normal=\" + time + \"ms, reflected=\" + time2 + \"ms, \" + 1000 * count / time2\n                + \" refelected ops/s, slower=\" + ((float) time2) / time);\n\n    }\n\n    public void testGetStringPerf() throws SecurityException, NoSuchMethodException, IllegalArgumentException,\n            IllegalAccessException, InvocationTargetException {\n        int count = 100000;\n\n        long start = System.currentTimeMillis();\n        for (int i = 0; i < count; i++) {\n            String x = getStringValue();\n        }\n        long time = System.currentTimeMillis() - start;\n\n        Method method = getClass().getMethod(\"getStringValue\");\n        long start2 = System.currentTimeMillis();\n        for (int i = 0; i < count; i++) {\n            String x = (String) method.invoke(this);\n        }\n        long time2 = System.currentTimeMillis() - start2;\n        DaoLog.d(\"get String: normal=\" + time + \"ms, reflected=\" + time2 + \"ms, \" + 1000 * count / time2\n                + \" refelected ops/s, slower=\" + ((float) time2) / time);\n    }\n}\n"
  },
  {
    "path": "tests/DaoTestPerformance/src/androidTest/java/org/greenrobot/greendao/performance/StringGenerator.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.performance;\n\nimport java.util.Random;\n\n/**\n * Helper class to generate a pre-determined set of random strings.\n */\npublic class StringGenerator {\n\n    // Fixed seed so we generate the same set of strings every time.\n    public static final long SEED = -2662502316022774L;\n    private static final int MIN_LENGTH = 5;\n    private static final int MAX_LENGTH = 500;\n    // limit to a fixed set of chars\n    private static final char[] CHARS = new char[]{'0', '1', '2', '3', '4', '5', '6', '7', '8',\n            '9', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p',\n            'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'};\n\n    /**\n     * Creates the same random sequence of strings.\n     */\n    public static String[] createFixedRandomStrings(int count) {\n        String[] strings = new String[count];\n\n        Random lengthRandom = new Random();\n        lengthRandom.setSeed(SEED);\n\n        Random stringRandom = new Random();\n        stringRandom.setSeed(SEED);\n\n        for (int i = 0; i < count; i++) {\n            int nextLength = MIN_LENGTH + lengthRandom.nextInt(MAX_LENGTH - MIN_LENGTH - 1);\n            char[] chars = new char[nextLength];\n            for (int j = 0; j < nextLength; j++) {\n                chars[j] = CHARS[stringRandom.nextInt(CHARS.length)];\n            }\n            strings[i] = new String(chars);\n        }\n        return strings;\n    }\n\n    /**\n     * Creates the same random sequence of indexes. To be used to select strings by {@link\n     * #createFixedRandomStrings(int)}.\n     */\n    public static int[] getFixedRandomIndices(int count, int maxIndex) {\n        int[] indices = new int[count];\n\n        Random random = new Random();\n        random.setSeed(StringGenerator.SEED);\n\n        for (int i = 0; i < count; i++) {\n            indices[i] = random.nextInt(maxIndex + 1);\n        }\n\n        return indices;\n    }\n}\n"
  },
  {
    "path": "tests/DaoTestPerformance/src/androidTest/java/org/greenrobot/greendao/performance/target/ArrayUtils.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.performance.target;\n\nimport java.lang.reflect.Array;\n\n// XXX these should be changed to reflect the actual memory allocator we use.\n// it looks like right now objects want to be powers of 2 minus 8\n// and the array size eats another 4 bytes\n\n/**\n * ArrayUtils contains some methods that you can call to find out\n * the most efficient increments by which to grow arrays.\n */\npublic class ArrayUtils\n{\n    private static Object[] EMPTY = new Object[0];\n    private static final int CACHE_SIZE = 73;\n    private static Object[] sCache = new Object[CACHE_SIZE];\n\n    private ArrayUtils() { /* cannot be instantiated */ }\n\n    public static int idealByteArraySize(int need) {\n        for (int i = 4; i < 32; i++)\n            if (need <= (1 << i) - 12)\n                return (1 << i) - 12;\n\n        return need;\n    }\n\n    public static int idealBooleanArraySize(int need) {\n        return idealByteArraySize(need);\n    }\n\n    public static int idealShortArraySize(int need) {\n        return idealByteArraySize(need * 2) / 2;\n    }\n\n    public static int idealCharArraySize(int need) {\n        return idealByteArraySize(need * 2) / 2;\n    }\n\n    public static int idealIntArraySize(int need) {\n        return idealByteArraySize(need * 4) / 4;\n    }\n\n    public static int idealFloatArraySize(int need) {\n        return idealByteArraySize(need * 4) / 4;\n    }\n\n    public static int idealObjectArraySize(int need) {\n        return idealByteArraySize(need * 4) / 4;\n    }\n\n    public static int idealLongArraySize(int need) {\n        return idealByteArraySize(need * 8) / 8;\n    }\n\n    /**\n     * Checks if the beginnings of two byte arrays are equal.\n     *\n     * @param array1 the first byte array\n     * @param array2 the second byte array\n     * @param length the number of bytes to check\n     * @return true if they're equal, false otherwise\n     */\n    public static boolean equals(byte[] array1, byte[] array2, int length) {\n        if (array1 == array2) {\n            return true;\n        }\n        if (array1 == null || array2 == null || array1.length < length || array2.length < length) {\n            return false;\n        }\n        for (int i = 0; i < length; i++) {\n            if (array1[i] != array2[i]) {\n                return false;\n            }\n        }\n        return true;\n    }\n\n    /**\n     * Returns an empty array of the specified type.  The intent is that\n     * it will return the same empty array every time to avoid reallocation,\n     * although this is not guaranteed.\n     */\n    public static <T> T[] emptyArray(Class<T> kind) {\n        if (kind == Object.class) {\n            return (T[]) EMPTY;\n        }\n\n        int bucket = ((System.identityHashCode(kind) / 8) & 0x7FFFFFFF) % CACHE_SIZE;\n        Object cache = sCache[bucket];\n\n        if (cache == null || cache.getClass().getComponentType() != kind) {\n            cache = Array.newInstance(kind, 0);\n            sCache[bucket] = cache;\n\n            // Log.e(\"cache\", \"new empty \" + kind.getName() + \" at \" + bucket);\n        }\n\n        return (T[]) cache;\n    }\n\n    /**\n     * Checks that value is present as at least one of the elements of the array.\n     * @param array the array to check in\n     * @param value the value to check for\n     * @return true if the value is present in the array\n     */\n    public static <T> boolean contains(T[] array, T value) {\n        for (T element : array) {\n            if (element == null) {\n                if (value == null) return true;\n            } else {\n                if (value != null && element.equals(value)) return true;\n            }\n        }\n        return false;\n    }\n}\n"
  },
  {
    "path": "tests/DaoTestPerformance/src/androidTest/java/org/greenrobot/greendao/performance/target/LongHashMapAmarena2DZechner.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.performance.target;\n\nimport org.greenrobot.greendao.DaoLog;\n\nimport java.util.Iterator;\n\n/**\n * An long to object hashmap, taken from Amarena2D (thanks Christoph :p).\n * \n * @author christop widulle\n * \n * @param <T>\n */\npublic class LongHashMapAmarena2DZechner<T> {\n\n    private Entry[] table;\n    private float loadFactor;\n    private int size, mask, capacity, threshold;\n\n    public LongHashMapAmarena2DZechner() {\n        this(16, 0.75f);\n    }\n\n    public LongHashMapAmarena2DZechner(int initialCapacity) {\n        this(initialCapacity, 0.75f);\n    }\n\n    public LongHashMapAmarena2DZechner(int initialCapacity, float loadFactor) {\n        if (initialCapacity > 1 << 30)\n            throw new IllegalArgumentException(\"initialCapacity is too large.\");\n        if (initialCapacity < 0)\n            throw new IllegalArgumentException(\"initialCapacity must be greater than zero.\");\n        if (loadFactor <= 0)\n            throw new IllegalArgumentException(\"initialCapacity must be greater than zero.\");\n        capacity = 1;\n        while (capacity < initialCapacity) {\n            capacity <<= 1;\n        }\n        this.loadFactor = loadFactor;\n        this.threshold = (int) (capacity * loadFactor);\n        this.table = new Entry[capacity];\n        this.mask = capacity - 1;\n    }\n\n    public boolean containsValue(Object value) {\n        Entry[] table = this.table;\n        for (int i = table.length; i-- > 0;)\n            for (Entry e = table[i]; e != null; e = e.next)\n                if (e.value.equals(value))\n                    return true;\n        return false;\n    }\n\n    public boolean containsKey(long key) {\n        int index = ((int) key) & mask;\n        for (Entry e = table[index]; e != null; e = e.next)\n            if (e.key == key)\n                return true;\n        return false;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public T get(long key) {\n        int index = (int) (key & mask);\n        for (Entry e = table[index]; e != null; e = e.next)\n            if (e.key == key)\n                return (T) e.value;\n        return null;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public T put(long key, T value) {\n        int index = (int) (key & mask);\n        // Check if key already exists.\n        for (Entry e = table[index]; e != null; e = e.next) {\n            if (e.key != key)\n                continue;\n            Object oldValue = e.value;\n            e.value = value;\n            return (T) oldValue;\n        }\n        table[index] = new Entry(key, value, table[index]);\n        if (size++ >= threshold) {\n            // Rehash.\n            int newCapacity = 2 * capacity;\n            Entry[] newTable = new Entry[newCapacity];\n            Entry[] src = table;\n            int bucketmask = newCapacity - 1;\n            for (int j = 0; j < src.length; j++) {\n                Entry e = src[j];\n                if (e != null) {\n                    src[j] = null;\n                    do {\n                        Entry next = e.next;\n                        index = (int) (e.key & bucketmask);\n                        e.next = newTable[index];\n                        newTable[index] = e;\n                        e = next;\n                    } while (e != null);\n                }\n            }\n            table = newTable;\n            capacity = newCapacity;\n            threshold = (int) (newCapacity * loadFactor);\n            mask = capacity - 1;\n        }\n        return null;\n    }\n\n    @SuppressWarnings(\"unchecked\")\n    public T remove(long key) {\n        int index = (int) (key & mask);\n        Entry prev = table[index];\n        Entry e = prev;\n        while (e != null) {\n            Entry next = e.next;\n            if (e.key == key) {\n                size--;\n                if (prev == e) {\n                    table[index] = next;\n                } else {\n                    prev.next = next;\n                }\n                return (T) e.value;\n            }\n            prev = e;\n            e = next;\n        }\n        return null;\n    }\n\n    public int size() {\n        return size;\n    }\n\n    public void clear() {\n        Entry[] table = this.table;\n        for (int index = table.length; --index >= 0;)\n            table[index] = null;\n        size = 0;\n    }\n\n    static class Entry {\n        final long key;\n        Object value;\n        Entry next;\n\n        Entry(long k, Object v, Entry n) {\n            key = k;\n            value = v;\n            next = n;\n        }\n    }\n\n    EntryIterable iterable = new EntryIterable();\n\n    public Iterable<T> values() {\n        iterable.reset();\n        return iterable;\n    }\n\n    class EntryIterable implements Iterable<T> {\n        int currIndex = -1;\n        Entry currEntry = null;\n\n        Iterator<T> iter = new Iterator<T>() {\n            @Override\n            public boolean hasNext() {\n                if (currEntry == null) {\n                    if (!loadNextEntry())\n                        return false;\n                } else {\n                    if (currEntry.next == null) {\n                        if (loadNextEntry() == false)\n                            return false;\n                    } else\n                        currEntry = currEntry.next;\n                }\n\n                return true;\n            }\n\n            @SuppressWarnings(\"synthetic-access\")\n            private boolean loadNextEntry() {\n                while (true) {\n                    currIndex++;\n                    if (currIndex >= table.length)\n                        return false;\n\n                    if (table[currIndex] == null)\n                        continue;\n                    else {\n                        currEntry = table[currIndex];\n                        return true;\n                    }\n                }\n            }\n\n            @SuppressWarnings(\"unchecked\")\n            @Override\n            public T next() {\n                return (T) currEntry.value;\n            }\n\n            @Override\n            public void remove() {\n                throw new UnsupportedOperationException(\"not implemented\");\n            }\n\n        };\n\n        public void reset() {\n            currIndex = -1;\n            currEntry = null;\n        }\n\n        @Override\n        public Iterator<T> iterator() {\n            return iter;\n        }\n\n    }\n\n    public void logStats() {\n        int collisions = 0;\n        for (Entry entry : table) {\n            while (entry != null && entry.next != null) {\n                collisions++;\n                entry = entry.next;\n            }\n        }\n        DaoLog.d(\"load: \" + ((float) size) / capacity + \", size: \" + size + \", capa: \" + capacity + \", collisions: \"\n                + collisions + \", collision ratio: \" + ((float) collisions) / size);\n    }\n\n}\n"
  },
  {
    "path": "tests/DaoTestPerformance/src/androidTest/java/org/greenrobot/greendao/performance/target/LongHashMapJDBM.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.performance.target;\n\nimport java.io.Serializable;\nimport java.util.Arrays;\nimport java.util.ConcurrentModificationException;\nimport java.util.Iterator;\nimport java.util.NoSuchElementException;\n\n/**\n * Hash Map which uses primitive long as key. \n * Main advantage is new instanceof of Long does not have to be created for each lookup.\n * <p>\n * This code comes from Android, which in turns comes to Apache Harmony. \n * This class was modified to use primitive longs and stripped down to consume less space. \n * <p>\n * Author of JDBM modifications: Jan Kotek\n * <p>\n * Note: This map have weakened hash function, this works well for JDBM, but may be wrong for many other applications.  \n */\npublic class LongHashMapJDBM<V> implements  Serializable {\n    private static final long serialVersionUID = 362499999763181265L;\n\n    protected int elementCount;\n\n    protected Entry<V>[] elementData;\n\n    private final float loadFactor;\n\n    protected int threshold;\n\n    transient int modCount = 0;\t\n\n    private static final int DEFAULT_SIZE = 16;\n    \n    transient Entry<V> reuseAfterDelete = null;\n\n    static final class Entry<V> {\n\n        Entry<V> next;\n\n        long key;\n        V value;\n        \n        public boolean equals(Object object) {\n            if (this == object) {\n                return true;\n            }\n            if (object instanceof Entry) {\n                Entry<?> entry = (Entry) object;\n                return ( key == entry.key)\n                        && (value == null ? entry.value == null : value\n                                .equals(entry.value));\n            }\n            return false;\n        }\n\n\n        \n        public int hashCode() {\n            return (int)(key)\n                    ^ (value == null ? 0 : value.hashCode());\n        }\n\n        \n        \n        public String toString() {\n            return key + \"=\" + value;\n        }\n        \n\n        \n        Entry(long theKey) {\n        \tthis.key = theKey;\n        \tthis.value = null;\n        }\n\n        Entry(long theKey, V theValue) {\n            this.key = theKey;\n            this.value = theValue;\n            //origKeyHash = (int)(theKey ^ (theKey >>> 32));\n        }\n\n    }\n    \n\n    interface EntryType<RT,VT> {\n        RT get(Entry<VT> entry);\n    }\n\n    static class HashMapIterator<E,VT> implements Iterator<E> {\n        private int position = 0;\n\n        int expectedModCount;\n\n        final EntryType<E, VT> type;\n\n        boolean canRemove = false;\n\n        Entry<VT> entry;\n\n        Entry<VT> lastEntry;\n\n        final LongHashMapJDBM<VT> associatedMap;\n\n        HashMapIterator(EntryType<E, VT> value, LongHashMapJDBM<VT> hm) {\n            associatedMap = hm;\n            type = value;\n            expectedModCount = hm.modCount;\n        }\n\n        public boolean hasNext() {\n            if (entry != null) {\n                return true;\n            }\n            // BEGIN android-changed\n            Entry<VT>[] elementData = associatedMap.elementData;\n            int length = elementData.length;\n            int newPosition = position;\n            boolean result = false;\n\n            while (newPosition < length) {\n                if (elementData[newPosition] == null) {\n                    newPosition++;\n                } else {\n                    result = true;\n                    break;\n                }\n            }\n\n            position = newPosition;\n            return result;\n            // END android-changed\n        }\n\n        void checkConcurrentMod() throws ConcurrentModificationException {\n            if (expectedModCount != associatedMap.modCount) {\n                throw new ConcurrentModificationException();\n            }\n        }\n\n        public E next() {\n            // BEGIN android-changed\n            // inline checkConcurrentMod()\n            if (expectedModCount != associatedMap.modCount) {\n                throw new ConcurrentModificationException();\n            }\n            if (!hasNext()) {\n                throw new NoSuchElementException();\n            }\n\n            Entry<VT> result;\n            Entry<VT> _entry  = entry;\n            if (_entry == null) {\n                result = lastEntry = associatedMap.elementData[position++];\n                entry = lastEntry.next;\n            } else {\n                if (lastEntry.next != _entry) {\n                    lastEntry = lastEntry.next;\n                }\n                result = _entry;\n                entry = _entry.next;\n            }\n            canRemove = true;\n            return type.get(result);\n            // END android-changed\n        }\n\n        public void remove() {\n            checkConcurrentMod();\n            if (!canRemove) {\n                throw new IllegalStateException();\n            }\n\n            canRemove = false;\n            associatedMap.modCount++;\n            if (lastEntry.next == entry) {\n                while (associatedMap.elementData[--position] == null) {\n                    // Do nothing\n                }\n                associatedMap.elementData[position] = associatedMap.elementData[position].next;\n                entry = null;\n            } else {\n                lastEntry.next = entry;\n            }\n            if(lastEntry!=null){\n            \tEntry<VT> reuse = lastEntry;\n            \tlastEntry = null;\n            \treuse.key = Long.MIN_VALUE;\n            \treuse.value = null;\n            \tassociatedMap.reuseAfterDelete = reuse;\n            }\n\n            associatedMap.elementCount--;\n            expectedModCount++;\n        }\n    }\n\n\n\n    @SuppressWarnings(\"unchecked\")\n    Entry<V>[] newElementArray(int s) {\n        return new Entry[s];\n    }\n\n    /**\n     * Constructs a new empty {@code HashMap} instance.\n     * \n     * @since Android 1.0\n     */\n    public LongHashMapJDBM() {\n        this(DEFAULT_SIZE);\n    }\n\n    /**\n     * Constructs a new {@code HashMap} instance with the specified capacity.\n     * \n     * @param capacity\n     *            the initial capacity of this hash map.\n     * @throws IllegalArgumentException\n     *                when the capacity is less than zero.\n     * @since Android 1.0\n     */\n    public LongHashMapJDBM(int capacity) {\n        if (capacity >= 0) {\n            elementCount = 0;\n            elementData = newElementArray(capacity == 0 ? 1 : capacity);\n            loadFactor = 0.75f; // Default load factor of 0.75\n            computeMaxSize();\n        } else {\n            throw new IllegalArgumentException();\n        }\n    }\n\n    /**\n     * Constructs a new {@code HashMap} instance with the specified capacity and\n     * load factor.\n     * \n     * @param capacity\n     *            the initial capacity of this hash map.\n     * @param loadFactor\n     *            the initial load factor.\n     * @throws IllegalArgumentException\n     *                when the capacity is less than zero or the load factor is\n     *                less or equal to zero.\n     * @since Android 1.0\n     */\n    public LongHashMapJDBM(int capacity, float loadFactor) {\n        if (capacity >= 0 && loadFactor > 0) {\n            elementCount = 0;\n            elementData = newElementArray(capacity == 0 ? 1 : capacity);\n            this.loadFactor = loadFactor;\n            computeMaxSize();\n        } else {\n            throw new IllegalArgumentException();\n        }\n    }\n\n\n\n    // BEGIN android-changed\n    /**\n     * Removes all mappings from this hash map, leaving it empty.\n     * \n     * @see #isEmpty\n     * @see #size\n     * @since Android 1.0\n     */\n    \n    public void clear() {\n        if (elementCount > 0) {\n            elementCount = 0;\n            Arrays.fill(elementData, null);\n            modCount++;\n        }\n    }\n    // END android-changed\n\n    /**\n     * Returns a shallow copy of this map.\n     * \n     * @return a shallow copy of this map.\n     * @since Android 1.0\n     */\n    \n\n    private void computeMaxSize() {\n        threshold = (int) (elementData.length * loadFactor);\n    }\n\n    /**\n     * Returns whether this map contains the specified key.\n     * \n     * @param key\n     *            the key to search for.\n     * @return {@code true} if this map contains the specified key,\n     *         {@code false} otherwise.\n     * @since Android 1.0\n     */\n    \n    public boolean containsKey(long key) {\n            int hash = (int)(key);\n            int index = (hash & 0x7FFFFFFF) % elementData.length;\n            Entry<V> m = findNonNullKeyEntry(key, index, hash);\n        return m != null;\n    }\n\n    /**\n     * Returns whether this map contains the specified value.\n     * \n     * @param value\n     *            the value to search for.\n     * @return {@code true} if this map contains the specified value,\n     *         {@code false} otherwise.\n     * @since Android 1.0\n     */\n    \n    public boolean containsValue(Object value) {\n        if (value != null) {\n            for (int i = elementData.length; --i >= 0;) {\n                Entry<V> entry = elementData[i];\n                while (entry != null) {\n                    if (value.equals(entry.value)) {\n                        return true;\n                    }\n                    entry = entry.next;\n                }\n            }\n        } else {\n            for (int i = elementData.length; --i >= 0;) {\n                Entry<V> entry = elementData[i];\n                while (entry != null) {\n                    if (entry.value == null) {\n                        return true;\n                    }\n                    entry = entry.next;\n                }\n            }\n        }\n        return false;\n    }\n\n\n    /**\n     * Returns the value of the mapping with the specified key.\n     * \n     * @param key\n     *            the key.\n     * @return the value of the mapping with the specified key, or {@code null}\n     *         if no mapping for the specified key is found.\n     * @since Android 1.0\n     */\n    \n    public V get(long key) {\n        Entry<V> m;\n        int hash = (int)(key);\n        int index = (hash & 0x7FFFFFFF) % elementData.length;\n        m = findNonNullKeyEntry(key, index, hash);\n\n        if (m != null) {\n            return m.value;\n        }\n        return null;\n    }\n\n    final Entry<V> findNonNullKeyEntry(long key, int index, int keyHash) {\n        Entry<V> m = elementData[index];\n            while (m != null) {\n\n                    if (key == m.key) {\n                        return m;\n                    }\n\n                m = m.next;\n\n        }\n        return null;\n    }\n\n\n    /**\n     * Returns whether this map is empty.\n     * \n     * @return {@code true} if this map has no elements, {@code false}\n     *         otherwise.\n     * @see #size()\n     * @since Android 1.0\n     */\n    \n    public boolean isEmpty() {\n        return elementCount == 0;\n    }\n\n    /**\n     * @return iterator over keys\n     */\n    \n//      public Iterator<K> keyIterator(){\n//                 return new HashMapIterator<K, K, V>(\n//                            new MapEntry.Type<K, K, V>() {\n//                                public K get(Entry<K, V> entry) {\n//                                    return entry.key;\n//                                }\n//                            }, HashMap.this);\n//\n//     }\n\n    /**\n     * Maps the specified key to the specified value.\n     * \n     * @param key\n     *            the key.\n     * @param value\n     *            the value.\n     * @return the value of any previous mapping with the specified key or\n     *         {@code null} if there was no such mapping.\n     * @since Android 1.0\n     */\n    \n\n    public V put(long key, V value) {\n        Entry<V> entry;\n            int hash =(int)(key);\n            int index = (hash & 0x7FFFFFFF) % elementData.length;\n            entry = findNonNullKeyEntry(key, index, hash);\n            if (entry == null) {\n                modCount++;\n                if (++elementCount > threshold) {\n                    rehash();\n                    index = (hash & 0x7FFFFFFF) % elementData.length;\n                }\n                entry = createHashedEntry(key, index);\n            }\n\n\n        V result = entry.value;\n        entry.value = value;\n        return result;\n    }\n\n    Entry<V> createEntry(long key, int index, V value) {\n        Entry<V> entry = reuseAfterDelete; \n        if(entry == null){ \n        \tentry = new Entry<V>(key, value);\n        }else{\n        \treuseAfterDelete = null;\n        \tentry.key = key;\n        \tentry.value = value;\n        }\n        \n        entry.next = elementData[index];\n        elementData[index] = entry;\n        return entry;\n    }\n\n    Entry<V> createHashedEntry(long key, int index) {\n        Entry<V> entry = reuseAfterDelete; \n        if(entry == null) {\n        \tentry = new Entry<V>(key);\n        }else{\n        \treuseAfterDelete = null;\n        \tentry.key = key;\n        \tentry.value = null;\n        }\n\n        entry.next = elementData[index];\n        elementData[index] = entry;\n        return entry;\n    }\n\n\n    void rehash(int capacity) {\n        int length = (capacity == 0 ? 1 : capacity << 1);\n\n        Entry<V>[] newData = newElementArray(length);\n        for (int i = 0; i < elementData.length; i++) {\n            Entry<V> entry = elementData[i];\n            while (entry != null) {\n                int index = ((int)entry.key & 0x7FFFFFFF) % length;\n                Entry<V> next = entry.next;\n                entry.next = newData[index];\n                newData[index] = entry;\n                entry = next;\n            }\n        }\n        elementData = newData;\n        computeMaxSize();\n    }\n\n    void rehash() {\n        rehash(elementData.length);\n    }\n\n    /**\n     * Removes the mapping with the specified key from this map.\n     * \n     * @param key\n     *            the key of the mapping to remove.\n     * @return the value of the removed mapping or {@code null} if no mapping\n     *         for the specified key was found.\n     * @since Android 1.0\n     */\n    \n    public V remove(long key) {\n        Entry<V> entry = removeEntry(key);\n        if(entry == null)\n        \treturn null;\n        V ret = entry.value;\n        entry.value = null;\n        entry.key = Long.MIN_VALUE;\n        reuseAfterDelete = entry;\n        \n        return ret;\n    }\n\n    Entry<V> removeEntry(long key) {\n        int index = 0;\n        Entry<V> entry;\n        Entry<V> last = null;\n\n        int hash = (int)(key);\n        index = (hash & 0x7FFFFFFF) % elementData.length;\n        entry = elementData[index];\n         while (entry != null && !(/*((int)entry.key) == hash &&*/ key == entry.key)) {\n             last = entry;\n              entry = entry.next;\n         }\n         \n         if (entry == null) {\n             return null;\n         }\n         \n        if (last == null) {\n            elementData[index] = entry.next;\n        } else {\n            last.next = entry.next;\n        }\n        modCount++;\n        elementCount--;\n        return entry;\n    }\n\n    /**\n     * Returns the number of elements in this map.\n     * \n     * @return the number of elements in this map.\n     * @since Android 1.0\n     */\n    \n    public int size() {\n        return elementCount;\n    }\n\n    /**\n     * @returns iterator over values in map\n     */\n    public Iterator<V> valuesIterator() {\n        return new HashMapIterator<V, V>(\n                new EntryType<V,  V>() {\n                    public V get(Entry< V> entry) {\n                        return entry.value;\n                    }\n                }, LongHashMapJDBM.this);\n\n    }\n\n\n}\n\n\n\n"
  },
  {
    "path": "tests/DaoTestPerformance/src/androidTest/java/org/greenrobot/greendao/performance/target/LongSparseArray.java",
    "content": "/*\n * Copyright (C) 2011-2016 Markus Junginger, greenrobot (http://greenrobot.org)\n *\n * This file is part of greenDAO Generator.\n *\n * greenDAO Generator is free software: you can redistribute it and/or modify\n * it under the terms of the GNU General Public License as published by\n * the Free Software Foundation, either version 3 of the License, or\n * (at your option) any later version.\n * greenDAO Generator is distributed in the hope that it will be useful,\n * but WITHOUT ANY WARRANTY; without even the implied warranty of\n * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\n * GNU General Public License for more details.\n *\n * You should have received a copy of the GNU General Public License\n * along with greenDAO Generator.  If not, see <http://www.gnu.org/licenses/>.\n */\n\npackage org.greenrobot.greendao.performance.target;\n\nimport android.util.Log;\n\n/**\n * SparseArrays map longs to Objects.  Unlike a normal array of Objects,\n * there can be gaps in the indices.  It is intended to be more efficient\n * than using a HashMap to map Longs to Objects.\n *\n * @hide\n */\npublic class LongSparseArray<E> {\n    private static final Object DELETED = new Object();\n    private boolean mGarbage = false;\n\n    /**\n     * Creates a new SparseArray containing no mappings.\n     */\n    public LongSparseArray() {\n        this(10);\n    }\n\n    /**\n     * Creates a new SparseArray containing no mappings that will not\n     * require any additional memory allocation to store the specified\n     * number of mappings.\n     */\n    public LongSparseArray(int initialCapacity) {\n        initialCapacity = ArrayUtils.idealIntArraySize(initialCapacity);\n\n        mKeys = new long[initialCapacity];\n        mValues = new Object[initialCapacity];\n        mSize = 0;\n    }\n    \n    /**\n     * @return A copy of all keys contained in the sparse array.\n     */\n    public long[] getKeys() {\n        int length = mKeys.length;\n        long[] result = new long[length];\n        System.arraycopy(mKeys, 0, result, 0, length);\n        return result;\n    }\n    \n    /**\n     * Sets all supplied keys to the given unique value.\n     * @param keys Keys to set\n     * @param uniqueValue Value to set all supplied keys to\n     */\n    public void setValues(long[] keys, E uniqueValue) {\n        int length = keys.length;\n        for (int i = 0; i < length; i++) {\n            put(keys[i], uniqueValue);\n        }\n    }\n\n    /**\n     * Gets the Object mapped from the specified key, or <code>null</code>\n     * if no such mapping has been made.\n     */\n    public E get(long key) {\n        return get(key, null);\n    }\n\n    /**\n     * Gets the Object mapped from the specified key, or the specified Object\n     * if no such mapping has been made.\n     */\n    public E get(long key, E valueIfKeyNotFound) {\n        int i = binarySearch(mKeys, 0, mSize, key);\n\n        if (i < 0 || mValues[i] == DELETED) {\n            return valueIfKeyNotFound;\n        } else {\n            return (E) mValues[i];\n        }\n    }\n\n    /**\n     * Removes the mapping from the specified key, if there was any.\n     */\n    public void delete(long key) {\n        int i = binarySearch(mKeys, 0, mSize, key);\n\n        if (i >= 0) {\n            if (mValues[i] != DELETED) {\n                mValues[i] = DELETED;\n                mGarbage = true;\n            }\n        }\n    }\n\n    /**\n     * Alias for {@link #delete(long)}.\n     */\n    public void remove(long key) {\n        delete(key);\n    }\n\n    private void gc() {\n        // Log.e(\"SparseArray\", \"gc start with \" + mSize);\n\n        int n = mSize;\n        int o = 0;\n        long[] keys = mKeys;\n        Object[] values = mValues;\n\n        for (int i = 0; i < n; i++) {\n            Object val = values[i];\n\n            if (val != DELETED) {\n                if (i != o) {\n                    keys[o] = keys[i];\n                    values[o] = val;\n                }\n\n                o++;\n            }\n        }\n\n        mGarbage = false;\n        mSize = o;\n\n        // Log.e(\"SparseArray\", \"gc end with \" + mSize);\n    }\n\n    /**\n     * Adds a mapping from the specified key to the specified value,\n     * replacing the previous mapping from the specified key if there\n     * was one.\n     */\n    public void put(long key, E value) {\n        int i = binarySearch(mKeys, 0, mSize, key);\n\n        if (i >= 0) {\n            mValues[i] = value;\n        } else {\n            i = ~i;\n\n            if (i < mSize && mValues[i] == DELETED) {\n                mKeys[i] = key;\n                mValues[i] = value;\n                return;\n            }\n\n            if (mGarbage && mSize >= mKeys.length) {\n                gc();\n\n                // Search again because indices may have changed.\n                i = ~binarySearch(mKeys, 0, mSize, key);\n            }\n\n            if (mSize >= mKeys.length) {\n                int n = ArrayUtils.idealIntArraySize(mSize + 1);\n\n                long[] nkeys = new long[n];\n                Object[] nvalues = new Object[n];\n\n                // Log.e(\"SparseArray\", \"grow \" + mKeys.length + \" to \" + n);\n                System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);\n                System.arraycopy(mValues, 0, nvalues, 0, mValues.length);\n\n                mKeys = nkeys;\n                mValues = nvalues;\n            }\n\n            if (mSize - i != 0) {\n                // Log.e(\"SparseArray\", \"move \" + (mSize - i));\n                System.arraycopy(mKeys, i, mKeys, i + 1, mSize - i);\n                System.arraycopy(mValues, i, mValues, i + 1, mSize - i);\n            }\n\n            mKeys[i] = key;\n            mValues[i] = value;\n            mSize++;\n        }\n    }\n\n    /**\n     * Returns the number of key-value mappings that this SparseArray\n     * currently stores.\n     */\n    public int size() {\n        if (mGarbage) {\n            gc();\n        }\n\n        return mSize;\n    }\n\n    /**\n     * Given an index in the range <code>0...size()-1</code>, returns\n     * the key from the <code>index</code>th key-value mapping that this\n     * SparseArray stores.\n     */\n    public long keyAt(int index) {\n        if (mGarbage) {\n            gc();\n        }\n\n        return mKeys[index];\n    }\n\n    /**\n     * Given an index in the range <code>0...size()-1</code>, returns\n     * the value from the <code>index</code>th key-value mapping that this\n     * SparseArray stores.\n     */\n    public E valueAt(int index) {\n        if (mGarbage) {\n            gc();\n        }\n\n        return (E) mValues[index];\n    }\n\n    /**\n     * Given an index in the range <code>0...size()-1</code>, sets a new\n     * value for the <code>index</code>th key-value mapping that this\n     * SparseArray stores.\n     */\n    public void setValueAt(int index, E value) {\n        if (mGarbage) {\n            gc();\n        }\n\n        mValues[index] = value;\n    }\n\n    /**\n     * Returns the index for which {@link #keyAt} would return the\n     * specified key, or a negative number if the specified\n     * key is not mapped.\n     */\n    public int indexOfKey(long key) {\n        if (mGarbage) {\n            gc();\n        }\n\n        return binarySearch(mKeys, 0, mSize, key);\n    }\n\n    /**\n     * Returns an index for which {@link #valueAt} would return the\n     * specified key, or a negative number if no keys map to the\n     * specified value.\n     * Beware that this is a linear search, unlike lookups by key,\n     * and that multiple keys can map to the same value and this will\n     * find only one of them.\n     */\n    public int indexOfValue(E value) {\n        if (mGarbage) {\n            gc();\n        }\n\n        for (int i = 0; i < mSize; i++)\n            if (mValues[i] == value)\n                return i;\n\n        return -1;\n    }\n\n    /**\n     * Removes all key-value mappings from this SparseArray.\n     */\n    public void clear() {\n        int n = mSize;\n        Object[] values = mValues;\n\n        for (int i = 0; i < n; i++) {\n            values[i] = null;\n        }\n\n        mSize = 0;\n        mGarbage = false;\n    }\n\n    /**\n     * Puts a key/value pair into the array, optimizing for the case where\n     * the key is greater than all existing keys in the array.\n     */\n    public void append(long key, E value) {\n        if (mSize != 0 && key <= mKeys[mSize - 1]) {\n            put(key, value);\n            return;\n        }\n\n        if (mGarbage && mSize >= mKeys.length) {\n            gc();\n        }\n\n        int pos = mSize;\n        if (pos >= mKeys.length) {\n            int n = ArrayUtils.idealIntArraySize(pos + 1);\n\n            long[] nkeys = new long[n];\n            Object[] nvalues = new Object[n];\n\n            // Log.e(\"SparseArray\", \"grow \" + mKeys.length + \" to \" + n);\n            System.arraycopy(mKeys, 0, nkeys, 0, mKeys.length);\n            System.arraycopy(mValues, 0, nvalues, 0, mValues.length);\n\n            mKeys = nkeys;\n            mValues = nvalues;\n        }\n\n        mKeys[pos] = key;\n        mValues[pos] = value;\n        mSize = pos + 1;\n    }\n\n    private static int binarySearch(long[] a, int start, int len, long key) {\n        int high = start + len, low = start - 1, guess;\n\n        while (high - low > 1) {\n            guess = (high + low) / 2;\n\n            if (a[guess] < key)\n                low = guess;\n            else\n                high = guess;\n        }\n\n        if (high == start + len)\n            return ~(start + len);\n        else if (a[high] == key)\n            return high;\n        else\n            return ~high;\n    }\n\n    private void checkIntegrity() {\n        for (int i = 1; i < mSize; i++) {\n            if (mKeys[i] <= mKeys[i - 1]) {\n                for (int j = 0; j < mSize; j++) {\n                    Log.e(\"FAIL\", j + \": \" + mKeys[j] + \" -> \" + mValues[j]);\n                }\n\n                throw new RuntimeException();\n            }\n        }\n    }\n\n    private long[] mKeys;\n    private Object[] mValues;\n    private int mSize;\n}"
  },
  {
    "path": "tests/DaoTestPerformance/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"org.greenrobot.daotest.dummyapp\"\n    android:versionCode=\"1\"\n    android:versionName=\"1.0\" >\n\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n\n    <application>\n        <uses-library android:name=\"android.test.runner\" />\n    </application>\n\n</manifest>"
  }
]