private <T, S extends M> ModelView<? extends T> toView(
     ModelBinding<T> binding,
     ModelRuleDescriptor sourceDescriptor,
     Inputs inputs,
     ModelRuleRegistrar modelRuleRegistrar,
     Class<S> itemType) {
   CollectionBuilder<S> builder =
       new DefaultCollectionBuilder<S>(
           binding.getPath(),
           new Instantiator<S>(itemType, container),
           sourceDescriptor,
           inputs,
           modelRuleRegistrar);
   ModelType<CollectionBuilder<S>> viewType =
       new ModelType.Builder<CollectionBuilder<S>>() {}.where(
               new ModelType.Parameter<S>() {}, ModelType.of(itemType))
           .build();
   CollectionBuilderModelView<S> view =
       new CollectionBuilderModelView<S>(viewType, builder, binding.getPath(), sourceDescriptor);
   @SuppressWarnings("unchecked")
   ModelView<T> cast = (ModelView<T>) view;
   return cast;
 }
 public <T> ModelView<? extends T> asWritable(
     ModelBinding<T> binding,
     ModelRuleDescriptor sourceDescriptor,
     Inputs inputs,
     ModelRuleRegistrar modelRuleRegistrar,
     C instance) {
   ModelType<T> targetType = binding.getReference().getType();
   if (canBeViewedAsWritable(targetType)) {
     ModelType<?> targetItemType = targetType.getTypeVariables().get(0);
     if (targetItemType.getRawClass().isAssignableFrom(itemType)) { // item type is super of base
       return toView(binding, sourceDescriptor, inputs, modelRuleRegistrar, itemType);
     } else { // item type is sub type
       Class<? extends M> subType = targetItemType.getRawClass().asSubclass(itemType);
       return toView(binding, sourceDescriptor, inputs, modelRuleRegistrar, subType);
     }
   } else {
     return null;
   }
 }