/// <summary>
        /// Evalute sphere physics, generate new velocities based on collisions, and update
        /// sphere positions
        /// </summary>
        protected void UpdateSpheres(GameTime gameTime)
        {
            Vector3 gravity    = Vector3.UnitY * -4.0f;
            float   shakeForce = 1.0f;

            // Tilt limit
            const float limit = 0.85f;

            // Tilt offset that determines where 'flat'
            const float tiltoffset = 0.76f;

            double accelReadingZ;
            double accelReadingY;

            float elapsedGameTime = (float)gameTime.ElapsedGameTime.TotalSeconds;

            // Read the current state of the accelerometer
            Vector3 currentAccelerometerReading = Accelerometer.GetState().Acceleration;

            // We need to reverse the accelerometer reading for the y axis depending on orientation
            if (Window.CurrentOrientation == DisplayOrientation.LandscapeLeft)
            {
                currentAccelerometerReading.Y = -currentAccelerometerReading.Y;
            }

            // Compute accelerometer magnitude
            Vector3 accelMag = Vector3.Zero;

            accelMag = currentAccelerometerReading;
            float newMag = accelMag.Length();

            // Detect a shake gesture. Search for a peak that is > 1.3f in magnitude.
            if (accelhistory[1] > 1.3f && accelhistory[0] < accelhistory[1] && accelhistory[1] > newMag)
            {
                // Compute shake force
                shakeForce += 10.0f * (accelhistory[1] - 1.3f) / 3.5f;
            }

            // MRU cache for accelerometer magnitudes
            accelhistory[0] = accelhistory[1];
            accelhistory[1] = newMag;

            // Read accelerometer Z and Y, which will be used for modifying gravity
            accelReadingZ = currentAccelerometerReading.Z;
            accelReadingY = currentAccelerometerReading.Y;

            // Limit the rotation based on accelerometer
            float rotateX = Math.Max(Math.Min((float)-(accelReadingZ + tiltoffset), limit), -limit);
            float rotateY = Math.Max(Math.Min((float)accelReadingY, limit), -limit);

            // Rotate gravity vector based on accelerometer input
            Matrix rotationToBeDone  = Matrix.CreateRotationX(rotateX * MathHelper.PiOver2);
            Matrix rotationToBeDone2 = Matrix.CreateRotationZ(rotateY * MathHelper.PiOver2);

            gravity = Vector3.Transform(gravity, rotationToBeDone);
            gravity = Vector3.Transform(gravity, rotationToBeDone2);

            // Update positions, add air friction and gravity
            for (int i = 0; i < numSpheres; i++)
            {
                Sphere mySphere = spheres[i];
                mySphere.Position += mySphere.Velocity * elapsedGameTime * 0.99f;
                // Apply accelleration due to gravity
                mySphere.Velocity += gravity * elapsedGameTime;
            }

            // Resolve sphere-sphere collisions
            for (int i = 0; i < numSpheres; i++)
            {
                for (int j = i + 1; j < numSpheres; j++)
                {
                    SphereCollisionImplicit(spheres[i], spheres[j]);
                }
            }

            // Resolve collisions with floor
            for (int i = 0; i < numSpheres; i++)
            {
                Sphere mySphere = spheres[i];
                if (mySphere.Position.Y < floorPlaneHeight + mySphere.Radius)
                {
                    // subtract out pre-accelerated gravity first
                    mySphere.Velocity -= gravity * elapsedGameTime;

                    // apply shake force
                    if (shakeForce > 1.0f)
                    {
                        // Add some upward momentum
                        mySphere.Velocity.Y += 0.1f;

                        // Compute current speed
                        float speed = mySphere.Velocity.Length();

                        // Limit new speed
                        float speedadjust = speed;
                        speedadjust = Math.Min(speed, 4.0f);
                        speedadjust = Math.Max(speed, 2.0f);

                        // normalize
                        mySphere.Velocity *= 1.0f / speed;

                        // accellerate based on shake force
                        mySphere.Velocity *= speedadjust * shakeForce;
                    }


                    mySphere.Position.Y = floorPlaneHeight + mySphere.Radius;
                    if (mySphere.Velocity.Y < 0)
                    {
                        // Determine "complete rest"
                        if (mySphere.Velocity.Y > (gravity.Y * elapsedGameTime * 2.0f) &&
                            mySphere.Velocity.LengthSquared() < (0.5 * 0.5))
                        {
                            mySphere.Velocity.Y = 0.0f;
                        }
                        else // Otherwise, bounce.
                        {
                            mySphere.Velocity.Y = -mySphere.Velocity.Y * collisionDamping;
                        }
                    }
                }

                // Resolves collisions with walls
                if (mySphere.Position.X < -worldSize + mySphere.Radius)
                {
                    mySphere.Position.X = -worldSize + mySphere.Radius;
                    if (mySphere.Velocity.X < 0)
                    {
                        mySphere.Velocity.X = -mySphere.Velocity.X * collisionDamping;
                    }
                }

                if (mySphere.Position.X > worldSize - mySphere.Radius)
                {
                    mySphere.Position.X = worldSize - mySphere.Radius;
                    if (mySphere.Velocity.X > 0)
                    {
                        mySphere.Velocity.X = -mySphere.Velocity.X * collisionDamping;
                    }
                }

                if (mySphere.Position.Z < -worldSize + mySphere.Radius)
                {
                    mySphere.Position.Z = -worldSize + mySphere.Radius;
                    if (mySphere.Velocity.Z < 0)
                    {
                        mySphere.Velocity.Z = -mySphere.Velocity.Z * collisionDamping;
                    }
                }

                if (mySphere.Position.Z > worldSize - mySphere.Radius)
                {
                    mySphere.Position.Z = worldSize - mySphere.Radius;
                    if (mySphere.Velocity.Z > 0)
                    {
                        mySphere.Velocity.Z = -mySphere.Velocity.Z * collisionDamping;
                    }
                }
            }
        }