Deprecate @Optional, introduce @Required
diff --git a/docs/examples.md b/docs/examples.md
index 3dc38e1..7ab7e91 100644
--- a/docs/examples.md
+++ b/docs/examples.md
@@ -10,11 +10,11 @@
     @Serializable
     data class Data(val a: Int, val b: Int)
     val data = Data(1, 2)
-    
+
     // Serialize with internal serializer for Data class
     assertEquals("{a:1,b:2}", Json.unquoted.stringify(data))
     assertEquals(data, Json.parse<Data>("{a:1,b:2}"))
-    
+
     // Serialize with external serializer for Data class
     @Serializer(forClass=Data::class)
     object ExtDataSerializer
@@ -22,58 +22,98 @@
     assertEquals(data, Json.parse(ExtDataSerializer, "{a:1,b:2}"))
     ```
 
- * In case of usage of **internal** serialization (`@Serializable` annotation on class), both body `val`s and `var`s are supported with any visibility levels.
-    
+ * In case of usage of **internal** serialization
+ (`@Serializable` annotation on class), both body `val`s and `var`s are supported with any visibility levels.
+
     ```kotlin
     @Serializable
     class Data(val a: Int) {
         private val b: String = "42"
-    
+
         override fun equals(other: Any?) = /*...*/
     }
-    
+
     assertEquals("{a:1, b:42}", Json.unquoted.stringify(Data(1)))
     assertEquals(Data(1), Json.unquoted.parse<Data>("{a:1, b:42}"))
     ```
 
-* Important note: In this case, body properties initializers and setters are not called. So, following approach would not work:
+ * Property will be considered _optional_ if it has default value.
+
+    ```kotlin
+    @Serializable
+    data class Data(val a: Int, val b: Int = 42)
+
+    // Serialization and deserialization with internal serializer
+    assertEquals("{a:0,b:42}",Json.unquoted.stringify(Data(0)))
+    assertEquals(Json.unquoted.parse<Data>("{a:0,b:43}"),Data(b = 43))
+    assertEquals(Json.unquoted.parse<Data>("{a:0,b:42}"),Data(0))
+    assertEquals(Json.unquoted.parse<Data>("{a:0}"),Data(0))
+
+    // This will throw SerializationException, because 'a' is missing.
+    Json.unquoted.parse<Data>("{b:0}")
+    ```
+
+    > Tip: you can omit default values during serialization with
+    `Json(encodeDefaults = false)` (see [here](runtime_usage#json)).
+
+
+ * By default, only properties which have
+ [backing fields](https://kotlinlang.org/docs/reference/properties.html#backing-fields)
+ will be serialized and restored back.
+
+    ```kotlin
+    @Serializable
+    data class Data(val a: Int) {
+        private val b: String
+            get() = "42"
+    }
+
+    // b is not in serialized form!
+    assertEquals("{a:1}", Json.unquoted.stringify(Data(1)))
+    ```
+
+    You should be careful with this, especially when you have hierarchy of serializable classes with several overrides.
+
+ * Moreover, if you have several properties with the same name and different backing fields
+ (e.g. `open/override` pair), a compiler exception will be thrown. To resolve such conflicts, use `@SerialName` (see [below](#Annotations)).
+
+ * Important note: In this case, body properties initializers and setters are not called. So, following approach would not work:
 
     ```kotlin
     @Serializable
     class Data(val a: String = "42") {
         val b: String = computeWithSideEffects()
-    
+
         private fun computeWithSideEffects(): String {
             println("I'm a side effect")
-            return "b" 
+            return "b"
         }
     }
-    
+
     // prints nothing.
     val data = Json.unquoted.parse<Data>("{a: 100500, b: 10}")
     ```
 
-* Initializers are called iff (if and only if) property is `@Transient` or `@Optional` and was not read (see below).
-    
+* Initializers are called iff (if and only if) property is `@Transient` or optional and was not read (see below).
+
     ```kotlin
     @Serializable
     class Data(val a: String = "42") {
-        @Optional
         val b: String = computeWithSideEffects()
-    
+
         private fun computeWithSideEffects(): String {
             println("I'm a side effect")
-            return "b" 
+            return "b"
         }
     }
-    
+
     // prints "I'm a side effect" once.
     val data = Json.unquoted.parse<Data>("{a: 100500, b: 10}")
     val data = Json.unquoted.parse<Data>("{a: 100500}")
     ```
 
 * *Common pattern*: Validation.
-    
+
     Such classes are not serializable, because they have constructor parameters which are not properties:
 
     ```kotlin
@@ -95,7 +135,7 @@
 
 * **External** deserialization (annotation `@Serializer(forClass=...)`) has more limitations: it supports only primary constructor's vals/vars and class body `var` properties with visibility higher than protected.  Body `val`  properties and all private properties are unseen for external serializer/deserializer.
     It also invokes all setters on body `var`s and all initialization expressions with init blocks.
