Merge "Revert "Allow collection type converters in query parameters"" into oc-mr1-support-27.0-dev
am: 7fa8eb8a64

Change-Id: I73cce00067d793ca7bbe9f63c8bbf926d8fdd77c
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/element_ext.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/element_ext.kt
index e9245cc..5f61e21 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/element_ext.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/ext/element_ext.kt
@@ -30,10 +30,7 @@
 import javax.lang.model.element.VariableElement
 import javax.lang.model.type.TypeKind
 import javax.lang.model.type.TypeMirror
-import javax.lang.model.type.WildcardType
 import javax.lang.model.util.SimpleAnnotationValueVisitor6
-import javax.lang.model.util.SimpleTypeVisitor7
-import javax.lang.model.util.Types
 import kotlin.reflect.KClass
 
 fun Element.hasAnyOf(vararg modifiers: Modifier): Boolean {
@@ -164,50 +161,3 @@
 fun AnnotationValue.getAsStringList(): List<String> {
     return ANNOTATION_VALUE_STRING_ARR_VISITOR.visit(this)
 }
-
-// a variant of Types.isAssignable that ignores variance.
-fun Types.isAssignableWithoutVariance(from: TypeMirror, to: TypeMirror): Boolean {
-    val assignable = isAssignable(from, to)
-    if (assignable) {
-        return true
-    }
-    if (from.kind != TypeKind.DECLARED || to.kind != TypeKind.DECLARED) {
-        return false
-    }
-    val declaredFrom = MoreTypes.asDeclared(from)
-    val declaredTo = MoreTypes.asDeclared(to)
-    val fromTypeArgs = declaredFrom.typeArguments
-    val toTypeArgs = declaredTo.typeArguments
-    // no type arguments, we don't need extra checks
-    if (fromTypeArgs.isEmpty() || fromTypeArgs.size != toTypeArgs.size) {
-        return false
-    }
-    // check erasure version first, if it does not match, no reason to proceed
-    if (!isAssignable(erasure(from), erasure(to))) {
-        return false
-    }
-    // convert from args to their upper bounds if it exists
-    val fromUpperBounds = fromTypeArgs.map {
-        it.getUpperBound()
-    }
-    // if there are no upper bound conversions, return.
-    if (fromUpperBounds.all { it == null }) {
-        return false
-    }
-    // try to move the types of the from to their upper bounds. It does not matter for the "to"
-    // because Types.isAssignable handles it as it is valid java
-    return (0 until fromTypeArgs.size).all { index ->
-        isAssignableWithoutVariance(
-                from = fromUpperBounds[index] ?: fromTypeArgs[index],
-                to = toTypeArgs[index])
-    }
-}
-
-// converts ? in Set< ? extends Foo> to Foo
-private fun TypeMirror.getUpperBound(): TypeMirror? {
-    return this.accept(object : SimpleTypeVisitor7<TypeMirror, Void?>() {
-        override fun visitWildcard(type: WildcardType, ignored: Void?): TypeMirror {
-            return type.extendsBound
-        }
-    }, null)
-}
\ No newline at end of file
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/PojoProcessor.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/PojoProcessor.kt
index f3b505d..cb63b6d 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/PojoProcessor.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/processor/PojoProcessor.kt
@@ -26,7 +26,6 @@
 import android.arch.persistence.room.ext.getAsStringList
 import android.arch.persistence.room.ext.hasAnnotation
 import android.arch.persistence.room.ext.hasAnyOf
-import android.arch.persistence.room.ext.isAssignableWithoutVariance
 import android.arch.persistence.room.ext.isCollection
 import android.arch.persistence.room.ext.toClassType
 import android.arch.persistence.room.processor.ProcessorErrors.CANNOT_FIND_GETTER_FOR_FIELD
@@ -217,8 +216,7 @@
                     } else if (!field.nameWithVariations.contains(paramName)) {
                         false
                     } else {
-                        // see: b/69164099
-                        typeUtils.isAssignableWithoutVariance(paramType, field.type)
+                        typeUtils.isAssignable(paramType, field.type)
                     }
                 }
 
@@ -557,8 +555,7 @@
 
         val matching = candidates
                 .filter {
-                    // b/69164099
-                    types.isAssignableWithoutVariance(getType(it), field.element.asType())
+                    types.isAssignable(getType(it), field.element.asType())
                             && (field.nameWithVariations.contains(it.simpleName.toString())
                             || nameVariations.contains(it.simpleName.toString()))
                 }
