/// <summary>
        /// Handles the SurfaceObserver's OnSurfaceChanged event.
        /// </summary>
        /// <param name="id">The identifier assigned to the surface which has changed.</param>
        /// <param name="changeType">The type of change that occurred on the surface.</param>
        /// <param name="bounds">The bounds of the surface.</param>
        /// <param name="updateTime">The date and time at which the change occurred.</param>
        private void SurfaceObserver_OnSurfaceChanged(UnityEngine.VR.WSA.SurfaceId id, UnityEngine.VR.WSA.SurfaceChange changeType, Bounds bounds, System.DateTime updateTime)
        {
            // Verify that the client of the Surface Observer is expecting updates.
            if (ObserverState != ObserverStates.Running)
            {
                return;
            }

            GameObject surface;

            switch (changeType)
            {
            // Adding and updating are nearly identical.  The only difference is if a new gameobject to contain
            // the surface needs to be created.
            case UnityEngine.VR.WSA.SurfaceChange.Added:
            case UnityEngine.VR.WSA.SurfaceChange.Updated:
                // Check to see if the surface is known to the observer.
                // If so, we want to add it for cleanup after we get new meshes
                // We do this because Unity doesn't properly cleanup baked collision data
                if (surfaces.TryGetValue(id.handle, out surface))
                {
                    pendingCleanup.Add(id.handle, surface);
                    surfaces.Remove(id.handle);
                }

                // Get an available surface object ready to be used
                surface = GetSurfaceObject(id.handle, transform);

                // Add the surface to our dictionary of known surfaces so
                // we can interact with it later.
                surfaces.Add(id.handle, surface);

                // Add the request to create the mesh for this surface to our work queue.
                QueueSurfaceDataRequest(id, surface);
                break;

            case UnityEngine.VR.WSA.SurfaceChange.Removed:
                // Always process surface removal events.
                // This code can be made more thread safe
                if (surfaces.TryGetValue(id.handle, out surface))
                {
                    surfaces.Remove(id.handle);
                    CleanupSurface(surface);
                    RemoveSurfaceObject(surface, false);
                }
                break;
            }

            // Event
            if (SurfaceChanged != null)
            {
                SurfaceChanged(id, changeType, bounds, updateTime);
            }
        }
        /// <summary>
        /// Handles the SurfaceObserver's OnSurfaceChanged event.
        /// </summary>
        /// <param name="id">The identifier assigned to the surface which has changed.</param>
        /// <param name="changeType">The type of change that occurred on the surface.</param>
        /// <param name="bounds">The bounds of the surface.</param>
        /// <param name="updateTime">The date and time at which the change occurred.</param>
        private void SurfaceObserver_OnSurfaceChanged(UnityEngine.VR.WSA.SurfaceId id, UnityEngine.VR.WSA.SurfaceChange changeType, Bounds bounds, DateTime updateTime)
        {
            // Verify that the client of the Surface Observer is expecting updates.
            if (ObserverState != ObserverStates.Running)
            {
                return;
            }

            switch (changeType)
            {
            case UnityEngine.VR.WSA.SurfaceChange.Added:
            case UnityEngine.VR.WSA.SurfaceChange.Updated:
                surfaceWorkQueue.Enqueue(id);
                break;

            case UnityEngine.VR.WSA.SurfaceChange.Removed:
                SurfaceObject?removedSurface = RemoveSurfaceIfFound(id.handle, destroyGameObject: false);
                if (removedSurface != null)
                {
                    ReclaimSurface(removedSurface.Value);
                }
                break;

            default:
                Debug.LogErrorFormat("Unexpected {0} value: {1}.", changeType.GetType(), changeType);
                break;
            }
        }