-    
+
     It isn't supported yet in JavaScript.
 
     ```kotlin
@@ -105,23 +145,23 @@
         val unseen = 42
         override fun equals(other: Any?) = /*..*/
     }
-    
+
     val data = Data().apply {
         a = 1
         b = 2
     }
-    
+
     // Serialize with external serializer for Data class
     @Serializer(forClass=Data::class)
     object ExtDataSerializer
-    
+
     assertEquals("{a:1,b:2}", Json.unquoted.stringify(ExtDataSerializer, data))
     assertEquals(data, Json.parse(ExtDataSerializer, "{a:1,b:2}"))
     ```
 
 * Having both` @Serialiable class A` and `@Serializer(forClass=A::class)` is possible. In this case, object marked as serializer will try to deserialize class A internally, and some *strange effects* may happen. But it's not exactly.
 
-## Annotations 
+## Annotations
 
 * `@SerialName` annotation for overriding property name with custom name in formats with name support, like JSON.
 
@@ -136,20 +176,20 @@
 
     assertEquals("{value1: a, value2: 42}", Json.unquoted.stringify(Names("a", 42)))
     ```
-    
+
     > Starting from 0.6, `@SerialName` can be used on classes, too.
 
-* `@Optional` annotation for supported properties. Note: `@Optional` constructor parameters require default values, but properties with default values without annotation are treated as required.
-    
+* `@Required` annotation for supported properties. It makes property with default value
+still be mandatory and always present in serialized form.
+
     ```kotlin
     @Serializable
