private static void HandleEndDictionary(JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state)
        {
            if (state.Current.SkipProperty)
            {
                // Todo: determine if this is reachable.
                return;
            }

            if (state.Current.IsDictionaryProperty)
            {
                // Handle special case of DataExtensionProperty where we just added a dictionary element to the extension property.
                // Since the JSON value is not a dictionary element (it's a normal property in JSON) a JsonTokenType.EndObject
                // encountered here is from the outer object so forward to HandleEndObject().
                if (state.Current.JsonClassInfo.DataExtensionProperty == state.Current.JsonPropertyInfo)
                {
                    HandleEndObject(ref reader, ref state);
                }
                else
                {
                    // We added the items to the dictionary already.
                    state.Current.EndProperty();
                }
            }
            else if (state.Current.IsIDictionaryConstructibleProperty)
            {
                Debug.Assert(state.Current.TempDictionaryValues != null);
                JsonDictionaryConverter converter = state.Current.JsonPropertyInfo.DictionaryConverter;
                state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, converter.CreateFromDictionary(ref state, state.Current.TempDictionaryValues, options));
                state.Current.EndProperty();
            }
            else
            {
                object value;
                if (state.Current.TempDictionaryValues != null)
                {
                    JsonDictionaryConverter converter = state.Current.JsonPropertyInfo.DictionaryConverter;
                    value = converter.CreateFromDictionary(ref state, state.Current.TempDictionaryValues, options);
                }
                else
                {
                    value = state.Current.ReturnValue;
                }

                if (state.IsLastFrame)
                {
                    // Set the return value directly since this will be returned to the user.
                    state.Current.Reset();
                    state.Current.ReturnValue = value;
                }
                else
                {
                    state.Pop();
                    ApplyObjectToEnumerable(value, ref state, ref reader);
                }
            }
        }
        private static void HandleEndDictionary(JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state)
        {
            if (state.Current.SkipProperty)
            {
                return;
            }

            if (state.Current.IsDictionaryProperty)
            {
                // We added the items to the dictionary already.
                state.Current.EndProperty();
            }
            else if (state.Current.IsIDictionaryConstructibleProperty)
            {
                Debug.Assert(state.Current.TempDictionaryValues != null);
                JsonDictionaryConverter converter = state.Current.JsonPropertyInfo.DictionaryConverter;
                state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, converter.CreateFromDictionary(ref state, state.Current.TempDictionaryValues, options));
                state.Current.EndProperty();
            }
            else
            {
                object value;
                if (state.Current.TempDictionaryValues != null)
                {
                    JsonDictionaryConverter converter = state.Current.JsonPropertyInfo.DictionaryConverter;
                    value = converter.CreateFromDictionary(ref state, state.Current.TempDictionaryValues, options);
                }
                else
                {
                    value = state.Current.ReturnValue;
                }

                if (state.IsLastFrame)
                {
                    // Set the return value directly since this will be returned to the user.
                    state.Current.Reset();
                    state.Current.ReturnValue = value;
                }
                else
                {
                    state.Pop();
                    ApplyObjectToEnumerable(value, ref state, ref reader);
                }
            }
        }
        private static void HandleEndDictionary(JsonSerializerOptions options, ref Utf8JsonReader reader, ref ReadStack state)
        {
            if (state.Current.IsDictionaryProperty)
            {
                // We added the items to the dictionary already.
                state.Current.ResetProperty();
            }
            else if (state.Current.IsIDictionaryConstructibleProperty)
            {
                Debug.Assert(state.Current.TempDictionaryValues != null);
                JsonDictionaryConverter converter = state.Current.JsonPropertyInfo.DictionaryConverter;
                state.Current.JsonPropertyInfo.SetValueAsObject(state.Current.ReturnValue, converter.CreateFromDictionary(ref state, state.Current.TempDictionaryValues, options));
                state.Current.ResetProperty();
            }
            else if (state.Current.IsKeyValuePairProperty)
            {
                JsonClassInfo elementClassInfo = state.Current.JsonPropertyInfo.ElementClassInfo;

                JsonPropertyInfo propertyInfo;
                if (elementClassInfo.ClassType == ClassType.KeyValuePair)
                {
                    propertyInfo = elementClassInfo.GetPolicyPropertyOfKeyValuePair();
                }
                else
                {
                    propertyInfo = elementClassInfo.GetPolicyProperty();
                }

                Debug.Assert(state.Current.TempDictionaryValues != null);
                state.Current.JsonPropertyInfo.SetValueAsObject(
                    state.Current.ReturnValue,
                    propertyInfo.CreateKeyValuePairInstance(ref state, state.Current.TempDictionaryValues, options));
                state.Current.ResetProperty();
            }
            else
            {
                object value;
                if (state.Current.TempDictionaryValues != null)
                {
                    if (state.Current.IsKeyValuePair)
                    {
                        JsonClassInfo elementClassInfo = state.Current.JsonClassInfo.ElementClassInfo;

                        JsonPropertyInfo propertyInfo;
                        if (elementClassInfo.ClassType == ClassType.KeyValuePair)
                        {
                            propertyInfo = elementClassInfo.GetPolicyPropertyOfKeyValuePair();
                        }
                        else
                        {
                            propertyInfo = elementClassInfo.GetPolicyProperty();
                        }

                        value = propertyInfo.CreateKeyValuePairInstance(ref state, state.Current.TempDictionaryValues, options);
                    }
                    else
                    {
                        JsonDictionaryConverter converter = state.Current.JsonPropertyInfo.DictionaryConverter;
                        value = converter.CreateFromDictionary(ref state, state.Current.TempDictionaryValues, options);
                    }
                }
                else
                {
                    value = state.Current.ReturnValue;
                }

                if (state.IsLastFrame)
                {
                    // Set the return value directly since this will be returned to the user.
                    state.Current.Reset();
                    state.Current.ReturnValue = value;
                }
                else
                {
                    state.Pop();
                    ApplyObjectToEnumerable(value, ref state, ref reader);
                }
            }
        }