diff --git a/room/compiler/src/main/kotlin/android/arch/persistence/room/solver/TypeAdapterStore.kt b/room/compiler/src/main/kotlin/android/arch/persistence/room/solver/TypeAdapterStore.kt
index d64300c..dcd5ee6 100644
--- a/room/compiler/src/main/kotlin/android/arch/persistence/room/solver/TypeAdapterStore.kt
+++ b/room/compiler/src/main/kotlin/android/arch/persistence/room/solver/TypeAdapterStore.kt
@@ -362,14 +362,8 @@
                 || MoreTypes.isTypeOf(java.util.Set::class.java, typeMirror))) {
             val declared = MoreTypes.asDeclared(typeMirror)
             val binder = findStatementValueBinder(declared.typeArguments.first(),
-                    null)
-            if (binder != null) {
-                return CollectionQueryParameterAdapter(binder)
-            } else {
-                // maybe user wants to convert this collection themselves. look for a match
-                val collectionBinder = findStatementValueBinder(typeMirror, null) ?: return null
-                return BasicQueryParameterAdapter(collectionBinder)
-            }
+                    null) ?: return null
+            return CollectionQueryParameterAdapter(binder)
         } else if (typeMirror is ArrayType && typeMirror.componentType.kind != TypeKind.BYTE) {
             val component = typeMirror.componentType
             val binder = findStatementValueBinder(component, null) ?: return null
@@ -445,10 +439,8 @@
     private fun getAllTypeConverters(input: TypeMirror, excludes: List<TypeMirror>):
             List<TypeConverter> {
         val types = context.processingEnv.typeUtils
-        // for input, check assignability because it defines whether we can use the method or not.
-        // for excludes, use exact match
         return typeConverters.filter { converter ->
-            types.isAssignable(input, converter.from) &&
+            types.isSameType(input, converter.from) &&
                     !excludes.any { types.isSameType(it, converter.to) }
         }
     }
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/solver/CustomTypeConverterResolutionTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/solver/CustomTypeConverterResolutionTest.kt
index ae635b2..d9b4997 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/solver/CustomTypeConverterResolutionTest.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/solver/CustomTypeConverterResolutionTest.kt
@@ -39,7 +39,6 @@
 import com.squareup.javapoet.FieldSpec
 import com.squareup.javapoet.MethodSpec
 import com.squareup.javapoet.ParameterSpec
-import com.squareup.javapoet.ParameterizedTypeName
 import com.squareup.javapoet.TypeName
 import com.squareup.javapoet.TypeSpec
 import org.junit.Test
@@ -84,26 +83,6 @@
                     }
                 }
                 """)
-        val CUSTOM_TYPE_SET = ParameterizedTypeName.get(
-                ClassName.get(Set::class.java), CUSTOM_TYPE)
-        val CUSTOM_TYPE_SET_CONVERTER = ClassName.get("foo.bar", "MySetConverter")
-        val CUSTOM_TYPE_SET_CONVERTER_JFO = JavaFileObjects.forSourceLines(
-                CUSTOM_TYPE_SET_CONVERTER.toString(),
-                """
-                package ${CUSTOM_TYPE_SET_CONVERTER.packageName()};
-                import java.util.HashSet;
-                import java.util.Set;
-                public class ${CUSTOM_TYPE_SET_CONVERTER.simpleName()} {
-                    @${TypeConverter::class.java.canonicalName}
-                    public static $CUSTOM_TYPE_SET toCustom(int value) {
-                        return null;
-                    }
-                    @${TypeConverter::class.java.canonicalName}
-                    public static int fromCustom($CUSTOM_TYPE_SET input) {
-                        return 0;
-                    }
-                }
-                """)
     }
 
     @Test
@@ -115,36 +94,6 @@
     }
 
     @Test
-    fun collection_forEntity() {
-        val entity = createEntity(
-                hasCustomField = true,
-                useCollection = true)
-        val database = createDatabase(
-                hasConverters = true,
-                hasDao = true,
-                useCollection = true)
-        val dao = createDao(
-                hasQueryWithCustomParam = false,
-                useCollection = true)
-        run(entity.toJFO(), dao.toJFO(), database.toJFO()).compilesWithoutError()
-    }
-
-    @Test
-    fun collection_forDao() {
-        val entity = createEntity(
-                hasCustomField = true,
-                useCollection = true)
-        val database = createDatabase(
-                hasConverters = true,
-                hasDao = true,
-                useCollection = true)
-        val dao = createDao(
-                hasQueryWithCustomParam = true,
-                useCollection = true)
-        run(entity.toJFO(), dao.toJFO(), database.toJFO()).compilesWithoutError()
-    }
-
-    @Test
     fun useFromDatabase_forQueryParameter() {
         val entity = createEntity()
         val database = createDatabase(hasConverters = true, hasDao = true)
@@ -221,29 +170,21 @@
 
     fun run(vararg jfos: JavaFileObject): CompileTester {
         return Truth.assertAbout(JavaSourcesSubjectFactory.javaSources())
-                .that(jfos.toList() + CUSTOM_TYPE_JFO + CUSTOM_TYPE_CONVERTER_JFO
-                        + CUSTOM_TYPE_SET_CONVERTER_JFO)
+                .that(jfos.toList() + CUSTOM_TYPE_JFO + CUSTOM_TYPE_CONVERTER_JFO)
                 .processedWith(RoomProcessor())
     }
 
-    private fun createEntity(
-            hasCustomField: Boolean = false,
-            hasConverters: Boolean = false,
-            hasConverterOnField: Boolean = false,
-            useCollection: Boolean = false): TypeSpec {
+    private fun createEntity(hasCustomField: Boolean = false,
+                             hasConverters: Boolean = false,
+                             hasConverterOnField: Boolean = false): TypeSpec {
         if (hasConverterOnField && hasConverters) {
             throw IllegalArgumentException("cannot have both converters")
         }
-        val type = if (useCollection) {
-            CUSTOM_TYPE_SET
-        } else {
-            CUSTOM_TYPE
-        }
         return TypeSpec.classBuilder(ENTITY).apply {
             addAnnotation(Entity::class.java)
             addModifiers(Modifier.PUBLIC)
             if (hasCustomField) {
-                addField(FieldSpec.builder(type, "myCustomField", Modifier.PUBLIC).apply {
+                addField(FieldSpec.builder(CUSTOM_TYPE, "myCustomField", Modifier.PUBLIC).apply {
                     if (hasConverterOnField) {
                         addAnnotation(createConvertersAnnotation())
                     }
@@ -258,15 +199,13 @@
         }.build()
     }
 
-    private fun createDatabase(
-            hasConverters: Boolean = false,
-            hasDao: Boolean = false,
-            useCollection: Boolean = false): TypeSpec {
+    private fun createDatabase(hasConverters: Boolean = false,
+                               hasDao: Boolean = false): TypeSpec {
         return TypeSpec.classBuilder(DB).apply {
             addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC)
             superclass(RoomTypeNames.ROOM_DB)
             if (hasConverters) {
-                addAnnotation(createConvertersAnnotation(useCollection = useCollection))
+                addAnnotation(createConvertersAnnotation())
             }
             addField(FieldSpec.builder(TypeName.INT, "id", Modifier.PUBLIC).apply {
                 addAnnotation(PrimaryKey::class.java)
@@ -286,13 +225,11 @@
         }.build()
     }
 
-    private fun createDao(
-            hasConverters: Boolean = false,
-            hasQueryReturningEntity: Boolean = false,
-            hasQueryWithCustomParam: Boolean = false,
-            hasMethodConverters: Boolean = false,
-            hasParameterConverters: Boolean = false,
-            useCollection: Boolean = false): TypeSpec {
+    private fun createDao(hasConverters: Boolean = false,
+                          hasQueryReturningEntity: Boolean = false,
+                          hasQueryWithCustomParam: Boolean = false,
+                          hasMethodConverters: Boolean = false,
+                          hasParameterConverters: Boolean = false): TypeSpec {
         val annotationCount = listOf(hasMethodConverters, hasConverters, hasParameterConverters)
                 .map { if (it) 1 else 0 }.sum()
         if (annotationCount > 1) {
@@ -305,7 +242,7 @@
             addAnnotation(Dao::class.java)
             addModifiers(Modifier.ABSTRACT, Modifier.PUBLIC)
             if (hasConverters) {
-                addAnnotation(createConvertersAnnotation(useCollection = useCollection))
+                addAnnotation(createConvertersAnnotation())
             }
             if (hasQueryReturningEntity) {
                 addMethod(MethodSpec.methodBuilder("loadAll").apply {
@@ -316,23 +253,18 @@
                     returns(ENTITY)
                 }.build())
             }
-            val customType = if (useCollection) {
-                CUSTOM_TYPE_SET
-            } else {
-                CUSTOM_TYPE
-            }
             if (hasQueryWithCustomParam) {
                 addMethod(MethodSpec.methodBuilder("queryWithCustom").apply {
                     addAnnotation(AnnotationSpec.builder(Query::class.java).apply {
                         addMember("value", S, "SELECT COUNT(*) FROM ${ENTITY.simpleName()} where" +
-                                " id = :custom")
+                                " id IN(:customs)")
                     }.build())
                     if (hasMethodConverters) {
-                        addAnnotation(createConvertersAnnotation(useCollection = useCollection))
+                        addAnnotation(createConvertersAnnotation())
                     }
-                    addParameter(ParameterSpec.builder(customType, "custom").apply {
+                    addParameter(ParameterSpec.builder(CUSTOM_TYPE, "customs").apply {
                         if (hasParameterConverters) {
-                            addAnnotation(createConvertersAnnotation(useCollection = useCollection))
+                            addAnnotation(createConvertersAnnotation())
                         }
                     }.build())
                     addModifiers(Modifier.ABSTRACT)
@@ -342,13 +274,8 @@
         }.build()
     }
 
-    private fun createConvertersAnnotation(useCollection: Boolean = false): AnnotationSpec {
-        val converter = if (useCollection) {
-            CUSTOM_TYPE_SET_CONVERTER
-        } else {
-            CUSTOM_TYPE_CONVERTER
-        }
+    private fun createConvertersAnnotation(): AnnotationSpec {
         return AnnotationSpec.builder(TypeConverters::class.java)
-                .addMember("value", "$T.class", converter).build()
+                .addMember("value", "$T.class", CUSTOM_TYPE_CONVERTER).build()
     }
 }
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/solver/TypeAssignmentTest.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/solver/TypeAssignmentTest.kt
deleted file mode 100644
index 0945ae1..0000000
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/solver/TypeAssignmentTest.kt
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.arch.persistence.room.solver
-
-import android.arch.persistence.room.ext.getAllFieldsIncludingPrivateSupers
-import android.arch.persistence.room.ext.isAssignableWithoutVariance
-import android.arch.persistence.room.testing.TestInvocation
-import com.google.testing.compile.JavaFileObjects
-import org.hamcrest.CoreMatchers.`is`
-import org.hamcrest.MatcherAssert.assertThat
-import org.junit.Test
-import simpleRun
-import javax.annotation.processing.ProcessingEnvironment
-import javax.lang.model.element.TypeElement
-import javax.lang.model.element.VariableElement
-
-class TypeAssignmentTest {
-    companion object {
-        private val TEST_OBJECT = JavaFileObjects.forSourceString("foo.bar.MyObject",
-                """
-            package foo.bar;
-            import java.util.Set;
-            import java.util.HashSet;
-            class MyObject {
-                String mString;
-                Integer mInteger;
-                Set<MyObject> mSet;
-                Set<? extends MyObject> mVarianceSet;
-                HashSet<MyObject> mHashSet;
-            }
-            """.trimIndent())
-    }
-
-    @Test
-    fun basic() {
-        runTest {
-            val testObject = typeElement("foo.bar.MyObject")
-            val string = testObject.getField(processingEnv, "mString")
-            val integer = testObject.getField(processingEnv, "mInteger")
-            assertThat(typeUtils.isAssignableWithoutVariance(string.asType(),
-                    integer.asType()),
-                    `is`(false))
-        }
-    }
-
-    @Test
-    fun generics() {
-        runTest {
-            val testObject = typeElement("foo.bar.MyObject")
-            val set = testObject.getField(processingEnv, "mSet").asType()
-            val hashSet = testObject.getField(processingEnv, "mHashSet").asType()
-            assertThat(typeUtils.isAssignableWithoutVariance(
-                    from = set,
-                    to = hashSet
-            ), `is`(false))
-            assertThat(typeUtils.isAssignableWithoutVariance(
-                    from = hashSet,
-                    to = set
-            ), `is`(true))
-        }
-    }
-
-    @Test
-    fun variance() {
-        /**
-         *  Set<User> userSet = null;
-         *  Set<? extends User> userSet2 = null;
-         *  userSet = userSet2;  // NOT OK for java but kotlin data classes hit this so we want
-         *                       // to accept it
-         */
-        runTest {
-            val testObject = typeElement("foo.bar.MyObject")
-            val set = testObject.getField(processingEnv, "mSet").asType()
-            val varianceSet = testObject.getField(processingEnv, "mVarianceSet").asType()
-            assertThat(typeUtils.isAssignableWithoutVariance(
-                    from = set,
-                    to = varianceSet
-            ), `is`(true))
-            assertThat(typeUtils.isAssignableWithoutVariance(
-                    from = varianceSet,
-                    to = set
-            ), `is`(true))
-        }
-    }
-
-    private fun TypeElement.getField(
-            env: ProcessingEnvironment,
-            name: String): VariableElement {
-        return getAllFieldsIncludingPrivateSupers(env).first {
-            it.simpleName.toString() == name
-        }
-    }
-
-    private fun runTest(handler: TestInvocation.() -> Unit) {
-        simpleRun(TEST_OBJECT) {
-            it.apply { handler() }
-        }.compilesWithoutError()
-    }
-}
\ No newline at end of file
diff --git a/room/compiler/src/test/kotlin/android/arch/persistence/room/testing/TestInvocation.kt b/room/compiler/src/test/kotlin/android/arch/persistence/room/testing/TestInvocation.kt
index e03f1db..86b6e01 100644
--- a/room/compiler/src/test/kotlin/android/arch/persistence/room/testing/TestInvocation.kt
+++ b/room/compiler/src/test/kotlin/android/arch/persistence/room/testing/TestInvocation.kt
@@ -29,6 +29,4 @@
     fun typeElement(qName: String): TypeElement {
         return processingEnv.elementUtils.getTypeElement(qName)
     }
-
-    val typeUtils by lazy { processingEnv.typeUtils }
 }
diff --git a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.TestDatabase/1.json b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.TestDatabase/1.json
index 04e7cad..e6bb21c 100644
--- a/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.TestDatabase/1.json
+++ b/room/integration-tests/kotlintestapp/schemas/android.arch.persistence.room.integration.kotlintestapp.TestDatabase/1.json
@@ -2,11 +2,11 @@
   "formatVersion": 1,
   "database": {
     "version": 1,
-    "identityHash": "c7e8b9f03366a1b0a03ab28b7c9c5ad7",
+    "identityHash": "933c7e2810b0f89ab84faa68bbea5852",
     "entities": [
       {
         "tableName": "Book",
-        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookId` TEXT NOT NULL, `title` TEXT NOT NULL, `bookPublisherId` TEXT NOT NULL, `languages` INTEGER NOT NULL, PRIMARY KEY(`bookId`), FOREIGN KEY(`bookPublisherId`) REFERENCES `Publisher`(`publisherId`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
+        "createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`bookId` TEXT NOT NULL, `title` TEXT NOT NULL, `bookPublisherId` TEXT NOT NULL, PRIMARY KEY(`bookId`), FOREIGN KEY(`bookPublisherId`) REFERENCES `Publisher`(`publisherId`) ON UPDATE NO ACTION ON DELETE NO ACTION DEFERRABLE INITIALLY DEFERRED)",
         "fields": [
           {
             "fieldPath": "bookId",
@@ -25,12 +25,6 @@
             "columnName": "bookPublisherId",
             "affinity": "TEXT",
             "notNull": true
-          },
-          {
-            "fieldPath": "languages",
-            "columnName": "languages",
-            "affinity": "INTEGER",
-            "notNull": true
           }
         ],
         "primaryKey": {
@@ -197,7 +191,7 @@
     ],
     "setupQueries": [
       "CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
-      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"c7e8b9f03366a1b0a03ab28b7c9c5ad7\")"
+      "INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, \"933c7e2810b0f89ab84faa68bbea5852\")"
     ]
   }
 }
\ No newline at end of file
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/BooksDao.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/BooksDao.kt
index 39e8cae..20e9d18 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/BooksDao.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/dao/BooksDao.kt
@@ -20,12 +20,10 @@
 import android.arch.persistence.room.Dao
 import android.arch.persistence.room.Insert
 import android.arch.persistence.room.Query
-import android.arch.persistence.room.TypeConverters
 import android.arch.persistence.room.integration.kotlintestapp.vo.Author
 import android.arch.persistence.room.integration.kotlintestapp.vo.Book
 import android.arch.persistence.room.integration.kotlintestapp.vo.BookAuthor
 import android.arch.persistence.room.integration.kotlintestapp.vo.BookWithPublisher
-import android.arch.persistence.room.integration.kotlintestapp.vo.Lang
 import android.arch.persistence.room.integration.kotlintestapp.vo.Publisher
 import android.arch.persistence.room.integration.kotlintestapp.vo.PublisherWithBooks
 import io.reactivex.Flowable
@@ -93,8 +91,4 @@
 
     @Query("UPDATE book SET title = :title WHERE bookId = :bookId")
     fun updateBookTitle(bookId: String, title: String?)
-
-    @Query("SELECT * FROM book WHERE languages & :langs != 0 ORDER BY bookId ASC")
-    @TypeConverters(Lang::class)
-    fun findByLanguages(langs: Set<Lang>): List<Book>
 }
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/BooksDaoTest.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/BooksDaoTest.kt
index 93be6e9..acc2c7d 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/BooksDaoTest.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/BooksDaoTest.kt
@@ -19,7 +19,6 @@
 import android.arch.persistence.room.integration.kotlintestapp.vo.Author
 import android.arch.persistence.room.integration.kotlintestapp.vo.Book
 import android.arch.persistence.room.integration.kotlintestapp.vo.BookWithPublisher
-import android.arch.persistence.room.integration.kotlintestapp.vo.Lang
 import android.arch.persistence.room.integration.kotlintestapp.vo.Publisher
 import android.database.sqlite.SQLiteConstraintException
 import android.support.test.filters.SmallTest
@@ -120,25 +119,4 @@
                 TestUtil.BOOK_2.bookId))
         assertThat(books, `is`(listOf(TestUtil.BOOK_2, TestUtil.BOOK_1)))
     }
-
-    @Test
-    fun findBooksByLanguage() {
-        booksDao.addPublishers(TestUtil.PUBLISHER)
-        val book1 = TestUtil.BOOK_1.copy(languages = setOf(Lang.TR))
-        val book2 = TestUtil.BOOK_2.copy(languages = setOf(Lang.ES, Lang.TR))
-        val book3 = TestUtil.BOOK_3.copy(languages = setOf(Lang.EN))
-        booksDao.addBooks(book1, book2, book3)
-
-        assertThat(booksDao.findByLanguages(setOf(Lang.EN, Lang.TR)),
-                `is`(listOf(book1, book2, book3)))
-
-        assertThat(booksDao.findByLanguages(setOf(Lang.TR)),
-                `is`(listOf(book1, book2)))
-
-        assertThat(booksDao.findByLanguages(setOf(Lang.ES)),
-                `is`(listOf(book2)))
-
-        assertThat(booksDao.findByLanguages(setOf(Lang.EN)),
-                `is`(listOf(book3)))
-    }
 }
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/TestUtil.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/TestUtil.kt
index 57546d0..c4d406c 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/TestUtil.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/test/TestUtil.kt
@@ -19,7 +19,6 @@
 import android.arch.persistence.room.integration.kotlintestapp.vo.Author
 import android.arch.persistence.room.integration.kotlintestapp.vo.Book
 import android.arch.persistence.room.integration.kotlintestapp.vo.BookAuthor
-import android.arch.persistence.room.integration.kotlintestapp.vo.Lang
 import android.arch.persistence.room.integration.kotlintestapp.vo.Publisher
 
 class TestUtil {
@@ -32,12 +31,8 @@
         val AUTHOR_1 = Author("a1", "author 1")
         val AUTHOR_2 = Author("a2", "author 2")
 
-        val BOOK_1 = Book("b1", "book title 1", "ph1",
-                setOf(Lang.EN))
-        val BOOK_2 = Book("b2", "book title 2", "ph1",
-                setOf(Lang.TR))
-        val BOOK_3 = Book("b3", "book title 2", "ph1",
-                setOf(Lang.ES))
+        val BOOK_1 = Book("b1", "book title 1", "ph1")
+        val BOOK_2 = Book("b2", "book title 2", "ph1")
 
         val BOOK_AUTHOR_1_1 = BookAuthor(BOOK_1.bookId, AUTHOR_1.authorId)
         val BOOK_AUTHOR_1_2 = BookAuthor(BOOK_1.bookId, AUTHOR_2.authorId)
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/Book.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/Book.kt
index fe4a600..794e60b 100644
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/Book.kt
+++ b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/Book.kt
@@ -19,16 +19,10 @@
 import android.arch.persistence.room.Entity
 import android.arch.persistence.room.ForeignKey
 import android.arch.persistence.room.PrimaryKey
-import android.arch.persistence.room.TypeConverters
 
 @Entity(foreignKeys = arrayOf(
         ForeignKey(entity = Publisher::class,
                 parentColumns = arrayOf("publisherId"),
                 childColumns = arrayOf("bookPublisherId"),
                 deferred = true)))
-data class Book(
-        @PrimaryKey val bookId: String,
-        val title: String,
-        val bookPublisherId: String,
-        @field:TypeConverters(Lang::class)
-        val languages: Set<Lang>)
+data class Book(@PrimaryKey val bookId: String, val title: String, val bookPublisherId: String)
diff --git a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/Lang.kt b/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/Lang.kt
deleted file mode 100644
index 1d5fb5c..0000000
--- a/room/integration-tests/kotlintestapp/src/androidTest/java/android/arch/persistence/room/integration/kotlintestapp/vo/Lang.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.arch.persistence.room.integration.kotlintestapp.vo
-
-import android.arch.persistence.room.TypeConverter
-
-/**
- * An enum class which gets saved as a bit set in the database.
- */
-enum class Lang {
-    TR,
-    EN,
-    ES;
-
-    companion object {
-        @JvmStatic
-        @TypeConverter
-        fun toInt(langs: Set<Lang>): Int {
-            return langs.fold(0) { left, lang ->
-                left.or(1 shl lang.ordinal)
-            }
-        }
-
-        @JvmStatic
-        @TypeConverter
-        fun toSet(value: Int): Set<Lang> {
-            return Lang.values().filter {
-                (1 shl it.ordinal).and(value) != 0
-            }.toSet()
-        }
-    }
-}
\ No newline at end of file
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/TestDatabase.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/TestDatabase.java
index 610afb2..2fad7b1 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/TestDatabase.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/TestDatabase.java
@@ -32,7 +32,6 @@
 import android.arch.persistence.room.integration.testapp.dao.UserPetDao;
 import android.arch.persistence.room.integration.testapp.dao.WithClauseDao;
 import android.arch.persistence.room.integration.testapp.vo.BlobEntity;
-import android.arch.persistence.room.integration.testapp.vo.Day;
 import android.arch.persistence.room.integration.testapp.vo.FunnyNamedEntity;
 import android.arch.persistence.room.integration.testapp.vo.Pet;
 import android.arch.persistence.room.integration.testapp.vo.PetCouple;
@@ -42,8 +41,6 @@
 import android.arch.persistence.room.integration.testapp.vo.User;
 
 import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
 
 @Database(entities = {User.class, Pet.class, School.class, PetCouple.class, Toy.class,
         BlobEntity.class, Product.class, FunnyNamedEntity.class},
@@ -77,25 +74,5 @@
                 return date.getTime();
             }
         }
-
-        @TypeConverter
-        public Set<Day> decomposeDays(int flags) {
-            Set<Day> result = new HashSet<>();
-            for (Day day : Day.values()) {
-                if ((flags & (1 << day.ordinal())) != 0) {
-                    result.add(day);
-                }
-            }
-            return result;
-        }
-
-        @TypeConverter
-        public int composeDays(Set<Day> days) {
-            int result = 0;
-            for (Day day : days) {
-                result |= 1 << day.ordinal();
-            }
-            return result;
-        }
     }
 }
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/UserDao.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/UserDao.java
index 69463da..0b184a9 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/UserDao.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/dao/UserDao.java
@@ -29,7 +29,6 @@
 import android.arch.persistence.room.Update;
 import android.arch.persistence.room.integration.testapp.TestDatabase;
 import android.arch.persistence.room.integration.testapp.vo.AvgWeightByAge;
-import android.arch.persistence.room.integration.testapp.vo.Day;
 import android.arch.persistence.room.integration.testapp.vo.User;
 import android.database.Cursor;
 
@@ -37,7 +36,6 @@
 
 import java.util.Date;
 import java.util.List;
-import java.util.Set;
 import java.util.concurrent.Callable;
 
 import io.reactivex.Flowable;
@@ -205,9 +203,6 @@
     @Query("UPDATE User set mWeight = :weight WHERE mId IN (:ids) AND mAge == :age")
     public abstract int updateByAgeAndIds(float weight, int age, List<Integer> ids);
 
-    @Query("SELECT * FROM user WHERE (mWorkDays & :days) != 0")
-    public abstract List<User> findUsersByWorkDays(Set<Day> days);
-
     // QueryLoader
 
     @Query("SELECT COUNT(*) from user")
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java
index 2f1ca54..f8049f3 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/test/SimpleEntityReadWriteTest.java
@@ -35,7 +35,6 @@
 import android.arch.persistence.room.integration.testapp.dao.UserDao;
 import android.arch.persistence.room.integration.testapp.dao.UserPetDao;
 import android.arch.persistence.room.integration.testapp.vo.BlobEntity;
-import android.arch.persistence.room.integration.testapp.vo.Day;
 import android.arch.persistence.room.integration.testapp.vo.Pet;
 import android.arch.persistence.room.integration.testapp.vo.Product;
 import android.arch.persistence.room.integration.testapp.vo.User;
@@ -58,9 +57,7 @@
 import java.util.Calendar;
 import java.util.Collections;
 import java.util.Date;
-import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 
 @SuppressWarnings("ArraysAsListWithZeroOrOneArgument")
 @SmallTest
@@ -527,35 +524,4 @@
         assertTrue("SQLiteConstraintException expected", caught);
         assertThat(mUserDao.count(), is(0));
     }
-
-    @Test
-    public void enumSet_simpleLoad() {
-        User a = TestUtil.createUser(3);
-        Set<Day> expected = toSet(Day.MONDAY, Day.TUESDAY);
-        a.setWorkDays(expected);
-        mUserDao.insert(a);
-        User loaded = mUserDao.load(3);
-        assertThat(loaded.getWorkDays(), is(expected));
-    }
-
-    @Test
-    public void enumSet_query() {
-        User user1 = TestUtil.createUser(3);
-        user1.setWorkDays(toSet(Day.MONDAY, Day.FRIDAY));
-        User user2 = TestUtil.createUser(5);
-        user2.setWorkDays(toSet(Day.MONDAY, Day.THURSDAY));
-        mUserDao.insert(user1);
-        mUserDao.insert(user2);
-        List<User> empty = mUserDao.findUsersByWorkDays(toSet(Day.WEDNESDAY));
-        assertThat(empty.size(), is(0));
-        List<User> friday = mUserDao.findUsersByWorkDays(toSet(Day.FRIDAY));
-        assertThat(friday, is(Arrays.asList(user1)));
-        List<User> monday = mUserDao.findUsersByWorkDays(toSet(Day.MONDAY));
-        assertThat(monday, is(Arrays.asList(user1, user2)));
-
-    }
-
-    private Set<Day> toSet(Day... days) {
-        return new HashSet<>(Arrays.asList(days));
-    }
 }
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/Day.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/Day.java
deleted file mode 100644
index e02b91c..0000000
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/Day.java
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.arch.persistence.room.integration.testapp.vo;
-
-public enum Day {
-    MONDAY,
-    TUESDAY,
-    WEDNESDAY,
-    THURSDAY,
-    FRIDAY,
-    SATURDAY,
-    SUNDAY
-}
diff --git a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/User.java b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/User.java
index a615819..a5b8839 100644
--- a/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/User.java
+++ b/room/integration-tests/testapp/src/androidTest/java/android/arch/persistence/room/integration/testapp/vo/User.java
@@ -23,8 +23,6 @@
 import android.arch.persistence.room.integration.testapp.TestDatabase;
 
 import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
 
 @Entity
 @TypeConverters({TestDatabase.Converters.class})
@@ -48,9 +46,6 @@
     @ColumnInfo(name = "custommm", collate = ColumnInfo.NOCASE)
     private String mCustomField;
 
-    // bit flags
-    private Set<Day> mWorkDays = new HashSet<>();
-
     public int getId() {
         return mId;
     }
@@ -115,15 +110,6 @@
         mCustomField = customField;
     }
 
-    public Set<Day> getWorkDays() {
-        return mWorkDays;
-    }
-
-    public void setWorkDays(
-            Set<Day> workDays) {
-        mWorkDays = workDays;
-    }
-
     @Override
     public boolean equals(Object o) {
         if (this == o) return true;
@@ -142,11 +128,8 @@
         if (mBirthday != null ? !mBirthday.equals(user.mBirthday) : user.mBirthday != null) {
             return false;
         }
-        if (mCustomField != null ? !mCustomField.equals(user.mCustomField)
-                : user.mCustomField != null) {
-            return false;
-        }
-        return mWorkDays != null ? mWorkDays.equals(user.mWorkDays) : user.mWorkDays == null;
+        return mCustomField != null ? mCustomField.equals(user.mCustomField)
+                : user.mCustomField == null;
     }
 
     @Override
@@ -159,7 +142,6 @@
         result = 31 * result + (mWeight != +0.0f ? Float.floatToIntBits(mWeight) : 0);
         result = 31 * result + (mBirthday != null ? mBirthday.hashCode() : 0);
         result = 31 * result + (mCustomField != null ? mCustomField.hashCode() : 0);
-        result = 31 * result + (mWorkDays != null ? mWorkDays.hashCode() : 0);
         return result;
     }
 
@@ -173,8 +155,7 @@
                 + ", mAdmin=" + mAdmin
                 + ", mWeight=" + mWeight
                 + ", mBirthday=" + mBirthday
-                + ", mCustomField='" + mCustomField + '\''
-                + ", mWorkDays=" + mWorkDays
+                + ", mCustom=" + mCustomField
                 + '}';
     }
 }