public bool TestOverlapBound(b2BoundValues b, b2Proxy p)
        {
            for (int axis = 0; axis < 2; ++axis)
            {
                List <b2Bound> bounds = m_bounds[axis];

                //b2Settings.b2Assert(p.lowerBounds[axis] < 2 * m_proxyCount);
                //b2Settings.b2Assert(p.upperBounds[axis] < 2 * m_proxyCount);

                b2Bound bound = bounds[(int)p.upperBounds[axis]];
                if (b.lowerValues[axis] > bound.value)
                {
                    return(false);
                }

                bound = bounds[(int)p.lowerBounds[axis]];
                if (b.upperValues[axis] < bound.value)
                {
                    return(false);
                }
            }

            return(true);
        }
        // Call MoveProxy as many times as you like, then when you are done
        // call Commit to finalized the proxy pairs (for your time step).
        public void MoveProxy(object proxy_, b2AABB aabb, b2Vec2 displacement)
        {
            b2Proxy proxy = proxy_ as b2Proxy;

            List <uint> as3arr;
            int         as3int;

            int     axis;
            uint    index;
            b2Bound bound;
            b2Bound prevBound;
            b2Bound nextBound;
            uint    nextProxyId;
            b2Proxy nextProxy;

            if (proxy == null)
            {
                //b2Settings.b2Assert(false);
                return;
            }

            if (aabb.IsValid() == false)
            {
                //b2Settings.b2Assert(false);
                return;
            }

            uint boundCount = (uint)(2 * m_proxyCount);

            // Get new bound values
            b2BoundValues newValues = new b2BoundValues();

            ComputeBounds(newValues.lowerValues, newValues.upperValues, aabb);

            // Get old bound values
            b2BoundValues oldValues = new b2BoundValues();

            for (axis = 0; axis < 2; ++axis)
            {
                bound = m_bounds[axis][(int)proxy.lowerBounds[axis]];
                oldValues.lowerValues[axis] = bound.value;
                bound = m_bounds[axis][(int)proxy.upperBounds[axis]];
                oldValues.upperValues[axis] = bound.value;
            }

            for (axis = 0; axis < 2; ++axis)
            {
                List <b2Bound> bounds = m_bounds[axis];

                uint lowerIndex = proxy.lowerBounds[axis];
                uint upperIndex = proxy.upperBounds[axis];

                uint lowerValue = (uint)newValues.lowerValues[axis];
                uint upperValue = (uint)newValues.upperValues[axis];

                bound = bounds[(int)lowerIndex];
                int deltaLower = (int)(lowerValue - bound.value);
                bound.value = lowerValue;

                bound = bounds[(int)upperIndex];
                int deltaUpper = (int)(upperValue - bound.value);
                bound.value = upperValue;

                //
                // Expanding adds overlaps
                //

                // Should we move the lower bound down?
                if (deltaLower < 0)
                {
                    index = lowerIndex;
                    while (index > 0 && lowerValue < (bounds[(int)(index - 1)] as b2Bound).value)
                    {
                        bound     = bounds[(int)index];
                        prevBound = bounds[(int)(index - 1)];

                        b2Proxy prevProxy = prevBound.proxy;

                        prevBound.stabbingCount++;

                        if (prevBound.IsUpper() == true)
                        {
                            if (TestOverlapBound(newValues, prevProxy))
                            {
                                m_pairManager.AddBufferedPair(proxy, prevProxy);
                            }

                            //prevProxy.upperBounds[axis]++;
                            as3arr = prevProxy.upperBounds;
                            as3int = (int)as3arr[axis];
                            as3int++;
                            as3arr[axis] = (uint)as3int;

                            bound.stabbingCount++;
                        }
                        else
                        {
                            //prevProxy.lowerBounds[axis]++;
                            as3arr = prevProxy.lowerBounds;
                            as3int = (int)as3arr[axis];
                            as3int++;
                            as3arr[axis] = (uint)as3int;

                            bound.stabbingCount--;
                        }

                        //proxy.lowerBounds[axis]--;
                        as3arr = proxy.lowerBounds;
                        as3int = (int)as3arr[axis];
                        as3int--;
                        as3arr[axis] = (uint)as3int;

                        // swap
                        //var temp:b2Bound = bound;
                        //bound = prevEdge;
                        //prevEdge = temp;
                        bound.Swap(prevBound);
                        //b2Math.Swap(bound, prevEdge);
                        --index;
                    }
                }

                // Should we move the upper bound up?
                if (deltaUpper > 0)
                {
                    index = upperIndex;
                    while (index < boundCount - 1 && (bounds[(int)(index + 1)] as b2Bound).value <= upperValue)
                    {
                        bound     = bounds[(int)index];
                        nextBound = bounds[(int)(index + 1)];
                        nextProxy = nextBound.proxy;

                        nextBound.stabbingCount++;

                        if (nextBound.IsLower() == true)
                        {
                            if (TestOverlapBound(newValues, nextProxy))
                            {
                                m_pairManager.AddBufferedPair(proxy, nextProxy);
                            }

                            //nextProxy.lowerBounds[axis]--;
                            as3arr = nextProxy.lowerBounds;
                            as3int = (int)as3arr[axis];
                            as3int--;
                            as3arr[axis] = (uint)as3int;

                            bound.stabbingCount++;
                        }
                        else
                        {
                            //nextProxy.upperBounds[axis]--;
                            as3arr = nextProxy.upperBounds;
                            as3int = (int)as3arr[axis];
                            as3int--;
                            as3arr[axis] = (uint)as3int;

                            bound.stabbingCount--;
                        }

                        //proxy.upperBounds[axis]++;
                        as3arr = proxy.upperBounds;
                        as3int = (int)as3arr[axis];
                        as3int++;
                        as3arr[axis] = (uint)as3int;

                        // swap
                        //var temp:b2Bound = bound;
                        //bound = nextEdge;
                        //nextEdge = temp;
                        bound.Swap(nextBound);
                        //b2Math.Swap(bound, nextEdge);
                        index++;
                    }
                }

                //
                // Shrinking removes overlaps
                //

                // Should we move the lower bound up?
                if (deltaLower > 0)
                {
                    index = lowerIndex;
                    while (index < boundCount - 1 && (bounds[(int)(index + 1)] as b2Bound).value <= lowerValue)
                    {
                        bound     = bounds[(int)index];
                        nextBound = bounds[(int)(index + 1)];

                        nextProxy = nextBound.proxy;

                        nextBound.stabbingCount--;

                        if (nextBound.IsUpper())
                        {
                            if (TestOverlapBound(oldValues, nextProxy))
                            {
                                m_pairManager.RemoveBufferedPair(proxy, nextProxy);
                            }

                            //nextProxy.upperBounds[axis]--;
                            as3arr = nextProxy.upperBounds;
                            as3int = (int)as3arr[axis];
                            as3int--;
                            as3arr[axis] = (uint)as3int;

                            bound.stabbingCount--;
                        }
                        else
                        {
                            //nextProxy.lowerBounds[axis]--;
                            as3arr = nextProxy.lowerBounds;
                            as3int = (int)as3arr[axis];
                            as3int--;
                            as3arr[axis] = (uint)as3int;

                            bound.stabbingCount++;
                        }

                        //proxy.lowerBounds[axis]++;
                        as3arr = proxy.lowerBounds;
                        as3int = (int)as3arr[axis];
                        as3int++;
                        as3arr[axis] = (uint)as3int;

                        // swap
                        //var temp:b2Bound = bound;
                        //bound = nextEdge;
                        //nextEdge = temp;
                        bound.Swap(nextBound);
                        //b2Math.Swap(bound, nextEdge);
                        index++;
                    }
                }

                // Should we move the upper bound down?
                if (deltaUpper < 0)
                {
                    index = upperIndex;
                    while (index > 0 && upperValue < (bounds[(int)(index - 1)] as b2Bound).value)
                    {
                        bound     = bounds[(int)index];
                        prevBound = bounds[(int)(index - 1)];

                        b2Proxy prevProxy = prevBound.proxy;

                        prevBound.stabbingCount--;

                        if (prevBound.IsLower() == true)
                        {
                            if (TestOverlapBound(oldValues, prevProxy))
                            {
                                m_pairManager.RemoveBufferedPair(proxy, prevProxy);
                            }

                            //prevProxy.lowerBounds[axis]++;
                            as3arr = prevProxy.lowerBounds;
                            as3int = (int)as3arr[axis];
                            as3int++;
                            as3arr[axis] = (uint)as3int;

                            bound.stabbingCount--;
                        }
                        else
                        {
                            //prevProxy.upperBounds[axis]++;
                            as3arr = prevProxy.upperBounds;
                            as3int = (int)as3arr[axis];
                            as3int++;
                            as3arr[axis] = (uint)as3int;

                            bound.stabbingCount++;
                        }

                        //proxy.upperBounds[axis]--;
                        as3arr = proxy.upperBounds;
                        as3int = (int)as3arr[axis];
                        as3int--;
                        as3arr[axis] = (uint)as3int;

                        // swap
                        //var temp:b2Bound = bound;
                        //bound = prevEdge;
                        //prevEdge = temp;
                        bound.Swap(prevBound);
                        //b2Math.Swap(bound, prevEdge);
                        index--;
                    }
                }
            }
        }