         # num_projects       - number of student projects
         # total_upgrades     - the total amount of each quota that has been applied (by anybody) to these student projects
         # your_upgrades      - total amount of each quota that this user has applied to these student projects
+        @_upgrade_is_invalid = false  # will get set to true by render_upgrade_row if invalid.
         for quota, total of purchased_upgrades
             remaining = total - (applied_upgrades[quota] ? 0)
             current   = total_upgrades[quota] ? 0


    render_upgrade_heading: (num_projects) ->
        <Row key="heading">
            <Col md=6>
                <b style={fontSize:'12pt'}>Quota</b>
            </Col>
            <Col md=6>
                <b style={fontSize:'12pt'}>Your contribution to each of {num_projects} student {misc.plural(num_projects, 'project')} (distributed equally)</b>
            </Col>
        </Row>

    upgrade_input_validation_state: (val, limit) ->
        return

    render_upgrade_row_input: (quota, input_type, current, yours, num_projects) ->
        ref = "upgrade_#{quota}"
        limit = undefined
        if input_type == 'number'
            val = @state.upgrades[quota] ? misc.round1(yours / num_projects)
            <span>
                <Input
                    type       = 'text'
                    ref        = {ref}
                    value      = {val}
                    bsStyle    = {@upgrade_input_validation_state(val, limit)}
                    onChange   = {=>u=@state.upgrades; u[quota] = @refs[ref].getValue(); @setState(upgrades:u)}
                />
            </span>

                {cur}
            </Col>
            <Col md=4>
                {@render_upgrade_row_input(quota, input_type, current, yours, num_projects, limit)}
            </Col>
            <Col md=2 style={marginTop: '8px'}>
                &times; {num_projects}
