@Override
  protected void onLayout(boolean changed, int l, int t, int r, int b) {
    int count = getChildCount();

    int left = 0;
    int top = 0;
    int right = r - l;
    int bottom = b - t;

    if (needsSort) {
      if (count > 1) { // No need to sort one item.
        viewSorter.clear();
        for (int i = 0; i < count; i++) {
          View child = getChildAt(i);
          TiCompositeLayout.LayoutParams params =
              (TiCompositeLayout.LayoutParams) child.getLayoutParams();
          params.index = i;
          viewSorter.add(child);
        }

        detachAllViewsFromParent();
        int i = 0;
        for (View child : viewSorter) {
          attachViewToParent(child, i++, child.getLayoutParams());
        }
      }
      needsSort = false;
    }

    int[] horizontal = new int[2];
    int[] vertical = new int[2];

    int currentHeight = 0;
    for (int i = 0; i < count; i++) {
      View child = getChildAt(i);
      TiCompositeLayout.LayoutParams params =
          (TiCompositeLayout.LayoutParams) child.getLayoutParams();
      if (child.getVisibility() != View.GONE) {
        // Dimension is required from Measure. Positioning is determined here.
        int childMeasuredWidth = child.getMeasuredWidth();
        int childMeasuredHeight = child.getMeasuredHeight();

        computePosition(
            params.optionLeft, params.optionRight, childMeasuredWidth, left, right, horizontal);

        if (this.vertical) {
          computeVerticalLayoutPosition(
              currentHeight,
              params.optionTop,
              params.optionBottom,
              childMeasuredHeight,
              top,
              bottom,
              vertical);
        } else {
          computePosition(
              params.optionTop, params.optionBottom, childMeasuredHeight, top, bottom, vertical);
        }

        if (DBG) {
          Log.d(
              TAG,
              child.getClass().getName()
                  + " {"
                  + horizontal[0]
                  + ","
                  + vertical[0]
                  + ","
                  + horizontal[1]
                  + ","
                  + vertical[1]
                  + "}");
        }

        int newWidth = horizontal[1] - horizontal[0];
        int newHeight = vertical[1] - vertical[0];
        if (newWidth != childMeasuredWidth || newHeight != childMeasuredHeight) {

          int newWidthSpec = MeasureSpec.makeMeasureSpec(newWidth, MeasureSpec.EXACTLY);
          int newHeightSpec = MeasureSpec.makeMeasureSpec(newHeight, MeasureSpec.EXACTLY);
          child.measure(newWidthSpec, newHeightSpec);
        }

        child.layout(horizontal[0], vertical[0], horizontal[1], vertical[1]);

        currentHeight += newHeight;
        if (params.optionTop != NOT_SET) {
          currentHeight += params.optionTop;
        }
      }
    }
  }