-    class Data(val a: Int = 0, @Optional val b: Int = 42) {
-       @Optional
+    class Data(@Required val a: Int = 0, val b: Int = 42) {
        var c = "Hello"
-    
+
        override fun equals(other: Any?) = /*...*/
     }
-    
+
     // Serialization and deserialization with internal serializer
     // External serializer also supported
     assertEquals("{a:0,b:42,c:Hello}",Json.unquoted.stringify(Data()))
@@ -157,71 +197,69 @@
     assertEquals(Json.unquoted.parse<Data>("{a:0,b:42,c:Hello}"),Data())
     assertEquals(Json.unquoted.parse<Data>("{a:0,c:Hello}"),Data())
     assertEquals(Json.unquoted.parse<Data>("{a:0}"),Data())
-    
+
     // This will throw SerializationException, because 'a' is missing.
     Json.unquoted.parse<Data>("{b:0}")
     ```
 
 * `@Transient` annotation for supported properties. This annotation excludes marked properties from process of serialization or deserialization. Requires default value. *Don't confuse with `kotlin.jvm.Transient`!*
-    
+
     ```kotlin
     @Serializable
     class Data(val a: Int = 0, @Transient val b: Int = 42) {
-        @Optional
         var c = "Hello"
-    
+
         @Transient
         var d = "World"
-    
+
         override fun equals(other: Any?) = /*...*/
     }
-    
+
     // Serialization and deserialization with internal serializer
     // External serializer also supported
     assertEquals("{a:0,c:Hello}",Json.unquoted.stringify(Data()))
     assertEquals(Json.unquoted.parse<Data>("{a:0,c:Hello}"),Data())
     assertEquals(Json.unquoted.parse<Data>("{a:0}"),Data())
-    
-    
-    // This will throw SerializationException, because 
+
+
+    // This will throw SerializationException, because
     // property 'b' is unknown to deserializer.
     Json.unquoted.parse<Data>("{a:0,b:100500,c:Hello}")
     ```
 
-* Initializing `@Transient` or `@Optional` fields in init blocks is not supported.
-    
+* Initializing `@Transient` or optional fields in init blocks is not supported.
+
     ```kotlin
     // This class is not serializable.
     class Data(val a: String = "42") {
-        @Optional
-        val b: String 
-    
+        val b: String
+
         init {
             b = "b"
         }
     }
     ```
 
-* Delegates are not supported. But you can mark them as `@Transient` and they would be instantiated as usual. So this code works fine:
-    
+* Delegates are not supported and they're by default `@Transient` (since they do not have backing field), so this example works fine:
+
     ```kotlin
     @Serializable
     data class WithDelegates(val myMap: Map<String, String>) {
-    
-        @Transient
+
+        // implicit @Transient
         val prop by myMap
     }
-    
+
     assertEquals("value", Json.unquoted.parse<WithDelegates>("{myMap:{prop:value}}").prop)
     ```
-    
+
 ## Nesting
 
 * Nested values are recursively serialized, enums, primitive types, arrays, lists and maps are supported, plus other serializable classes.
-    
+
     ```kotlin
     enum class TintEnum { LIGHT, DARK }
-    
+
     @Serializable
     data class Data(
             val a: String,
@@ -229,11 +267,11 @@
             val c: Map<String, TintEnum>
     )
     val data = Data("Str", listOf(1, 2), mapOf("lt" to TintEnum.LIGHT, "dk" to TintEnum.DARK))
-    
+
     // Serialize with internal serializer for Data class
     assertEquals("{a:Str,b:[1,2],c:{lt:LIGHT,dk:DARK}}", Json.unquoted.stringify(data))
     assertEquals(data, Json.parse<Data>("{a:Str,b:[1,2],c:{lt:LIGHT,dk:DARK}}"))
-    
+
     // Serialize with external serializer for Data class
     @Serializer(forClass=Data::class)
     object ExtDataSerializer
diff --git a/docs/runtime_usage.md b/docs/runtime_usage.md
index d8d838b..6dfa5c2 100644
--- a/docs/runtime_usage.md
+++ b/docs/runtime_usage.md
@@ -52,7 +52,7 @@
 * unquoted - means that all field names and other objects (where it's possible) would not be wrapped in quotes. Useful for debugging.
 * indented - classic pretty-printed multiline JSON.
 * indent - size of indent, applicable if parameter above is true.
-* encodeDefaults - set this to false to omit writing @Optional properties if they are equal to theirs default values.
+* encodeDefaults - set this to false to omit writing optional properties if they are equal to theirs default values.
 
 You can also use one of predefined instances, like `Json.plain`, `Json.indented`, `Json.nonstrict` or `Json.unquoted`. API is duplicated in companion object, so `Json.parse(...)` equals to `Json.plain.parse(...)`
 
@@ -121,7 +121,7 @@
 is signed ZigZag representation (`sintXX`), and `FIXED` is `fixedXX` type. `uintXX` and `sfixedXX` are not supported yet.
 
 Repeated fields represented as lists. Because format spec says that if the list is empty, there will be no elements in the stream with such tag,
-you must explicitly mark any field of list type with `@Optional` annotation with default ` = emptyList()`. Same for maps. Update mode for Protobuf is set to `UPDATE` and can't be changed, thus allowing merging several scattered lists into one.
+you must explicitly mark any field of list type with default ` = emptyList()`. Same for maps. Update mode for Protobuf is set to `UPDATE` and can't be changed, thus allowing merging several scattered lists into one.
 
 Other known issues and limitations:
 
diff --git a/runtime/common/src/main/kotlin/kotlinx/serialization/Annotations.kt b/runtime/common/src/main/kotlin/kotlinx/serialization/Annotations.kt
index d72bfdb..6bbd0b1 100644
--- a/runtime/common/src/main/kotlin/kotlinx/serialization/Annotations.kt
+++ b/runtime/common/src/main/kotlin/kotlinx/serialization/Annotations.kt
@@ -46,8 +46,12 @@
  * Optional properties must have default values.
  */
 @Target(AnnotationTarget.PROPERTY)
+@Deprecated("All properties with default values are considered optional now")
 annotation class Optional
 
+@Target(AnnotationTarget.PROPERTY)
+annotation class Required
+
 /**
  * Marks this property invisible for whole serialization framework.
  * Transient properties must have default values.
diff --git a/runtime/common/src/test/kotlin/kotlinx/serialization/json/JsonOptionalTests.kt b/runtime/common/src/test/kotlin/kotlinx/serialization/json/JsonOptionalTests.kt
index f18ff4a..9806fe9 100644
--- a/runtime/common/src/test/kotlin/kotlinx/serialization/json/JsonOptionalTests.kt
+++ b/runtime/common/src/test/kotlin/kotlinx/serialization/json/JsonOptionalTests.kt
@@ -11,9 +11,7 @@
 
     @Suppress("EqualsOrHashCode")
     @Serializable
-    internal class Data(val a: Int, @Optional val b: Int = 42) {
-        constructor(): this(0)
-
+    internal class Data(@Required val a: Int = 0, @Optional val b: Int = 42) {
         @Optional
         var c = "Hello"
 
@@ -35,7 +33,7 @@
     @Test
     fun testAll() = parametrizedTest { useStreaming ->
         assertEquals("{a:0,b:42,c:Hello}", unquoted.stringify(Data(), useStreaming))
-        assertEquals(unquoted.parse("{a:0,b:43,c:Hello}", useStreaming), Data(a = 0, b = 43))
+        assertEquals(unquoted.parse("{a:0,b:43,c:Hello}", useStreaming), Data(b = 43))
         assertEquals(unquoted.parse("{a:0,b:42,c:Hello}", useStreaming), Data())
     }