private <T extends ComponentSpec> void registerImplementation(
     ComponentSpecFactory components, List<ModelView<?>> inputs) {
   ServiceRegistry serviceRegistry =
       ModelViews.assertType(inputs.get(0), ModelType.of(ServiceRegistry.class)).getInstance();
   final Instantiator instantiator = serviceRegistry.get(Instantiator.class);
   final ProjectIdentifier projectIdentifier =
       ModelViews.assertType(inputs.get(1), ModelType.of(ProjectIdentifier.class)).getInstance();
   final ProjectSourceSet projectSourceSet =
       ModelViews.assertType(inputs.get(2), ModelType.of(ProjectSourceSet.class)).getInstance();
   components.registerFactory(
       Cast.<ModelType<ComponentSpec>>uncheckedCast(publicType),
       descriptor,
       new BiFunction<ComponentSpec, String, MutableModelNode>() {
         @Override
         public ComponentSpec apply(String name, MutableModelNode modelNode) {
           ComponentSpecIdentifier id =
               new DefaultComponentSpecIdentifier(projectIdentifier.getPath(), name);
           return BaseComponentSpec.create(
               implementationType.getConcreteClass(),
               id,
               modelNode,
               projectSourceSet,
               instantiator);
         }
       });
   components.registerImplementation(
       Cast.<ModelType<T>>uncheckedCast(publicType),
       descriptor,
       Cast.<ModelType<? extends T>>uncheckedCast(implementationType));
   if (COMPONENT_SPEC_INTERNAL_MODEL_TYPE.isAssignableFrom(implementationType)) {
     components.registerInternalView(publicType, descriptor, COMPONENT_SPEC_INTERNAL_MODEL_TYPE);
   }
 }
 @Override
 protected void execute(
     MutableModelNode modelNode, ComponentSpecFactory components, List<ModelView<?>> inputs) {
   components.registerPublicType(publicType);
   if (implementationType != null) {
     registerImplementation(components, inputs);
   }
   for (Class<?> internalView : internalViews) {
     components.registerInternalView(publicType, descriptor, ModelType.of(internalView));
   }
 }