protected override MeasuredLayout calculateMeasuredLayout(Bounds perantBounds)
        {
            MeasuredLayout calculatedRootItem = base.calculateMeasuredLayout(perantBounds);

            calculatedRootItem.type         = "CustomPlacementLayout";
            calculatedRootItem.drawable     = this;
            calculatedRootItem.reactiveView = this;

            Bounds resultBounds = calculatedRootItem.getBounds().clone();

            double largestX = 0;
            double largestY = 0;

            foreach (ILayoutItem layoutItem in childLayoutItems)
            {
                MeasuredLayout nextChild = layoutItem.getMeasuredLayout(resultBounds);
                nextChild.reactiveView = (ReactiveView)layoutItem;

                double width  = nextChild.getBounds().rect.Width;
                double height = nextChild.getBounds().rect.Height;

                if (width > largestX)
                {
                    largestX = width;
                }
                if (height > largestY)
                {
                    largestY = height;
                }

                calculatedRootItem.addCalculatedChild(nextChild);
            }

            if (sizeParams.Width == WRAP_CONTENTS)
            {
                calculatedRootItem.getBounds().rect.Width = largestX;

                foreach (MeasuredLayout layoutItem in calculatedRootItem.getCalculatedChildren())
                {
                    layoutItem.getBounds().rect.Location = new Point(layoutItem.getBounds().rect.Location.X + largestX / 2, layoutItem.getBounds().rect.Location.Y);
                }
            }
            if (sizeParams.Width == WRAP_CONTENTS)
            {
                calculatedRootItem.getBounds().rect.Height = largestY;

                foreach (MeasuredLayout layoutItem in calculatedRootItem.getCalculatedChildren())
                {
                    layoutItem.getBounds().rect.Location = new Point(layoutItem.getBounds().rect.Location.X, layoutItem.getBounds().rect.Location.Y + largestY / 2);
                }
            }

            return(calculatedRootItem);
        }
        protected override MeasuredLayout calculateMeasuredLayout(Bounds perantBounds)
        {
            MeasuredLayout calculatedRootItem = new MeasuredLayout();

            calculatedRootItem.type         = "Fragment";
            calculatedRootItem.drawable     = this;
            calculatedRootItem.reactiveView = this;
            calculatedRootItem.setBounds(perantBounds.clone());

            double largestX = 0;
            double largestY = 0;

            foreach (ILayoutItem layoutItem in childLayoutItems)
            {
                MeasuredLayout nextChild = layoutItem.getMeasuredLayout(perantBounds.clone());
                nextChild.reactiveView = (ReactiveView)layoutItem;

                nextChild.getBounds().rect.Location = new Point(0, 0);

                double width  = nextChild.getBounds().rect.Width;
                double height = nextChild.getBounds().rect.Height;

                if (width > largestX)
                {
                    largestX = width;
                }
                if (height > largestY)
                {
                    largestY = height;
                }

                calculatedRootItem.addCalculatedChild(nextChild);
            }

            if (sizeParams.Width == WRAP_CONTENTS)
            {
                calculatedRootItem.getBounds().rect.Width = largestX;
            }
            if (sizeParams.Width == WRAP_CONTENTS)
            {
                calculatedRootItem.getBounds().rect.Height = largestY;
            }

            return(calculatedRootItem);
        }
        protected override MeasuredLayout calculateMeasuredLayout(Bounds perantBounds)
        {
            MeasuredLayout calculatedItem = base.calculateMeasuredLayout(perantBounds);

            calculatedItem.type         = "ScrollLayout";
            calculatedItem.drawable     = this;
            calculatedItem.reactiveView = this;

            if (childLayoutItems.Count > 0)
            {
                MeasuredLayout child       = childLayoutItems[0].getMeasuredLayout(perantBounds);
                Bounds         childBounds = child.getBounds();
                childBounds.rect.Offset(new Vector(offset.X, offset.Y));
                calculatedItem.addCalculatedChild(child);
            }

            return(calculatedItem);
        }
        protected override MeasuredLayout calculateMeasuredLayout(Bounds perantBounds)
        {
            Bounds resultBounds = perantBounds.clone();

            MeasuredLayout calculatedRootItem = new MeasuredLayout();

            calculatedRootItem.type         = "StackLayout";
            calculatedRootItem.drawable     = this;
            calculatedRootItem.reactiveView = this;

            Bounds itemBounds = calculateBounds(resultBounds.rect, new Rect());

            if (sizeParams.Width == WRAP_CONTENTS) // This gives the child a chance to match to this items perants dimension if this item is wrapping
            {
                itemBounds.rect.Width = perantBounds.rect.Width;
            }
            if (sizeParams.Height == WRAP_CONTENTS)
            {
                itemBounds.rect.Height = perantBounds.rect.Height;
            }

            calculatedRootItem.setBounds(itemBounds);

            Point maxChildDimensions = getMaxFixedChildDimensions(calculatedRootItem.getBounds());

            double largestX = maxChildDimensions.X;
            double largestY = maxChildDimensions.Y;
            double yOffset  = 0;
            double xOffset  = 0;

            foreach (ILayoutItem layoutItem in childLayoutItems)
            {
                Bounds boundsOffsetFromStart = calculatedRootItem.getBounds().clone();

                if (!vertical_orientation && sizeParams.Height == WRAP_CONTENTS)
                {
                    boundsOffsetFromStart.rect.Height = largestY;
                }

                if (vertical_orientation && sizeParams.Width == WRAP_CONTENTS)
                {
                    boundsOffsetFromStart.rect.Width = largestX;
                }

                // The new bounds for each child must take into account the space that has allready been used UNLESS ...
                if (vertical_orientation)
                {
                    boundsOffsetFromStart.rect = new Rect(new Point(0, yOffset), new Size(boundsOffsetFromStart.rect.Width, Math.Max(boundsOffsetFromStart.rect.Height - yOffset, 0)));
                }
                else if (!vertical_orientation)
                {
                    boundsOffsetFromStart.rect = new Rect(new Point(xOffset, 0), new Size(Math.Max(boundsOffsetFromStart.rect.Width - xOffset, 0), boundsOffsetFromStart.rect.Height));
                }

                // .. unless if the child uses a pecentage of the perants dimension, in which case pass the original width

                // Use the original perants width if the child is using a percentage of the perants width (in this case the space currently used is ignored)
                if (((BaseLayout)layoutItem).sizeParams.WidthPercent > 0)
                {
                    boundsOffsetFromStart.rect.Width = perantBounds.rect.Width;
                    boundsOffsetFromStart.rect.X     = perantBounds.rect.X;
                }
                // Use the original perants height if the child is using a percentage of the perants height
                if (((BaseLayout)layoutItem).sizeParams.HeightPercent > 0)
                {
                    boundsOffsetFromStart.rect.Height = perantBounds.rect.Height;
                    boundsOffsetFromStart.rect.Y      = perantBounds.rect.Y;
                }

                MeasuredLayout nextChild = layoutItem.getMeasuredLayout(boundsOffsetFromStart);
                nextChild.setBounds(offsetBounds(yOffset, xOffset, nextChild.getBounds()));

                calculatedRootItem.addCalculatedChild(nextChild);

                yOffset += nextChild.getBounds().rect.Height;
                xOffset += nextChild.getBounds().rect.Width;
            }


            // if the bounds were set to the perants (if the param was wrap) then change to the calcualted dimension
            if (vertical_orientation)
            {
                if (sizeParams.Width == WRAP_CONTENTS)
                {
                    calculatedRootItem.getBounds().rect.Width = largestX;
                }
                if (sizeParams.Height == WRAP_CONTENTS)
                {
                    calculatedRootItem.getBounds().rect.Height = yOffset;
                }
            }
            else
            {
                if (sizeParams.Width == WRAP_CONTENTS)
                {
                    calculatedRootItem.getBounds().rect.Width = xOffset;
                }
                if (sizeParams.Height == WRAP_CONTENTS)
                {
                    calculatedRootItem.getBounds().rect.Height = largestY;
                }
            }


            if (invertDirection)
            {
                inverseBounds(calculatedRootItem, !vertical_orientation, vertical_orientation);
            }

            return(calculatedRootItem);
        }