{% if is_main_component %}
pub fn instantiate_main_component<R: 'static + RenderContext>(instance_registry: Rc<RefCell<InstanceRegistry<R>>>) -> Rc<RefCell<ComponentInstance<R>>> {
    ComponentInstance::instantiate( InstantiationArgs{
        properties: PropertiesCoproduct::{{ properties_coproduct_variant }}( {{ component_properties_struct }}::default() ),
        handler_registry:  Some(Rc::new(RefCell::new({
            #[allow(unused_mut)]
            let mut handler_registry = HandlerRegistry::default();
                {% for key, value in events %}
                handler_registry.{{key}}_handlers =  vec![
                    {% for handler in value %}
                        {%- if key in ['will_render','did_mount'] -%}
                            |properties, ctx|{
                                let properties = &mut *properties.as_ref().borrow_mut();
                                let properties = if let PropertiesCoproduct::{{ properties_coproduct_variant }}(p) = properties {p} else {unreachable!()};
                                {{ component_properties_struct }}::{{handler}}(properties,ctx);
                            },
                        {% else %}
                        |stack_frame, ctx, args|{
                            let properties = ((*stack_frame).borrow().get_properties());
                            let properties = &mut *properties.as_ref().borrow_mut();
                            let properties = if let PropertiesCoproduct::{{ properties_coproduct_variant }}(p) = properties {p} else {unreachable!()};
                                {{ component_properties_struct }}::{{handler}}(properties,ctx,args);
                            },
                        {% endif %}
                    {% endfor %}
                ];
                {% endfor %}
            handler_registry
        }))),
        instance_registry: Rc::clone(&instance_registry),
        common_properties: CommonProperties::default(),
        children: None,
        component_template: Some(Rc::new(RefCell::new(vec![{{render_nodes_literal}}]))),
        scroller_args: None,
        slot_index: None,
        repeat_source_expression_vec: None,
        repeat_source_expression_range: None,
        conditional_boolean_expression: None,
        compute_properties_fn: Some(Box::new(|properties, rtc|{
            let properties = &mut *properties.as_ref().borrow_mut();
            let properties = if let PropertiesCoproduct::{{ properties_coproduct_variant }}(p) = properties {p} else {unreachable!()};

            {% for prop in properties %}
            if let Some(new_value) = rtc.compute_eased_value(properties.{{prop.0.name}}._get_transition_manager()) {
            properties.{{ prop.0.name }}.set(new_value);
            } else if let Some(new_value) = rtc.compute_vtable_value(properties.{{ prop.0.name }}._get_vtable_id()) {
            let new_value = if let TypesCoproduct::{{ prop.1 }}(v) = new_value { v } else { unreachable!() };
            properties.{{ prop.0.name }}.set(new_value);
            }
            {% endfor %}
        })),
    })
}

{% else %}
#[allow(non_snake_case)]
pub fn instantiate_{{ snake_case_type_id }}<R: 'static + RenderContext>(instance_registry: Rc<RefCell<InstanceRegistry<R>>>, mut args: InstantiationArgs<R>) -> Rc<RefCell<ComponentInstance<R>>>  {
    args.component_template = Some(Rc::new(RefCell::new(vec![{{render_nodes_literal}}])));

    args.handler_registry = Some(Rc::new(RefCell::new({
     #[allow(unused_mut)]
     let mut handler_registry = HandlerRegistry::default();
     {% for key, value in events %}
     handler_registry.{{key}}_handlers =  vec![
     {% for handler in value %}
         {%- if key in ['will_render','did_mount'] -%}
             |properties, ctx|{
             let properties = &mut *properties.as_ref().borrow_mut();
             let properties = if let PropertiesCoproduct::{{ properties_coproduct_variant }}(p) = properties {p} else {unreachable!()};
             {{ component_properties_struct }}::{{handler}}(properties,ctx);
             },
     {% else %}
         |stack_frame, ctx, args|{
         let properties = ((*stack_frame).borrow().get_properties());
         let properties = &mut *properties.as_ref().borrow_mut();
         let properties = if let PropertiesCoproduct::{{ properties_coproduct_variant }}(p) = properties {p} else {unreachable!()};
         {{ component_properties_struct }}::{{handler}}(properties,ctx,args);
         },
     {% endif %}
     {% endfor %}
     ];
     {% endfor %}
     handler_registry})));

    args.compute_properties_fn = Some(Box::new(|properties, rtc|{
        let properties = &mut *properties.as_ref().borrow_mut();
        let properties = if let PropertiesCoproduct::{{ properties_coproduct_variant }}(p) = properties {p} else {unreachable!()};

        {% for prop in properties %}
            if let Some(new_value) = rtc.compute_eased_value(properties.{{prop.0.name}}._get_transition_manager()) {
            properties.{{ prop.0.name }}.set(new_value);
            } else if let Some(new_value) = rtc.compute_vtable_value(properties.{{ prop.0.name }}._get_vtable_id()) {
            let new_value = if let TypesCoproduct::{{ prop.1 }}(v) = new_value { v } else { unreachable!() };
            properties.{{ prop.0.name }}.set(new_value);
            }
        {% endfor %}
    }));

    ComponentInstance::instantiate(args)
}
{% endif %}

