ICU-20121 Adding span field for FormattedList.
diff --git a/icu4c/source/i18n/listformatter.cpp b/icu4c/source/i18n/listformatter.cpp
index 5968284..6881421 100644
--- a/icu4c/source/i18n/listformatter.cpp
+++ b/icu4c/source/i18n/listformatter.cpp
@@ -420,6 +420,21 @@
     if (U_FAILURE(errorCode)) {
         return FormattedList(errorCode);
     }
+
+    // Add span fields and sort
+    ConstrainedFieldPosition cfpos;
+    cfpos.constrainField(UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD);
+    int32_t i = 0;
+    handler.setCategory(UFIELD_CATEGORY_LIST_SPAN);
+    while (result->nextPosition(cfpos, errorCode)) {
+        handler.addAttribute(i++, cfpos.getStart(), cfpos.getLimit());
+    }
+    handler.getError(errorCode);
+    if (U_FAILURE(errorCode)) {
+        return FormattedList(errorCode);
+    }
+    result->sort();
+
     return FormattedList(result.orphan());
 }
 #endif
diff --git a/icu4c/source/i18n/unicode/listformatter.h b/icu4c/source/i18n/unicode/listformatter.h
index b11676d..bf956ba 100644
--- a/icu4c/source/i18n/unicode/listformatter.h
+++ b/icu4c/source/i18n/unicode/listformatter.h
@@ -66,6 +66,13 @@
 /**
  * An immutable class containing the result of a list formatting operation.
  *
+ * When calling nextPosition():
+ * The fields are returned from start to end. The special field category
+ * UFIELD_CATEGORY_LIST_SPAN is used to indicate which argument
+ * was inserted at the given position. The span category will
+ * always occur before the corresponding instance of UFIELD_CATEGORY_LIST
+ * in the nextPosition() iterator.
+ *
  * Not intended for public subclassing.
  *
  * @draft ICU 64
diff --git a/icu4c/source/i18n/unicode/uformattedvalue.h b/icu4c/source/i18n/unicode/uformattedvalue.h
index 362408b..1fe977f 100644
--- a/icu4c/source/i18n/unicode/uformattedvalue.h
+++ b/icu4c/source/i18n/unicode/uformattedvalue.h
@@ -80,6 +80,13 @@
 #endif
 
     /**
+     * Category for spans in a list.
+     *
+     * @draft ICU 64
+     */
+    UFIELD_CATEGORY_LIST_SPAN = 0x1000 + UFIELD_CATEGORY_LIST,
+
+    /**
      * Category for spans in a date interval.
      *
      * @draft ICU 64
diff --git a/icu4c/source/i18n/unicode/ulistformatter.h b/icu4c/source/i18n/unicode/ulistformatter.h
index cf730bf..2afc50d 100644
--- a/icu4c/source/i18n/unicode/ulistformatter.h
+++ b/icu4c/source/i18n/unicode/ulistformatter.h
@@ -114,6 +114,13 @@
  *
  * You can think of this method as a cast between types.
  *
+ * When calling ufmtval_nextPosition():
+ * The fields are returned from start to end. The special field category
+ * UFIELD_CATEGORY_LIST_SPAN is used to indicate which argument
+ * was inserted at the given position. The span category will
+ * always occur before the corresponding instance of UFIELD_CATEGORY_LIST
+ * in the ufmtval_nextPosition() iterator.
+ *
  * @param uresult The object containing the formatted string.
  * @param ec Set if an error occurs.
  * @return A UFormattedValue owned by the input object.
diff --git a/icu4c/source/test/cintltst/ulistfmttest.c b/icu4c/source/test/cintltst/ulistfmttest.c
index b89f1b3..5eb5a1e 100644
--- a/icu4c/source/test/cintltst/ulistfmttest.c
+++ b/icu4c/source/test/cintltst/ulistfmttest.c
@@ -147,11 +147,14 @@
         assertSuccess("Formatting", &ec);
         static const UFieldPositionWithCategory expectedFieldPositions[] = {
             // field, begin index, end index
+            {UFIELD_CATEGORY_LIST_SPAN, 0, 0, 5},
             {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 0, 5},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 7, 16},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 27},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 5, 7},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22}};
+            {UFIELD_CATEGORY_LIST_SPAN, 1, 7, 16},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 7, 16},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22},
+            {UFIELD_CATEGORY_LIST_SPAN, 2, 22, 27},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 27}};
         checkMixedFormattedValue(
             message,
             ulistfmt_resultAsValue(fl, &ec),
@@ -175,19 +178,26 @@
         assertSuccess("Formatting", &ec);
         static const UFieldPositionWithCategory expectedFieldPositions[] = {
             // field, begin index, end index
+            {UFIELD_CATEGORY_LIST_SPAN, 0, 0,  1},
             {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 0,  1},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 3,  4},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 6,  7},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 9,  10},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 12, 13},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 15, 16},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 23},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 1,  3},
+            {UFIELD_CATEGORY_LIST_SPAN, 1, 3,  4},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 3,  4},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 4,  6},
+            {UFIELD_CATEGORY_LIST_SPAN, 2, 6,  7},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 6,  7},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 7,  9},
+            {UFIELD_CATEGORY_LIST_SPAN, 3, 9,  10},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 9,  10},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 10, 12},
+            {UFIELD_CATEGORY_LIST_SPAN, 4, 12, 13},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 12, 13},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 13, 15},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22}};
+            {UFIELD_CATEGORY_LIST_SPAN, 5, 15, 16},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 15, 16},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22},
+            {UFIELD_CATEGORY_LIST_SPAN, 6, 22, 23},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 23}};
         checkMixedFormattedValue(
             message,
             ulistfmt_resultAsValue(fl, &ec),
diff --git a/icu4c/source/test/intltest/listformattertest.cpp b/icu4c/source/test/intltest/listformattertest.cpp
index 239eb78..955c3d9 100644
--- a/icu4c/source/test/intltest/listformattertest.cpp
+++ b/icu4c/source/test/intltest/listformattertest.cpp
@@ -556,11 +556,14 @@
         FormattedList result = fmt->formatStringsToValue(inputs, UPRV_LENGTHOF(inputs), status);
         static const UFieldPositionWithCategory expectedFieldPositions[] = {
             // field, begin index, end index
+            {UFIELD_CATEGORY_LIST_SPAN, 0, 0, 5},
             {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 0, 5},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 7, 16},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 27},
             {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 5, 7},
-            {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22}};
+            {UFIELD_CATEGORY_LIST_SPAN, 1, 7, 16},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 7, 16},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_LITERAL_FIELD, 16, 22},
+            {UFIELD_CATEGORY_LIST_SPAN, 2, 22, 27},
+            {UFIELD_CATEGORY_LIST, ULISTFMT_ELEMENT_FIELD, 22, 27}};
         checkMixedFormattedValue(
             message,
             result,