internal static IDictionary <string, string> GetKeysFromPrefixFromProvider(
            IValueProvider provider,
            string prefix
            )
        {
            IEnumerableValueProvider enumeratedProvider = provider as IEnumerableValueProvider;

            return((enumeratedProvider != null)
              ? enumeratedProvider.GetKeysFromPrefix(prefix)
              : null);
        }
            public UnvalidatedEnumerableValueProvider(object valueProvider)
            {
                this.ValueProviderAsUnvalidatedValueProvider = valueProvider as IUnvalidatedValueProvider;
                this.ValueProviderAsEnumerableValueProvider  = valueProvider as IEnumerableValueProvider;

                if (this.ValueProviderAsUnvalidatedValueProvider == null)
                {
                    throw new ArgumentException("The valueProvider must be a '" + typeof(IUnvalidatedValueProvider).FullName + "'.");
                }

                if (this.ValueProviderAsEnumerableValueProvider == null)
                {
                    throw new ArgumentException("The valueProvider must be a '" + typeof(IEnumerableValueProvider).FullName + "'.");
                }
            }
        internal object UpdateDictionary(ControllerContext controllerContext, ModelBindingContext bindingContext, Type keyType, Type valueType)
        {
            bool stopOnIndexNotFound;
            IEnumerable <string> indexes;

            GetIndexes(bindingContext, out stopOnIndexNotFound, out indexes);

            IModelBinder keyBinder   = Binders.GetBinder(keyType);
            IModelBinder valueBinder = Binders.GetBinder(valueType);

            // build up a list of items from the request
            List <KeyValuePair <object, object> > modelList = new List <KeyValuePair <object, object> >();

            foreach (string currentIndex in indexes)
            {
                string subIndexKey   = CreateSubIndexName(bindingContext.ModelName, currentIndex);
                string keyFieldKey   = CreateSubPropertyName(subIndexKey, "key");
                string valueFieldKey = CreateSubPropertyName(subIndexKey, "value");

                if (!(bindingContext.ValueProvider.ContainsPrefix(keyFieldKey) && bindingContext.ValueProvider.ContainsPrefix(valueFieldKey)))
                {
                    if (stopOnIndexNotFound)
                    {
                        // we ran out of elements to pull
                        break;
                    }
                    else
                    {
                        continue;
                    }
                }

                // bind the key
                ModelBindingContext keyBindingContext = new ModelBindingContext()
                {
                    ModelMetadata = ModelMetadataProviders.Current.GetMetadataForType(null, keyType),
                    ModelName     = keyFieldKey,
                    ModelState    = bindingContext.ModelState,
                    ValueProvider = bindingContext.ValueProvider
                };
                object thisKey = keyBinder.BindModel(controllerContext, keyBindingContext);

                // we need to merge model errors up
                AddValueRequiredMessageToModelState(controllerContext, bindingContext.ModelState, keyFieldKey, keyType, thisKey);
                if (!keyType.IsInstanceOfType(thisKey))
                {
                    // we can't add an invalid key, so just move on
                    continue;
                }

                // bind the value
                modelList.Add(CreateEntryForModel(controllerContext, bindingContext, valueType, valueBinder, valueFieldKey, thisKey));
            }

            // Let's try another method
            if (modelList.Count == 0)
            {
                IEnumerableValueProvider enumerableValueProvider = bindingContext.ValueProvider as IEnumerableValueProvider;
                if (enumerableValueProvider != null)
                {
                    IDictionary <string, string> keys = enumerableValueProvider.GetKeysFromPrefix(bindingContext.ModelName);
                    foreach (var thisKey in keys)
                    {
                        modelList.Add(CreateEntryForModel(controllerContext, bindingContext, valueType, valueBinder, thisKey.Value, thisKey.Key));
                    }
                }
            }

            // if there weren't any elements at all in the request, just return
            if (modelList.Count == 0)
            {
                return(null);
            }

            // replace the original collection
            object dictionary = bindingContext.Model;

            CollectionHelpers.ReplaceDictionary(keyType, valueType, dictionary, modelList);
            return(dictionary);
        }