void GridLayout::SizeRowsAndColumns(bool layout, int width, int height,
        gfx::Size* pref)
    {
        // Make sure the master columns have been calculated.
        CalculateMasterColumnsIfNecessary();
        pref->SetSize(0, 0);
        if(rows_.empty())
        {
            return;
        }

        // Calculate the preferred width of each of the columns. Some views'
        // preferred heights are derived from their width, as such we need to
        // calculate the size of the columns first.
        for(std::vector<ColumnSet*>::iterator i=column_sets_.begin();
            i!=column_sets_.end(); ++i)
        {
            (*i)->CalculateSize();
            pref->set_width(std::max(pref->width(), (*i)->LayoutWidth()));
        }
        pref->set_width(pref->width() + left_inset_ + right_inset_);

        // Go over the columns again and set them all to the size we settled for.
        width = width ? width : pref->width();
        for(std::vector<ColumnSet*>::iterator i=column_sets_.begin();
            i!=column_sets_.end(); ++i)
        {
            // We're doing a layout, divy up any extra space.
            (*i)->Resize(width - (*i)->LayoutWidth() - left_inset_ - right_inset_);
            // And reset the x coordinates.
            (*i)->ResetColumnXCoordinates();
        }

        // Reset the height of each row.
        LayoutElement::ResetSizes(&rows_);

        // Do the following:
        // . If the view is aligned along it's baseline, obtain the baseline from the
        //   view and update the rows ascent/descent.
        // . Reset the remaining_height of each view state.
        // . If the width the view will be given is different than it's pref, ask
        //   for the height given a particularly width.
        for(std::vector<ViewState*>::iterator i=view_states_.begin();
            i!=view_states_.end(); ++i)
        {
            ViewState* view_state = *i;
            view_state->remaining_height = view_state->pref_height;

            if(view_state->v_align == BASELINE)
            {
                view_state->baseline = view_state->view->GetBaseline();
            }

            if(view_state->h_align == FILL)
            {
                // The view is resizable. As the pref height may vary with the width,
                // ask for the pref again.
                int actual_width = view_state->column_set->GetColumnWidth(
                    view_state->start_col, view_state->col_span);
                if(actual_width!=view_state->pref_width &&
                    !view_state->pref_height_fixed)
                {
                    // The width this view will get differs from it's preferred. Some Views
                    // pref height varies with it's width; ask for the preferred again.
                    view_state->pref_height =
                        view_state->view->GetHeightForWidth(actual_width);
                    view_state->remaining_height = view_state->pref_height;
                }
            }
        }

        // Update the height/ascent/descent of each row from the views.
        std::vector<ViewState*>::iterator view_states_iterator = view_states_.begin();
        for(; view_states_iterator!=view_states_.end() &&
            (*view_states_iterator)->row_span==1; ++view_states_iterator)
        {
            ViewState* view_state = *view_states_iterator;
            Row* row = rows_[view_state->start_row];
            row->AdjustSize(view_state->remaining_height);
            if(view_state->baseline!=-1 &&
                view_state->baseline<=view_state->pref_height)
            {
                row->AdjustSizeForBaseline(view_state->baseline,
                    view_state->pref_height - view_state->baseline);
            }
            view_state->remaining_height = 0;
        }

        // Distribute the height of each view with a row span > 1.
        for(; view_states_iterator!=view_states_.end(); ++view_states_iterator)
        {
            ViewState* view_state = *view_states_iterator;

            // Update the remaining_width from columns this view_state touches.
            UpdateRemainingHeightFromRows(view_state);

            // Distribute the remaining height.
            DistributeRemainingHeight(view_state);
        }

        // Update the location of each of the rows.
        LayoutElement::CalculateLocationsFromSize(&rows_);

        // We now know the preferred height, set it here.
        pref->set_height(rows_[rows_.size()-1]->Location() +
            rows_[rows_.size()-1]->Size() + top_inset_ + bottom_inset_);

        if(layout && height!=pref->height())
        {
            // We're doing a layout, and the height differs from the preferred height,
            // divy up the extra space.
            LayoutElement::DistributeDelta(height-pref->height(), &rows_);

            // Reset y locations.
            LayoutElement::CalculateLocationsFromSize(&rows_);
        }
    }