Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/CallbackLock.cs
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/CallbackLock.cs	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/CallbackLock.cs	(revision 28895)
@@ -0,0 +1,46 @@
+﻿// -----------------------------------------------------------------------
+// <copyright file="CallbackLock.cs" company="Microsoft">
+//     Copyright (c) Microsoft Corporation.  All rights reserved.
+// </copyright>
+// -----------------------------------------------------------------------
+
+namespace Microsoft.Kinect.Toolkit
+{
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Threading;
+
+    public delegate void LockExitEventHandler();
+
+    /// <summary>
+    /// Utility class that encapsulates critical section-like locking
+    /// and an event that gets fired after we exit the lock.  Its
+    /// purpose in life is to delay calling event handlers until after
+    /// we exit the lock.  If you call event handlers while you hold a
+    /// lock it's easy to deadlock.  Those event handlers could
+    /// choose to block on something on a different thread that's
+    /// waiting on our lock.
+    /// </summary>
+    public sealed class CallbackLock : IDisposable
+    {
+        private readonly object lockObject;
+
+        public CallbackLock(object lockTarget)
+        {
+            this.lockObject = lockTarget;
+            Monitor.Enter(lockTarget);
+        }
+
+        [SuppressMessage("Microsoft.Design", "CA1009:DeclareEventHandlersCorrectly", Justification = "Helper event to defer actions until after lock exit doesn't need arguments")]
+        public event LockExitEventHandler LockExit;
+
+        public void Dispose()
+        {
+            Monitor.Exit(lockObject);
+            if (LockExit != null)
+            {
+                LockExit();
+            }
+        }
+    }
+}
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/ContextEventWrapper.cs
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/ContextEventWrapper.cs	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/ContextEventWrapper.cs	(revision 28895)
@@ -0,0 +1,393 @@
+﻿//-----------------------------------------------------------------------
+// <copyright file="ContextEventWrapper.cs" company="Microsoft Corporation">
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// </copyright>
+// <summary>
+// This file contains the internal classes used to track the synchronization
+// context and events handling.
+// </summary>
+//-----------------------------------------------------------------------
+
+namespace Microsoft.Kinect.Toolkit
+{
+    using System;
+    using System.Reflection;
+    using System.Threading;
+
+    /// <summary>
+    /// The possible methods for sending data to the synchronization context.
+    /// </summary>
+    public enum ContextSynchronizationMethod
+    {
+        /// <summary>
+        /// The send method is used to pass synchronous message to the context.
+        /// </summary>
+        Send,
+
+        /// <summary>
+        /// The post method is used to pass an asynchronous message to the context.
+        /// </summary>
+        Post
+    }
+
+    /// <summary>
+    /// Wrapper that holds a collection of event handlers for a specific type and associates
+    /// a context with them.
+    /// </summary>
+    /// <typeparam name="T">EventArgs for the specific event.</typeparam>
+    /// <remarks>
+    /// Note that this has the implementation of IDisposable but not the interface.
+    /// You may call Dispose on it if you need to.  Otherwise you can let the GC handle
+    /// things.
+    /// </remarks>
+    public class ContextEventWrapper<T> where T : EventArgs 
+    {
+        /// <summary>
+        /// This holds the list of context to handler mappings.
+        /// </summary>
+        private readonly ThreadSafeCollection<ContextHandlerPair> actualHandlers;
+
+        /// <summary>
+        /// This is the method used process the message by the synchronization context.
+        /// </summary>
+        private readonly ContextSynchronizationMethod method;
+
+        /// <summary>
+        /// This keeps track of the disposed state of the object.
+        /// </summary>
+        private bool isDisposed;
+        
+        /// <summary>
+        /// Initializes a new instance of the ContextEventWrapper class.
+        /// </summary>
+        /// <param name="method">Determines whether the context will use Post or Send. Default is Post.</param>
+        public ContextEventWrapper(ContextSynchronizationMethod method)
+        {
+            isDisposed = false;
+            this.method = method;
+            actualHandlers = new ThreadSafeCollection<ContextHandlerPair>();
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the ContextEventWrapper class.
+        /// </summary>
+        public ContextEventWrapper() : this(ContextSynchronizationMethod.Post)
+        {
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether this wrapper has any actual handlers registered.
+        /// </summary>
+        public bool HasHandlers
+        {
+            get { return actualHandlers.Count > 0; }
+        }
+
+        /// <summary>
+        /// Adds an event handler and associates it with the current context.
+        /// </summary>
+        /// <param name="originalHandler">The new event to add to the list of handlers.</param>
+        public void AddHandler(EventHandler<T> originalHandler)
+        {
+            if (originalHandler != null)
+            {
+                actualHandlers.Add(new ContextHandlerPair(originalHandler, new SynchronizationContextIdentifier(SynchronizationContext.Current)));
+            }
+        }
+
+        /// <summary>
+        /// Removes the event handler associated with the current context.
+        /// </summary>
+        /// <param name="originalHandler">The event to remove from the list of handlers.</param>
+        public void RemoveHandler(EventHandler<T> originalHandler)
+        {
+            SynchronizationContextIdentifier currentContextId = new SynchronizationContextIdentifier(SynchronizationContext.Current);
+            ContextHandlerPair pairToRemove = null;
+
+            // Find the first matching pair
+            foreach (ContextHandlerPair pair in actualHandlers)
+            {
+                EventHandler<T> handler = pair.Handler;
+                SynchronizationContextIdentifier contextId = pair.ContextId;
+
+                if (currentContextId == contextId && handler == originalHandler)
+                {
+                    // Stop on first find
+                    pairToRemove = pair;
+                    break;
+                }
+            }
+
+            // remove if found
+            if (pairToRemove != null)
+            {
+                actualHandlers.Remove(pairToRemove);
+            }
+        }
+
+        /// <summary>
+        /// Invokes all registered event handlers.
+        /// </summary>
+        /// <param name="sender">The sender of the message.</param>
+        /// <param name="eventArgs">The event arguments to be passed to the handler.</param>
+        public void Invoke(object sender, T eventArgs)
+        {
+            if (HasHandlers)
+            {
+                // Invoke each handler on the list
+                // Note:  Enumerator is a snapshotting enumerator, so this is thread-safe and reentrency safe.
+                foreach (ContextHandlerPair pair in actualHandlers)
+                {
+                    EventHandler<T> handler = pair.Handler;
+                    SynchronizationContext context = pair.ContextId.Context;
+
+                    if (context == null)
+                    {
+                        handler(sender, eventArgs);
+                    }
+                    else if (method == ContextSynchronizationMethod.Post)
+                    {
+                        context.Post(SendOrPostDelegate, new ContextEventHandlerArgsWrapper(handler, sender, eventArgs));
+                    }
+                    else if (method == ContextSynchronizationMethod.Send)
+                    {
+                        context.Send(SendOrPostDelegate, new ContextEventHandlerArgsWrapper(handler, sender, eventArgs));
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// This method marks the object as disposed.
+        /// </summary>
+        public void Dispose()
+        {
+            isDisposed = true;
+            actualHandlers.Clear();
+        }
+
+        /// <summary>
+        /// Internal handler that matches the delegates for SynchronizationContext.Post/Send.
+        /// </summary>
+        /// <param name="state">State packed as ContextEventHandlerArgsWrapper ( handler + sender + args ).</param>
+        private void SendOrPostDelegate(object state)
+        {
+            // This can get disposed before the marshalling is done
+            if (isDisposed)
+            {
+                return;
+            }
+
+            var currentState = (ContextEventHandlerArgsWrapper)state;
+            currentState.Handler(currentState.Sender, currentState.Args);
+        }
+
+        /// <summary>
+        /// Container class to hold event handler, sender and args so that it can be
+        /// marshalled using the Synchronization context.
+        /// </summary>
+        private class ContextEventHandlerArgsWrapper
+        {
+            /// <summary>
+            /// Initializes a new instance of the ContextEventHandlerArgsWrapper class.
+            /// </summary>
+            /// <param name="handler">The event handler.</param>
+            /// <param name="sender">The sending object.</param>
+            /// <param name="args">The argument object.</param>
+            public ContextEventHandlerArgsWrapper(EventHandler<T> handler, object sender, T args)
+            {
+                Handler = handler;
+                Sender = sender;
+                Args = args;
+            }
+
+            /// <summary>
+            /// Gets the associated event handler.
+            /// </summary>
+            public EventHandler<T> Handler { get; private set; }
+
+            /// <summary>
+            /// Gets the sending object.
+            /// </summary>
+            public object Sender { get; private set; }
+
+            /// <summary>
+            /// Gets the event arguments object.
+            /// </summary>
+            public T Args { get; private set; }
+        }
+
+        /// <summary> 
+        /// Identifies a SynchronizationContext taking the potential that it is a DispatcherSynchronizationContext 
+        /// into account. While the actual SynchronizationContext instance may change, the internal referenced
+        /// Dispatcher will not, so we use this for determining identity when available.
+        /// </summary>
+        private class SynchronizationContextIdentifier
+        {
+            /// <summary>
+            /// Name of the internal field in DispatcherSynchronizationContext to reflect on when
+            /// comparing SynchronizationContextIdentifiers.
+            /// </summary>
+            private const string DispatcherFieldName = "_dispatcher";
+
+            /// <summary>
+            /// The unqualified name of the DispatcherSynchronizationContext type.
+            /// </summary>
+            private const string DispatcherSynchronizationContextName = "DispatcherSynchronizationContext";
+
+            /// <summary>
+            /// Storage for the Dispatcher object, if one exists.
+            /// </summary>
+            private object dispatcherObject;
+
+            /// <summary>
+            /// Initializes a new instance of the SynchronizationContextIdentifier class.
+            /// </summary>
+            /// <param name="context">The SynchronizationContext to extract identity for.</param>
+            public SynchronizationContextIdentifier(SynchronizationContext context)
+            {
+                Context = context;
+
+                if (!object.ReferenceEquals(context, null))
+                {
+                    Type contextType = context.GetType();
+                    if (DispatcherSynchronizationContextName == contextType.Name)
+                    {
+                        FieldInfo dispatcherField = contextType.GetField(DispatcherFieldName, BindingFlags.Instance | BindingFlags.NonPublic);
+                        if (dispatcherField != null)
+                        {
+                            dispatcherObject = dispatcherField.GetValue(context);
+                        }
+                    }
+                }
+            }
+
+            /// <summary>
+            /// Gets the SynchronizationContext held by the SynchronizationContextIdentifier.
+            /// </summary>
+            public SynchronizationContext Context { get; private set; }
+
+            /// <summary>
+            /// This method compares two SynchronizationContextIdentifiers.
+            /// </summary>
+            /// <param name="contextId1">The first SynchronizationContextIdentifier to compare.</param>
+            /// <param name="contextId2">The second SynchronizationContextIdentifier to compare.</param>
+            /// <returns>Returns true if they are equal, false otherwise.</returns>
+            public static bool operator ==(SynchronizationContextIdentifier contextId1, SynchronizationContextIdentifier contextId2)
+            {
+                if (object.ReferenceEquals(contextId1, null) || object.ReferenceEquals(contextId2, null))
+                {
+                    return false;
+                }
+
+                return contextId1.Equals(contextId2);
+            }
+
+            /// <summary>
+            /// This method compares two SynchronizationContextIdentifiers.
+            /// </summary>
+            /// <param name="contextId1">The first SynchronizationContextIdentifier to compare.</param>
+            /// <param name="contextId2">The second SynchronizationContextIdentifier to compare.</param>
+            /// <returns>Returns false if they are equal, true otherwise.</returns>
+            public static bool operator !=(SynchronizationContextIdentifier contextId1, SynchronizationContextIdentifier contextId2)
+            {
+                if (object.ReferenceEquals(contextId1, null) || object.ReferenceEquals(contextId2, null))
+                {
+                    return true;
+                }
+
+                return !contextId1.Equals(contextId2);
+            }
+
+            /// <summary>
+            /// Gets the hashcode of the object.
+            /// </summary>
+            /// <returns>Hashcode of the SynchronizationContextIdentifier.</returns>
+            public override int GetHashCode()
+            {
+                if (object.ReferenceEquals(dispatcherObject, null))
+                {
+                    return object.ReferenceEquals(Context, null) ? 0 : Context.GetHashCode();
+                }
+                else
+                {
+                    return dispatcherObject.GetHashCode();
+                }
+            }
+
+            /// <summary>
+            /// Returns whether this SynchronizationContextIdentifier is equivalent to obj.
+            /// </summary>
+            /// <param name="obj">The object to compare for equivalence.</param>
+            /// <returns>True if this SynchronizationContextIdentifier is equivalent to obj, false otherwise.</returns>
+            public override bool Equals(object obj)
+            {
+                SynchronizationContextIdentifier contextId = obj as SynchronizationContextIdentifier;
+
+                if (object.ReferenceEquals(contextId, null))
+                {
+                    return false;
+                }
+
+                return this.Equals(contextId);
+            }
+
+            /// <summary>
+            /// Returns whether this SynchronizationContextIdentifier is equivalent to obj.
+            /// </summary>
+            /// <param name="contextId">The object to compare for equivalence.</param>
+            /// <returns>True if this SynchronizationContextIdentifier is equivalent to obj, false otherwise.</returns>
+            public bool Equals(SynchronizationContextIdentifier contextId)
+            {
+                if (object.ReferenceEquals(contextId, null))
+                {
+                    return false;
+                }
+
+                if (dispatcherObject == null && contextId.dispatcherObject == null)
+                {
+                    // If no Dispatcher is present, just compare the SynchronizationContexts.
+                    return Context == contextId.Context;
+                }
+
+                return dispatcherObject == contextId.dispatcherObject;
+            }
+        }
+
+        /// <summary>
+        /// Container class to associate an event handler with a context so that they
+        /// act as a single key in a list.
+        /// </summary>
+        private class ContextHandlerPair
+        {
+            /// <summary>
+            /// Initializes a new instance of the ContextHandlerPair class.
+            /// </summary>
+            /// <param name="handler">The target handler.</param>
+            /// <param name="contextId">The target context identifier.</param>
+            public ContextHandlerPair(EventHandler<T> handler, SynchronizationContextIdentifier contextId)
+            {
+                Handler = handler;
+                ContextId = contextId;
+            }
+
+            /// <summary>
+            /// Gets the associated synchronization context identifier.
+            /// </summary>
+            public SynchronizationContextIdentifier ContextId
+            {
+                get;
+                private set;
+            }
+
+            /// <summary>
+            /// Gets the associated event handler.
+            /// </summary>
+            public EventHandler<T> Handler
+            {
+                get;
+                private set;
+            }
+        }
+    }
+}
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectChangedEventArgs.cs
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectChangedEventArgs.cs	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectChangedEventArgs.cs	(revision 28895)
@@ -0,0 +1,27 @@
+﻿// -----------------------------------------------------------------------
+// <copyright file="KinectChangedEventArgs.cs" company="Microsoft">
+//     Copyright (c) Microsoft Corporation.  All rights reserved.
+// </copyright>
+// -----------------------------------------------------------------------
+
+namespace Microsoft.Kinect.Toolkit
+{
+    using System;
+    using Microsoft.Kinect;
+
+    /// <summary>
+    /// Args for the KinectChanged event
+    /// </summary>
+    public class KinectChangedEventArgs : EventArgs
+    {
+        public KinectChangedEventArgs(KinectSensor oldSensor, KinectSensor newSensor)
+        {
+            this.OldSensor = oldSensor;
+            this.NewSensor = newSensor;
+        }
+
+        public KinectSensor OldSensor { get; private set; }
+
+        public KinectSensor NewSensor { get; private set; }
+    }
+}
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooser.cs
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooser.cs	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooser.cs	(revision 28895)
@@ -0,0 +1,454 @@
+﻿// -----------------------------------------------------------------------
+// <copyright file="KinectSensorChooser.cs" company="Microsoft">
+//     Copyright (c) Microsoft Corporation.  All rights reserved.
+// </copyright>
+// -----------------------------------------------------------------------
+
+namespace Microsoft.Kinect.Toolkit
+{
+    using System;
+    using System.Collections.Generic;
+    using System.ComponentModel;
+    using System.Diagnostics;
+    using System.IO;
+    using Microsoft.Kinect;
+
+    /// <summary>
+    /// Sensor chooser has three high-level states:
+    ///    ChooserStatus.None - chooser hasn't been started or is stopped
+    ///    ChooserStatus.SensorStarted - chooser has found and started a sensor for you.
+    ///    ChooserStatus.[everything else] - chooser has not found you a sensor and here is why.
+    /// Because there may be multiple sensors connected to the system, multiple flags
+    /// may get set when the chooser cannot get you a sensor.
+    /// </summary>
+    [Flags]
+    public enum ChooserStatus
+    {
+        /// <summary>
+        /// Chooser has not been started or it has been stopped
+        /// </summary>
+        None = 0x00000000,
+
+        /// <summary>
+        /// Don't have a sensor yet, some sensor is initializing, you may not get it
+        /// </summary>
+        SensorInitializing = 0x00000001,
+
+        /// <summary>
+        /// This KinectSensorChooser has a connected and started sensor.
+        /// </summary>
+        SensorStarted = 0x00000002,
+
+        /// <summary>
+        /// There are no sensors available on the system.  If one shows up
+        /// we will try to use it automatically.
+        /// </summary>
+        NoAvailableSensors = 0x00000010,
+
+        /// <summary>
+        /// Available sensor is in use by another application
+        /// </summary>
+        SensorConflict = 0x00000020,
+
+        /// <summary>
+        /// The available sensor is not powered.  If it receives power we
+        /// will try to use it automatically.
+        /// </summary>
+        SensorNotPowered = 0x00000040,
+
+        /// <summary>
+        /// There is not enough bandwidth on the USB controller available
+        /// for this sensor.
+        /// </summary>
+        SensorInsufficientBandwidth = 0x00000080,
+
+        /// <summary>
+        /// Available sensor is not genuine.
+        /// </summary>
+        SensorNotGenuine = 0x00000100,
+
+        /// <summary>
+        /// Available sensor is not supported
+        /// </summary>
+        SensorNotSupported = 0x00000200,
+
+        /// <summary>
+        /// Available sensor has an error
+        /// </summary>
+        SensorError = 0x00000400,
+    }
+
+    /// <summary>
+    /// Component that automatically finds a Kinect and handles updates
+    /// to the sensor.
+    /// </summary>
+    public class KinectSensorChooser : INotifyPropertyChanged
+    {
+        private readonly object lockObject = new object();
+
+        private readonly ContextEventWrapper<KinectChangedEventArgs> kinectChangedContextWrapper =
+            new ContextEventWrapper<KinectChangedEventArgs>(ContextSynchronizationMethod.Post);
+
+        private readonly ContextEventWrapper<PropertyChangedEventArgs> propertyChangedContextWrapper =
+            new ContextEventWrapper<PropertyChangedEventArgs>(ContextSynchronizationMethod.Post);
+
+        private readonly Dictionary<PropertyChangedEventHandler, EventHandler<PropertyChangedEventArgs>> changedHandlers =
+            new Dictionary<PropertyChangedEventHandler, EventHandler<PropertyChangedEventArgs>>();
+
+        private bool isStarted;
+        private string requiredConnectionId;
+
+        /// <summary>
+        /// Event triggered when the choosen KinectSensor changed.  This is
+        /// roughly equivalent to monitoring the PropertyChanged event
+        /// and watching for the "Kinect" property.
+        /// </summary>
+        public event EventHandler<KinectChangedEventArgs> KinectChanged
+        {
+            // ContextEventWrapper<> is already thread safe so no locking
+            add { this.kinectChangedContextWrapper.AddHandler(value); }
+
+            remove { this.kinectChangedContextWrapper.RemoveHandler(value); }
+        }
+
+        public event PropertyChangedEventHandler PropertyChanged
+        {
+            // ContextEventWrapper<> needs EvendHandler<> defined
+            // handlers.  PropertyChangedEventHandler is not like
+            // that so we wrap it in a handler that is.  These
+            // handlers need to be tracked so the proper thing
+            // gets removed.
+            // Need to lock to protect the changedHandlers data.
+            add
+            {
+                lock (lockObject)
+                {
+                    EventHandler<PropertyChangedEventArgs> handler = (sender, args) => value(sender, args);
+                    changedHandlers[value] = handler;
+                    this.propertyChangedContextWrapper.AddHandler(handler);
+                }
+            }
+
+            remove
+            {
+                lock (lockObject)
+                {
+                    EventHandler<PropertyChangedEventArgs> handler = changedHandlers[value];
+                    changedHandlers.Remove(value);
+                    this.propertyChangedContextWrapper.RemoveHandler(handler);
+                }
+            }
+        }
+
+        /// <summary>
+        /// The DeviceConnectionId for the sensor.  Set this to null to
+        /// have the KinectSensorChooser find the first available sensor.
+        /// </summary>
+        public string RequiredConnectionId
+        {
+            get
+            {
+                return requiredConnectionId;
+            }
+
+            set
+            {
+                if (value == requiredConnectionId)
+                {
+                    return;
+                }
+
+                using (var callbackLock = new CallbackLock(lockObject))
+                {
+                    // Check again in case someone else changed something
+                    // while we were waiting on the lock.
+                    if (value == requiredConnectionId)
+                    {
+                        // We are already looking for the sensor they want.
+                        return;
+                    }
+
+                    requiredConnectionId = value;
+
+                    if (requiredConnectionId == null)
+                    {
+                        // We went from having a required connection id
+                        // to not having one.  Nothing more to do.
+                        return;
+                    }
+
+                    if (this.Kinect != null && this.Kinect.DeviceConnectionId == requiredConnectionId)
+                    {
+                        // The sensor we have happens to be the one they asked for.
+                        return;
+                    }
+
+                    // We either have no sensor or the sensor we have isn't the one they asked for
+                    TryFindAndStartKinect(callbackLock);
+                }
+            }
+        }
+
+        /// <summary>
+        /// The sensor that this component has connected to.
+        /// When this changes clients will get INotifyPropertyChanged events.
+        /// </summary>
+        public KinectSensor Kinect { get; private set; }
+
+        /// <summary>
+        /// The status of the current sensor or why we cannot retrieve a sensor.
+        /// When this changes clients will get INotifyPropertyChanged events.
+        /// </summary>
+        public ChooserStatus Status { get; private set; }
+
+        /// <summary>
+        /// Starts choosing a sensor.  In the typical case, a sensor will
+        /// be found and events will be fired before this function returns.
+        /// </summary>
+        public void Start()
+        {
+            if (!isStarted)
+            {
+                using (var callbackLock = new CallbackLock(lockObject))
+                {
+                    // Check again in case someone else started while
+                    // we were waiting on the lock.
+                    if (!isStarted)
+                    {
+                        isStarted = true;
+
+                        KinectSensor.KinectSensors.StatusChanged += KinectSensorsOnStatusChanged;
+
+                        TryFindAndStartKinect(callbackLock);
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gives up the current sensor if it has one.  Stops watching for new sensors.
+        /// </summary>
+        public void Stop()
+        {
+            if (isStarted)
+            {
+                using (var callbackLock = new CallbackLock(lockObject))
+                {
+                    // Check again in case someone stopped us while
+                    // we were waiting on the lock.
+                    if (isStarted)
+                    {
+                        isStarted = false;
+
+                        KinectSensor.KinectSensors.StatusChanged -= KinectSensorsOnStatusChanged;
+
+                        SetSensorAndStatus(callbackLock, null, ChooserStatus.None);
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Called to retry finding a sensor when the SensorConflict or
+        /// NoAvailableSensors flags are set.
+        /// </summary>
+        public void TryResolveConflict()
+        {
+            using (var callbackLock = new CallbackLock(lockObject))
+            {
+                TryFindAndStartKinect(callbackLock);
+            }
+        }
+
+        private static ChooserStatus GetErrorStatusFromSensor(KinectSensor sensor)
+        {
+            ChooserStatus retval;
+            switch (sensor.Status)
+            {
+            case KinectStatus.Undefined:
+                retval = ChooserStatus.SensorError;
+                break;
+            case KinectStatus.Disconnected:
+                retval = ChooserStatus.SensorError;
+                break;
+            case KinectStatus.Connected:
+                // not an error state
+                retval = 0;
+                break;
+            case KinectStatus.Initializing:
+                retval = ChooserStatus.SensorInitializing;
+                break;
+            case KinectStatus.Error:
+                retval = ChooserStatus.SensorError;
+                break;
+            case KinectStatus.NotPowered:
+                retval = ChooserStatus.SensorNotPowered;
+                break;
+            case KinectStatus.NotReady:
+                retval = ChooserStatus.SensorError;
+                break;
+            case KinectStatus.DeviceNotGenuine:
+                retval = ChooserStatus.SensorNotGenuine;
+                break;
+            case KinectStatus.DeviceNotSupported:
+                retval = ChooserStatus.SensorNotSupported;
+                break;
+            case KinectStatus.InsufficientBandwidth:
+                retval = ChooserStatus.SensorInsufficientBandwidth;
+                break;
+            default:
+                throw new ArgumentOutOfRangeException("sensor");
+            }
+
+            return retval;
+        }
+
+        private void KinectSensorsOnStatusChanged(object sender, StatusChangedEventArgs e)
+        {
+            if (e != null)
+            {
+                if ((e.Sensor == this.Kinect) || (this.Kinect == null))
+                {
+                    using (var callbackLock = new CallbackLock(lockObject))
+                    {
+                        // Check again in case things changed while we were
+                        // waiting on the lock.
+                        if ((e.Sensor == this.Kinect) || (this.Kinect == null))
+                        {
+                            // Something about our sensor changed or we don't have a sensor.
+                            TryFindAndStartKinect(callbackLock);
+                        }
+                    }
+                }
+            }
+        }
+
+        /// <summary>
+        /// Helper to update our external status.
+        /// </summary>
+        /// <param name="callbackLock">Used to delay notifications to the client until after we exit the lock.</param>
+        /// <param name="newKinect">The new sensor</param>
+        /// <param name="newChooserStatus">The status we want to report to clients</param>
+        private void SetSensorAndStatus(CallbackLock callbackLock, KinectSensor newKinect, ChooserStatus newChooserStatus)
+        {
+            KinectSensor oldKinect = Kinect;
+            if (oldKinect != newKinect)
+            {
+                if (oldKinect != null)
+                {
+                    oldKinect.Stop();
+                }
+
+                Kinect = newKinect;
+
+                callbackLock.LockExit += () => this.kinectChangedContextWrapper.Invoke(this, new KinectChangedEventArgs(oldKinect, newKinect));
+                callbackLock.LockExit += () => RaisePropertyChanged("Kinect");
+            }
+
+            if (Status != newChooserStatus)
+            {
+                Status = newChooserStatus;
+
+                callbackLock.LockExit += () => RaisePropertyChanged("Status");
+            }
+        }
+
+        /// <summary>
+        /// Called when we don't have a sensor or possibly have the wrong sensor
+        /// and we want to see if we can get one.
+        /// </summary>
+        private void TryFindAndStartKinect(CallbackLock callbackLock)
+        {
+            if (!isStarted)
+            {
+                // We aren't started so we don't need to be finding anything.
+                Debug.Assert(Status == ChooserStatus.None, "isStarted and Status out of sync");
+                return;
+            }
+
+            if (Kinect != null && Kinect.Status == KinectStatus.Connected)
+            {
+                if (requiredConnectionId == null)
+                {
+                    // we already have an appropriate sensor
+                    Debug.Assert(Status == ChooserStatus.SensorStarted, "Chooser in unexpected state");
+                    return;
+                }
+
+                if (Kinect.DeviceConnectionId == requiredConnectionId)
+                {
+                    // we already have the requested sensor
+                    Debug.Assert(Status == ChooserStatus.SensorStarted, "Chooser in unexpected state");
+                    return;
+                }
+            }
+
+            KinectSensor newSensor = null;
+            ChooserStatus newStatus = 0;
+
+            if (KinectSensor.KinectSensors.Count == 0)
+            {
+                newStatus = ChooserStatus.NoAvailableSensors;
+            }
+            else
+            {
+                foreach (KinectSensor sensor in KinectSensor.KinectSensors)
+                {
+                    if (requiredConnectionId != null && sensor.DeviceConnectionId != requiredConnectionId)
+                    {
+                        // client has set a required connection Id and this
+                        // sensor does not have that Id
+                        newStatus |= ChooserStatus.NoAvailableSensors;
+                        continue;
+                    }
+
+                    if (sensor.Status != KinectStatus.Connected)
+                    {
+                        // Sensor is in some unusable state
+                        newStatus |= GetErrorStatusFromSensor(sensor);
+                        continue;
+                    }
+
+                    if (sensor.IsRunning)
+                    {
+                        // Sensor is already in use by this application
+                        newStatus |= ChooserStatus.NoAvailableSensors;
+                        continue;
+                    }
+
+                    // There is a potentially available sensor, try to start it
+                    try
+                    {
+                        sensor.Start();
+                    }
+                    catch (IOException)
+                    {
+                        // some other app has this sensor.
+                        newStatus |= ChooserStatus.SensorConflict;
+                        continue;
+                    }
+                    catch (InvalidOperationException)
+                    {
+                        // TODO: In multi-proc scenarios, this is getting thrown at the start before we see IOException.  Need to understand.
+                        // some other app has this sensor.
+                        newStatus |= ChooserStatus.SensorConflict;
+                        continue;
+                    }
+
+                    // Woo hoo, we have a started sensor.
+                    newStatus = ChooserStatus.SensorStarted;
+                    newSensor = sensor;
+                    break;
+                }
+            }
+
+            SetSensorAndStatus(callbackLock, newSensor, newStatus);
+        }
+
+        private void RaisePropertyChanged(string propertyName)
+        {
+            // We should never be in a lock at this point.
+            this.propertyChangedContextWrapper.Invoke(this, new PropertyChangedEventArgs(propertyName));
+        }
+    }
+}
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooserUI.xaml
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooserUI.xaml	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooserUI.xaml	(revision 28895)
@@ -0,0 +1,430 @@
+﻿<UserControl x:Class="Microsoft.Kinect.Toolkit.KinectSensorChooserUI"
+             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
+             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
+             mc:Ignorable="d"
+             d:DesignWidth="228" d:DesignHeight="160">
+    <UserControl.Resources>
+        <SolidColorBrush x:Key="purpleBrush" Color="#FF52318F" />
+        <SolidColorBrush x:Key="blueBrush" Color="#FF00BCF2" />
+        <SolidColorBrush x:Key="yellowErrorBrush" Color="#FFFCEE1E" />
+        <SolidColorBrush x:Key="lightGreyBrush" Color="#FFD2D2D2" />
+        <SolidColorBrush x:Key="mediumGreyBrush" Color="#FF969696" />
+        <SolidColorBrush x:Key="darkGreyBrush" Color="#FF505050" />
+
+        <Style x:Key="smallStatusGridGtyle" TargetType="{x:Type Grid}">
+            <Setter Property="Background" Value="Transparent"/>
+            <Setter Property="Visibility" Value="Hidden"/>
+        </Style>
+
+        <Style x:Key="pathContainerStyle" TargetType="{x:Type Grid}">
+            <Setter Property="HorizontalAlignment" Value="Center"/>
+            <Setter Property="VerticalAlignment" Value="Center"/>
+            <Setter Property="VerticalAlignment" Value="Bottom" />
+            <Setter Property="Margin" Value="0,0,0,5" />
+        </Style>
+
+        <Style x:Key="expandedStatusGridGtyle" TargetType="{x:Type Grid}">
+            <Setter Property="Background" Value="Transparent"/>
+            <Setter Property="Visibility" Value="Hidden"/>
+            <Setter Property="HorizontalAlignment" Value="Stretch"/>
+            <Setter Property="VerticalAlignment" Value="Stretch"/>
+        </Style>
+
+        <Style x:Key="RefreshButtonStyle" TargetType="{x:Type Button}">
+            <Setter Property="Template" Value="{DynamicResource RefreshButtonTemplate}"/>
+            <Setter Property="FontSize" Value="10.667"/>
+            <Setter Property="Foreground" Value="White"/>
+            <Style.Triggers>
+                <Trigger Property="IsEnabled" Value="False">
+                    <Setter Property="Visibility" Value="Collapsed" />
+                </Trigger>
+            </Style.Triggers>
+        </Style>
+
+        <ControlTemplate x:Key="RefreshButtonTemplate" TargetType="{x:Type ButtonBase}">
+            <StackPanel Background="Transparent">
+                <Grid HorizontalAlignment="Center">
+                    <Path Fill="{TemplateBinding Foreground}" Data="F1 M 11.991,0.000 C 9.454,0.000 6.895,0.803 4.722,2.461 C -0.550,6.482 -1.558,14.011 2.461,19.280 C 4.821,22.374 8.395,24.000 12.010,24.000 C 14.548,24.000 17.106,23.198 19.280,21.541 C 24.549,17.522 25.558,9.991 21.540,4.720 C 19.177,1.626 15.605,0.000 11.991,0.000 M 11.992,1.588 L 11.991,1.588 C 15.270,1.588 18.290,3.081 20.276,5.684 C 23.759,10.250 22.880,16.797 18.317,20.277 C 16.487,21.673 14.305,22.412 12.010,22.412 C 8.729,22.412 5.709,20.919 3.724,18.316 C 2.037,16.105 1.312,13.370 1.682,10.614 C 2.052,7.858 3.474,5.411 5.686,3.724 C 7.515,2.327 9.696,1.588 11.992,1.588"/>
+                    <Path Fill="{TemplateBinding Foreground}" Data="F1 M 15.030,9.356 L 11.993,9.510 L 13.431,10.937 L 17.534,10.846 L 17.534,10.849 L 17.534,10.846 L 17.536,10.848 L 17.534,10.846 L 17.587,6.743 L 16.149,5.319 L 16.018,8.354"/>
+                    <Path Fill="{TemplateBinding Foreground}" Data="F1 M 8.607,11.368 L 6.413,11.342 C 7.114,7.714 10.219,5.895 13.292,6.490 C 14.979,6.816 16.413,7.872 17.223,9.389 L 15.455,10.335 C 14.930,9.353 14.002,8.671 12.911,8.458 C 10.923,8.075 8.992,9.379 8.607,11.368"/>
+                    <Path Fill="{TemplateBinding Foreground}" Data="F1 M 9.003,14.643 L 12.040,14.488 L 10.602,13.063 L 6.498,13.154 L 6.498,13.152 L 6.498,13.154 L 6.495,13.153 L 6.498,13.154 L 6.444,17.258 L 7.883,18.681 L 8.014,15.647"/>
+                    <Path Fill="{TemplateBinding Foreground}" Data="F1 M 10.644,17.580 C 8.954,17.252 7.519,16.195 6.708,14.673 L 8.479,13.730 C 9.002,14.713 9.932,15.398 11.024,15.609 C 13.015,15.996 14.946,14.689 15.331,12.700 L 17.587,12.722 C 16.911,16.217 13.719,18.174 10.644,17.580"/>
+                </Grid>
+                <ContentPresenter ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" ContentStringFormat="{TemplateBinding ContentStringFormat}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
+            </StackPanel>
+            <ControlTemplate.Triggers>
+                <Trigger Property="IsMouseOver" Value="True">
+                    <Setter Property="Foreground" Value="{StaticResource blueBrush}"/>
+                </Trigger>
+                <Trigger Property="IsPressed"  Value="True">
+                    <Setter Property="Foreground" Value="{StaticResource mediumGreyBrush}"/>
+                </Trigger>
+            </ControlTemplate.Triggers>
+        </ControlTemplate>
+        
+    </UserControl.Resources>
+
+    <Grid x:Name="layoutRoot" MouseEnter="OnRootGridMouseEnter" GotKeyboardFocus="OnRootGridGotKeyboardFocus" Focusable="True" Width="40" Height="40" HorizontalAlignment="Center" VerticalAlignment="Top">
+        <VisualStateManager.VisualStateGroups>
+            <VisualStateGroup x:Name="SensorStatusStates">
+                <VisualStateGroup.Transitions>
+                    <VisualTransition GeneratedDuration="0" To="AllSetNotListening">
+                        <Storyboard>
+                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="allSetNotListeningContent">
+                                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
+                                <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
+                                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
+                                <EasingDoubleKeyFrame KeyTime="0:0:3" Value="0"/>
+                            </DoubleAnimationUsingKeyFrames>
+                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="allSetNotListeningContent">
+                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                                <DiscreteObjectKeyFrame KeyTime="0:0:0.3" Value="{x:Static Visibility.Visible}"/>
+                                <DiscreteObjectKeyFrame KeyTime="0:0:3" Value="{x:Static Visibility.Hidden}"/>
+                            </ObjectAnimationUsingKeyFrames>
+                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedAllSetNotListeningContent">
+                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                                <DiscreteObjectKeyFrame KeyTime="0:0:0.3" Value="{x:Static Visibility.Visible}"/>
+                            </ObjectAnimationUsingKeyFrames>
+                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="expandedAllSetNotListeningContent">
+                                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
+                                <EasingDoubleKeyFrame KeyTime="0:0:0.3" Value="1"/>
+                                <EasingDoubleKeyFrame KeyTime="0:0:2" Value="1"/>
+                            </DoubleAnimationUsingKeyFrames>
+                        </Storyboard>
+                    </VisualTransition>
+                    <VisualTransition GeneratedDuration="0" To="Error">
+                        <Storyboard>
+                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedErrorContent">
+                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                                <DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Visible}"/>
+                            </ObjectAnimationUsingKeyFrames>
+                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="expandedErrorContent">
+                                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
+                                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
+                            </DoubleAnimationUsingKeyFrames>
+                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="errorContent">
+                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                                <DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Visible}"/>
+                            </ObjectAnimationUsingKeyFrames>
+                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="errorContent">
+                                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
+                                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
+                            </DoubleAnimationUsingKeyFrames>
+                        </Storyboard>
+                    </VisualTransition>
+                    <VisualTransition From="Error" GeneratedDuration="0">
+                        <Storyboard>
+                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="errorContent">
+                                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
+                            </DoubleAnimationUsingKeyFrames>
+                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="errorContent">
+                                <DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Hidden}"/>
+                            </ObjectAnimationUsingKeyFrames>
+                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="expandedErrorContent">
+                                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
+                            </DoubleAnimationUsingKeyFrames>
+                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedErrorContent">
+                                <DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Hidden}"/>
+                            </ObjectAnimationUsingKeyFrames>
+                        </Storyboard>
+                    </VisualTransition>
+                    <VisualTransition GeneratedDuration="0" To="AllSetListening">
+                        <Storyboard>
+                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="allSetListeningContent">
+                                <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                                <DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Visible}"/>
+                            </ObjectAnimationUsingKeyFrames>
+                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="allSetListeningContent">
+                                <EasingDoubleKeyFrame KeyTime="0" Value="0"/>
+                                <EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
+                            </DoubleAnimationUsingKeyFrames>
+                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedAllSetListeningContent">
+                            	<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                            </ObjectAnimationUsingKeyFrames>
+                            <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="expandedAllSetListeningContent">
+                            	<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
+                            	<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
+                            </DoubleAnimationUsingKeyFrames>
+                        </Storyboard>
+                    </VisualTransition>
+                    <VisualTransition GeneratedDuration="0" To="NoAvailableSensors">
+                    	<Storyboard>
+                    		<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="noAvailableSensorsContent">
+                    			<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                    		</ObjectAnimationUsingKeyFrames>
+                    		<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="noAvailableSensorsContent">
+                    			<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
+                    			<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
+                    		</DoubleAnimationUsingKeyFrames>
+                    		<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedNoAvailableSensorsContent">
+                    			<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                    		</ObjectAnimationUsingKeyFrames>
+                    		<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="expandedNoAvailableSensorsContent">
+                    			<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
+                    			<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
+                    		</DoubleAnimationUsingKeyFrames>
+                    	</Storyboard>
+                    </VisualTransition>
+                    <VisualTransition From="NoAvailableSensors" GeneratedDuration="0">
+                    	<Storyboard>
+                    		<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="expandedNoAvailableSensorsContent">
+                    			<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
+                    		</DoubleAnimationUsingKeyFrames>
+                    		<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedNoAvailableSensorsContent">
+                    			<DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Hidden}"/>
+                    		</ObjectAnimationUsingKeyFrames>
+                    		<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="noAvailableSensorsContent">
+                    			<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
+                    		</DoubleAnimationUsingKeyFrames>
+                    		<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="noAvailableSensorsContent">
+                    			<DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Hidden}"/>
+                    		</ObjectAnimationUsingKeyFrames>
+                    	</Storyboard>
+                    </VisualTransition>
+                    <VisualTransition From="AllSetListening" GeneratedDuration="0">
+                    	<Storyboard>
+                    		<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="expandedAllSetListeningContent">
+                    			<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
+                    		</DoubleAnimationUsingKeyFrames>
+                    		<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedAllSetListeningContent">
+                    			<DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Hidden}"/>
+                    		</ObjectAnimationUsingKeyFrames>
+                    		<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="allSetListeningContent">
+                    			<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
+                    		</DoubleAnimationUsingKeyFrames>
+                    		<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="allSetListeningContent">
+                    			<DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Hidden}"/>
+                    		</ObjectAnimationUsingKeyFrames>
+                    	</Storyboard>
+                    </VisualTransition>
+                    <VisualTransition GeneratedDuration="0" To="Initializing">
+                    	<Storyboard>
+                    		<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="initializingContent">
+                    			<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
+                    			<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
+                    		</DoubleAnimationUsingKeyFrames>
+                    		<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="expandedInitializingContent">
+                    			<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
+                    			<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="1"/>
+                    		</DoubleAnimationUsingKeyFrames>
+                    		<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="initializingContent">
+                    			<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                    		</ObjectAnimationUsingKeyFrames>
+                    		<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedInitializingContent">
+                    			<DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                    		</ObjectAnimationUsingKeyFrames>
+                    	</Storyboard>
+                    </VisualTransition>
+                    <VisualTransition From="Initializing" GeneratedDuration="0">
+                    	<Storyboard>
+                    		<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="initializingContent">
+                    			<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
+                    		</DoubleAnimationUsingKeyFrames>
+                    		<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="expandedInitializingContent">
+                    			<EasingDoubleKeyFrame KeyTime="0:0:0.2" Value="0"/>
+                    		</DoubleAnimationUsingKeyFrames>
+                    		<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="initializingContent">
+                    			<DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Hidden}"/>
+                    		</ObjectAnimationUsingKeyFrames>
+                    		<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedInitializingContent">
+                    			<DiscreteObjectKeyFrame KeyTime="0:0:0.2" Value="{x:Static Visibility.Hidden}"/>
+                    		</ObjectAnimationUsingKeyFrames>
+                    	</Storyboard>
+                    </VisualTransition>
+                </VisualStateGroup.Transitions>
+                <VisualState x:Name="Stopped"/>
+                <VisualState x:Name="Initializing">
+                    <Storyboard>
+                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="initializingContent">
+                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                        </ObjectAnimationUsingKeyFrames>
+                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedInitializingContent">
+                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                        </ObjectAnimationUsingKeyFrames>
+                    </Storyboard>
+                </VisualState>
+                <VisualState x:Name="AllSetListening">
+                    <Storyboard>
+                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="allSetListeningContent">
+                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                        </ObjectAnimationUsingKeyFrames>
+                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedAllSetListeningContent">
+                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                        </ObjectAnimationUsingKeyFrames>
+                    </Storyboard>
+                </VisualState>
+                <VisualState x:Name="NoAvailableSensors">
+                    <Storyboard>
+                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="noAvailableSensorsContent">
+                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                        </ObjectAnimationUsingKeyFrames>
+                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedNoAvailableSensorsContent">
+                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                        </ObjectAnimationUsingKeyFrames>
+                    </Storyboard>
+                </VisualState>
+                <VisualState x:Name="Error">
+                    <Storyboard>
+                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="errorContent">
+                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                        </ObjectAnimationUsingKeyFrames>
+                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedErrorContent">
+                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                        </ObjectAnimationUsingKeyFrames>
+                    </Storyboard>
+                </VisualState>
+                <VisualState x:Name="AllSetNotListening">
+                    <Storyboard>
+                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="allSetNotListeningContent">
+                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Hidden}"/>
+                        </ObjectAnimationUsingKeyFrames>
+                        <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="expandedAllSetNotListeningContent">
+                            <DiscreteObjectKeyFrame KeyTime="0" Value="{x:Static Visibility.Visible}"/>
+                        </ObjectAnimationUsingKeyFrames>
+                    </Storyboard>
+                </VisualState>
+            </VisualStateGroup>
+        </VisualStateManager.VisualStateGroups>
+
+        <Grid x:Name="initializingContent" Style="{StaticResource smallStatusGridGtyle}" Background="{StaticResource lightGreyBrush}">
+            <Grid Style="{StaticResource pathContainerStyle}">
+                <Path Data="F1 M 12.998,6.278 C 14.367,6.545 15.607,7.183 16.602,8.106 L 11.160,8.382 L 14.037,11.235 L 22.242,11.054 L 22.350,2.847 L 19.473,0.000 L 19.253,5.095 C 17.730,3.706 15.843,2.744 13.760,2.341 C 7.613,1.150 1.404,4.790 0.000,12.046 L 4.391,12.097 C 5.160,8.120 9.021,5.511 12.998,6.278 Z">
+                    <Path.Fill>
+                        <RadialGradientBrush MappingMode="Absolute" GradientOrigin="313.146,-385.129" Center="313.146,-385.129" RadiusX="16.356" RadiusY="16.356">
+                            <RadialGradientBrush.GradientStops>
+                                <GradientStop Offset="0.00" Color="#ffffffff"/>
+                                <GradientStop Offset="0.36" Color="#ffffffff"/>
+                                <GradientStop Offset="0.53" Color="#ffffffff"/>
+                                <GradientStop Offset="0.73" Color="#ffffffff"/>
+                                <GradientStop Offset="0.94" Color="#ffffffff"/>
+                            </RadialGradientBrush.GradientStops>
+                            <RadialGradientBrush.Transform>
+                                <MatrixTransform Matrix="1.000,0.000,-0.000,-1.000,-295.639,-382.415" />
+                            </RadialGradientBrush.Transform>
+                        </RadialGradientBrush>
+                    </Path.Fill>
+                </Path>
+                <Path Data="F1 M 9.352,20.511 C 7.983,20.246 6.742,19.607 5.748,18.683 L 11.189,18.408 L 8.313,15.554 L 0.107,15.736 L 0.000,23.943 L 2.877,26.791 L 3.097,21.695 C 4.620,23.083 6.507,24.046 8.590,24.449 C 14.736,25.640 20.945,22.000 22.350,14.744 L 17.959,14.693 C 17.189,18.669 13.328,21.279 9.352,20.511 Z">
+                    <Path.Fill>
+                        <RadialGradientBrush MappingMode="Absolute" GradientOrigin="-658.202,2109.564" Center="-658.202,2109.564" RadiusX="16.357" RadiusY="16.357">
+                            <RadialGradientBrush.GradientStops>
+                                <GradientStop Offset="0.00" Color="#ffffffff"/>
+                                <GradientStop Offset="0.36" Color="#ffffffff"/>
+                                <GradientStop Offset="0.53" Color="#ffffffff"/>
+                                <GradientStop Offset="0.73" Color="#ffffffff"/>
+                                <GradientStop Offset="0.94" Color="#ffffffff"/>
+                            </RadialGradientBrush.GradientStops>
+                            <RadialGradientBrush.Transform>
+                                <MatrixTransform Matrix="-1.000,0.000,0.000,1.000,-653.360,-2085.489" />
+                            </RadialGradientBrush.Transform>
+                        </RadialGradientBrush>
+                    </Path.Fill>
+                </Path>
+            </Grid>
+        </Grid>
+        <Grid  x:Name="allSetNotListeningContent" Style="{StaticResource smallStatusGridGtyle}" Background="{StaticResource purpleBrush}">
+            <Grid Style="{StaticResource pathContainerStyle}">
+                <Path Fill="#ffffffff" Data="F1 M 7.749,4.152 C 7.094,4.152 6.563,3.623 6.563,2.968 C 6.563,2.314 7.094,1.783 7.749,1.783 C 8.402,1.783 8.933,2.314 8.933,2.968 C 8.933,3.623 8.402,4.152 7.749,4.152 Z M 13.817,4.152 C 13.162,4.152 12.632,3.623 12.632,2.968 C 12.632,2.314 13.162,1.783 13.817,1.783 C 14.473,1.783 15.001,2.314 15.001,2.968 C 15.001,3.623 14.473,4.152 13.817,4.152 Z M 18.185,4.152 C 17.529,4.152 16.999,3.623 16.999,2.968 C 16.999,2.314 17.529,1.783 18.185,1.783 C 18.837,1.783 19.369,2.314 19.369,2.968 C 19.369,3.623 18.837,4.152 18.185,4.152 Z M 30.059,0.000 L 1.940,0.000 C 0.875,0.000 0.000,0.873 0.000,1.941 L 0.000,3.996 C 0.000,5.062 0.875,5.935 1.940,5.935 L 30.059,5.935 C 31.126,5.935 32.000,5.062 32.000,3.996 L 32.000,1.941 C 32.000,0.873 31.126,0.000 30.059,0.000 Z"/>
+                <Path Fill="#ffffffff" Data="F1 M 20.437,8.683 C 20.031,8.509 16.960,7.454 16.960,7.454 L 15.023,7.454 C 15.023,7.454 11.952,8.509 11.543,8.683 C 11.137,8.856 10.894,8.940 10.979,9.245 C 11.034,9.444 11.168,9.916 11.312,10.315 C 11.378,10.506 11.475,10.634 11.667,10.634 C 11.770,10.634 20.213,10.634 20.316,10.634 C 20.507,10.634 20.603,10.506 20.671,10.315 C 20.814,9.916 20.950,9.444 21.005,9.245 C 21.089,8.940 20.847,8.856 20.437,8.683 Z"/>
+            </Grid>
+        </Grid>
+        <Grid x:Name="allSetListeningContent" Style="{StaticResource smallStatusGridGtyle}" Background="{StaticResource blueBrush}">
+            <Grid Style="{StaticResource pathContainerStyle}">
+                <Path Fill="#ffffffff" Data="F1 M 5.880,14.295 C 3.545,14.295 1.649,12.397 1.649,10.065 C 1.649,9.605 1.282,9.238 0.823,9.238 C 0.365,9.238 0.000,9.605 0.000,10.065 C 0.000,13.040 2.189,15.476 5.055,15.889 L 5.055,19.576 L 3.232,19.576 C 2.774,19.576 2.406,19.959 2.406,20.400 C 2.406,20.860 2.774,21.242 3.232,21.242 L 8.512,21.242 C 8.971,21.242 9.338,20.860 9.338,20.400 C 9.338,19.959 8.971,19.576 8.512,19.576 L 6.708,19.576 L 6.708,15.889 C 9.557,15.476 11.764,13.040 11.764,10.065 C 11.764,9.605 11.397,9.238 10.938,9.238 C 10.481,9.238 10.112,9.605 10.112,10.065 C 10.112,12.397 8.219,14.295 5.883,14.295 M 9.098,10.372 C 8.930,12.009 7.557,13.289 5.883,13.289 L 5.880,13.289 C 4.189,13.289 2.831,12.009 2.646,10.372 L 4.352,10.372 L 4.352,8.721 L 2.617,8.721 L 2.617,8.469 L 2.617,7.528 L 4.352,7.528 L 4.352,5.860 L 2.617,5.860 L 2.617,4.666 L 4.352,4.666 L 4.352,3.016 L 2.643,3.016 C 2.770,1.341 4.159,0.000 5.881,0.000 C 7.586,0.000 8.977,1.341 9.104,3.016 L 7.413,3.016 L 7.413,4.666 L 9.147,4.666 L 9.147,5.860 L 7.413,5.860 L 7.413,7.528 L 9.147,7.528 L 9.147,8.469 L 9.147,8.721 L 7.413,8.721 L 7.413,10.372 L 9.098,10.372 Z"/>
+            </Grid>
+        </Grid>
+        <Grid x:Name="noAvailableSensorsContent" Style="{StaticResource smallStatusGridGtyle}" Background="{StaticResource darkGreyBrush}">
+            <Grid Style="{StaticResource pathContainerStyle}">
+                <Path Fill="{StaticResource yellowErrorBrush}" Data="F1 M 14.800,13.834 C 14.216,14.163 13.861,14.781 13.861,15.440 L 13.857,16.161 L 12.021,16.161 L 12.021,15.440 C 12.021,14.143 12.734,12.919 13.858,12.243 C 14.480,11.917 14.873,11.288 14.873,10.583 C 14.873,9.571 14.023,8.723 12.988,8.723 C 11.975,8.723 11.125,9.571 11.125,10.583 L 11.125,10.804 L 9.285,10.804 L 9.285,10.583 C 9.285,8.549 10.952,6.884 12.988,6.884 C 15.048,6.884 16.714,8.549 16.714,10.583 C 16.714,11.926 15.979,13.163 14.800,13.834 Z M 13.781,19.073 C 13.541,19.311 13.259,19.409 12.939,19.409 C 12.620,19.409 12.338,19.311 12.121,19.073 C 11.882,18.856 11.762,18.577 11.762,18.261 C 11.762,17.941 11.882,17.658 12.121,17.418 C 12.338,17.204 12.621,17.084 12.939,17.084 C 13.259,17.084 13.541,17.204 13.779,17.418 C 13.998,17.659 14.118,17.942 14.118,18.261 C 14.118,18.575 13.998,18.856 13.781,19.073 Z M 12.988,0.000 L 0.000,21.253 L 12.988,21.253 L 26.000,21.253 L 12.988,0.000 Z"/>
+            </Grid>
+        </Grid>
+        <Grid x:Name="errorContent" Style="{StaticResource smallStatusGridGtyle}" Background="{StaticResource darkGreyBrush}">
+            <Grid Style="{StaticResource pathContainerStyle}">
+                <Path Fill="{StaticResource yellowErrorBrush}" Data="F1 M 12.992,18.767 C 12.586,18.767 12.223,18.634 11.945,18.394 C 11.695,18.126 11.555,17.819 11.555,17.473 C 11.555,17.079 11.695,16.769 11.979,16.519 C 12.234,16.288 12.596,16.165 12.992,16.165 C 13.420,16.165 13.760,16.291 14.033,16.544 C 14.308,16.774 14.443,17.083 14.443,17.473 C 14.443,17.831 14.313,18.139 14.041,18.398 C 13.795,18.637 13.432,18.767 12.992,18.767 Z M 14.303,7.252 L 13.995,15.069 L 11.979,15.069 L 11.685,7.252 L 14.303,7.252 Z M 12.988,0.000 L 0.000,21.254 L 12.988,21.254 L 26.000,21.254 L 12.988,0.000 Z"/>
+            </Grid>
+        </Grid>
+
+        <Popup x:Name="expandedPopup" AllowsTransparency="True" PopupAnimation="Fade" Opened="ExpandedPopupOnOpened" MouseLeave="OnExpandedPopupMouseLeave" Placement="Center" PlacementTarget="{Binding ElementName=layoutRoot}" Width="300">
+            <Grid x:Name="popupGrid" Background="{StaticResource darkGreyBrush}" Focusable="True"  GotKeyboardFocus="OnPopupGridGotKeyboardFocus">
+                <StackPanel Margin="10,15,10,10">
+                    <Grid>
+                        <Grid x:Name="expandedInitializingContent" Style="{StaticResource expandedStatusGridGtyle}">
+                            <Grid Style="{StaticResource pathContainerStyle}">
+                                <Path Data="F1 M 12.998,6.278 C 14.367,6.545 15.607,7.183 16.602,8.106 L 11.160,8.382 L 14.037,11.235 L 22.242,11.054 L 22.350,2.847 L 19.473,0.000 L 19.253,5.095 C 17.730,3.706 15.843,2.744 13.760,2.341 C 7.613,1.150 1.404,4.790 0.000,12.046 L 4.391,12.097 C 5.160,8.120 9.021,5.511 12.998,6.278 Z">
+                                    <Path.Fill>
+                                        <RadialGradientBrush MappingMode="Absolute" GradientOrigin="313.146,-385.129" Center="313.146,-385.129" RadiusX="16.356" RadiusY="16.356">
+                                            <RadialGradientBrush.GradientStops>
+                                                <GradientStop Offset="0.00" Color="#ffffffff"/>
+                                                <GradientStop Offset="0.36" Color="#ffffffff"/>
+                                                <GradientStop Offset="0.53" Color="#ffffffff"/>
+                                                <GradientStop Offset="0.73" Color="#ffffffff"/>
+                                                <GradientStop Offset="0.94" Color="#ffffffff"/>
+                                            </RadialGradientBrush.GradientStops>
+                                            <RadialGradientBrush.Transform>
+                                                <MatrixTransform Matrix="1.000,0.000,-0.000,-1.000,-295.639,-382.415" />
+                                            </RadialGradientBrush.Transform>
+                                        </RadialGradientBrush>
+                                    </Path.Fill>
+                                </Path>
+                                <Path Data="F1 M 9.352,20.511 C 7.983,20.246 6.742,19.607 5.748,18.683 L 11.189,18.408 L 8.313,15.554 L 0.107,15.736 L 0.000,23.943 L 2.877,26.791 L 3.097,21.695 C 4.620,23.083 6.507,24.046 8.590,24.449 C 14.736,25.640 20.945,22.000 22.350,14.744 L 17.959,14.693 C 17.189,18.669 13.328,21.279 9.352,20.511 Z">
+                                    <Path.Fill>
+                                        <RadialGradientBrush MappingMode="Absolute" GradientOrigin="-658.202,2109.564" Center="-658.202,2109.564" RadiusX="16.357" RadiusY="16.357">
+                                            <RadialGradientBrush.GradientStops>
+                                                <GradientStop Offset="0.00" Color="#ffffffff"/>
+                                                <GradientStop Offset="0.36" Color="#ffffffff"/>
+                                                <GradientStop Offset="0.53" Color="#ffffffff"/>
+                                                <GradientStop Offset="0.73" Color="#ffffffff"/>
+                                                <GradientStop Offset="0.94" Color="#ffffffff"/>
+                                            </RadialGradientBrush.GradientStops>
+                                            <RadialGradientBrush.Transform>
+                                                <MatrixTransform Matrix="-1.000,0.000,0.000,1.000,-653.360,-2085.489" />
+                                            </RadialGradientBrush.Transform>
+                                        </RadialGradientBrush>
+                                    </Path.Fill>
+                                </Path>
+                            </Grid>
+                        </Grid>
+                        <Grid x:Name="expandedAllSetNotListeningContent" Style="{StaticResource expandedStatusGridGtyle}">
+                            <Grid Style="{StaticResource pathContainerStyle}">
+                                <Path Fill="#ffffffff" Data="F1 M 7.749,4.152 C 7.094,4.152 6.563,3.623 6.563,2.968 C 6.563,2.314 7.094,1.783 7.749,1.783 C 8.402,1.783 8.933,2.314 8.933,2.968 C 8.933,3.623 8.402,4.152 7.749,4.152 Z M 13.817,4.152 C 13.162,4.152 12.632,3.623 12.632,2.968 C 12.632,2.314 13.162,1.783 13.817,1.783 C 14.473,1.783 15.001,2.314 15.001,2.968 C 15.001,3.623 14.473,4.152 13.817,4.152 Z M 18.185,4.152 C 17.529,4.152 16.999,3.623 16.999,2.968 C 16.999,2.314 17.529,1.783 18.185,1.783 C 18.837,1.783 19.369,2.314 19.369,2.968 C 19.369,3.623 18.837,4.152 18.185,4.152 Z M 30.059,0.000 L 1.940,0.000 C 0.875,0.000 0.000,0.873 0.000,1.941 L 0.000,3.996 C 0.000,5.062 0.875,5.935 1.940,5.935 L 30.059,5.935 C 31.126,5.935 32.000,5.062 32.000,3.996 L 32.000,1.941 C 32.000,0.873 31.126,0.000 30.059,0.000 Z"/>
+                                <Path Fill="#ffffffff" Data="F1 M 20.437,8.683 C 20.031,8.509 16.960,7.454 16.960,7.454 L 15.023,7.454 C 15.023,7.454 11.952,8.509 11.543,8.683 C 11.137,8.856 10.894,8.940 10.979,9.245 C 11.034,9.444 11.168,9.916 11.312,10.315 C 11.378,10.506 11.475,10.634 11.667,10.634 C 11.770,10.634 20.213,10.634 20.316,10.634 C 20.507,10.634 20.603,10.506 20.671,10.315 C 20.814,9.916 20.950,9.444 21.005,9.245 C 21.089,8.940 20.847,8.856 20.437,8.683 Z"/>
+                            </Grid>
+                        </Grid>
+                        <Grid x:Name="expandedAllSetListeningContent" Style="{StaticResource expandedStatusGridGtyle}">
+                            <Grid Style="{StaticResource pathContainerStyle}">
+                                <Path Fill="#ffffffff" Data="F1 M 5.880,14.295 C 3.545,14.295 1.649,12.397 1.649,10.065 C 1.649,9.605 1.282,9.238 0.823,9.238 C 0.365,9.238 0.000,9.605 0.000,10.065 C 0.000,13.040 2.189,15.476 5.055,15.889 L 5.055,19.576 L 3.232,19.576 C 2.774,19.576 2.406,19.959 2.406,20.400 C 2.406,20.860 2.774,21.242 3.232,21.242 L 8.512,21.242 C 8.971,21.242 9.338,20.860 9.338,20.400 C 9.338,19.959 8.971,19.576 8.512,19.576 L 6.708,19.576 L 6.708,15.889 C 9.557,15.476 11.764,13.040 11.764,10.065 C 11.764,9.605 11.397,9.238 10.938,9.238 C 10.481,9.238 10.112,9.605 10.112,10.065 C 10.112,12.397 8.219,14.295 5.883,14.295 M 9.098,10.372 C 8.930,12.009 7.557,13.289 5.883,13.289 L 5.880,13.289 C 4.189,13.289 2.831,12.009 2.646,10.372 L 4.352,10.372 L 4.352,8.721 L 2.617,8.721 L 2.617,8.469 L 2.617,7.528 L 4.352,7.528 L 4.352,5.860 L 2.617,5.860 L 2.617,4.666 L 4.352,4.666 L 4.352,3.016 L 2.643,3.016 C 2.770,1.341 4.159,0.000 5.881,0.000 C 7.586,0.000 8.977,1.341 9.104,3.016 L 7.413,3.016 L 7.413,4.666 L 9.147,4.666 L 9.147,5.860 L 7.413,5.860 L 7.413,7.528 L 9.147,7.528 L 9.147,8.469 L 9.147,8.721 L 7.413,8.721 L 7.413,10.372 L 9.098,10.372 Z"/>
+                            </Grid>
+                        </Grid>
+                        <Grid x:Name="expandedNoAvailableSensorsContent" Style="{StaticResource expandedStatusGridGtyle}">
+                            <Grid Style="{StaticResource pathContainerStyle}">
+                                <Path Fill="{StaticResource yellowErrorBrush}" Data="F1 M 40.361,13.834 C 39.777,14.163 39.422,14.781 39.422,15.440 L 39.418,16.161 L 37.582,16.161 L 37.582,15.440 C 37.582,14.143 38.295,12.919 39.419,12.243 C 40.042,11.917 40.434,11.288 40.434,10.583 C 40.434,9.571 39.584,8.723 38.549,8.723 C 37.536,8.723 36.686,9.571 36.686,10.583 L 36.686,10.804 L 34.846,10.804 L 34.846,10.583 C 34.846,8.549 36.513,6.884 38.549,6.884 C 40.609,6.884 42.275,8.549 42.275,10.583 C 42.275,11.926 41.541,13.163 40.361,13.834 Z M 39.342,19.073 C 39.102,19.311 38.820,19.409 38.500,19.409 C 38.181,19.409 37.899,19.311 37.682,19.073 C 37.443,18.856 37.323,18.577 37.323,18.261 C 37.323,17.941 37.443,17.658 37.682,17.418 C 37.899,17.204 38.182,17.084 38.500,17.084 C 38.820,17.084 39.102,17.204 39.340,17.418 C 39.559,17.659 39.679,17.942 39.679,18.261 C 39.679,18.575 39.559,18.856 39.342,19.073 Z M 38.549,0.000 L 25.561,21.253 L 38.549,21.253 L 51.561,21.253 L 38.549,0.000 Z"/>
+                                <Path Fill="#ffffffff" Data="F1 M 19.267,14.549 C 18.572,14.549 18.002,13.983 18.002,13.287 C 18.002,12.591 18.572,12.038 19.267,12.038 C 19.947,12.038 20.516,12.591 20.516,13.287 C 20.516,13.983 19.947,14.549 19.267,14.549 Z M 14.638,14.549 C 13.943,14.549 13.374,13.983 13.374,13.287 C 13.374,12.591 13.943,12.038 14.638,12.038 C 15.334,12.038 15.887,12.591 15.887,13.287 C 15.887,13.983 15.334,14.549 14.638,14.549 Z M 8.204,14.549 C 7.508,14.549 6.955,13.983 6.955,13.287 C 6.955,12.591 7.508,12.038 8.204,12.038 C 8.898,12.038 9.467,12.591 9.467,13.287 C 9.467,13.983 8.898,14.549 8.204,14.549 Z M 2.050,10.145 C 0.923,10.145 0.000,11.067 0.000,12.196 L 0.000,14.378 C 0.000,15.504 0.923,16.427 2.050,16.427 L 26.598,16.427 L 30.443,10.145 L 2.050,10.145 Z"/>
+                                <Path Fill="#ffffffff" Data="F1 M 21.646,19.340 C 21.218,19.155 17.968,18.038 17.968,18.038 L 15.905,18.038 C 15.905,18.038 12.656,19.155 12.228,19.340 C 11.800,19.528 11.536,19.618 11.627,19.939 C 11.692,20.149 11.829,20.649 11.988,21.070 C 12.048,21.272 12.151,21.415 12.353,21.415 C 12.461,21.415 21.413,21.415 21.521,21.415 C 21.723,21.415 21.825,21.272 21.901,21.070 C 22.044,20.649 22.196,20.149 22.247,19.939 C 22.338,19.618 22.074,19.528 21.646,19.340 Z"/>
+                            </Grid>
+                        </Grid>
+                        <Grid x:Name="expandedErrorContent" Style="{StaticResource expandedStatusGridGtyle}">
+                            <Grid Style="{StaticResource pathContainerStyle}">
+                                <Path Fill="{StaticResource yellowErrorBrush}" Data="F1 M 38.553,18.767 C 38.147,18.767 37.784,18.634 37.506,18.394 C 37.256,18.126 37.116,17.819 37.116,17.473 C 37.116,17.079 37.256,16.769 37.540,16.519 C 37.795,16.288 38.157,16.165 38.553,16.165 C 38.981,16.165 39.321,16.291 39.594,16.544 C 39.869,16.774 40.004,17.083 40.004,17.473 C 40.004,17.831 39.874,18.139 39.602,18.398 C 39.356,18.637 38.993,18.767 38.553,18.767 Z M 39.864,7.252 L 39.556,15.069 L 37.540,15.069 L 37.246,7.252 L 39.864,7.252 Z M 38.549,0.000 L 25.561,21.254 L 38.549,21.254 L 51.561,21.254 L 38.549,0.000 Z"/>
+                                <Path Fill="#ffffffff" Data="F1 M 19.267,14.550 C 18.572,14.550 18.002,13.983 18.002,13.287 C 18.002,12.592 18.572,12.038 19.267,12.038 C 19.947,12.038 20.516,12.592 20.516,13.287 C 20.516,13.983 19.947,14.550 19.267,14.550 Z M 14.638,14.550 C 13.943,14.550 13.374,13.983 13.374,13.287 C 13.374,12.592 13.943,12.038 14.638,12.038 C 15.334,12.038 15.887,12.592 15.887,13.287 C 15.887,13.983 15.334,14.550 14.638,14.550 Z M 8.204,14.550 C 7.508,14.550 6.955,13.983 6.955,13.287 C 6.955,12.592 7.508,12.038 8.204,12.038 C 8.898,12.038 9.467,12.592 9.467,13.287 C 9.467,13.983 8.898,14.550 8.204,14.550 Z M 2.050,10.145 C 0.923,10.145 0.000,11.067 0.000,12.196 L 0.000,14.379 C 0.000,15.505 0.923,16.428 2.050,16.428 L 26.598,16.428 L 30.443,10.145 L 2.050,10.145 Z"/>
+                                <Path Fill="#ffffffff" Data="F1 M 21.646,19.341 C 21.218,19.155 17.968,18.038 17.968,18.038 L 15.905,18.038 C 15.905,18.038 12.656,19.155 12.228,19.341 C 11.800,19.528 11.536,19.618 11.627,19.939 C 11.692,20.149 11.829,20.649 11.988,21.070 C 12.048,21.272 12.151,21.415 12.353,21.415 C 12.461,21.415 21.413,21.415 21.521,21.415 C 21.723,21.415 21.825,21.272 21.901,21.070 C 22.044,20.649 22.196,20.149 22.247,19.939 C 22.338,19.618 22.074,19.528 21.646,19.341 Z"/>
+                            </Grid>
+                        </Grid>
+                    </Grid>
+                    <TextBlock Margin="0,20,0,0" Foreground="White" 
+                            VerticalAlignment="Center" HorizontalAlignment="Center" 
+                            FontSize="14.667" 
+                            Name="MessageTextBlock" TextWrapping="WrapWithOverflow"
+                            Text="{Binding Path=Message}" />
+                    <Grid>
+                        <TextBlock HorizontalAlignment="Left" VerticalAlignment="Bottom" Visibility="{Binding Path=MoreInformationVisibility}" FontSize="10.667">
+                            <Hyperlink Foreground="{StaticResource yellowErrorBrush}" Cursor="Hand" Name="TellMeMoreLink" RequestNavigate="TellMeMoreLinkRequestNavigate" ToolTip="{Binding Path=MoreInformation}" NavigateUri="{Binding MoreInformationUri}">Help</Hyperlink>
+                        </TextBlock>
+                        <Button Style="{StaticResource RefreshButtonStyle}" HorizontalAlignment="Right" VerticalAlignment="Bottom" Command="{Binding RetryCommand}">_Refresh</Button>
+                    </Grid>
+                </StackPanel>
+            </Grid>
+        </Popup>
+    </Grid>
+</UserControl>
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooserUI.xaml.cs
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooserUI.xaml.cs	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooserUI.xaml.cs	(revision 28895)
@@ -0,0 +1,273 @@
+﻿// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="KinectSensorChooserUI.xaml.cs" company="Microsoft">
+//     Copyright (c) Microsoft Corporation.  All rights reserved.
+// </copyright>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace Microsoft.Kinect.Toolkit
+{
+    using System;
+    using System.ComponentModel;
+    using System.Diagnostics;
+    using System.Globalization;
+    using System.Windows;
+    using System.Windows.Controls;
+    using System.Windows.Data;
+    using System.Windows.Documents;
+    using System.Windows.Input;
+    using System.Windows.Navigation;
+    using System.Windows.Threading;
+
+    /// <summary>
+    /// Interaction logic for KinectSensorChooserUI.xaml
+    /// </summary>
+    public partial class KinectSensorChooserUI : UserControl
+    {
+        /// <summary>
+        /// Set this to true when the application is listining for audio input from the sensor.
+        /// UI will show a microphone icon.
+        /// </summary>
+        public static readonly DependencyProperty IsListeningProperty = DependencyProperty.Register(
+            "IsListening", typeof(bool), typeof(KinectSensorChooserUI), new PropertyMetadata(false));
+
+        /// <summary>
+        /// The KinectSensorChooser whose status we are displaying.
+        /// </summary>
+        public static readonly DependencyProperty KinectSensorChooserProperty = DependencyProperty.Register(
+            "KinectSensorChooser", typeof(KinectSensorChooser), typeof(KinectSensorChooserUI), new PropertyMetadata(null));
+
+        /// <summary>
+        /// Used internally to transfer the visual state from the view model to the
+        /// VisualStateManager defined in XAML.
+        /// </summary>
+        public static readonly DependencyProperty VisualStateProperty = DependencyProperty.Register(
+            "VisualState", 
+            typeof(string), 
+            typeof(KinectSensorChooserUI), 
+            new PropertyMetadata(null, (o, args) => ((KinectSensorChooserUI)o).OnVisualstateChanged((string)args.NewValue)));
+
+        /// <summary>
+        /// Timer used to check if the mouse is still in the popup when we activated
+        /// the popup with a mouse hover.  We do this because the mouse may not be
+        /// in the popup when it comes up and we will never get a mouse leave event.
+        /// </summary>
+        private readonly DispatcherTimer popupCloseCheck;
+
+        private bool suppressPopupOnFocus;
+
+        private Window parentWindow;
+
+        /// <summary>
+        /// Initializes a new instance of the KinectSensorChooserUI class
+        /// </summary>
+        public KinectSensorChooserUI()
+        {
+            Loaded += OnLoaded;
+            Unloaded += OnUnloaded;
+
+            this.InitializeComponent();
+            this.popupCloseCheck = new DispatcherTimer(
+                TimeSpan.FromMilliseconds(1000), DispatcherPriority.Normal, this.OnPopupCloseCheckFired, this.Dispatcher);
+
+            var viewModel = new KinectSensorChooserUIViewModel();
+            this.layoutRoot.DataContext = viewModel;
+
+            var visualStateBinding = new Binding("VisualState") { Source = viewModel };
+            SetBinding(VisualStateProperty, visualStateBinding);
+
+            var sensorChooserBinding = new Binding("KinectSensorChooser") { Source = this };
+            BindingOperations.SetBinding(viewModel, KinectSensorChooserUIViewModel.KinectSensorChooserProperty, sensorChooserBinding);
+
+            var isListeningBinding = new Binding("IsListening") { Source = this };
+            BindingOperations.SetBinding(viewModel, KinectSensorChooserUIViewModel.IsListeningProperty, isListeningBinding);
+
+            this.expandedPopup.LayoutUpdated += this.ExpandedPopupOnLayoutUpdated;
+        }
+
+        /// <summary>
+        /// Set this to true when the application is listining for audio input from the sensor.
+        /// UI will show a microphone icon.  Value is passed through to the view model.
+        /// </summary>
+        public bool IsListening
+        {
+            get
+            {
+                return (bool)this.GetValue(IsListeningProperty);
+            }
+
+            set
+            {
+                this.SetValue(IsListeningProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The KinectSensorChooser whose status we are displaying.  Value is
+        /// passed through to the view model.
+        /// </summary>
+        public KinectSensorChooser KinectSensorChooser
+        {
+            get
+            {
+                return (KinectSensorChooser)this.GetValue(KinectSensorChooserProperty);
+            }
+
+            set
+            {
+                this.SetValue(KinectSensorChooserProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// Used internally to transfer the visual state from the view model to the
+        /// VisualStateManager defined in XAML.
+        /// </summary>
+        public string VisualState
+        {
+            get
+            {
+                return (string)this.GetValue(VisualStateProperty);
+            }
+
+            set
+            {
+                this.SetValue(VisualStateProperty, value);
+            }
+        }
+
+        private void OnLoaded(object sender, RoutedEventArgs routedEventArgs)
+        {
+            this.parentWindow = Window.GetWindow(this);
+            if (parentWindow != null)
+            {
+                parentWindow.Deactivated += ParentWindowOnDeactivated;
+            }
+        }
+
+        private void OnUnloaded(object sender, RoutedEventArgs routedEventArgs)
+        {
+            if (this.parentWindow != null)
+            {
+                parentWindow.Deactivated -= ParentWindowOnDeactivated;
+            }
+        }
+
+        private void ParentWindowOnDeactivated(object sender, EventArgs eventArgs)
+        {
+            this.ClosePopup();
+        }
+
+        private void ClosePopup()
+        {
+            this.expandedPopup.IsOpen = false;
+        }
+
+        private void OpenPopup()
+        {
+            this.expandedPopup.IsOpen = true;
+        }
+
+        private void OnRootGridGotKeyboardFocus(object sender, RoutedEventArgs e)
+        {
+            if (!this.suppressPopupOnFocus)
+            {
+                OpenPopup();
+            }
+        }
+
+        private void OnRootGridMouseEnter(object sender, MouseEventArgs e)
+        {
+            OpenPopup();
+        }
+
+        private void ExpandedPopupOnLayoutUpdated(object sender, EventArgs eventArgs)
+        {
+            // makes the popup top-aligned with its parent
+            this.expandedPopup.VerticalOffset = (this.popupGrid.ActualHeight - this.layoutRoot.ActualHeight - 1.0) / 2.0;
+        }
+
+        private void ExpandedPopupOnOpened(object sender, EventArgs eventArgs)
+        {
+            this.popupCloseCheck.Stop();
+
+            if (this.layoutRoot.IsKeyboardFocusWithin)
+            {
+                Keyboard.Focus(this.popupGrid);
+            }
+            else
+            {
+                this.popupCloseCheck.Start();
+            }
+        }
+
+        private void OnExpandedPopupMouseLeave(object sender, MouseEventArgs e)
+        {
+            this.ClosePopup();
+        }
+
+        private void OnPopupCloseCheckFired(object sender, EventArgs e)
+        {
+            this.popupCloseCheck.Stop();
+            if (this.expandedPopup.IsOpen && !this.popupGrid.IsMouseOver && !this.popupGrid.IsKeyboardFocusWithin)
+            {
+                this.ClosePopup();
+            }
+        }
+
+        private void OnPopupGridGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
+        {
+            var oldFocus = e.OldFocus as FrameworkElement;
+            var newFocus = e.NewFocus as FrameworkElement;
+
+            if (newFocus == this.popupGrid)
+            {
+                if (oldFocus != this.layoutRoot)
+                {
+                    // Focus is returning to us after being tabbed around our children.
+                    // That is our signal to quit the popup.
+                    this.suppressPopupOnFocus = true;
+                    this.layoutRoot.Focusable = false;
+                    e.Handled = true;
+
+                    // There doesn't seem to be an easy way to generically tell which way the user was
+                    // navigating with the keyboard (tab or shift+tab) check if the shift key is pressed
+                    FocusNavigationDirection direction = ((Keyboard.Modifiers & ModifierKeys.Shift) != 0)
+                                                             ? FocusNavigationDirection.Previous
+                                                             : FocusNavigationDirection.Next;
+
+                    this.ClosePopup();
+                    this.MoveFocus(new TraversalRequest(direction));
+                    this.layoutRoot.Focusable = true;
+                    this.suppressPopupOnFocus = false;
+                }
+            }
+        }
+
+        private void OnVisualstateChanged(string newState)
+        {
+            VisualStateManager.GoToState(this, newState, true);
+        }
+
+        private void TellMeMoreLinkRequestNavigate(object sender, RequestNavigateEventArgs e)
+        {
+            var hyperlink = e.OriginalSource as Hyperlink;
+            if (hyperlink != null)
+            {
+                try
+                {
+                    // Careful - ensure that this NavigateUri comes from a trusted source, as in this sample, before launching a process using it.
+                    Process.Start(new ProcessStartInfo(hyperlink.NavigateUri.ToString()));
+                }
+                catch (Win32Exception)
+                {
+                    // No default browser was set to handle the http request or unable to launch the browser
+                    MessageBox.Show(string.Format(CultureInfo.CurrentCulture, Properties.Resources.NoDefaultBrowserAvailable, hyperlink.NavigateUri));
+                }
+
+                this.ClosePopup();
+            }
+
+            e.Handled = true;
+        }
+    }
+}
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooserUIViewModel.cs
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooserUIViewModel.cs	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/KinectSensorChooserUIViewModel.cs	(revision 28895)
@@ -0,0 +1,383 @@
+﻿// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="KinectSensorChooserUIViewModel.cs" company="Microsoft">
+//     Copyright (c) Microsoft Corporation.  All rights reserved.
+// </copyright>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace Microsoft.Kinect.Toolkit
+{
+    using System;
+    using System.Diagnostics.CodeAnalysis;
+    using System.Windows;
+    using System.Windows.Data;
+    using System.Windows.Input;
+    using Microsoft.Kinect.Toolkit.Properties;
+
+    /// <summary>
+    /// View model for the KinectSensorChooser.
+    /// </summary>
+    public class KinectSensorChooserUIViewModel : DependencyObject
+    {
+        [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "ReadOnlyDependencyProperty requires private static field to be initialized prior to the public static field")]
+        private static readonly DependencyPropertyKey MessagePropertyKey = DependencyProperty.RegisterReadOnly(
+            "Message", typeof(string), typeof(KinectSensorChooserUIViewModel), new PropertyMetadata(string.Empty));
+
+        [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "ReadOnlyDependencyProperty requires private static field to be initialized prior to the public static field")]
+        private static readonly DependencyPropertyKey MoreInformationPropertyKey = DependencyProperty.RegisterReadOnly(
+            "MoreInformation", typeof(string), typeof(KinectSensorChooserUIViewModel), new PropertyMetadata(string.Empty));
+
+        [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "ReadOnlyDependencyProperty requires private static field to be initialized prior to the public static field")]
+        private static readonly DependencyPropertyKey MoreInformationUriPropertyKey =
+            DependencyProperty.RegisterReadOnly(
+                "MoreInformationUri", typeof(Uri), typeof(KinectSensorChooserUIViewModel), new PropertyMetadata(null));
+
+        [SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "ReadOnlyDependencyProperty requires private static field to be initialized prior to the public static field")]
+        private static readonly DependencyPropertyKey MoreInformationVisibilityPropertyKey =
+            DependencyProperty.RegisterReadOnly(
+                "MoreInformationVisibility",
+                typeof(Visibility),
+                typeof(KinectSensorChooserUIViewModel),
+                new PropertyMetadata(Visibility.Collapsed));
+
+        /// <summary>
+        /// Set this to true when the application is listining for audio input from the sensor.
+        /// UI will show a microphone icon.
+        /// </summary>
+        public static readonly DependencyProperty IsListeningProperty = DependencyProperty.Register(
+            "IsListening", 
+            typeof(bool), 
+            typeof(KinectSensorChooserUIViewModel), 
+            new PropertyMetadata(false, (o, args) => ((KinectSensorChooserUIViewModel)o).IsListeningChanged()));
+
+        /// <summary>
+        /// The KinectSensorChooser whose status we are displaying.
+        /// </summary>
+        public static readonly DependencyProperty KinectSensorChooserProperty = DependencyProperty.Register(
+            "KinectSensorChooser", 
+            typeof(KinectSensorChooser), 
+            typeof(KinectSensorChooserUIViewModel), 
+            new PropertyMetadata(
+                null, 
+                (o, args) => ((KinectSensorChooserUIViewModel)o).OnKinectKinectSensorChooserChanged((KinectSensorChooser)args.NewValue)));
+
+        /// <summary>
+        /// The current ChooserStatus of our KinectSensorChooser
+        /// </summary>
+        public static readonly DependencyProperty StatusProperty = DependencyProperty.Register(
+            "Status", 
+            typeof(ChooserStatus), 
+            typeof(KinectSensorChooserUIViewModel), 
+            new PropertyMetadata(ChooserStatus.None, (o, args) => ((KinectSensorChooserUIViewModel)o).OnStatusChanged()));
+
+        /// <summary>
+        /// The state we want the VisualStateManager in the UI to be in.
+        /// </summary>
+        public static readonly DependencyProperty VisualStateProperty = DependencyProperty.Register(
+            "VisualState", typeof(string), typeof(KinectSensorChooserUIViewModel), new PropertyMetadata(null));
+
+        /// <summary>
+        /// The short message to display.
+        /// </summary>
+        public static readonly DependencyProperty MessageProperty = MessagePropertyKey.DependencyProperty;
+
+        /// <summary>
+        /// The more descriptive message to display.
+        /// </summary>
+        public static readonly DependencyProperty MoreInformationProperty = MoreInformationPropertyKey.DependencyProperty;
+
+        /// <summary>
+        /// Uri for more information on the state we are in.
+        /// </summary>
+        public static readonly DependencyProperty MoreInformationUriProperty = MoreInformationUriPropertyKey.DependencyProperty;
+
+        /// <summary>
+        /// The visibility we want for the MoreInformation Uri.
+        /// </summary>
+        public static readonly DependencyProperty MoreInformationVisibilityProperty = MoreInformationVisibilityPropertyKey.DependencyProperty;
+
+        private RelayCommand retryCommand;
+
+        /// <summary>
+        /// Set this to true when the application is listining for audio input from the sensor.
+        /// UI will show a microphone icon.
+        /// </summary>
+        public bool IsListening
+        {
+            get
+            {
+                return (bool)this.GetValue(IsListeningProperty);
+            }
+
+            set
+            {
+                this.SetValue(IsListeningProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The KinectSensorChooser whose status we are displaying.
+        /// </summary>
+        public KinectSensorChooser KinectSensorChooser
+        {
+            get
+            {
+                return (KinectSensorChooser)this.GetValue(KinectSensorChooserProperty);
+            }
+
+            set
+            {
+                this.SetValue(KinectSensorChooserProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The short message to display.
+        /// </summary>
+        public string Message
+        {
+            get
+            {
+                return (string)this.GetValue(MessageProperty);
+            }
+
+            private set
+            {
+                this.SetValue(MessagePropertyKey, value);
+            }
+        }
+
+        /// <summary>
+        /// The more descriptive message to display.
+        /// </summary>
+        public string MoreInformation
+        {
+            get
+            {
+                return (string)this.GetValue(MoreInformationProperty);
+            }
+
+            private set
+            {
+                this.SetValue(MoreInformationPropertyKey, value);
+            }
+        }
+
+        /// <summary>
+        /// Uri for more information on the state we are in.
+        /// </summary>
+        public Uri MoreInformationUri
+        {
+            get
+            {
+                return (Uri)this.GetValue(MoreInformationUriProperty);
+            }
+
+            private set
+            {
+                this.SetValue(MoreInformationUriPropertyKey, value);
+            }
+        }
+
+        /// <summary>
+        /// The visibility we want for the MoreInformation Uri.
+        /// </summary>
+        public Visibility MoreInformationVisibility
+        {
+            get
+            {
+                return (Visibility)this.GetValue(MoreInformationVisibilityProperty);
+            }
+
+            private set
+            {
+                this.SetValue(MoreInformationVisibilityPropertyKey, value);
+            }
+        }
+
+        /// <summary>
+        /// Command to retry getting a sensor.
+        /// </summary>
+        public ICommand RetryCommand
+        {
+            get
+            {
+                if (this.retryCommand == null)
+                {
+                    this.retryCommand = new RelayCommand(this.Retry, this.CanRetry);
+                }
+
+                return this.retryCommand;
+            }
+        }
+
+        /// <summary>
+        /// The current ChooserStatus of our KinectSensorChooser
+        /// </summary>
+        public ChooserStatus Status
+        {
+            get
+            {
+                return (ChooserStatus)this.GetValue(StatusProperty);
+            }
+
+            set
+            {
+                this.SetValue(StatusProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// The state we want the VisualStateManager in the UI to be in.
+        /// </summary>
+        public string VisualState
+        {
+            get
+            {
+                return (string)this.GetValue(VisualStateProperty);
+            }
+
+            set
+            {
+                this.SetValue(VisualStateProperty, value);
+            }
+        }
+
+        /// <summary>
+        /// Determines if the retry command is available
+        /// </summary>
+        /// <returns>true if retry is valid, false otherwise</returns>
+        private bool CanRetry()
+        {
+            // You can retry if another app was using the sensor the last
+            // time we tried.  You can also retry if the only problem was
+            // that there were no sensors available since this app may
+            // have released one.
+            return (0 != (this.Status & ChooserStatus.SensorConflict)) || (this.Status == ChooserStatus.NoAvailableSensors);
+        }
+
+        private void IsListeningChanged()
+        {
+            this.UpdateState();
+        }
+
+        private void OnKinectKinectSensorChooserChanged(KinectSensorChooser newValue)
+        {
+            if (newValue != null)
+            {
+                var statusBinding = new Binding("Status") { Source = newValue };
+                BindingOperations.SetBinding(this, StatusProperty, statusBinding);
+            }
+            else
+            {
+                BindingOperations.ClearBinding(this, StatusProperty);
+            }
+        }
+
+        private void OnStatusChanged()
+        {
+            this.UpdateState();
+        }
+
+        private void Retry()
+        {
+            if (this.KinectSensorChooser != null)
+            {
+                this.KinectSensorChooser.TryResolveConflict();
+            }
+        }
+
+        private void UpdateState()
+        {
+            string newVisualState;
+            string message;
+            string moreInfo = null;
+            Uri moreInfoUri = null;
+
+            if ((this.Status & ChooserStatus.SensorStarted) != 0)
+            {
+                if (this.IsListening)
+                {
+                    newVisualState = "AllSetListening";
+                    message = Resources.MessageAllSetListening;
+                }
+                else
+                {
+                    newVisualState = "AllSetNotListening";
+                    message = Resources.MessageAllSet;
+                }
+            }
+            else if ((this.Status & ChooserStatus.SensorInitializing) != 0)
+            {
+                newVisualState = "Initializing";
+                message = Resources.MessageInitializing;
+            }
+            else if ((this.Status & ChooserStatus.SensorConflict) != 0)
+            {
+                newVisualState = "Error";
+                message = Resources.MessageConflict;
+                moreInfo = Resources.MoreInformationConflict;
+                moreInfoUri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239812");
+            }
+            else if ((this.Status & ChooserStatus.SensorNotGenuine) != 0)
+            {
+                newVisualState = "Error";
+                message = Resources.MessageNotGenuine;
+                moreInfo = Resources.MoreInformationNotGenuine;
+                moreInfoUri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239813");
+            }
+            else if ((this.Status & ChooserStatus.SensorNotSupported) != 0)
+            {
+                newVisualState = "Error";
+                message = Resources.MessageNotSupported;
+                moreInfo = Resources.MoreInformationNotSupported;
+                moreInfoUri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239814");
+            }
+            else if ((this.Status & ChooserStatus.SensorError) != 0)
+            {
+                newVisualState = "Error";
+                message = Resources.MessageError;
+                moreInfo = Resources.MoreInformationError;
+                moreInfoUri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239817");
+            }
+            else if ((this.Status & ChooserStatus.SensorInsufficientBandwidth) != 0)
+            {
+                newVisualState = "Error";
+                message = Resources.MessageInsufficientBandwidth;
+                moreInfo = Resources.MoreInformationInsufficientBandwidth;
+                moreInfoUri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239818");
+            }
+            else if ((this.Status & ChooserStatus.SensorNotPowered) != 0)
+            {
+                newVisualState = "Error";
+                message = Resources.MessageNotPowered;
+                moreInfo = Resources.MoreInformationNotPowered;
+                moreInfoUri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239819");
+            }
+            else if ((this.Status & ChooserStatus.NoAvailableSensors) != 0)
+            {
+                newVisualState = "NoAvailableSensors";
+                message = Resources.MessageNoAvailableSensors;
+                moreInfo = Resources.MoreInformationNoAvailableSensors;
+                moreInfoUri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239815");
+            }
+            else
+            {
+                newVisualState = "Stopped";
+                message = Resources.MessageNoAvailableSensors;
+                moreInfo = Resources.MoreInformationNoAvailableSensors;
+                moreInfoUri = new Uri("http://go.microsoft.com/fwlink/?LinkID=239815");
+            }
+
+            this.Message = message;
+            this.MoreInformation = moreInfo;
+            this.MoreInformationUri = moreInfoUri;
+            this.MoreInformationVisibility = moreInfoUri == null ? Visibility.Collapsed : Visibility.Visible;
+            if (this.retryCommand != null)
+            {
+                this.retryCommand.InvokeCanExecuteChanged();
+            }
+
+            this.VisualState = newVisualState;
+        }
+    }
+}
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Microsoft.Kinect.Toolkit.csproj
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Microsoft.Kinect.Toolkit.csproj	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Microsoft.Kinect.Toolkit.csproj	(revision 28895)
@@ -0,0 +1,98 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProjectGuid>{C6F9C31B-6130-4443-A5CC-EF0664552ECD}</ProjectGuid>
+    <OutputType>library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Microsoft.Kinect.Toolkit</RootNamespace>
+    <AssemblyName>Microsoft.Kinect.Toolkit</AssemblyName>
+    <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+    <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <RunCodeAnalysis>true</RunCodeAnalysis>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <RunCodeAnalysis>true</RunCodeAnalysis>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Kinect">
+      <HintPath>$(KINECTSDK10_DIR)\Assemblies\Microsoft.Kinect.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xaml">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="WindowsBase" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="CallbackLock.cs" />
+    <Compile Include="ContextEventWrapper.cs" />
+    <Compile Include="KinectChangedEventArgs.cs" />
+    <Compile Include="KinectSensorChooser.cs" />
+    <Compile Include="KinectSensorChooserUI.xaml.cs">
+      <DependentUpon>KinectSensorChooserUI.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="KinectSensorChooserUiViewModel.cs" />
+    <Compile Include="Properties\AssemblyInfo.cs">
+      <SubType>Code</SubType>
+    </Compile>
+    <Compile Include="Properties\Resources.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DesignTime>True</DesignTime>
+      <DependentUpon>Resources.resx</DependentUpon>
+    </Compile>
+    <Compile Include="Properties\Settings.Designer.cs">
+      <AutoGen>True</AutoGen>
+      <DependentUpon>Settings.settings</DependentUpon>
+      <DesignTimeSharedInput>True</DesignTimeSharedInput>
+    </Compile>
+    <Compile Include="RelayCommand.cs" />
+    <Compile Include="ThreadSafeCollection.cs" />
+    <EmbeddedResource Include="Properties\Resources.resx">
+      <Generator>ResXFileCodeGenerator</Generator>
+      <LastGenOutput>Resources.Designer.cs</LastGenOutput>
+    </EmbeddedResource>
+    <None Include="Properties\Settings.settings">
+      <Generator>SettingsSingleFileGenerator</Generator>
+      <LastGenOutput>Settings.Designer.cs</LastGenOutput>
+    </None>
+    <AppDesigner Include="Properties\" />
+  </ItemGroup>
+  <ItemGroup>
+    <Page Include="KinectSensorChooserUI.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
+</Project>
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/AssemblyInfo.cs
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/AssemblyInfo.cs	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/AssemblyInfo.cs	(revision 28895)
@@ -0,0 +1,41 @@
+﻿using System;
+using System.Reflection;
+using System.Resources;
+using System.Runtime.CompilerServices;
+using System.Runtime.InteropServices;
+using System.Windows;
+using System.Windows.Markup;
+
+// General Information about an assembly is controlled through the following 
+// set of attributes. Change these attribute values to modify the information
+// associated with an assembly.
+[assembly: AssemblyTitle("Microsoft.Kinect.Toolkit")]
+
+// Setting ComVisible to false makes the types in this assembly not visible 
+// to COM components.  If you need to access a type in this assembly from 
+// COM, set the ComVisible attribute to true on that type.
+[assembly: ComVisible(false)]
+
+// In order to begin building localizable applications, set 
+// <UICulture>CultureYouAreCodingWith</UICulture> in your .csproj file
+// inside a <PropertyGroup>.  For example, if you are using US english
+// in your source files, set the <UICulture> to en-US.  Then uncomment
+// the NeutralResourceLanguage attribute below.  Update the "en-US" in
+// the line below to match the UICulture setting in the project file.
+
+////[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)]
+
+[assembly: ThemeInfo(
+    ResourceDictionaryLocation.None, // where theme specific resource dictionaries are located
+    // (used if a resource is not found in the page, 
+    // or application resource dictionaries)
+    ResourceDictionaryLocation.SourceAssembly // where the generic resource dictionary is located
+    // (used if a resource is not found in the page, 
+    // app, or any theme specific resource dictionaries)
+)]
+
+[assembly: NeutralResourcesLanguageAttribute("en-US")]
+[assembly: CLSCompliant(true)]
+[assembly: AssemblyVersion("1.8.0.0")]
+[assembly: XmlnsDefinition("http://schemas.microsoft.com/kinect/2013", "Microsoft.Kinect.Toolkit")]
+[assembly: XmlnsPrefix("http://schemas.microsoft.com/kinect/2013", "k")]
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/Resources.Designer.cs
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/Resources.Designer.cs	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/Resources.Designer.cs	(revision 28895)
@@ -0,0 +1,234 @@
+﻿//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.17929
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Microsoft.Kinect.Toolkit.Properties {
+    using System;
+    
+    
+    /// <summary>
+    ///   A strongly-typed resource class, for looking up localized strings, etc.
+    /// </summary>
+    // This class was auto-generated by the StronglyTypedResourceBuilder
+    // class via a tool like ResGen or Visual Studio.
+    // To add or remove a member, edit your .ResX file then rerun ResGen
+    // with the /str option, or rebuild your VS project.
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
+    [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    internal class Resources {
+        
+        private static global::System.Resources.ResourceManager resourceMan;
+        
+        private static global::System.Globalization.CultureInfo resourceCulture;
+        
+        [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
+        internal Resources() {
+        }
+        
+        /// <summary>
+        ///   Returns the cached ResourceManager instance used by this class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Resources.ResourceManager ResourceManager {
+            get {
+                if (object.ReferenceEquals(resourceMan, null)) {
+                    global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Microsoft.Kinect.Toolkit.Properties.Resources", typeof(Resources).Assembly);
+                    resourceMan = temp;
+                }
+                return resourceMan;
+            }
+        }
+        
+        /// <summary>
+        ///   Overrides the current thread's CurrentUICulture property for all
+        ///   resource lookups using this strongly typed resource class.
+        /// </summary>
+        [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
+        internal static global::System.Globalization.CultureInfo Culture {
+            get {
+                return resourceCulture;
+            }
+            set {
+                resourceCulture = value;
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Parameter of type {0} not of of expected type {1}.
+        /// </summary>
+        internal static string DelegateCommandCastException {
+            get {
+                return ResourceManager.GetString("DelegateCommandCastException", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to All set!.
+        /// </summary>
+        internal static string MessageAllSet {
+            get {
+                return ResourceManager.GetString("MessageAllSet", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Kinect is listening.
+        /// </summary>
+        internal static string MessageAllSetListening {
+            get {
+                return ResourceManager.GetString("MessageAllSetListening", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to This Kinect is being used by another application..
+        /// </summary>
+        internal static string MessageConflict {
+            get {
+                return ResourceManager.GetString("MessageConflict", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Oops, there is an error..
+        /// </summary>
+        internal static string MessageError {
+            get {
+                return ResourceManager.GetString("MessageError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Initializing....
+        /// </summary>
+        internal static string MessageInitializing {
+            get {
+                return ResourceManager.GetString("MessageInitializing", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Too many USB devices! Please unplug one or more..
+        /// </summary>
+        internal static string MessageInsufficientBandwidth {
+            get {
+                return ResourceManager.GetString("MessageInsufficientBandwidth", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Kinect required.
+        /// </summary>
+        internal static string MessageNoAvailableSensors {
+            get {
+                return ResourceManager.GetString("MessageNoAvailableSensors", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to This sensor is not genuine!.
+        /// </summary>
+        internal static string MessageNotGenuine {
+            get {
+                return ResourceManager.GetString("MessageNotGenuine", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Plug my power cord in!.
+        /// </summary>
+        internal static string MessageNotPowered {
+            get {
+                return ResourceManager.GetString("MessageNotPowered", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Kinect for Xbox not supported..
+        /// </summary>
+        internal static string MessageNotSupported {
+            get {
+                return ResourceManager.GetString("MessageNotSupported", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to This application needs a Kinect for Windows sensor in order to function. However, another application is using the Kinect Sensor..
+        /// </summary>
+        internal static string MoreInformationConflict {
+            get {
+                return ResourceManager.GetString("MoreInformationConflict", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The Kinect Sensor is plugged in, however an error has occurred. For steps to resolve, please click the &quot;Help&quot; link..
+        /// </summary>
+        internal static string MoreInformationError {
+            get {
+                return ResourceManager.GetString("MoreInformationError", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The Kinect Sensor needs the majority of the USB Bandwidth of a USB Controller. If other devices are in contention for that bandwidth, the Kinect Sensor may not be able to function..
+        /// </summary>
+        internal static string MoreInformationInsufficientBandwidth {
+            get {
+                return ResourceManager.GetString("MoreInformationInsufficientBandwidth", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to This application needs a Kinect for Windows sensor in order to function. Please plug one into the PC..
+        /// </summary>
+        internal static string MoreInformationNoAvailableSensors {
+            get {
+                return ResourceManager.GetString("MoreInformationNoAvailableSensors", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to This application needs a genuine Kinect for Windows sensor in order to function. Please plug one into the PC..
+        /// </summary>
+        internal static string MoreInformationNotGenuine {
+            get {
+                return ResourceManager.GetString("MoreInformationNotGenuine", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to The Kinect Sensor is plugged into the computer with its USB connection, but the power plug appears to be not powered..
+        /// </summary>
+        internal static string MoreInformationNotPowered {
+            get {
+                return ResourceManager.GetString("MoreInformationNotPowered", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to This application needs a Kinect for Windows sensor in order to function. Please plug one into the PC..
+        /// </summary>
+        internal static string MoreInformationNotSupported {
+            get {
+                return ResourceManager.GetString("MoreInformationNotSupported", resourceCulture);
+            }
+        }
+        
+        /// <summary>
+        ///   Looks up a localized string similar to Unable to launch the default web browser. Trying to navigate to: {0}.
+        /// </summary>
+        internal static string NoDefaultBrowserAvailable {
+            get {
+                return ResourceManager.GetString("NoDefaultBrowserAvailable", resourceCulture);
+            }
+        }
+    }
+}
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/Resources.resx
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/Resources.resx	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/Resources.resx	(revision 28895)
@@ -0,0 +1,177 @@
+﻿<?xml version="1.0" encoding="utf-8"?>
+<root>
+  <!-- 
+    Microsoft ResX Schema 
+    
+    Version 2.0
+    
+    The primary goals of this format is to allow a simple XML format 
+    that is mostly human readable. The generation and parsing of the 
+    various data types are done through the TypeConverter classes 
+    associated with the data types.
+    
+    Example:
+    
+    ... ado.net/XML headers & schema ...
+    <resheader name="resmimetype">text/microsoft-resx</resheader>
+    <resheader name="version">2.0</resheader>
+    <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
+    <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
+    <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
+    <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
+    <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
+        <value>[base64 mime encoded serialized .NET Framework object]</value>
+    </data>
+    <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
+        <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
+        <comment>This is a comment</comment>
+    </data>
+                
+    There are any number of "resheader" rows that contain simple 
+    name/value pairs.
+    
+    Each data row contains a name, and value. The row also contains a 
+    type or mimetype. Type corresponds to a .NET class that support 
+    text/value conversion through the TypeConverter architecture. 
+    Classes that don't support this are serialized and stored with the 
+    mimetype set.
+    
+    The mimetype is used for serialized objects, and tells the 
+    ResXResourceReader how to depersist the object. This is currently not 
+    extensible. For a given mimetype the value must be set accordingly:
+    
+    Note - application/x-microsoft.net.object.binary.base64 is the format 
+    that the ResXResourceWriter will generate, however the reader can 
+    read any of the formats listed below.
+    
+    mimetype: application/x-microsoft.net.object.binary.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
+            : and then encoded with base64 encoding.
+    
+    mimetype: application/x-microsoft.net.object.soap.base64
+    value   : The object must be serialized with 
+            : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
+            : and then encoded with base64 encoding.
+
+    mimetype: application/x-microsoft.net.object.bytearray.base64
+    value   : The object must be serialized into a byte array 
+            : using a System.ComponentModel.TypeConverter
+            : and then encoded with base64 encoding.
+    -->
+  <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
+    <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
+    <xsd:element name="root" msdata:IsDataSet="true">
+      <xsd:complexType>
+        <xsd:choice maxOccurs="unbounded">
+          <xsd:element name="metadata">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" />
+              </xsd:sequence>
+              <xsd:attribute name="name" use="required" type="xsd:string" />
+              <xsd:attribute name="type" type="xsd:string" />
+              <xsd:attribute name="mimetype" type="xsd:string" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="assembly">
+            <xsd:complexType>
+              <xsd:attribute name="alias" type="xsd:string" />
+              <xsd:attribute name="name" type="xsd:string" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="data">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+                <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
+              <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
+              <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
+              <xsd:attribute ref="xml:space" />
+            </xsd:complexType>
+          </xsd:element>
+          <xsd:element name="resheader">
+            <xsd:complexType>
+              <xsd:sequence>
+                <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
+              </xsd:sequence>
+              <xsd:attribute name="name" type="xsd:string" use="required" />
+            </xsd:complexType>
+          </xsd:element>
+        </xsd:choice>
+      </xsd:complexType>
+    </xsd:element>
+  </xsd:schema>
+  <resheader name="resmimetype">
+    <value>text/microsoft-resx</value>
+  </resheader>
+  <resheader name="version">
+    <value>2.0</value>
+  </resheader>
+  <resheader name="reader">
+    <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <resheader name="writer">
+    <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
+  </resheader>
+  <data name="DelegateCommandCastException" xml:space="preserve">
+    <value>Parameter of type {0} not of of expected type {1}</value>
+  </data>
+  <data name="MessageAllSet" xml:space="preserve">
+    <value>All set!</value>
+  </data>
+  <data name="MessageAllSetListening" xml:space="preserve">
+    <value>Kinect is listening</value>
+  </data>
+  <data name="MessageConflict" xml:space="preserve">
+    <value>This Kinect is being used by another application.</value>
+  </data>
+  <data name="MessageError" xml:space="preserve">
+    <value>Oops, there is an error.</value>
+  </data>
+  <data name="MessageInitializing" xml:space="preserve">
+    <value>Initializing...</value>
+  </data>
+  <data name="MessageInsufficientBandwidth" xml:space="preserve">
+    <value>Too many USB devices! Please unplug one or more.</value>
+  </data>
+  <data name="MessageNoAvailableSensors" xml:space="preserve">
+    <value>Kinect required</value>
+  </data>
+  <data name="MessageNotGenuine" xml:space="preserve">
+    <value>This sensor is not genuine!</value>
+  </data>
+  <data name="MessageNotPowered" xml:space="preserve">
+    <value>Plug my power cord in!</value>
+  </data>
+  <data name="MessageNotSupported" xml:space="preserve">
+    <value>Kinect for Xbox not supported.</value>
+  </data>
+  <data name="MoreInformationConflict" xml:space="preserve">
+    <value>This application needs a Kinect for Windows sensor in order to function. However, another application is using the Kinect Sensor.</value>
+  </data>
+  <data name="MoreInformationError" xml:space="preserve">
+    <value>The Kinect Sensor is plugged in, however an error has occurred. For steps to resolve, please click the "Help" link.</value>
+  </data>
+  <data name="MoreInformationInsufficientBandwidth" xml:space="preserve">
+    <value>The Kinect Sensor needs the majority of the USB Bandwidth of a USB Controller. If other devices are in contention for that bandwidth, the Kinect Sensor may not be able to function.</value>
+  </data>
+  <data name="MoreInformationNoAvailableSensors" xml:space="preserve">
+    <value>This application needs a Kinect for Windows sensor in order to function. Please plug one into the PC.</value>
+  </data>
+  <data name="MoreInformationNotGenuine" xml:space="preserve">
+    <value>This application needs a genuine Kinect for Windows sensor in order to function. Please plug one into the PC.</value>
+  </data>
+  <data name="MoreInformationNotPowered" xml:space="preserve">
+    <value>The Kinect Sensor is plugged into the computer with its USB connection, but the power plug appears to be not powered.</value>
+  </data>
+  <data name="MoreInformationNotSupported" xml:space="preserve">
+    <value>This application needs a Kinect for Windows sensor in order to function. Please plug one into the PC.</value>
+  </data>
+  <data name="NoDefaultBrowserAvailable" xml:space="preserve">
+    <value>Unable to launch the default web browser. Trying to navigate to: {0}</value>
+  </data>
+</root>
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/Settings.Designer.cs
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/Settings.Designer.cs	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/Settings.Designer.cs	(revision 28895)
@@ -0,0 +1,26 @@
+﻿//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.239
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+namespace Microsoft.Kinect.Toolkit.Properties {
+    
+    
+    [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
+    [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "10.0.0.0")]
+    internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
+        
+        private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
+        
+        public static Settings Default {
+            get {
+                return defaultInstance;
+            }
+        }
+    }
+}
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/Settings.settings
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/Settings.settings	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/Properties/Settings.settings	(revision 28895)
@@ -0,0 +1,7 @@
+﻿<?xml version='1.0' encoding='utf-8'?>
+<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
+  <Profiles>
+    <Profile Name="(Default)" />
+  </Profiles>
+  <Settings />
+</SettingsFile>
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/RelayCommand.cs
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/RelayCommand.cs	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/RelayCommand.cs	(revision 28895)
@@ -0,0 +1,232 @@
+﻿// --------------------------------------------------------------------------------------------------------------------
+// <copyright file="RelayCommand.cs" company="Microsoft">
+//     Copyright (c) Microsoft Corporation.  All rights reserved.
+// </copyright>
+// --------------------------------------------------------------------------------------------------------------------
+
+namespace Microsoft.Kinect.Toolkit
+{
+    using System;
+    using System.Globalization;
+    using System.Windows.Input;
+    using Microsoft.Kinect.Toolkit.Properties;
+
+    /// <summary>
+    /// Command that executes a delegate that takes no parameters.
+    /// </summary>
+    public class RelayCommand : ICommand
+    {
+        /// <summary>
+        /// Delegate to be executed 
+        /// </summary>
+        private Action executeDelegate;
+
+        /// <summary>
+        /// Predicate determining whether this command can currently execute
+        /// </summary>
+        private Func<bool> canExecuteDelegate;
+
+        private EventHandler canExecuteEventhandler;
+
+        /// <summary>
+        /// Initializes a new instance of the RelayCommand class with the provided delegate and predicate
+        /// </summary>
+        /// <param name="executeDelegate">Delegate to be executed</param>
+        /// <param name="canExecuteDelegate">Predicate determining whether this command can currently execute</param>
+        public RelayCommand(Action executeDelegate, Func<bool> canExecuteDelegate)
+        {
+            if (null == executeDelegate)
+            {
+                throw new ArgumentNullException("executeDelegate");
+            }
+
+            this.canExecuteDelegate = canExecuteDelegate;
+            this.executeDelegate = executeDelegate;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the RelayCommand class with the provided delegate
+        /// </summary>
+        /// <param name="executeDelegate">Delegate to be executed</param>
+        public RelayCommand(Action executeDelegate)
+            : this(executeDelegate, null)
+        {
+        }
+
+        /// <summary>
+        /// Event signaling that the possibility of this command executing has changed
+        /// </summary>
+        public event EventHandler CanExecuteChanged
+        {
+            add
+            {
+                this.canExecuteEventhandler += value;
+                CommandManager.RequerySuggested += value;
+            }
+
+            remove
+            {
+                this.canExecuteEventhandler -= value;
+                CommandManager.RequerySuggested -= value;
+            }
+        }
+
+        /// <summary>
+        /// Evaluates whether the command can currently execute
+        /// </summary>
+        /// <param name="parameter">ICommand required parameter that is ignored</param>
+        /// <returns>True if the command can currently execute, false otherwise</returns>
+        public bool CanExecute(object parameter)
+        {
+            if (null == this.canExecuteDelegate)
+            {
+                return true;
+            }
+
+            return this.canExecuteDelegate.Invoke();
+        }
+
+        /// <summary>
+        /// Executes the associated delegate
+        /// </summary>
+        /// <param name="parameter">ICommand required parameter that is ignored</param>
+        public void Execute(object parameter)
+        {
+            this.executeDelegate.Invoke();
+        }
+
+        /// <summary>
+        /// Raises the CanExecuteChanged event to signal that the possibility of execution has changed
+        /// </summary>
+        public void InvokeCanExecuteChanged()
+        {
+            if (null != canExecuteDelegate)
+            {
+                EventHandler handler = this.canExecuteEventhandler;
+                if (null != handler)
+                {
+                    handler(this, EventArgs.Empty);
+                }
+            }
+        }
+    }
+
+    public class RelayCommand<T> : ICommand where T : class
+    {
+        /// <summary>
+        /// Delegate to be executed 
+        /// </summary>
+        private Action<T> executeDelegate;
+
+        /// <summary>
+        /// Predicate determining whether this command can currently execute
+        /// </summary>
+        private Predicate<T> canExecuteDelegate;
+
+        private EventHandler canExecuteEventhandler;
+
+        /// <summary>
+        /// Initializes a new instance of the RelayCommand class with the provided delegate and predicate
+        /// </summary>
+        /// <param name="executeDelegate">Delegate to be executed</param>
+        /// <param name="canExecuteDelegate">Predicate determining whether this command can currently execute</param>
+        public RelayCommand(Action<T> executeDelegate, Predicate<T> canExecuteDelegate)
+        {
+            if (null == executeDelegate)
+            {
+                throw new ArgumentNullException("executeDelegate");
+            }
+
+            this.canExecuteDelegate = canExecuteDelegate;
+            this.executeDelegate = executeDelegate;
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the RelayCommand class with the provided delegate
+        /// </summary>
+        /// <param name="executeDelegate">Delegate to be executed</param>
+        public RelayCommand(Action<T> executeDelegate)
+            : this(executeDelegate, null)
+        {
+        }
+
+        /// <summary>
+        /// Event signaling that the possibility of this command executing has changed
+        /// </summary>
+        public event EventHandler CanExecuteChanged
+        {
+            add
+            {
+                this.canExecuteEventhandler += value;
+                CommandManager.RequerySuggested += value;
+            }
+
+            remove
+            {
+                this.canExecuteEventhandler -= value;
+                CommandManager.RequerySuggested -= value;
+            }
+        }
+
+        /// <summary>
+        /// Evaluates whether the command can currently execute
+        /// </summary>
+        /// <param name="parameter">Context of type T used for evaluating the current possibility of execution</param>
+        /// <returns>True if the command can currently execute, false otherwise</returns>
+        public bool CanExecute(object parameter)
+        {
+            if (null == parameter)
+            {
+                throw new ArgumentNullException("parameter");
+            }
+
+            if (null == this.canExecuteDelegate)
+            {
+                return true;
+            }
+
+            T castParameter = parameter as T;
+            if (null == castParameter)
+            {
+                throw new InvalidCastException(string.Format(CultureInfo.InvariantCulture, Resources.DelegateCommandCastException, parameter.GetType().FullName, typeof(T).FullName));
+            }
+
+            return this.canExecuteDelegate.Invoke(castParameter);
+        }
+
+        /// <summary>
+        /// Executes the associated delegate
+        /// </summary>
+        /// <param name="parameter">Parameter of type T passed to the associated delegate</param>
+        public void Execute(object parameter)
+        {
+            if (null == parameter)
+            {
+                throw new ArgumentNullException("parameter");
+            }
+
+            T castParameter = parameter as T;
+            if (null == castParameter)
+            {
+                throw new InvalidCastException(string.Format(CultureInfo.InvariantCulture, Resources.DelegateCommandCastException, parameter.GetType().FullName, typeof(T).FullName));
+            }
+
+            this.executeDelegate.Invoke(castParameter);
+        }
+
+        /// <summary>
+        /// Raises the CanExecuteChanged event to signal that the possibility of execution has changed
+        /// </summary>
+        public void InvokeCanExecuteChanged()
+        {
+            if (null != canExecuteDelegate)
+            {
+                EventHandler handler = this.canExecuteEventhandler;
+                if (null != handler)
+                {
+                    handler(this, EventArgs.Empty);
+                }
+            }
+        }
+    }
+}
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/ThreadSafeCollection.cs
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/ThreadSafeCollection.cs	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/ThreadSafeCollection.cs	(revision 28895)
@@ -0,0 +1,423 @@
+﻿//-----------------------------------------------------------------------
+// <copyright file="ThreadSafeCollection.cs" company="Microsoft Corporation">
+// Copyright (c) Microsoft Corporation. All rights reserved.
+// </copyright>
+// <summary>
+// A list with locking semantics so it can be used cross-thread.
+// </summary>
+//-----------------------------------------------------------------------
+
+
+namespace Microsoft.Kinect.Toolkit
+{
+    using System;
+    using System.Collections;
+    using System.Collections.Generic;
+
+    /// <summary>
+    /// IList implementation with locking on all operations.
+    /// </summary>
+    /// <typeparam name="T">Type of generic IList to implement.</typeparam>
+    public sealed class ThreadSafeCollection<T> : IList<T>
+    {
+        /// <summary>
+        /// Lock object to use for all operations.
+        /// </summary>
+        private readonly object lockObject;
+
+        /// <summary>
+        /// Wrapped collection object.
+        /// </summary>
+        private readonly List<T> list = new List<T>();
+        
+        /// <summary>
+        /// Initializes a new instance of the ThreadSafeCollection class with a new lock.
+        /// </summary>
+        public ThreadSafeCollection() : this(new object())
+        {
+        }
+
+        /// <summary>
+        /// Initializes a new instance of the ThreadSafeCollection class with an existing new lock.
+        /// </summary>
+        /// <param name="existingLock">Existing lock to use for this collection.</param>
+        public ThreadSafeCollection(object existingLock)
+        {
+            this.lockObject = existingLock;
+        }
+
+        /// <summary>
+        /// Gets the number of elements actually contained in the ThreadSafeCollection&lt;T&gt;.
+        /// </summary>
+        public int Count
+        {
+            get
+            {
+                lock (this.lockObject)
+                {
+                    return list.Count;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets a value indicating whether the collection is read only.  Returns true.
+        /// </summary>
+        public bool IsReadOnly
+        {
+            get
+            {
+                lock (this.lockObject)
+                {
+                    return false;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Gets or sets the element at the specified index.
+        /// </summary>
+        /// <param name="index">The zero-based index of the element to get or set.</param>
+        /// <returns>The element at the specified index.</returns>
+        public T this[int index]
+        {
+            get
+            {
+                lock (this.lockObject)
+                {
+                    return list[index];
+                }
+            }
+
+            set
+            {
+                lock (this.lockObject)
+                {
+                    list[index] = value;
+                }
+            }
+        }
+
+        /// <summary>
+        /// Adds an object to the end of the ThreadSafeCollection&lt;T&gt;.
+        /// </summary>
+        /// <param name="item">
+        /// The object to be added to the end of the ThreadSafeCollection&lt;T&gt;.
+        /// The value can be null for reference types.
+        /// </param>
+        public void Add(T item)
+        {
+            lock (this.lockObject)
+            {
+                list.Add(item);
+            }
+        }
+
+        /// <summary>
+        /// Removes all elements from the ThreadSafeCollection&lt;T&gt;.
+        /// </summary>
+        public void Clear()
+        {
+            lock (this.lockObject)
+            {
+                list.Clear();
+            }
+        }
+
+        /// <summary>
+        /// Determines whether an element is in the ThreadSafeCollection&lt;T&gt;.
+        /// </summary>
+        /// <param name="item">
+        /// The object to locate in the ThreadSafeCollection&lt;T&gt;. The value
+        /// can be null for reference types.
+        /// </param>
+        /// <returns>
+        /// true if item is found in the ThreadSafeCollection&lt;T&gt;; otherwise,
+        /// false.
+        /// </returns>
+        public bool Contains(T item)
+        {
+            lock (this.lockObject)
+            {
+                return list.Contains(item);
+            }
+        }
+
+        /// <summary>
+        /// Copies the entire ThreadSafeCollection&lt;T&gt; to a compatible one-dimensional
+        /// array, starting at the beginning of the target array.
+        /// </summary>
+        /// <param name="array">
+        /// The one-dimensional System.Array that is the destination of the elements
+        /// copied from ThreadSafeCollection&lt;T&gt;. The System.Array must have
+        /// zero-based indexing.
+        /// </param>
+        /// <param name="arrayIndex">
+        /// The zero-based index in array at which copying begins.
+        /// </param>
+        /// <exception cref="System.ArgumentNullException">Array is null.</exception>
+        /// <exception cref="System.ArgumentOutOfRangeException">ArrayIndex is less than 0.</exception>
+        /// <exception cref="System.ArgumentException">
+        /// The number of elements in the source ThreadSafeCollection&lt;T&gt; is
+        /// greater than the available space from arrayIndex to the end of the destination
+        /// array.
+        /// </exception>
+        public void CopyTo(T[] array, int arrayIndex)
+        {
+            lock (this.lockObject)
+            {
+                list.CopyTo(array, arrayIndex);
+            }
+        }
+
+        /// <summary>
+        /// Copies the entire ThreadSafeCollection&lt;Tgt; to a compatible one-dimensional
+        /// array, starting at the beginning of the target array.
+        /// </summary>
+        /// <param name="array">
+        /// The one-dimensional System.Array that is the destination of the elements
+        /// copied from System.Collections.Generic.List&lt;Tgt;. The System.Array must have
+        /// zero-based indexing.
+        /// </param>
+        /// <exception cref="System.ArgumentNullException">Array is null.</exception>
+        /// <exception cref="System.ArgumentException">
+        /// The number of elements in the source ThreadSafeCollection&lt;Tgt; is
+        /// greater than the number of elements that the destination array can contain.
+        /// </exception>
+        public void CopyTo(T[] array)
+        {
+            lock (this.lockObject)
+            {
+                list.CopyTo(array);
+            }
+        }
+
+        /// <summary>
+        /// Adds the elements of the specified collection to the end of the ThreadSafeCollection&lt;T&gt;.
+        /// </summary>
+        /// <param name="collection">
+        /// The collection whose elements should be added to the end of the ThreadSafeCollection&lt;T&gt;.
+        /// The collection itself cannot be null, but it can contain elements that are
+        /// null, if type T is a reference type.
+        /// </param>
+        /// <exception cref="System.ArgumentNullException">Collection is null.</exception>
+        public void AddRange(IEnumerable<T> collection)
+        {
+            lock (this.lockObject)
+            {
+                list.AddRange(collection);
+            }
+        }
+
+        /// <summary>
+        /// Searches for the specified object and returns the zero-based index of the
+        /// first occurrence within the entire ThreadSafeCollection&lt;T&gt;.
+        /// </summary>
+        /// <param name="item">
+        /// The object to locate in the ThreadSafeCollection&lt;T&gt;. The value
+        /// can be null for reference types.
+        /// </param>
+        /// <returns>
+        /// The zero-based index of the first occurrence of item within the entire ThreadSafeCollection&lt;T&gt;,
+        /// if found; otherwise, –1.
+        /// </returns>
+        public int IndexOf(T item)
+        {
+            lock (this.lockObject)
+            {
+                return list.IndexOf(item);
+            }
+        }
+
+        /// <summary>
+        /// Inserts an element into the ThreadSafeCollection&lt;T&gt; at the specified
+        /// index.
+        /// </summary>
+        /// <param name="index">
+        /// The zero-based index at which item should be inserted.
+        /// </param>
+        /// <param name="item">
+        /// The object to insert. The value can be null for reference types.
+        /// </param>
+        /// <exception cref="ArgumentOutOfRangeException">Index is less than 0.-or-index is greater than ThreadSafeCollection&lt;T&gt;.Count.</exception>
+        public void Insert(int index, T item)
+        {
+            lock (this.lockObject)
+            {
+                list.Insert(index, item);
+            }
+        }
+
+        /// <summary>
+        /// Removes the element at the specified index of the ThreadSafeCollection&lt;T&gt;.
+        /// </summary>
+        /// <param name="index">The zero-based index of the element to remove.</param>
+        /// <exception cref="System.ArgumentOutOfRangeException">Index is less than 0.-or-index is equal to or greater than ThreadSafeCollection&lt;T&gt;.Count.</exception>
+        public void RemoveAt(int index)
+        {
+            lock (this.lockObject)
+            {
+                list.RemoveAt(index);
+            }
+        }
+
+        /// <summary>
+        /// Removes the first occurrence of a specific object from the ThreadSafeCollection&lt;T&gt;.
+        /// </summary>
+        /// <param name="item">
+        /// The object to remove from the ThreadSafeCollection&lt;T&gt;. The value
+        /// can be null for reference types.
+        /// </param>
+        /// <returns>
+        /// true if item is successfully removed; otherwise, false. This method also
+        /// returns false if item was not found in the ThreadSafeCollection&lt;T&gt;.
+        /// </returns>
+        public bool Remove(T item)
+        {
+            lock (this.lockObject)
+            {
+                return list.Remove(item);
+            }
+        }
+
+        /// <summary>
+        /// Returns an enumerator that iterates through the ThreadSafeCollection&lt;T&gt;.
+        /// </summary>
+        /// <remarks>This enumerator is a SNAPSHOT of the collection.  Keep this in mind when using this enumerator.</remarks>
+        /// <returns>A ThreadSafeCollection&lt;T&gt;.Enumerator for the ThreadSafeCollection&lt;T&gt;.</returns>
+        IEnumerator<T> IEnumerable<T>.GetEnumerator()
+        {
+            lock (this.lockObject)
+            {
+                return NewEnumerator();
+            }
+        }
+
+        /// <summary>
+        /// Returns an enumerator that iterates through the ThreadSafeCollection&lt;T&gt;.
+        /// </summary>
+        /// <remarks>This enumerator is a SNAPSHOT of the collection.  Keep this in mind when using this enumerator.</remarks>
+        /// <returns>A ThreadSafeCollection&lt;T&gt;.Enumerator for the ThreadSafeCollection&lt;T&gt;.</returns>
+        IEnumerator IEnumerable.GetEnumerator()
+        {
+            lock (this.lockObject)
+            {
+                return NewEnumerator();
+            }
+        }
+
+        /// <summary>
+        /// Returns an enumerator that iterates through the ThreadSafeCollection&lt;T&gt;.
+        /// </summary>
+        /// <remarks>This support function exists to satisfy code quality warning CA2000.  Otherwise, it would be in-line.</remarks>
+        /// <returns>A ThreadSafeCollection&lt;T&gt;.Enumerator for the ThreadSafeCollection&lt;T&gt;.</returns>
+        private IEnumerator<T> NewEnumerator()
+        {
+            return new ThreadSafeEnumerator(this);
+        }
+
+        /// <summary>
+        /// Provides a SNAPSHOT enumerator of the collection.  Keep this in mind when using this enumerator.
+        /// </summary>
+        private class ThreadSafeEnumerator : IEnumerator<T>
+        {
+            /// <summary>
+            /// Snapshot to enumerate.
+            /// </summary>
+            private readonly ThreadSafeCollection<T> collection;
+
+            /// <summary>
+            /// Internal enumerator of the snapshot.
+            /// </summary>
+            private readonly IEnumerator<T> enumerator;
+
+            /// <summary>
+            /// Initializes a new instance of the ThreadSafeEnumerator class, creating a snapshot of the given collection.
+            /// </summary>
+            /// <param name="collection">List to snapshot.</param>
+            public ThreadSafeEnumerator(ThreadSafeCollection<T> collection)
+            {
+                lock (collection.lockObject)
+                {
+                    // Make snapshot of passed in collection.
+                    this.collection = new ThreadSafeCollection<T>();
+                    this.collection.AddRange(collection);
+
+                    // Wrapped enumerator.
+                    enumerator = this.collection.list.GetEnumerator();
+                }
+            }
+
+            /// <summary>
+            /// Gets the element in the collection at the current position of the enumerator.
+            /// </summary>
+            /// <returns>The element in the collection at the current position of the enumerator.</returns>
+            public T Current
+            {
+                get
+                {
+                    lock (this.collection.lockObject)
+                    {
+                        return enumerator.Current;
+                    }
+                }
+            }
+
+            /// <summary>
+            /// Gets the element in the collection at the current position of the enumerator.
+            /// </summary>
+            /// <returns>The element in the collection at the current position of the enumerator.</returns>
+            object IEnumerator.Current
+            {
+                get
+                {
+                    lock (this.collection.lockObject)
+                    {
+                        return enumerator.Current;
+                    }
+                }
+            }
+
+            /// <summary>
+            /// Disposes the underlying enumerator.  Does not set collection or enumerator to null so calls will still
+            /// proxy to the disposed instance (and throw the proper exception).
+            /// </summary>
+            public void Dispose()
+            {
+                lock (this.collection.lockObject)
+                {
+                    enumerator.Dispose();
+                }
+            }
+
+            /// <summary>
+            /// Advances the enumerator to the next element of the collection.
+            /// </summary>
+            /// <returns>
+            /// true if the enumerator was successfully advanced to the next element; false
+            /// if the enumerator has passed the end of the collection.
+            /// </returns>
+            /// <exception cref="System.InvalidOperationException">The collection was modified after the enumerator was created.</exception>
+            public bool MoveNext()
+            {
+                lock (this.collection.lockObject)
+                {
+                    return enumerator.MoveNext();
+                }
+            }
+
+            /// <summary>
+            /// Sets the enumerator to its initial position, which is before the first element
+            /// in the collection.
+            /// </summary>
+            /// <exception cref="System.InvalidOperationException">The collection was modified after the enumerator was created.</exception>
+            public void Reset()
+            {
+                lock (this.collection.lockObject)
+                {
+                    enumerator.Reset();
+                }
+            }
+        }
+    }
+}
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/obj/Debug/KinectSensorChooserUI.g.i.cs
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/obj/Debug/KinectSensorChooserUI.g.i.cs	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/obj/Debug/KinectSensorChooserUI.g.i.cs	(revision 28895)
@@ -0,0 +1,355 @@
+﻿#pragma checksum "..\..\KinectSensorChooserUI.xaml" "{406ea660-64cf-4c82-b6f0-42d48172a799}" "29144CDD798F9BDAB587254C87A40769"
+//------------------------------------------------------------------------------
+// <auto-generated>
+//     This code was generated by a tool.
+//     Runtime Version:4.0.30319.34011
+//
+//     Changes to this file may cause incorrect behavior and will be lost if
+//     the code is regenerated.
+// </auto-generated>
+//------------------------------------------------------------------------------
+
+using System;
+using System.Diagnostics;
+using System.Windows;
+using System.Windows.Automation;
+using System.Windows.Controls;
+using System.Windows.Controls.Primitives;
+using System.Windows.Data;
+using System.Windows.Documents;
+using System.Windows.Ink;
+using System.Windows.Input;
+using System.Windows.Markup;
+using System.Windows.Media;
+using System.Windows.Media.Animation;
+using System.Windows.Media.Effects;
+using System.Windows.Media.Imaging;
+using System.Windows.Media.Media3D;
+using System.Windows.Media.TextFormatting;
+using System.Windows.Navigation;
+using System.Windows.Shapes;
+using System.Windows.Shell;
+
+
+namespace Microsoft.Kinect.Toolkit {
+    
+    
+    /// <summary>
+    /// KinectSensorChooserUI
+    /// </summary>
+    public partial class KinectSensorChooserUI : System.Windows.Controls.UserControl, System.Windows.Markup.IComponentConnector {
+        
+        
+        #line 69 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Grid layoutRoot;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 71 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.VisualStateGroup SensorStatusStates;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 237 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.VisualState Stopped;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 238 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.VisualState Initializing;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 248 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.VisualState AllSetListening;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 258 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.VisualState NoAvailableSensors;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 268 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.VisualState Error;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 278 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.VisualState AllSetNotListening;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 291 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Grid initializingContent;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 327 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Grid allSetNotListeningContent;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 333 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Grid allSetListeningContent;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 338 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Grid noAvailableSensorsContent;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 343 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Grid errorContent;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 349 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Primitives.Popup expandedPopup;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 350 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Grid popupGrid;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 353 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Grid expandedInitializingContent;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 389 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Grid expandedAllSetNotListeningContent;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 395 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Grid expandedAllSetListeningContent;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 400 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Grid expandedNoAvailableSensorsContent;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 407 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.Grid expandedErrorContent;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 418 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Controls.TextBlock MessageTextBlock;
+        
+        #line default
+        #line hidden
+        
+        
+        #line 422 "..\..\KinectSensorChooserUI.xaml"
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1823:AvoidUnusedPrivateFields")]
+        internal System.Windows.Documents.Hyperlink TellMeMoreLink;
+        
+        #line default
+        #line hidden
+        
+        private bool _contentLoaded;
+        
+        /// <summary>
+        /// InitializeComponent
+        /// </summary>
+        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+        public void InitializeComponent() {
+            if (_contentLoaded) {
+                return;
+            }
+            _contentLoaded = true;
+            System.Uri resourceLocater = new System.Uri("/Microsoft.Kinect.Toolkit;component/kinectsensorchooserui.xaml", System.UriKind.Relative);
+            
+            #line 1 "..\..\KinectSensorChooserUI.xaml"
+            System.Windows.Application.LoadComponent(this, resourceLocater);
+            
+            #line default
+            #line hidden
+        }
+        
+        [System.Diagnostics.DebuggerNonUserCodeAttribute()]
+        [System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
+        [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Never)]
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity")]
+        [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
+        void System.Windows.Markup.IComponentConnector.Connect(int connectionId, object target) {
+            switch (connectionId)
+            {
+            case 1:
+            this.layoutRoot = ((System.Windows.Controls.Grid)(target));
+            
+            #line 69 "..\..\KinectSensorChooserUI.xaml"
+            this.layoutRoot.MouseEnter += new System.Windows.Input.MouseEventHandler(this.OnRootGridMouseEnter);
+            
+            #line default
+            #line hidden
+            
+            #line 69 "..\..\KinectSensorChooserUI.xaml"
+            this.layoutRoot.GotKeyboardFocus += new System.Windows.Input.KeyboardFocusChangedEventHandler(this.OnRootGridGotKeyboardFocus);
+            
+            #line default
+            #line hidden
+            return;
+            case 2:
+            this.SensorStatusStates = ((System.Windows.VisualStateGroup)(target));
+            return;
+            case 3:
+            this.Stopped = ((System.Windows.VisualState)(target));
+            return;
+            case 4:
+            this.Initializing = ((System.Windows.VisualState)(target));
+            return;
+            case 5:
+            this.AllSetListening = ((System.Windows.VisualState)(target));
+            return;
+            case 6:
+            this.NoAvailableSensors = ((System.Windows.VisualState)(target));
+            return;
+            case 7:
+            this.Error = ((System.Windows.VisualState)(target));
+            return;
+            case 8:
+            this.AllSetNotListening = ((System.Windows.VisualState)(target));
+            return;
+            case 9:
+            this.initializingContent = ((System.Windows.Controls.Grid)(target));
+            return;
+            case 10:
+            this.allSetNotListeningContent = ((System.Windows.Controls.Grid)(target));
+            return;
+            case 11:
+            this.allSetListeningContent = ((System.Windows.Controls.Grid)(target));
+            return;
+            case 12:
+            this.noAvailableSensorsContent = ((System.Windows.Controls.Grid)(target));
+            return;
+            case 13:
+            this.errorContent = ((System.Windows.Controls.Grid)(target));
+            return;
+            case 14:
+            this.expandedPopup = ((System.Windows.Controls.Primitives.Popup)(target));
+            
+            #line 349 "..\..\KinectSensorChooserUI.xaml"
+            this.expandedPopup.Opened += new System.EventHandler(this.ExpandedPopupOnOpened);
+            
+            #line default
+            #line hidden
+            
+            #line 349 "..\..\KinectSensorChooserUI.xaml"
+            this.expandedPopup.MouseLeave += new System.Windows.Input.MouseEventHandler(this.OnExpandedPopupMouseLeave);
+            
+            #line default
+            #line hidden
+            return;
+            case 15:
+            this.popupGrid = ((System.Windows.Controls.Grid)(target));
+            
+            #line 350 "..\..\KinectSensorChooserUI.xaml"
+            this.popupGrid.GotKeyboardFocus += new System.Windows.Input.KeyboardFocusChangedEventHandler(this.OnPopupGridGotKeyboardFocus);
+            
+            #line default
+            #line hidden
+            return;
+            case 16:
+            this.expandedInitializingContent = ((System.Windows.Controls.Grid)(target));
+            return;
+            case 17:
+            this.expandedAllSetNotListeningContent = ((System.Windows.Controls.Grid)(target));
+            return;
+            case 18:
+            this.expandedAllSetListeningContent = ((System.Windows.Controls.Grid)(target));
+            return;
+            case 19:
+            this.expandedNoAvailableSensorsContent = ((System.Windows.Controls.Grid)(target));
+            return;
+            case 20:
+            this.expandedErrorContent = ((System.Windows.Controls.Grid)(target));
+            return;
+            case 21:
+            this.MessageTextBlock = ((System.Windows.Controls.TextBlock)(target));
+            return;
+            case 22:
+            this.TellMeMoreLink = ((System.Windows.Documents.Hyperlink)(target));
+            
+            #line 422 "..\..\KinectSensorChooserUI.xaml"
+            this.TellMeMoreLink.RequestNavigate += new System.Windows.Navigation.RequestNavigateEventHandler(this.TellMeMoreLinkRequestNavigate);
+            
+            #line default
+            #line hidden
+            return;
+            }
+            this._contentLoaded = true;
+        }
+    }
+}
+
Index: other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/obj/Debug/Microsoft.Kinect.Toolkit_MarkupCompile.i.cache
===================================================================
--- other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/obj/Debug/Microsoft.Kinect.Toolkit_MarkupCompile.i.cache	(revision 28895)
+++ other-projects/playing-in-the-street/summer-2013/trunk/Microsoft.Kinect.Toolkit/obj/Debug/Microsoft.Kinect.Toolkit_MarkupCompile.i.cache	(revision 28895)
@@ -0,0 +1,20 @@
+﻿Microsoft.Kinect.Toolkit
+
+
+library
+C#
+.cs
+C:\Users\David\Documents\Visual Studio 2013\Projects\Kinect-Summer-2013\Microsoft.Kinect.Toolkit\obj\Debug\
+Microsoft.Kinect.Toolkit
+none
+false
+CODE_ANALYSIS;DEBUG;TRACE
+
+1-1341555513
+
+121017912942
+91065153925
+KinectSensorChooserUI.xaml;
+
+False
+
