diff --git a/compiler2/record.c b/compiler2/record.c
index 6331a10b6a679cbdb7afa9a2fe2bbe99d8c54e63..c3ae41ffeb8b7ecef4dccfe0e3eef890f1fc0814 100644
--- a/compiler2/record.c
+++ b/compiler2/record.c
@@ -3219,7 +3219,16 @@ char* generate_json_decoder(char* src, const struct_def* sdef)
 
     boolean has_metainfo_enabled = FALSE;
     for (int i = 0; i < sdef->nElements; ++i) {
-      src = mputprintf(src, "  boolean %s_found = FALSE;\n", sdef->elements[i].name);
+      if (sdef->elements[i].jsonDefaultValue) {
+        // initialize fields with their default values (they will be overwritten
+        // later, if the JSON document contains data for these fields)
+        src = mputprintf(src,
+          "  field_%s.JSON_decode(%s_descr_, DUMMY_BUFFER, p_silent);\n"
+          , sdef->elements[i].name, sdef->elements[i].typedescrname);
+      }
+      else {
+        src = mputprintf(src, "  boolean %s_found = FALSE;\n", sdef->elements[i].name);
+      }
       if (sdef->elements[i].jsonMetainfoUnbound) {
         // initialize meta info states
         src = mputprintf(src, 
@@ -3259,10 +3268,12 @@ char* generate_json_decoder(char* src, const struct_def* sdef)
       src = mputprintf(src,
         // check field name
         "if (%d == name_len && 0 == strncmp(fld_name, \"%s\", name_len)) {\n"
-        "        %s_found = TRUE;\n"
         , (int)strlen(sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname)
-        , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname
-        , sdef->elements[i].name);
+        , sdef->elements[i].jsonAlias ? sdef->elements[i].jsonAlias : sdef->elements[i].dispname);
+      if (!sdef->elements[i].jsonDefaultValue) {
+        src = mputprintf(src,
+          "        %s_found = TRUE;\n", sdef->elements[i].name);
+      }
       if (has_metainfo_enabled) {
         src = mputstr(src, "        if (is_metainfo) {\n");
         if (sdef->elements[i].jsonMetainfoUnbound) {
@@ -3416,59 +3427,60 @@ char* generate_json_decoder(char* src, const struct_def* sdef)
           , (unsigned long) strlen(sdef->elements[i].dispname)
           , sdef->elements[i].dispname);
       }
-      src = mputprintf(src,
-        "if (!%s_found) {\n"
-        , sdef->elements[i].name);
-      if (sdef->elements[i].jsonDefaultValue) {
+      if (!sdef->elements[i].jsonDefaultValue) {
         src = mputprintf(src,
-          "    field_%s.JSON_decode(%s_descr_, DUMMY_BUFFER, p_silent);\n"
-          , sdef->elements[i].name, sdef->elements[i].typedescrname);
-      }
-      else if (sdef->elements[i].isOptional) {
-        // if the conditions in attribute 'choice' indicate that this field is
-        // mandatory, then display an error
-        if (sdef->elements[i].jsonChosen != NULL) {
-          int j;
-          boolean has_otherwise = FALSE;
-          for (j = 0; j < sdef->elements[i].jsonChosen->nElements; j++) {
-            if (sdef->elements[i].jsonChosen->list[j].nElements == 0) {
-              has_otherwise = TRUE;
-              break;
-            }
-          }
-          boolean first_found = FALSE;
-          for (j = 0; j < sdef->elements[i].jsonChosen->nElements; j++) {
-            if ((!has_otherwise && sdef->elements[i].jsonChosen->list[j].fieldnum != -2) ||
-                 (has_otherwise && sdef->elements[i].jsonChosen->list[j].fieldnum == -2)) {
-              if (!first_found) {
-                src = mputstr(src, "    if (");
-                first_found = TRUE;
+          "if (!%s_found) {\n"
+          , sdef->elements[i].name);
+        if (sdef->elements[i].isOptional) {
+          // if the conditions in attribute 'choice' indicate that this field is
+          // mandatory, then display an error
+          if (sdef->elements[i].jsonChosen != NULL) {
+            int j;
+            boolean has_otherwise = FALSE;
+            boolean omit_otherwise = FALSE;
+            for (j = 0; j < sdef->elements[i].jsonChosen->nElements; j++) {
+              if (sdef->elements[i].jsonChosen->list[j].nElements == 0) {
+                has_otherwise = TRUE;
+                if (sdef->elements[i].jsonChosen->list[j].fieldnum == -2) {
+                  omit_otherwise = TRUE;
+                }
+                break;
               }
-              else {
-                src = mputstr(src, "\n        || ");
+            }
+            boolean first_found = FALSE;
+            for (j = 0; j < sdef->elements[i].jsonChosen->nElements; j++) {
+              if (((!has_otherwise || omit_otherwise) && sdef->elements[i].jsonChosen->list[j].fieldnum != -2) ||
+                   (has_otherwise && !omit_otherwise && sdef->elements[i].jsonChosen->list[j].fieldnum == -2)) {
+                if (!first_found) {
+                  src = mputstr(src, "    if (");
+                  first_found = TRUE;
+                }
+                else {
+                  src = mputstr(src, "\n        || ");
+                }
+                src = genRawFieldChecker(src, sdef->elements[i].jsonChosen->list + j, !has_otherwise || omit_otherwise);
               }
-              src = genRawFieldChecker(src, sdef->elements[i].jsonChosen->list + j, !has_otherwise);
+            }
+            if (first_found) {
+              src = mputprintf(src,
+                ") {\n"
+                "      JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_CHOSEN_FIELD_OMITTED, \"%s\");\n"
+                "      return JSON_ERROR_FATAL;\n"
+                "    }\n", sdef->elements[i].dispname);
             }
           }
-          if (first_found) {
-            src = mputprintf(src,
-              ") {\n"
-              "      JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_CHOSEN_FIELD_OMITTED, \"%s\");\n"
-              "      return JSON_ERROR_FATAL;\n"
-              "    }\n", sdef->elements[i].dispname);
-          }
+          src = mputprintf(src,
+            "    field_%s = OMIT_VALUE;\n"
+            , sdef->elements[i].name);
+        } else {
+          src = mputprintf(src,
+            "    JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_MISSING_FIELD_ERROR, \"%s\");\n"
+            "    return JSON_ERROR_FATAL;\n"
+            , sdef->elements[i].dispname);
         }
-        src = mputprintf(src,
-          "    field_%s = OMIT_VALUE;\n"
-          , sdef->elements[i].name);
-      } else {
-        src = mputprintf(src,
-          "    JSON_ERROR(TTCN_EncDec::ET_INVAL_MSG, JSON_DEC_MISSING_FIELD_ERROR, \"%s\");\n"
-          "    return JSON_ERROR_FATAL;\n"
-          , sdef->elements[i].dispname);
-      }
-      src = mputstr(src,
-        "  }\n  ");
+        src = mputstr(src,
+          "  }\n  ");
+      } // if there's no default value
     }
     src = mputstr(src,
       "\n  return (int)dec_len;\n");
diff --git a/regression_test/json/AttributeTestcases.ttcn b/regression_test/json/AttributeTestcases.ttcn
index 1b6141fff5dcc81c2a6b0e999477cede6a6d29df..ab87a95b7576a0d3c38135059661c2149d72d70a 100644
--- a/regression_test/json/AttributeTestcases.ttcn
+++ b/regression_test/json/AttributeTestcases.ttcn
@@ -627,6 +627,54 @@ testcase tc_attribute_chosen_negtest() runs on MTC {
   setverdict(pass);
 }
 
+// Testing JSON decoding with attributes 'chosen' and 'default'.
+// (The conditions in the attribute 'chosen' depend on fields that have default values.)
+testcase tc_attribute_chosen_default() runs on MTC {
+  // Test #1: both fields use their default values
+  var octetstring buff := char2oct("{\"field\":{\"num\":1,\"str\":\"abc\"}}");
+  var PduWithId2 dec_exp := { protocolId1 := 1, protocolId2 := 0, field := { type1 := { num := 1, str := "abc" } } };
+  var PduWithId2 dec := f_dec_pduwithid2(buff);
+  if (dec != dec_exp) {
+    setverdict(fail, "Test #1 failed. Expected: ", dec_exp, ", got: ", dec);
+  }
+  
+  // Test #2: the first field uses its default value, the second decodes its value from the buffer
+  buff := char2oct("{\"protocolId2\":-1,\"field\":{\"num\":1,\"str\":\"abc\"}}");
+  dec_exp := { protocolId1 := 1, protocolId2 := -1, field := { type1 := { num := 1, str := "abc" } } };
+  dec := f_dec_pduwithid2(buff);
+  if (dec != dec_exp) {
+    setverdict(fail, "Test #2 failed. Expected: ", dec_exp, ", got: ", dec);
+  }
+  
+  // Test #3: the second field uses its default value, the first decodes its value from the buffer
+  buff := char2oct("{\"protocolId1\":6,\"field\":{\"num\":1,\"str\":\"abc\"}}");
+  dec_exp := { protocolId1 := 6, protocolId2 := 0, field := { type3 := { num := 1.0, str := "abc" } } };
+  dec := f_dec_pduwithid2(buff);
+  if (dec != dec_exp) {
+    setverdict(fail, "Test #3 failed. Expected: ", dec_exp, ", got: ", dec);
+  }
+  
+  // Test #4: both fields decode their values from the buffer
+  buff := char2oct("{\"protocolId1\":6,\"protocolId2\":-1}");
+  dec_exp := { protocolId1 := 6, protocolId2 := -1, field := omit };
+  dec := f_dec_pduwithid2(buff);
+  if (dec != dec_exp) {
+    setverdict(fail, "Test #4 failed. Expected: ", dec_exp, ", got: ", dec);
+  }
+  
+  // Test #5: both fields decode their values from the buffer,
+  // however, the first field appears after the union field in the buffer,
+  // so its default value is used when checking the conditions of the attribute 'chosen'
+  buff := char2oct("{\"protocolId2\":-1,\"field\":{\"num\":1,\"str\":\"abc\"},\"protocolId1\":6}");
+  dec_exp := { protocolId1 := 6, protocolId2 := -1, field := { type1 := { num := 1, str := "abc" } } };
+  dec := f_dec_pduwithid2(buff);
+  if (dec != dec_exp) {
+    setverdict(fail, "Test #5 failed. Expected: ", dec_exp, ", got: ", dec);
+  }
+  
+  setverdict(pass);
+}
+
 
 control {
   execute(tc_NoAttributeOnUpperLevel())
@@ -655,5 +703,6 @@ control {
   execute(tc_attribute_default_struct());
   execute(tc_attribute_chosen());
   execute(tc_attribute_chosen_negtest());
+  execute(tc_attribute_chosen_default());
 }
 }
diff --git a/regression_test/json/Functions.ttcn b/regression_test/json/Functions.ttcn
index edb639f0896bb5306ff337e4a8397c738a15f1c0..b764eff2316db619af5181eba8451a6e7a60d051 100644
--- a/regression_test/json/Functions.ttcn
+++ b/regression_test/json/Functions.ttcn
@@ -430,6 +430,9 @@ external function f_dec_null(in octetstring x) return HasNull
 external function f_dec_pduwithid(in octetstring x) return PduWithId
   with { extension "prototype(convert) decode(JSON)" }
   
+external function f_dec_pduwithid2(in octetstring x) return PduWithId2
+  with { extension "prototype(convert) decode(JSON)" }
+  
 //============== Internal Functions ====================
   
 function f_check_encoding(in octetstring encoded, in octetstring expected) {
diff --git a/regression_test/json/Types.ttcn b/regression_test/json/Types.ttcn
index 5ce1cd3d65cf2f22a607c897eb48b773d35436d7..e1e0eca094aaa031655f67555390508f7622699e 100644
--- a/regression_test/json/Types.ttcn
+++ b/regression_test/json/Types.ttcn
@@ -351,6 +351,17 @@ type record StructType3 {
 
 type record of PduWithId PduWithIdList;
 
+type record PduWithId2 {
+  integer protocolId1,
+  integer protocolId2,
+  Choices field optional
+}
+with {
+  variant (field) "chosen (type1, { protocolId1 = 1, protocolId2 = 1 }; type2, protocolId1 = 0; type3, protocolId2 = 0; omit, otherwise)";
+  variant (protocolId1) "default (1)";
+  variant (protocolId2) "default (0)";
+}
+
 } with {
   encode "JSON";
   extension "anytype integer, charstring, R, RoI, Thing";
diff --git a/usrguide/referenceguide.doc b/usrguide/referenceguide.doc
index 40f6d4b2fb2e9988ee9bf1514dca8905303f138c..9468b943a56d4ed8cdf60000bbe537ad15c6e4bb 100644
Binary files a/usrguide/referenceguide.doc and b/usrguide/referenceguide.doc differ