private void updateChildrenSize(final int widthMeasureSpec, final int heightMeasureSpec) {
    for (int i = 0; i < getChildCount(); i++) {
      final ViewConstraints viewConstraints = mViewConstraints[i];
      final View v = viewConstraints.getView();
      final LayoutParams layoutParams = (LayoutParams) v.getLayoutParams();
      final int mL = layoutParams.leftMargin,
          mR = layoutParams.rightMargin,
          mT = layoutParams.topMargin,
          mB = layoutParams.bottomMargin;
      measureChildWithMargins(v, widthMeasureSpec, 0, heightMeasureSpec, 0);

      if (!viewConstraints.isHorizontalSpring()) {
        Value childWidth;
        if (v.getVisibility() == View.GONE) {
          childWidth = mLayoutMath.variable(0);
        } else if (layoutParams.relativeWidth > 0) {
          childWidth =
              mRootConstraints
                  .innerRight
                  .subtract(mRootConstraints.innerLeft)
                  .multiply(mLayoutMath.variable(layoutParams.relativeWidth))
                  .divide(mLayoutMath.variable(RELATIVE_SIZE_DENOMINATOR));
        } else {
          childWidth = mLayoutMath.variable(v.getMeasuredWidth());
        }

        viewConstraints.leftMargin.setValue(mL);
        viewConstraints.rightMargin.setValue(mR);

        Value outerWidth = childWidth.add(mLayoutMath.variable(mL + mR)).retain();
        viewConstraints.setWidth(outerWidth);
        outerWidth.release();
      }

      if (!viewConstraints.isVerticalSpring()) {
        Value childHeight;
        if (v.getVisibility() == View.GONE) {
          childHeight = mLayoutMath.variable(0);
        } else if (layoutParams.relativeHeight > 0) {
          childHeight =
              mRootConstraints
                  .innerBottom
                  .subtract(mRootConstraints.innerTop)
                  .multiply(mLayoutMath.variable(layoutParams.relativeHeight))
                  .divide(mLayoutMath.variable(RELATIVE_SIZE_DENOMINATOR));
        } else {
          childHeight = mLayoutMath.variable(v.getMeasuredHeight());
        }

        viewConstraints.topMargin.setValue(mT);
        viewConstraints.bottomMargin.setValue(mB);

        Value outerHeight = childHeight.add(mLayoutMath.variable(mT + mB)).retain();
        viewConstraints.setHeight(outerHeight);
        outerHeight.release();
      }
    }
  }
  private void handleSprings(
      final Stack<ViewConstraints> springMetrics,
      final boolean isWrapContentWidth,
      final boolean isWrapContentHeight) {
    if (!springMetrics.isEmpty()) {
      mHorizontalChains.clear();
      mVerticalChains.clear();
      while (!springMetrics.isEmpty()) {
        final ViewConstraints spring = springMetrics.pop();
        final ViewConstraints chainHeadX = getChainHorizontalHead(spring);
        final ViewConstraints chainHeadY = getChainVerticalHead(spring);
        if (chainHeadX != null) {
          if (isWrapContentWidth && mMinWidth <= 0) {
            throw new IllegalStateException(
                "Horizontal springs not supported when layout width is wrap_content");
          }
          mHorizontalChains.add(chainHeadX);
        }
        if (chainHeadY != null) {
          if (isWrapContentHeight && mMinHeight <= 0) {
            throw new IllegalStateException(
                "Vertical springs not supported when layout height is wrap_content and minHeight is not defined");
          }
          mVerticalChains.add(chainHeadY);
        }
      }

      for (int i = 0; i < mHorizontalChains.size(); i++) {
        final ViewConstraints chainHead = mHorizontalChains.get(i);
        int totalWeight = 0;
        Value contentWidth = mLayoutMath.variable(0);
        final ValueWrapper totalWeightWrapper = mLayoutMath.wrap();
        final ValueWrapper chainWidthWrapper = mLayoutMath.wrap();
        ViewConstraints chainElem = chainHead, prevElem = null;
        Value start = chainElem.left, end;
        while (chainElem != null) {
          if (chainElem.isHorizontalSpring()) {
            chainElem.markHorizontalSpringUsed();
            final int weight = ((LayoutParams) chainElem.getView().getLayoutParams()).widthWeight;
            totalWeight += weight;
            final Value width =
                chainWidthWrapper
                    .multiply(mLayoutMath.variable(weight))
                    .divide(totalWeightWrapper)
                    .max(mLayoutMath.variable(0))
                    .retain();
            chainElem.setWidth(width);
            width.release();
          } else {
            contentWidth = contentWidth.add(chainElem.getWidth());
          }
          prevElem = chainElem;
          chainElem = chainElem.nextX;
        }
        end = prevElem.right;
        totalWeightWrapper.setValueObject(mLayoutMath.variable(totalWeight));
        chainWidthWrapper.setValueObject(end.subtract(start).subtract(contentWidth));
      }

      for (int i = 0; i < mVerticalChains.size(); i++) {
        final ViewConstraints chainHead = mVerticalChains.get(i);
        int totalWeight = 0;
        Value contentHeight = mLayoutMath.variable(0);
        final ValueWrapper totalWeightWrapper = mLayoutMath.wrap();
        final ValueWrapper chainWidthWrapper = mLayoutMath.wrap();
        ViewConstraints chainElem = chainHead, prevElem = null;
        Value start = chainElem.top, end;
        while (chainElem != null) {
          if (chainElem.isVerticalSpring()) {
            chainElem.markVerticalSpringUsed();
            final int weight = ((LayoutParams) chainElem.getView().getLayoutParams()).heightWeight;
            totalWeight += weight;
            final Value height =
                chainWidthWrapper
                    .multiply(mLayoutMath.variable(weight))
                    .divide(totalWeightWrapper)
                    .max(mLayoutMath.variable(0))
                    .retain();
            chainElem.setHeight(height);
            height.release();
          } else {
            contentHeight = contentHeight.add(chainElem.getHeight());
          }
          prevElem = chainElem;
          chainElem = chainElem.nextY;
        }
        end = prevElem.bottom;
        totalWeightWrapper.setValueObject(mLayoutMath.variable(totalWeight));
        chainWidthWrapper.setValueObject(end.subtract(start).subtract(contentHeight));
      }
    }
  }