<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://blogs.msdn.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Coding4Fun : web miscellaneous</title><link>http://blogs.msdn.com/coding4fun/archive/tags/web+miscellaneous/default.aspx</link><description>Tags: web miscellaneous</description><dc:language>en-US</dc:language><generator>CommunityServer 2.1 SP1 (Build: 61025.2)</generator><item><title>Silverlight 3 File Transfer Application</title><link>http://blogs.msdn.com/coding4fun/archive/2009/09/03/9876572.aspx</link><pubDate>Fri, 04 Sep 2009 09:43:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9876572</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>2</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9876572.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9876572</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9876572</wfw:comment><description>&lt;ul&gt;   &lt;li&gt;&lt;strong&gt;Author: &lt;/strong&gt;&lt;a href="http://www.gmontrone.com/" target="_blank"&gt;Giovanni Montrone&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Difficulty: &lt;/b&gt;Intermediate &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Time Required:&lt;/b&gt; 5-10 hours &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Cost: &lt;/b&gt;Free &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Software: &lt;/b&gt;&lt;a href="http://msdn.com/express/"&gt;Visual Web Developer Express SP1&lt;/a&gt; (or Visual Studio 2008 SP1), &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyID=2050e580-f1d5-4040-bb09-e6185591b6b5&amp;amp;displaylang=en" target="_blank"&gt;Silverlight 3 SDK&lt;/a&gt;,&amp;#160; &lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=9442B0F2-7465-417A-88F3-5E7B5409E9DD&amp;amp;displaylang=en" target="_blank"&gt;Silverlight 3 Tools for VS&lt;/a&gt;, &lt;a href="http://www.codeplex.com/Silverlight" target="_blank"&gt;Silverlight Toolkit&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Hardware: &lt;/b&gt;None &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Use it Now: &lt;a href="http://www.gmontrone.com/SLFileSend/SLFileSenderTestPage.aspx" target="_blank"&gt;Run the Application&lt;/a&gt;&lt;/b&gt; &lt;/li&gt;    &lt;li&gt;&lt;strong&gt;Source Download: &lt;/strong&gt;&lt;a href="http://slfilesend.codeplex.com/" target="_blank"&gt;&lt;strong&gt;CodePlex&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Introduction&lt;/h3&gt;  &lt;p&gt;Every once in a while I will run into a situation where I need to send a file to someone, but struggle to find an easy way of doing it.&amp;#160; Instant messenger programs usually work until you run into a situation where someone just cannot send or receive a file from chat client whether it’s due to firewalls, differing client versions, or multi-IM incompatibilities.&amp;#160; Other times, I will try to send the file via email just to find out that the person’s email server blocks specific extensions.&amp;#160; This quick application will allow two users to quickly and easily connect to a Silverlight 3 client and send each other files.&amp;#160; &lt;/p&gt;  &lt;h3&gt;Overview&lt;/h3&gt;  &lt;p&gt;In this application, a user will connect to the Silverlight application and choose to either host or join a session.&amp;#160; If a user decides to host a session, he or she will be given a random eight character session key, and he or she will be in a waiting status until another user connects.&amp;#160; When a user wishes to connect to the host, he or she can supply the host’s session key which will establish a connection between the two users.&amp;#160; Once connected, the users will be able to send files to one another, and will also be able to chat with each other via simple text messages.&lt;/p&gt;  &lt;p&gt;&lt;a href="http://www.coding4fun.net/images/ca982cecb767_2D39/SendFile.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="SendFile" border="0" alt="SendFile" src="http://www.coding4fun.net/images/ca982cecb767_2D39/SendFile_thumb.jpg" width="544" height="237" /&gt;&lt;/a&gt; &lt;/p&gt;  &lt;h3&gt;Polling Duplex&lt;/h3&gt;  &lt;p&gt;Sending a file from one client application to another requires a common central point in order to properly route the message from one user to another.&amp;#160; Since it is easy to host a Silverlight application in an ASP.NET page, we will use an ASP.NET back end to manage all communications between all connected users.&amp;#160; In order to do this, we must be able to host a service that is able to accept incoming messages from the Silverlight client, and perform a push back out to the intended recipient.&amp;#160; This is accomplished by using the WCF Polling Duplex (&lt;strong&gt;System.ServiceModel.PollingDuplex.dll&lt;/strong&gt;) channel.&amp;#160; Silverlight 3 allows us to directly add a service reference to a service of this type, and handles all of the complexities for us.&amp;#160; I began by using the&lt;strong&gt; DuplexService.cs&lt;/strong&gt; file from a sample application from MIX09 when Silverlight 3 beta was released.&amp;#160; The code starts us out with a couple of base abstract classes, and interfaces that we must inherit from in order to create our own service.&amp;#160; &lt;/p&gt;  &lt;h3&gt;FileSendService&lt;/h3&gt;  &lt;p&gt;The two main things we need to do in order to create our own service is to define custom message types that will be used for communication, and override the base &lt;strong&gt;DuplexService&lt;/strong&gt; class to properly handle these messages.&amp;#160; We will create our custom message types by using &lt;strong&gt;DuplexMessage&lt;/strong&gt; (defined in &lt;strong&gt;DuplexService.cs&lt;/strong&gt;) as our base class.&amp;#160; Our message classes must be defined with the &lt;strong&gt;[DataContract]&lt;/strong&gt; attribute, and the the member variables must be public and contain the &lt;strong&gt;[DataMember]&lt;/strong&gt; attribute.&amp;#160; This will allow our Silverlight client project to share these definitions using a service reference.&amp;#160; Additionally, the Duplex message class must have the &lt;strong&gt;[KnownType]&lt;/strong&gt; attribute for each descendant message created.&lt;/p&gt;  &lt;p&gt;&amp;#160;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;  &lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;   &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 98.08%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; height: 90px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;p&gt;[KnownType(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(HostSessionMessage))]&lt;br /&gt;[KnownType(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(JoinSessionMessage))]&lt;br /&gt;[KnownType(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(FileBeginUploadMessage))]&lt;br /&gt;[KnownType(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(FileTransferBytesMessage))]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; DuplexMessage { }&lt;/p&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;[DataContract]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; HostSessionMessage : DuplexMessage&lt;br /&gt;{&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Username;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[DataContract]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; JoinSessionMessage : DuplexMessage&lt;br /&gt;{&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Username;&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; SessionKey;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[DataContract]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; FileBeginUploadMessage : DuplexMessage&lt;br /&gt;{&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; FileName;&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;long&lt;/span&gt; TotalBytes;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;[DataContract]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; FileTransferBytesMessage : DuplexMessage&lt;br /&gt;{&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;long&lt;/span&gt; StartByte;&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;long&lt;/span&gt; PacketSize;&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] Bytes;&lt;br /&gt;    [DataMember]&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; EndFile;&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&amp;lt;DataContract(&lt;span style="color: #0000ff"&gt;Namespace&lt;/span&gt; := &lt;span style="color: #006080"&gt;&amp;quot;http://samples.microsoft.com/silverlight2/duplex&amp;quot;&lt;/span&gt;), &lt;br /&gt;KnownType(&lt;span style="color: #0000ff"&gt;GetType&lt;/span&gt;(HostSessionMessage)), KnownType(&lt;span style="color: #0000ff"&gt;GetType&lt;/span&gt;(JoinSessionMessage)), KnownType(&lt;span style="color: #0000ff"&gt;GetType&lt;/span&gt;(FileBeginUploadMessage)), KnownType(&lt;span style="color: #0000ff"&gt;GetType&lt;/span&gt;(FileTransferBytesMessage))&amp;gt; _&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; DuplexMessage&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Class&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&amp;lt;DataContract()&amp;gt; _&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; HostSessionMessage&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Inherits&lt;/span&gt; DuplexMessage&lt;br /&gt;    &amp;lt;DataMember()&amp;gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; Username &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;DataContract()&amp;gt; _&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; JoinSessionMessage&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Inherits&lt;/span&gt; DuplexMessage&lt;br /&gt;    &amp;lt;DataMember()&amp;gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; Username &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;    &amp;lt;DataMember()&amp;gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; SessionKey &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;DataContract()&amp;gt; _&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; FileTransferBytesMessage&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Inherits&lt;/span&gt; DuplexMessage&lt;br /&gt;    &amp;lt;DataMember()&amp;gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; StartByte &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Long&lt;/span&gt;&lt;br /&gt;    &amp;lt;DataMember()&amp;gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; PacketSize &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Long&lt;/span&gt;&lt;br /&gt;    &amp;lt;DataMember()&amp;gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; Bytes() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Byte&lt;/span&gt;&lt;br /&gt;    &amp;lt;DataMember()&amp;gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; EndFile &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Boolean&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;DataContract()&amp;gt; _&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; FileBeginUploadMessage&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Inherits&lt;/span&gt; DuplexMessage&lt;br /&gt;    &amp;lt;DataMember()&amp;gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; FileName &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;    &amp;lt;DataMember()&amp;gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; TotalBytes &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Long&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Class&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The next step is to create our &lt;strong&gt;FileSendService&lt;/strong&gt; class which descends from the &lt;strong&gt;DuplexService&lt;/strong&gt; class as described above.&amp;#160; We override the &lt;strong&gt;OnMessage&lt;/strong&gt; method so that we can do custom processing based on the type of message sent as shown below.&amp;#160; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 99.68%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; height: 210px; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 97.9%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; height: 286px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; FileSendService : DuplexService&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; List&amp;lt;SessionConnectionInfo&amp;gt; sessionConnections = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;SessionConnectionInfo&amp;gt;();&lt;br /&gt;&lt;br /&gt;    {...}&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;override&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; OnMessage(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; sessionId, DuplexMessage data)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (data &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; HostSessionMessage)&lt;br /&gt;            CreateHostSession(data &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; HostSessionMessage);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (data &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; JoinSessionMessage)&lt;br /&gt;            JoinSession(data &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; JoinSessionMessage);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (data &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; FileBeginUploadMessage)&lt;br /&gt;            StartSendFile(data &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; FileBeginUploadMessage);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            SendMessage(data);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;}&lt;/pre&gt;

  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 99.22%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; height: 159px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (data &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; JoinSessionMessage)&lt;br /&gt;            JoinSession(data &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; JoinSessionMessage);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (data &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; FileBeginUploadMessage)&lt;br /&gt;            StartSendFile(data &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; FileBeginUploadMessage);&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            SendMessage(data);&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;}&lt;/pre&gt;

  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;br /&gt;    }&lt;br /&gt;    &lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; FileSenderServiceFactory&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Inherits&lt;/span&gt; DuplexServiceFactory(Of FileSendService)&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&amp;lt;AspNetCompatibilityRequirements(RequirementsMode := AspNetCompatibilityRequirementsMode.Allowed)&amp;gt; _&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; FileSendService&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Inherits&lt;/span&gt; DuplexService&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; sessionConnections &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; List(Of SessionConnectionInfo)()&lt;br /&gt;&lt;br /&gt;    ...&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Protected&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Overrides&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; OnMessage(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sessionId &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; data &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; DuplexMessage)&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;TypeOf&lt;/span&gt; data &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; HostSessionMessage &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            CreateHostSession(&lt;span style="color: #0000ff"&gt;TryCast&lt;/span&gt;(data, HostSessionMessage))&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;ElseIf&lt;/span&gt; &lt;span style="color: #0000ff"&gt;TypeOf&lt;/span&gt; data &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; JoinSessionMessage &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            JoinSession(&lt;span style="color: #0000ff"&gt;TryCast&lt;/span&gt;(data, JoinSessionMessage))&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;ElseIf&lt;/span&gt; &lt;span style="color: #0000ff"&gt;TypeOf&lt;/span&gt; data &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; FileBeginUploadMessage &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            StartSendFile(&lt;span style="color: #0000ff"&gt;TryCast&lt;/span&gt;(data, FileBeginUploadMessage))&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;&lt;br /&gt;            SendMessage(data)&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Class&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Since we are going to have to keep track of each host and user connected to that host, we will create a class,&amp;#160; &lt;strong&gt;SessionConnectionInfo&lt;/strong&gt;, to manage the relevant data.&amp;#160; When a user decides to host a session, our &lt;strong&gt;OnMessage&lt;/strong&gt; method will receive a &lt;strong&gt;HostSessionMessage&lt;/strong&gt; which will scan our&lt;strong&gt; List&amp;lt;SessionConnectionInfo&amp;gt;&lt;/strong&gt; to see if there is another host with the same username.&amp;#160; If not found, a new &lt;strong&gt;SessionConnectionInfo&lt;/strong&gt; object is created along with a randomly generated session key.&amp;#160; When a user attempts to join a session, the &lt;strong&gt;OnMessage&lt;/strong&gt; method will receive a &lt;strong&gt;JoinSessionMessage&lt;/strong&gt; containing a session key and the name of the user joining the session.&amp;#160; The service will search for a &lt;strong&gt;SessionConnectionInfo&lt;/strong&gt; object containing that session key, and if found, establishes a connection between the two users.&amp;#160; &lt;/p&gt;

&lt;p&gt;&amp;#160;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; height: 308px; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; SessionConnectionInfo&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; HostUserName { get; set; }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ConnectedUsername { get; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; set; }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; SessionKey { get; set; }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; ConnectedUserInternalSession { get; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; set; }&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; HostInternalSession { get; set; }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; UserConnected&lt;br /&gt;    {&lt;br /&gt;        get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; ConnectedUserInternalSession != &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty; }&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; SessionConnectionInfo()&lt;br /&gt;    {&lt;br /&gt;        ConnectedUserInternalSession = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty;&lt;br /&gt;        ConnectedUsername = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Empty;&lt;br /&gt;    }&lt;br /&gt;&lt;br /&gt;    ....&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&amp;#160;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; SessionConnectionInfo&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; privateHostUserName &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; HostUserName() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; privateHostUserName&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)&lt;br /&gt;            privateHostUserName = value&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; privateConnectedUsername &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; ConnectedUsername() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; privateConnectedUsername&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)&lt;br /&gt;            privateConnectedUsername = value&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; privateSessionKey &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; SessionKey() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; privateSessionKey&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)&lt;br /&gt;            privateSessionKey = value&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; privateConnectedUserInternalSession &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; ConnectedUserInternalSession() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; privateConnectedUserInternalSession&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)&lt;br /&gt;            privateConnectedUserInternalSession = value&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; privateHostInternalSession &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; HostInternalSession() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; privateHostInternalSession&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)&lt;br /&gt;            privateHostInternalSession = value&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;ReadOnly&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; UserConnected() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Boolean&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; ConnectedUserInternalSession &amp;lt;&amp;gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.Empty&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt;()&lt;br /&gt;        ConnectedUserInternalSession = &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.Empty&lt;br /&gt;        ConnectedUsername = &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.Empty&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Class&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;h2&gt;Client Side&lt;/h2&gt;

&lt;p&gt;Now that we have the basic server side complete, we can add a service reference, and create the necessary service reference.&amp;#160; Our service is hosted within ASP.NET via a simple xml file (see &lt;strong&gt;FileSendService.svc&lt;/strong&gt;), which allows our Silverlight project to see it.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.coding4fun.net/images/ca982cecb767_2D39/AddServiceRef.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="Add Service Ref" border="0" alt="Add Service Ref" src="http://www.coding4fun.net/images/ca982cecb767_2D39/AddServiceRef_thumb.jpg" width="540" height="475" /&gt;&lt;/a&gt; &lt;/p&gt;

&lt;p&gt;Be sure to mark the checkbox “Always generate message contracts”.&amp;#160; Note that your web portion of the project must be compiled before you will be able to “Discover” the service.&lt;/p&gt;

&lt;p&gt;We will now have access to the &lt;strong&gt;DuplexServiceClient&lt;/strong&gt; class which will allow us to send and receive messages to the server.&amp;#160; We instantiate the service as shown below.&amp;#160; In order to do this, you must manually add a reference to &lt;strong&gt;System.ServiceModel.PollingDuplex&lt;/strong&gt; assembly.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; DuplexServiceClient fileDuplexService;&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; CustomBinding binding = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; CustomBinding(&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; PollingDuplexBindingElement(),&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; BinaryMessageEncodingBindingElement(),&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; HttpTransportBindingElement());&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; MainPage()&lt;br /&gt;{&lt;br /&gt;    InitializeComponent();&lt;br /&gt;    fileDuplexService = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; DuplexServiceClient(binding, &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; EndpointAddress(&lt;span style="color: #006080"&gt;&amp;quot;http://localhost:9797/FileSendService.svc&amp;quot;&lt;/span&gt;));&lt;br /&gt;    ...&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; fileDuplexService &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; DuplexServiceClient&lt;br /&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; binding &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; CustomBinding(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; PollingDuplexBindingElement(), &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; BinaryMessageEncodingBindingElement(), &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; HttpTransportBindingElement())&lt;br /&gt;&lt;/p&gt;&lt;p&gt;    &lt;br /&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt;()&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160; InitializeComponent()&lt;br /&gt;    fileDuplexService = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; DuplexServiceClient(binding, &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; EndpointAddress(&lt;span style="color: #006080"&gt;&amp;quot;http://localhost:9797/FileSendService.svc&amp;quot;&lt;/span&gt;))&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;Note that at the time of this writing, adding the service reference does not properly create the &lt;strong&gt;ServiceReferences.ClientConfig&lt;/strong&gt; file.&amp;#160; This is the reason the above is done using code.&lt;/p&gt;

&lt;p&gt;Now that our service is setup, we need to set it up to handle sending and receiving of messages.&amp;#160;&amp;#160; In order to send a message, we must first create a &lt;strong&gt;DupexMessage&lt;/strong&gt; (or a descendant), and use the &lt;strong&gt;SendToServiceAsync&lt;/strong&gt; method.&amp;#160; This requires a &lt;strong&gt;SendToService&lt;/strong&gt; object which will contain the message, and an optional &lt;strong&gt;userState&lt;/strong&gt; object which we can use to tag the request.&amp;#160; In this case, we will pass an enum value which represents the status of our upload.&amp;#160; In the example below, when the user clicks on the send file button, after choosing the file, we open our file, and send a &lt;strong&gt;FileBeginUpload&lt;/strong&gt; message which contains the file name and its size.&amp;#160; Note that the server is set to deny any file that is greater than 20 million bytes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; btnSendFile_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;br /&gt; {&lt;br /&gt;     OpenFileDialog openFileDialog = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; OpenFileDialog();&lt;br /&gt;     openFileDialog.Multiselect = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;     openFileDialog.ShowDialog();&lt;br /&gt;     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (openFileDialog.File != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;     {&lt;br /&gt;         fileToSend = openFileDialog.File.OpenRead();&lt;br /&gt;&lt;br /&gt;         FileBeginUploadMessage fsm = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FileBeginUploadMessage();&lt;br /&gt;         fsm.FileName = openFileDialog.File.Name;&lt;br /&gt;         fsm.TotalBytes = openFileDialog.File.Length;&lt;br /&gt;         fileDuplexService.SendToServiceAsync(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SendToService(fsm), FileSendState.FileStart);&lt;br /&gt;         ....&lt;br /&gt;     }&lt;br /&gt; }&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; btnSendFile_Click(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; RoutedEventArgs)&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; openFileDialog &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; OpenFileDialog()&lt;br /&gt;    openFileDialog.Multiselect = &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;&lt;br /&gt;    openFileDialog.ShowDialog()&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; openFileDialog.File IsNot &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;        fileToSend = openFileDialog.File.OpenRead()&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; fsm &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; FileBeginUploadMessage()&lt;br /&gt;        fsm.FileName = openFileDialog.File.Name&lt;br /&gt;        fsm.TotalBytes = openFileDialog.File.Length&lt;br /&gt;        totalBytesSent = 0&lt;br /&gt;        fileDuplexService.SendToServiceAsync(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; SendToService(fsm), FileSendState.FileStart)&lt;br /&gt;        ....&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The service object fires two main events that need to be handled: &lt;strong&gt;SendToServiceCompleted&lt;/strong&gt; and &lt;strong&gt;SendToClientReceived&lt;/strong&gt;. &lt;strong&gt;SendToServiceCompleted&lt;/strong&gt; is the event which is fired after the server acknowledges that it has received and processed a message that the client has sent.&amp;#160; Once the server receives and processes the &lt;strong&gt;FileBeginUploadMessage&lt;/strong&gt;, the event handler below will receive the results.&amp;#160; In this case, if there isn’t an error, and the value of &lt;strong&gt;userState&lt;/strong&gt; is &lt;strong&gt;FileSendState.FileStart&lt;/strong&gt;,&amp;#160; the method will send a &lt;strong&gt;FileTransferBytesMessage&lt;/strong&gt; which will send the bytes from the file.&amp;#160; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;p&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; FileDuplexServiceSendToServiceCompleted(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, System.ComponentModel.AsyncCompletedEventArgs e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e.Error == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        {...}&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((FileSendState)e.UserState == FileSendState.FileEnd)&lt;br /&gt;        {&lt;br /&gt;            fileToSend.Close();&lt;br /&gt;            fileProgress.Value = 100;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; ((FileSendState)e.UserState == FileSendState.FileStart || (FileSendState)e.UserState == FileSendState.FileContinue)&lt;br /&gt;        {&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;br /&gt;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160;&amp;#160; ...&lt;br /&gt;            FileTransferBytesMessage fileMessage = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FileTransferBytesMessage();&lt;br /&gt;            fileMessage.StartByte = totalBytesSent;&lt;br /&gt;            fileMessage.EndFile = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;br /&gt;            fileMessage.PacketSize = CHUNK;&lt;br /&gt;&lt;br /&gt;            ...&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] bytes = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[numBytesToRead];&lt;br /&gt;            fileToSend.Read(bytes, 0, numBytesToRead);&lt;br /&gt;            totalBytesSent += numBytesToRead;&lt;br /&gt;            fileMessage.Bytes = bytes;&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (fileMessage.EndFile)&lt;br /&gt;                fileDuplexService.SendToServiceAsync(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SendToService(fileMessage), FileSendState.FileEnd);&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;                fileDuplexService.SendToServiceAsync(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SendToService(fileMessage), FileSendState.FileContinue);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;}&lt;/p&gt;&lt;/pre&gt;
&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; FileDuplexServiceSendToServiceCompleted(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; System.ComponentModel.AsyncCompletedEventArgs)&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; e.&lt;span style="color: #0000ff"&gt;Error&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; e.UserState &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;CType&lt;/span&gt;(e.UserState, FileSendState) = FileSendState.FileEnd &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            fileToSend.Close()&lt;br /&gt;            fileProgress.Value = 100&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;CType&lt;/span&gt;(e.UserState, FileSendState) = FileSendState.FileStart &lt;span style="color: #0000ff"&gt;OrElse&lt;/span&gt; &lt;span style="color: #0000ff"&gt;CType&lt;/span&gt;(e.UserState, FileSendState) = FileSendState.FileContinue &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            ...&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; fileMessage &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; FileTransferBytesMessage()&lt;br /&gt;            fileMessage.StartByte = totalBytesSent&lt;br /&gt;            fileMessage.EndFile = &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;&lt;br /&gt;            fileMessage.PacketSize = CHUNK&lt;br /&gt;            ...&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; bytes(numBytesToRead - 1) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Byte&lt;/span&gt;&lt;br /&gt;            fileToSend.Read(bytes, 0, numBytesToRead)&lt;br /&gt;            totalBytesSent += numBytesToRead&lt;br /&gt;            fileMessage.Bytes = bytes&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; fileMessage.EndFile &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;                fileDuplexService.SendToServiceAsync(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; SendToService(fileMessage), FileSendState.FileEnd)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;&lt;br /&gt;                fileDuplexService.SendToServiceAsync(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; SendToService(fileMessage), FileSendState.FileContinue)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;The &lt;strong&gt;SendToClientReceived&lt;/strong&gt; event is fired when a message has been sent from the service.&amp;#160; In this case, the client will check to see which message was received and process it accordingly.&amp;#160; The method below shows that when a &lt;strong&gt;FileBeginUpload&lt;/strong&gt; message is received, the user is prompted to accept or deny the file.&amp;#160; If the user does not accept the file, a &lt;strong&gt;FileDenyMessage&lt;/strong&gt; will be sent which will notify the sender to stop sending bytes.&amp;#160; If accepted, file bytes are added to a buffer.&amp;#160; &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; FileDuplexServiceSendToClientReceived(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, SendToClientReceivedEventArgs e)&lt;br /&gt;{&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e.Error == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e.request.msg &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; ClientConnectedMessage)&lt;br /&gt;        {&lt;br /&gt;            ClientConnectedMessage msg = (ClientConnectedMessage)e.request.msg;&lt;br /&gt;            AddMsgToListbox(msg.Username + &lt;span style="color: #006080"&gt;&amp;quot; has just connected.&amp;quot;&lt;/span&gt;);&lt;br /&gt;            connectedTo = msg.Username;&lt;br /&gt;            UIState = UIState.Chat;&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e.request.msg &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; HostSessionServerMessage)&lt;br /&gt;        {&lt;br /&gt;            HostSessionServerMessage hssm = e.request.msg &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; HostSessionServerMessage;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (hssm.Failed) {...}&lt;br /&gt;            SessionCreated(hssm);&lt;br /&gt;&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e.request.msg &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; JoinSessionServerMessage)&lt;br /&gt;        {&lt;br /&gt;            JoinSessionServerMessage jssm = e.request.msg &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; JoinSessionServerMessage;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (jssm.Failed) {....}&lt;br /&gt;            SessionJoined(jssm);&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e.request.msg &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; FileBeginUploadMessage )&lt;br /&gt;        {&lt;br /&gt;            FileBeginUploadMessage fsm = (FileBeginUploadMessage)e.request.msg;&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; sizeInKB = (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;)fsm.TotalBytes / 1024;&lt;br /&gt;            totalRevd = 0;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (MessageBox.Show(connectedTo + &lt;span style="color: #006080"&gt;&amp;quot; would like to send you the file: &amp;quot;&lt;/span&gt; + fsm.FileName + &lt;span style="color: #006080"&gt;&amp;quot;, Size: &amp;quot;&lt;/span&gt; + sizeInKB + &lt;span style="color: #006080"&gt;&amp;quot;.  Would you like to receive this file?&amp;quot;&lt;/span&gt;, &lt;span style="color: #006080"&gt;&amp;quot;File Upload&amp;quot;&lt;/span&gt;, MessageBoxButton.OKCancel) == MessageBoxResult.OK)&lt;br /&gt;            {&lt;br /&gt;                bytesReceived = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;&lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;&amp;gt;((&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;)fsm.TotalBytes);&lt;br /&gt;                fileNameReceiving = fsm.FileName;&lt;br /&gt;                ....&lt;br /&gt;            }&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;br /&gt;            {&lt;br /&gt;                fileDuplexService.SendToServiceAsync(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SendToService(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FileDenyMessage()));&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (e.request.msg &lt;span style="color: #0000ff"&gt;is&lt;/span&gt; FileTransferBytesMessage)&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (bytesReceived == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;return&lt;/span&gt;;&lt;br /&gt;            FileTransferBytesMessage fm = (FileTransferBytesMessage)e.request.msg;&lt;br /&gt;            bytesReceived.AddRange(fm.Bytes);&lt;br /&gt;            ....&lt;br /&gt;        }&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; {....}&lt;br /&gt;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; FileDuplexServiceSendToClientReceived(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; SendToClientReceivedEventArgs)&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; e.&lt;span style="color: #0000ff"&gt;Error&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;TypeOf&lt;/span&gt; e.request.msg &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; ClientConnectedMessage &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; msg &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ClientConnectedMessage = &lt;span style="color: #0000ff"&gt;CType&lt;/span&gt;(e.request.msg, ClientConnectedMessage)&lt;br /&gt;            AddMsgToListbox(msg.Username &amp;amp; &lt;span style="color: #006080"&gt;&amp;quot; has just connected.&amp;quot;&lt;/span&gt;)&lt;br /&gt;            connectedTo = msg.Username&lt;br /&gt;            UIState = UIState.Chat&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;ElseIf&lt;/span&gt; &lt;span style="color: #0000ff"&gt;TypeOf&lt;/span&gt; e.request.msg &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; HostSessionServerMessage &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; hssm &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; HostSessionServerMessage = &lt;span style="color: #0000ff"&gt;TryCast&lt;/span&gt;(e.request.msg, HostSessionServerMessage)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; hssm.Failed &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt; ...&lt;br /&gt;&lt;br /&gt;            SessionCreated(hssm)&lt;br /&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;ElseIf&lt;/span&gt; &lt;span style="color: #0000ff"&gt;TypeOf&lt;/span&gt; e.request.msg &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; JoinSessionServerMessage &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; jssm &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; JoinSessionServerMessage = &lt;span style="color: #0000ff"&gt;TryCast&lt;/span&gt;(e.request.msg, JoinSessionServerMessage)&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; jssm.Failed &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt; ...&lt;br /&gt;&lt;br /&gt;            SessionJoined(jssm)&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;ElseIf&lt;/span&gt; &lt;span style="color: #0000ff"&gt;TypeOf&lt;/span&gt; e.request.msg &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; FileBeginUploadMessage &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; fsm &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; FileBeginUploadMessage = &lt;span style="color: #0000ff"&gt;CType&lt;/span&gt;(e.request.msg, FileBeginUploadMessage)&lt;br /&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; sizeInKB &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; = &lt;span style="color: #0000ff"&gt;CInt&lt;/span&gt;(Fix(fsm.TotalBytes)) / 1024&lt;br /&gt;            totalRevd = 0&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; MessageBox.Show(connectedTo &amp;amp; &lt;span style="color: #006080"&gt;&amp;quot; would like to send you the file: &amp;quot;&lt;/span&gt; &amp;amp; fsm.FileName &amp;amp; &lt;span style="color: #006080"&gt;&amp;quot;, Size: &amp;quot;&lt;/span&gt; &amp;amp; sizeInKB &amp;amp; &lt;span style="color: #006080"&gt;&amp;quot; KB.  Would you like to receive this file?&amp;quot;&lt;/span&gt;, &lt;span style="color: #006080"&gt;&amp;quot;File Upload&amp;quot;&lt;/span&gt;, MessageBoxButton.OKCancel) = MessageBoxResult.OK &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;                bytesReceived = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; List(Of &lt;span style="color: #0000ff"&gt;Byte&lt;/span&gt;)(&lt;span style="color: #0000ff"&gt;CInt&lt;/span&gt;(Fix(fsm.TotalBytes)))&lt;br /&gt;                fileNameReceiving = fsm.FileName&lt;br /&gt;                ...&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;&lt;br /&gt;                fileDuplexService.SendToServiceAsync(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; SendToService(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; FileDenyMessage()))&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;ElseIf&lt;/span&gt; &lt;span style="color: #0000ff"&gt;TypeOf&lt;/span&gt; e.request.msg &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; FileTransferBytesMessage &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; bytesReceived &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; fm &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; FileTransferBytesMessage = &lt;span style="color: #0000ff"&gt;CType&lt;/span&gt;(e.request.msg, FileTransferBytesMessage)&lt;br /&gt;            bytesReceived.AddRange(fm.Bytes)&lt;br /&gt;            ...&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;ElseIf&lt;/span&gt; &lt;br /&gt;          ...&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;When the file is complete, the user will be presented with two buttons.&amp;#160; One button will allow the user to save, and the other will allow the user to discard/ignore the file.&amp;#160; If the user chooses to save, a &lt;strong&gt;SaveFileDialog&lt;/strong&gt; is created, and we use the filename to assign the default extension and filter so that when the user saves the file, no extension needs to be typed in.&amp;#160; Once the dialog appears and the user enters the file name, the bytes will be written to disk.&amp;#160; Finally we send a message back to the server which will notify the sender that user has done something with the file.&amp;#160; During file send operations, the Send File button is disabled, and becomes re-enabled once a file has been received, cancelled, or denied.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; void btnSaveFile_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, RoutedEventArgs e)&lt;br /&gt;{&lt;br /&gt;    SaveFileDialog sfd = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SaveFileDialog();&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; extension = GetExtension(fileNameReceiving);&lt;br /&gt;    sfd.DefaultExt = extension;&lt;br /&gt;    sfd.Filter = extension +  &lt;span style="color: #006080"&gt;&amp;quot; Files|&amp;quot;&lt;/span&gt; + extension;&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (sfd.ShowDialog() == &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;)&lt;br /&gt;    {&lt;br /&gt;        using (Stream fsx = sfd.OpenFile())&lt;br /&gt;        {&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;byte&lt;/span&gt;[] fBytes = bytesReceived.ToArray();&lt;br /&gt;            fsx.Write(fBytes, 0, fBytes.Length);&lt;br /&gt;            fsx.Close();&lt;br /&gt;        }&lt;br /&gt;&lt;br /&gt;        fileDuplexService.SendToServiceAsync(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; SendToService(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; FileReceivedMessage()));&lt;br /&gt;        UIState = UIState.Chat;&lt;br /&gt;        btnSendFile.IsEnabled = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;p&gt;&amp;#160;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;

&lt;div style="border-bottom: silver 1px solid; border-left: silver 1px solid; padding-bottom: 4px; line-height: 12pt; background-color: #f4f4f4; margin: 20px 0px 10px; padding-left: 4px; width: 97.5%; padding-right: 4px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; max-height: 200px; font-size: 8pt; overflow: auto; border-top: silver 1px solid; cursor: text; border-right: silver 1px solid; padding-top: 4px" id="codeSnippetWrapper"&gt;
  &lt;pre style="border-bottom-style: none; padding-bottom: 0px; line-height: 12pt; border-right-style: none; background-color: #f4f4f4; margin: 0em; padding-left: 0px; width: 100%; padding-right: 0px; font-family: &amp;#39;Courier New&amp;#39;, courier, monospace; border-top-style: none; color: black; font-size: 8pt; border-left-style: none; overflow: visible; padding-top: 0px" id="codeSnippet"&gt;&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; btnSaveFile_Click(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; RoutedEventArgs)&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; sfd &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; SaveFileDialog()&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; extension &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt; = GetExtension(fileNameReceiving)&lt;br /&gt;    sfd.DefaultExt = extension&lt;br /&gt;    sfd.Filter = extension &amp;amp; &lt;span style="color: #006080"&gt;&amp;quot; Files|&amp;quot;&lt;/span&gt; &amp;amp; extension&lt;br /&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; sfd.ShowDialog() = &lt;span style="color: #0000ff"&gt;True&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;br /&gt;        Using fsx &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Stream = sfd.OpenFile()&lt;br /&gt;            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; fBytes() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Byte&lt;/span&gt; = bytesReceived.ToArray()&lt;br /&gt;            fsx.Write(fBytes, 0, fBytes.Length)&lt;br /&gt;            fsx.Close()&lt;br /&gt;        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Using&lt;br /&gt;&lt;br /&gt;        fileDuplexService.SendToServiceAsync(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; SendToService(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; FileReceivedMessage()))&lt;br /&gt;        UIState = UIState.Chat&lt;br /&gt;        btnSendFile.IsEnabled = &lt;span style="color: #0000ff"&gt;True&lt;/span&gt;&lt;br /&gt;    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;br /&gt;&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;

  &lt;br /&gt;&lt;/div&gt;

&lt;h3&gt;&amp;#160;&lt;/h3&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;Overall, the application does what I set out for it to.&amp;#160; It allows a user to send a file to another user and even does basic chat.&amp;#160; There is definitely a lot of room for improvement, and some general additions that can make this more robust.&amp;#160; Right now we keep a list of connections, but never do basic pinging to see if the clients are still there.&amp;#160; The only way to know if a client has disconnected is when a message fails, or when the user decides to hit the disconnect button. Better maintenance of this list is needed.&amp;#160; The file bytes are basically being stored in memory, which is why i set a file size limit, but I’m sure with things like Silverlight local storage, we can increase the limit.&amp;#160; &lt;/p&gt;

&lt;h3&gt;Thanks&lt;/h3&gt;

&lt;p&gt;I would like to thank &lt;a href="http://www.brianpeek.com/"&gt;Brian Peek&lt;/a&gt; for taking the time to review my article and test the code.&lt;/p&gt;

&lt;h3&gt;Additional Notes&lt;/h3&gt;

&lt;p&gt;The ASP.NET project requires a file called System.ServiceModel.PollingDuplex.dll to be added as a reference.&amp;#160; Somewhere between Silverlight 3 Beta and Silverlight 3 RTW, the file was no longer available via the basic add .NET reference link.&amp;#160; In order to add the file, I had to browse for it in &lt;strong&gt;%Program Files%\Microsoft SDKs\Silverlight\v3.0\Libraries\Server&lt;/strong&gt;.&amp;#160; For 64 bit users, it will be the &lt;strong&gt;Program Files (x86)&lt;/strong&gt; folder.&amp;#160; &lt;/p&gt;

&lt;p&gt;For ease of use, I used a static port (9797) for this project. When deploying to a server, you must rename all references of http://localhost:9797 in the Silverlight project.&amp;#160; This will remain true until the config file is supported. &lt;/p&gt;

&lt;p&gt;The user interface uses the Silverlight Toolkit TwilightBlue theme.&amp;#160; For more information about this,&amp;#160; see &lt;a title="http://www.codeplex.com/Silverlight" href="http://www.codeplex.com/Silverlight"&gt;http://www.codeplex.com/Silverlight&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9876572" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/utility/default.aspx">utility</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/web+miscellaneous/default.aspx">web miscellaneous</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/web/default.aspx">web</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Silverlight/default.aspx">Silverlight</category></item><item><title>Adding Sidetone to Skype</title><link>http://blogs.msdn.com/coding4fun/archive/2009/06/09/9583391.aspx</link><pubDate>Wed, 10 Jun 2009 00:44:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:9583391</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>0</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/9583391.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=9583391</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=9583391</wfw:comment><description>&lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/AddingSidetonetoSkype_B0D/clip_image001_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; margin-left: 0px; border-left-width: 0px; margin-right: 0px" title="clip_image001" border="0" alt="clip_image001" align="right" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/AddingSidetonetoSkype_B0D/clip_image001_thumb.jpg" width="240" height="91" /&gt;&lt;/a&gt;Ever use a headset with Skype – and were frustrated that it was &lt;i&gt;too&lt;/i&gt; quiet? This article shows how to add the sound of your own voice to the headset and not feel exhausted from shouting to be heard.&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;&lt;b&gt;Compiled version: &lt;/b&gt;&lt;a href="http://skypesidetone.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=25436"&gt;Download&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Source Code:&lt;/b&gt; &lt;a href="http://skypesidetone.codeplex.com/Release/ProjectReleases.aspx?ReleaseId=25435"&gt;Download C#&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Difficulty:&lt;/b&gt; Intermediate &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Time Required:&lt;/b&gt; 1-3 hours &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Cost:&lt;/b&gt; free &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Software Needed:&lt;/b&gt; &lt;a href="http://skype.com/"&gt;Skype&lt;/a&gt; (&lt;a href="https://developer.skype.com/Download"&gt;Sype4Com&lt;/a&gt;), &lt;a href="http://www.microsoft.com/windows/directx/default.mspx"&gt;DirectX&lt;/a&gt;, &lt;a href="http://www.microsoft.com/express/download/"&gt;Visual Basic or Visual C# Express&lt;/a&gt; &lt;/li&gt;    &lt;li&gt;&lt;b&gt;Hardware:&lt;/b&gt; none &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;Skype: I find your lack of feedback disturbing.&lt;/h3&gt;  &lt;p&gt;This article will discuss how to build a software tool that makes it easier to talk into Skype with a headset.&lt;/p&gt;  &lt;p&gt;Recently my family began experimenting with Skype, but we found that talking over Skype can be exhausting with headphones. After doing a little research, I learned that the problem was that we only heard the other party. You’d think that this is a good thing, but we have a social brain that works hard to gauge our behavior and adjust.&lt;/p&gt;  &lt;p&gt;The answer is to feed a little bit of the microphone back into the earpiece, so that our brain knows how loud we're talking. This is called &lt;i&gt;side tone&lt;/i&gt; in the telecommunication industry. Without it, we talk louder and louder until we’re sure that we’ll be heard.&lt;/p&gt;  &lt;p&gt;I couldn’t find a Skype plug-in to do this… but I had just read a &lt;a href="http://blogs.msdn.com/coding4fun/archive/2009/02/02/9391048.aspx"&gt;Coding4Fun article, by Mark Heath, about adding audio effects to Skype&lt;/a&gt;. I decided I was going to write a tool to add this feedback.&lt;/p&gt;  &lt;h4&gt;How to use the tool&lt;/h4&gt;  &lt;p&gt;First, let’s take a look at how to use the application. Once it is running, there will be a microphone icon in the lower right hand corner of the screen:&lt;/p&gt;  &lt;p&gt;Figure 1: Icon in the system notification tray&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/AddingSidetonetoSkype_B0D/clip_image004_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image004" border="0" alt="clip_image004" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/AddingSidetonetoSkype_B0D/clip_image004_thumb.jpg" width="160" height="53" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Clicking on it, will get the application control window:&lt;/p&gt;  &lt;p&gt;Figure 2: The application's controls&lt;/p&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/AddingSidetonetoSkype_B0D/clip_image006_2.jpg"&gt;&lt;img style="border-right-width: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px" title="clip_image006" border="0" alt="clip_image006" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/AddingSidetonetoSkype_B0D/clip_image006_thumb.jpg" width="447" height="333" /&gt;&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;Let’s look at the side tone controls:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The “Side Tones” check box enables or disables the side tone. If you have headphones, you'll want this on; if you have loud speakers, you'll want it off. &lt;/li&gt;    &lt;li&gt;The slider controls the volume of the microphone in the headset. You can change it while talking. The volume will vary with microphone and headset. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;You can do a “sound check” to see if the feedback is working by clicking on the Sound Check button, and adjusting the volume. I found that the volume setting that works best in a conversation is much, much lower than what works in a sound check.&lt;/p&gt;  &lt;p&gt;Next, let’s look at the AGC (“Automatic Gain Control”) section. When making a call, the software can automatically adjust how loud you sound to the other party:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;When “Low Pass” is checked, the headphone feedback is at 44100 samples/sec. The microphone sound is filtered to keep only the sounds below 8 Khz, converted to 16000/samples per second and sent to Skype. When it is not checked, headphone feedback is at 16000 samples/sec, and sent to Skype without the low pass filter. &lt;/li&gt;    &lt;li&gt;When &amp;quot;Skype AutoGain&amp;quot; is checked, it signals to Skype that Skype can use its own algorithm. When clear, Skype is told not to apply any adjustments. &lt;/li&gt;    &lt;li&gt;When &amp;quot;AutoGain&amp;quot; is checked, the custom Automatic Gain Control algorithm is used. &lt;/li&gt; &lt;/ul&gt;  &lt;p&gt;The Automatic Gain Control has three sliders:&lt;/p&gt;  &lt;ul&gt;   &lt;li&gt;The “Cutoff” slider controls the distinction between background noise and conversation. Sound below this level is cutoff and silence is sent to Skype. This will vary with microphone – more sensitive (expensive) microphones will pick more background noise and be better with a higher setting.&lt;/li&gt;    &lt;li&gt;The “Normal” slider controls the volume when you are talking normally. The Gain Control tries to raise the volume to this level. &lt;/li&gt;    &lt;li&gt;The “Loud” slider controls the volume when you talk exceptionally loud. This rarely happens, but when you &lt;i&gt;do&lt;/i&gt; talk louder than the Normal level, the Gain Control tries to adjust the volume to this level. &lt;/li&gt; &lt;/ul&gt;  &lt;h3&gt;How the Software Works&lt;/h3&gt;  &lt;p&gt;I originally started this project by creating an effect for the &lt;a href="http://blogs.msdn.com/coding4fun/archive/2009/02/02/9391048.aspx"&gt;Skype Voice Changer&lt;/a&gt;. My plan was to open a WaveStream, begin playing it on the headphones and copy the microphone stream to it.&lt;/p&gt;  &lt;p&gt;I quickly found that this was not the way to add feedback. The underlying “WaveOut” system had a huge latency: Everything I heard in the headphones was at least a second or more behind what I was saying. This made it even harder to talk than before, and I had to abandon it.&lt;/p&gt;  &lt;p&gt;While researching the problem I found a DirectSound code sample that I could modify into doing what I wanted. (This initial prototype didn’t coordinate with Skype – it attached to the microphone and copied the sounds to the output, at a lower volume. But it was on &lt;i&gt;always on.&lt;/i&gt;) The sound in the headphones is still slightly behind (the microphone) but is barely perceptible, and we’ll muffle it a bit more to make it less distinguishable.&lt;/p&gt;  &lt;p&gt;From here on I shall describe the major – or technically interesting – components of the program. We’ll look at:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;DirectSound and Circular buffers &lt;/li&gt;    &lt;li&gt;Sample Window and Sizing the buffers &lt;/li&gt;    &lt;li&gt;Using WaitHandle’s to Synchronize with DirectSound &lt;/li&gt;    &lt;li&gt;IIR Filters &lt;/li&gt;    &lt;li&gt;Automatic Gain Control &lt;/li&gt;    &lt;li&gt;Estimating loudness &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;Note: I won’t be describing how to connect to Skype. Mark Heath’s description is very good.&lt;/p&gt;  &lt;h4&gt;DirectSound and Circular Buffers&lt;/h4&gt;  &lt;p&gt;The DirectSound code is in AudioLoop.cs. The module sets DirectSound to capture sound from the default recording device at 16bits / sample at either 16000 or 44100 samples per second. The capture and playback buffers are configured in “looping” mode to act as circular buffers. The capture buffer eventually overwrites samples, and we’ll lose them if we don’t act fast enough; if we don’t update the playback buffer, it will repeat the same sound over and over.&lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;StartMicrophone() &lt;/strong&gt;procedure sets up the capture and playback buffers. Then it creates a thread to do the work. The thread is at a high priority so that if the OS has a choice between (say) email or processing sound, it does the sound.&lt;/p&gt;  &lt;p&gt;The &lt;strong&gt;StopMicrophone() &lt;/strong&gt;procedure stops the worker thread and cleans up the resources.&lt;/p&gt;  &lt;p&gt;The software processes a fixed number of samples at a time, called the “sample window.” The buffers are several times the size of sample window, so that the system can keep capturing and playing while the software is processing them. The sound processing loop is the heart of the application:&lt;/p&gt;  &lt;ol&gt;   &lt;li&gt;Wait for the next sample window to be ready &lt;/li&gt;    &lt;li&gt;Copy the samples from the capture buffer &lt;/li&gt;    &lt;li&gt;Process the samples and send the results to the playback buffer &lt;/li&gt;    &lt;li&gt;Process the samples and sends the results to Skype &lt;/li&gt; &lt;/ol&gt;  &lt;p&gt;&lt;b&gt;C#      &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;  &lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;while&lt;/span&gt; (Runnable)
{
    &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; I = 0, offset = 0; Runnable &amp;amp;&amp;amp; I &amp;lt; _bufferPositions; I++, offset += bufferSize)
    {
        &lt;span class="rem"&gt;// Wait for the sample areas to be ready&lt;/span&gt;
        notificationEvent[I].WaitOne(Timeout.Infinite, &lt;span class="kwrd"&gt;true&lt;/span&gt;);

        &lt;span class="rem"&gt;// Get the sound samples&lt;/span&gt;
        &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] buffer = (&lt;span class="kwrd"&gt;byte&lt;/span&gt;[]) captureBuffer.Read(offset, &lt;span class="kwrd"&gt;typeof&lt;/span&gt; (&lt;span class="kwrd"&gt;byte&lt;/span&gt;), LockFlag.None, bufferSize);

        &lt;span class="rem"&gt;// Convert samples to 16bit PCM &lt;/span&gt;
        &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; L = buffer.Length, J = 10, K = 0; K &amp;lt; L; K += 2)
            PCM16Buffer[J++] = (Int16) ((UInt16) buffer[K] | (((UInt16) buffer[K + 1]) &amp;lt;&amp;lt; 8));

        &lt;span class="rem"&gt;// Play them out to the ear, if applicable&lt;/span&gt;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != playbackBuffer)
        {
            &lt;span class="rem"&gt;// Perform a low pass filter to &amp;quot;muffle&amp;quot; the sound&lt;/span&gt;
            Butterworth(PCM16Buffer, 10, LPSample, Coefs);

            &lt;span class="rem"&gt;// put the muffled sample into the output buffer&lt;/span&gt;
            &lt;span class="rem"&gt;// -- The lock flag seems to work, but others may work too&lt;/span&gt;
            playbackBuffer.Write(Idx, LPSample, LockFlag.None);
            Idx += buffer.Length;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (Idx &amp;gt;= 4*bufferSize)
                Idx -= 4*bufferSize;
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (!playing)
            {
                playbackBuffer.Volume = _Volume;
                playbackBuffer.Play(0, BufferPlayFlags.Looping);
                playing = &lt;span class="kwrd"&gt;true&lt;/span&gt;;
            }
        }

        &lt;span class="rem"&gt;// Process the sound and deliver it to Skype&lt;/span&gt;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (&lt;span class="kwrd"&gt;null&lt;/span&gt; != outStream)
        {
            &lt;span class="kwrd"&gt;int&lt;/span&gt; L = AGC.Process(PCM16Buffer, 10, buffer);
            &lt;span class="kwrd"&gt;if&lt;/span&gt; (0 != L)
                outStream.BeginSend(buffer, 0, L, SocketFlags.None, SendCallback, &lt;span class="kwrd"&gt;null&lt;/span&gt;);
            &lt;span class="rem"&gt;// Note: could send out pink noise if L == 0&lt;/span&gt;
        }

        &lt;span class="rem"&gt;// Move the sliding window of the previous 10 samples into the start&lt;/span&gt;
        &lt;span class="rem"&gt;// of the PCM16Buffer&lt;/span&gt;
        &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; K = 0, J = PCM16Buffer.Length - 10; K &amp;lt; 10; K++, J++)
            PCM16Buffer[K] = PCM16Buffer[J];
    }
}&lt;/pre&gt;
&lt;style type="text/css"&gt;

.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/style&gt;

&lt;p&gt;Note the “for” loop at the bottom of the code. This preserves the last 10 incoming samples at the start of the buffer. This is needed to make the sound processing smooth, and will be discussed a bit later.&lt;/p&gt;

&lt;h4&gt;Sample Window and Sizing the Buffers&lt;/h4&gt;

&lt;p&gt;How big should the sample window be? This is bit of a trade off in responsiveness and design complexity.&lt;/p&gt;

&lt;p&gt;I chose a window big enough to hold 10 milliseconds of sound. Since the ear is sensitive sound to delays of even 30 milliseconds, I cut this done so that a delay wouldn’t be perceptible. (When I tried a 50 millisecond window, my voice came out the headphone sounding like an echo... and I found myself talking slower and slower.) The sample window could be made smaller, but I am sure that there is a point where the OS won’t schedule the audio loop to wake-n-run more frequently. And, as the sample window gets smaller, the processing may drop in quality, because it doesn’t have enough to work with.&lt;/p&gt;

&lt;p&gt;The capture buffer is 8 times the size of the sample window. This ratio is arbitrary, but I wanted the buffer to be about an order of magnitude larger. My rationale is that if the processing falls behind, the sound – for the Skype call – won’t be dropped. I feel that it is more important to preserve sound quality for the other party than to preserve the quality of feedback.&lt;/p&gt;

&lt;p&gt;The playback buffer is four times the sample window. I wanted it small, so that if the processing fell behind, the replaying of a sound will seem to be a continuation of a current sound.&lt;/p&gt;

&lt;p&gt;When writing the sound to the playback buffer, we have to track where in the buffer to put the samples. I tried to use GetCurrentPosition() to find where to write to next into the playback buffer; this created terrible sound. Instead, the software uses a local variable to track where to write next.&lt;/p&gt;

&lt;h4&gt;DirectSound and Notifications&lt;/h4&gt;

&lt;p&gt;How do we keep in sync with the sound capture – how do we know when a sample buffer is ready?&lt;/p&gt;

&lt;p&gt;The application gives a table of buffer indices and WaitHandle’s to DirectSound. When the capture buffer’s write index reaches one of those indices, it signals the corresponding WaitHandle. The worker thread cycles performs a WaitOne() one each of the WaitHandle’s, one at a time. As a convenience, we use a specific kind of WaitHandle called AutoResetEvent. This type of WaitHandle sets itself back to a “wait” state once WaitOne() returns.&lt;/p&gt;

&lt;p&gt;If the thread has gotten behind, the WaitOne will return immediately, the loop processes the sample, and begins to catch up with the work.&lt;/p&gt;

&lt;p&gt;We must use a separate AutoResetEvent for each of the 8 capture windows. The AutoResetEvent doesn’t tell us if it was signaled multiple times. If only one AutoResetEvent handle were used, it wouldn’t know that two (or more) sample windows were ready. Instead, it would process just one, falling further behind, adding latency. This would happen randomly overtime, and be hard to test consistently.&lt;/p&gt;

&lt;h4&gt;IIR: Infinite Impulse Response Filters&lt;/h4&gt;

&lt;p&gt;This project came together so quickly, so easy – once I found the right approach – that I couldn't resist getting fancy. I added a low-pass filter to muffle the feedback a little. And I added automatic gain control, as an experimental option.&lt;/p&gt;

&lt;p&gt;For both of these I used a filtering algorithm called “IIR” (this stands for Infinite Impulse Response – but that term is a confusing mouthful, so let’s just call it IIR). IIR is a special purpose virtual machine. Low-pass filters, high-pass filters, combinations of those filters, and even equalizers, can be specified, and use very specific techniques (like a compiler) to convert them into an IIR implementation.&lt;/p&gt;

&lt;p&gt;(You could, instead, “compile” the filters to be the resistor values to use in a hardware circuit. &lt;i&gt;That’s programming in solder!)&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;The machine code for these IIR virtual machines is just two list of coefficients, called A &amp;amp; B. The software emulator is code that &lt;i&gt;looks&lt;/i&gt; like the following bit of code:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;Out[0] = Sample[0];
Out[1] = Sample[1];
&lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; Idx = 2; Idx &amp;lt; N; Idx++)
{
    Out[Idx] =
    B0 * Sample[Idx]
 + B1 * Sample[Idx - 1]
 + B2 * Sample[Idx - 2]
        &lt;span class="rem"&gt;// … more like this …&lt;/span&gt;
        &lt;span class="rem"&gt;// Next, the feed back&lt;/span&gt;
 - A1 * Out[Idx - 1]
 - A2 * Out[Idx - 2]
        &lt;span class="rem"&gt;// … more like this …&lt;/span&gt;
 ;
}&lt;/pre&gt;

&lt;p&gt;IIRs are easy to implement - and take less CPU power than other methods. But sometimes they sound poor; if they sound too bad, you’ll want to use a different technique. I found that the low-pass filters in this project work will for some microphones, and add a slight crackle to others.&lt;/p&gt;

&lt;h4&gt;Example Low Pass Filter&lt;/h4&gt;

&lt;p&gt;For the low pass filter to create the muffling, I used a Butterworth filter, using the code below. It takes a buffer of signed, 16-bit samples, and then converts the 16-bit values into a byte array suitable for the sound buffer.&lt;/p&gt;

&lt;p&gt;The filter code is a bit different than the example code in the previous section. Most of the differences are for speed.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;This code doesn’t use a buffer for the old values, instead uses separate variables for the elements of the buffer.&amp;#160; It uses I_0,I_1,I_2 instead of Sample[Idx], Sample[Idx-1], and Sample[Idx-2]. It also uses O_1, and O_2 instead of Out[Idx-1] and Out[Idx-2]. &lt;/li&gt;

  &lt;li&gt;The A and B coefficients are put into a single array. It also &lt;i&gt;adds&lt;/i&gt; two of the sample input values, and is missing a coefficient; this is because the B0 and B2 coefficients are always the same for this kind of filter. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;There is one difference that is not for speed. These are tricks done to make the filter smooth, and needed because the sample window is so small. They preserve the state of filter. If we didn’t preserve them, the filter would be starting and stopping so frequently that it would add distracting clicks to the output sound. The filters performance would be weakened, because the sample window isn’t big enough to hold sounds lower than (about) 200 Hz. Preserving these values, the filter isn’t starting and stopping, and doesn’t really know about the sample window. All of the IIR filters in this program use similar techniques.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;O_1, O_2 are explicitly preserved across calls by being stored in class variables &lt;/li&gt;

  &lt;li&gt;I_1 and I_2 are preserved by the audio loop (remember the warning about preserving 10 samples at the bottom of the loop?) The audio loop preserves the last 10 samples at the start of InBuffer. When this procedure is called, it retrieves the last two samples. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;C#&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;double&lt;/span&gt; O_1 = 0.0, O_2=0.0;

&lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;void&lt;/span&gt; Butterworth(Int16[] InBuffer, &lt;span class="kwrd"&gt;int&lt;/span&gt; Ofs, &lt;span class="kwrd"&gt;byte&lt;/span&gt;[] OutBuffer, &lt;span class="kwrd"&gt;double&lt;/span&gt;[] Coefs)
{
  &lt;span class="kwrd"&gt;double&lt;/span&gt; C0=Coefs[0], C1=Coefs[1], C2 = Coefs[2], C3=Coefs[3];
  &lt;span class="kwrd"&gt;double&lt;/span&gt; I_1=InBuffer[Ofs-1], I_2= InBuffer[Ofs-2];
  &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; L = InBuffer . Length, J=0, I = Ofs; I &amp;lt; L; I++)
  {
     &lt;span class="kwrd"&gt;double&lt;/span&gt; I_0 = InBuffer[I];

     &lt;span class="rem"&gt;// Filter the samples&lt;/span&gt;
     &lt;span class="kwrd"&gt;double&lt;/span&gt; A = (I_0 + I_2) * C0 + I_1 * C1;
     I_2 = I_1;
     I_1 = I_0;

     A = A - O_1 * C2 - O_2 * C3;
     O_2 = O_1;
     O_1 = A;

     &lt;span class="rem"&gt;// Convert it back to 16 bit&lt;/span&gt;
     Int16 S;
     &lt;span class="kwrd"&gt;if&lt;/span&gt; (A &amp;lt; -32767) S = -32767;
     &lt;span class="kwrd"&gt;if&lt;/span&gt; (A &amp;gt; 32767)  S = 32767;
     &lt;span class="kwrd"&gt;else&lt;/span&gt; S = (Int16) A;

     &lt;span class="rem"&gt;// Store it&lt;/span&gt;
     OutBuffer[J++] = (&lt;span class="kwrd"&gt;byte&lt;/span&gt;)(S &amp;amp; 0xFF);
     OutBuffer[J++] = (&lt;span class="kwrd"&gt;byte&lt;/span&gt;)(((UInt16)S &amp;gt;&amp;gt; 8) &amp;amp; 0xFF);
  }
}&lt;/pre&gt;

&lt;p&gt;Automatic Gain Control&lt;/p&gt;

&lt;p&gt;I decided next to tackle a problem where my wife's voice did not carry well on calls. This happens a lot to her with cell phones – and answering machines. I was pretty sure that the problem was poor automatic-gain-control (AGC). The typical amplifier in a headset (and in Skype) estimates how loud our voice is, then increases – or decreases – the volume to a reasonable level. It was deciding that my wife's voice was background noise, and cutting her off.&lt;/p&gt;

&lt;p&gt;I chose to write an alternate gain control that amplified the sound and passed it to Skype. That way we'd have four to choose from: The one built into the Microphone, the Soundcard’s, Mine, and Skype’s. (To be fair, these automatic gain controls work well in most cases).&lt;/p&gt;

&lt;p&gt;The main portion of the gain control is implemented in the file GainControl.cs. The control algorithm is:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Calculate (or estimate) how loud we are currently talking (using the Analyze() procedure) &lt;/li&gt;

  &lt;li&gt;If the loudness is very low, no one is talking… so set the output to zero. (Without this step, the volume of noise and hum would be cranked up) &lt;/li&gt;

  &lt;li&gt;Otherwise, compute the guess-gain by dividing how loud the sound of our voice should be by how loud it currently is &lt;/li&gt;

  &lt;li&gt;Compute the gain (called MaxGain) at which the sound will start clipping. If the guess-gain is louder than this, reduce it to MaxGain. &lt;/li&gt;

  &lt;li&gt;The software adjusts the gain for a gentle transition – especially in the case when we go from absolute quiet, to the start of talking. It does this by tracking the gain (called PrevGain) used in previous sample and the current one. &lt;/li&gt;

  &lt;li&gt;Multiple all the samples by this gain value. &lt;/li&gt;

  &lt;li&gt;If the sample rate is greater than 16000 samples/sec 
    &lt;ol&gt;
      &lt;li&gt;Do a low pass filter at 8 khz (again in IIR form). This helps prevent artifacts from down sampling &lt;/li&gt;

      &lt;li&gt;Resample the sound to 16000 &lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The portion of code that calculates the gain looks like (CutOff_dB, LowGain_dB, and TgtGain_dB are the three slider values):&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (!AutoGain)
    Gain = 1.0;
&lt;span class="kwrd"&gt;else&lt;/span&gt;
{
    &lt;span class="kwrd"&gt;double&lt;/span&gt; MaxGain;
    &lt;span class="kwrd"&gt;double&lt;/span&gt; dB = Analyze(InBuffer, Ofs, &lt;span class="kwrd"&gt;out&lt;/span&gt; MaxGain);

    &lt;span class="kwrd"&gt;if&lt;/span&gt; (dB &amp;lt; CutOff_dB)
        Gain = 0.0;
    &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (dB &amp;lt; LowGain_dB + 4.0)
    {
        Gain = Math.Exp((LowGain_dB - dB) * db2log);
    }
    &lt;span class="kwrd"&gt;else&lt;/span&gt;
    {
        Gain = Math.Exp((TgtGain_dB - dB) * db2log);
    }
    Gain = (0.4 * Gain + 0.6 * PrevGain);
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (Gain &amp;gt; MaxGain)
        Gain = MaxGain;
    PrevGain = Gain;
}

&lt;span class="rem"&gt;// Skip further process if there is silence&lt;/span&gt;
&lt;span class="kwrd"&gt;if&lt;/span&gt; (0.0 == Gain)
{
    &lt;span class="kwrd"&gt;return&lt;/span&gt; 0;
}&lt;/pre&gt;

&lt;p&gt;If you look at the code, you’ll see that we don’t compare directly with LowGain_db; rather we compare the estimate volume with LowGain_db+4. This gives a little “hysteresis” – if we raise our voice momentarily, the software won’t suddenly make it the highest possible volume. Instead, the software lowers the volume a little bit.&lt;/p&gt;

&lt;p&gt;When the software changes the sample rate, it basically needs to know how many input samples to skip. At the start of a call, the software computes this, calling it InInc:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// Calculate how we resample to 16Khz&lt;/span&gt;
InInc = (&lt;span class="kwrd"&gt;int&lt;/span&gt;)(1024.0 * SampleRate / 16000.0);&lt;/pre&gt;

&lt;p&gt;The process of applying the gain adjustment, performing a low pass filter and re-sampling is below:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;int&lt;/span&gt; NumSamples = InBuffer.Length;
&lt;span class="kwrd"&gt;int&lt;/span&gt; End = OutBuffer.Length;
&lt;span class="kwrd"&gt;int&lt;/span&gt; NextIdxForOut = -InInc;
&lt;span class="kwrd"&gt;int&lt;/span&gt; OutIdx = 0;
&lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; I = Ofs; OutIdx &amp;lt; End &amp;amp;&amp;amp; I &amp;lt; NumSamples; I++)
{
    &lt;span class="rem"&gt;// Retrieve the sample&lt;/span&gt;
    Int16 S = InBuffer[I];
    &lt;span class="kwrd"&gt;double&lt;/span&gt; I_0 = S;

    &lt;span class="rem"&gt;// Apply Gain&lt;/span&gt;
    I_0 *= Gain;

    &lt;span class="rem"&gt;// 8khz low pass filter &lt;/span&gt;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (DoLP)
    {
        &lt;span class="rem"&gt;// Simple Butterworth 8KHz low-pass filter&lt;/span&gt;
        &lt;span class="kwrd"&gt;double&lt;/span&gt; A = (I_0 + DS_I_2) * LP[0] + DS_I_1 * LP[1];
        DS_I_2 = DS_I_1;
        DS_I_1 = I_0;
        I_0 = A - DS_O_1 * LP[2] - DS_O_2 * LP[3];
        DS_O_2 = DS_O_1;
        DS_O_1 = I_0;

        &lt;span class="rem"&gt;// Change sample rate&lt;/span&gt;
        &lt;span class="kwrd"&gt;int&lt;/span&gt; Tmp = NextIdxForOut / 1024;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (I &amp;lt; Tmp)
            &lt;span class="kwrd"&gt;continue&lt;/span&gt;;
        NextIdxForOut += InInc;
    }

    &lt;span class="rem"&gt;// Convert it back to 16 bit&lt;/span&gt;
    S = (Int16)I_0;

    &lt;span class="rem"&gt;// Store it&lt;/span&gt;
    OutBuffer[OutIdx++] = (&lt;span class="kwrd"&gt;byte&lt;/span&gt;)(S &amp;amp; 0xFF);
    OutBuffer[OutIdx++] = (&lt;span class="kwrd"&gt;byte&lt;/span&gt;)(((UInt16)S &amp;gt;&amp;gt; 8) &amp;amp; 0xFF);
}&lt;/pre&gt;

&lt;p&gt;Estimating Volume&lt;/p&gt;

&lt;p&gt;How loud “it should be” is controlled by a slider on the screen. The software estimates how loud the sound is by using &lt;a href="http://replaygain.hydrogenaudio.org/equal_loudness.html"&gt;an algorithm devised by David Robinson&lt;/a&gt; that takes into account how it sounds &lt;i&gt;to a person&lt;/i&gt;. This way we can increase the gain on hard to hear sounds, and reduce the gain on sounds that a person is very sensitive to.&lt;/p&gt;

&lt;p&gt;The loudness estimator, implemented in the Analysis procedure in GainAnalysis.cs, uses the following algorithm:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;Uses a combination of two (IIR) filters to make the sound to reflect how our ears hear it. &lt;/li&gt;

  &lt;li&gt;Compute the Mean-Square value of the filtered sound (called MS) &lt;/li&gt;

  &lt;li&gt;Track the last 750 ms of these values. &lt;/li&gt;

  &lt;li&gt;Make a sorted copy of these. &lt;/li&gt;

  &lt;li&gt;Retrieve the first non-zero value at least 95% of the way into the buffer. This is so that we don’t take the loudest sample and assume that is how the person is talking. &lt;/li&gt;

  &lt;li&gt;If MS (the value computed in step 2) is much quieter, use that one instead &lt;/li&gt;

  &lt;li&gt;Convert this value into dB scale by performing a logarithm on it. &lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The code to “normalize” the sound into how a person hears it is below. Along the way it computes the square of the samples (used in step 2). Like the earlier IIR filters, these preserves their variables across the calls. The first IIR is a yulewalk filter, but it preserves it old intermediary values in an array. Like the trick in AudioLoop, where we copy the last 10 samples into the start of the current buffer, the analysis procedure copies the last 10 immediate values into the start of YuleTmp array.&lt;/p&gt;

&lt;p&gt;The output of the yulewalk filter is feed into a 150Hz high pass filter. It is essentially the same as the low-pass filter described earlier.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; L = Samples.Length, N = Ofs; N &amp;lt; L; N++)
{
    &lt;span class="kwrd"&gt;int&lt;/span&gt; _V = Samples[N];
    &lt;span class="kwrd"&gt;double&lt;/span&gt; V = _V;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (_V &amp;gt; MaxSample) MaxSample = _V;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (-_V &amp;gt; MaxSample) MaxSample = -_V;

    &lt;span class="rem"&gt;// Perform yulewalk filter&lt;/span&gt;
    &lt;span class="kwrd"&gt;double&lt;/span&gt; S = V * YuleCoefs[0];
    &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; J = N - 1, I = 1; I &amp;lt; 11; I++, J--)
        S += Samples[J] * YuleCoefs[I];
    &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; J = N - 1, I = 11; I &amp;lt; 21; I++, J--)
        S -= YuleTmp[J] * YuleCoefs[I];

    &lt;span class="rem"&gt;// Store for the feedback into the next stage of the yule walk&lt;/span&gt;
    YuleTmp[N] = S;


    &lt;span class="rem"&gt;// Perform butterworth high-pass filter stage, using S as an input&lt;/span&gt;
    &lt;span class="kwrd"&gt;double&lt;/span&gt; Accum =
       (S + GA_I_2) * HPCoefs[0]
       + GA_I_1 * HPCoefs[1];
    GA_I_2 = GA_I_1;
    GA_I_1 = S;
    Accum = Accum - GA_O_1 * HPCoefs[2] - GA_O_2 * HPCoefs[3];

    GA_O_2 = GA_O_1;
    GA_O_1 = Accum;

    &lt;span class="rem"&gt;// The square of the filtered results&lt;/span&gt;
    Sum += Accum * Accum;
}

&lt;span class="rem"&gt;// Copy the intermediate yulewalk state for the next&lt;/span&gt;
&lt;span class="rem"&gt;// (this is needed since we are looking at a fairly small time window)&lt;/span&gt;
&lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; I = 0, J = YuleTmp.Length - 10; I &amp;lt; 10; I++)
    YuleTmp[I] = YuleTmp[J];&lt;/pre&gt;

&lt;p&gt;The mean-squared is computed:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// The mean square of the filtered results&lt;/span&gt;
&lt;span class="kwrd"&gt;double&lt;/span&gt; MS = Sum / NumSamples;&lt;/pre&gt;

&lt;p&gt;Tracking the last 750ms of samples is a simple matter of putting it into a circular queue:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;MSQueue[QIdx++] = MS;
&lt;span class="kwrd"&gt;if&lt;/span&gt; (QIdx &amp;gt;= MSQueue . Length)
   QIdx = 0;&lt;/pre&gt;

&lt;p&gt;Next, is the code to finding the first non-zero value 95% of the way into the buffer. It is a straightforward copy-the-array, sort it, and fetch:&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;Array.Copy(MSQueue, SortedQ, MSQueue.Length);
Array.Sort(SortedQ);

&lt;span class="rem"&gt;// Return the 95% &lt;/span&gt;
&lt;span class="kwrd"&gt;double&lt;/span&gt; X = SortedQ[Q95Idx]; 
&lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; I = Q95Idx +1; X &amp;lt; 400.0 &amp;amp;&amp;amp; I &amp;lt; SortedQ . Length; I++)
      X = SortedQ[I];&lt;/pre&gt;

&lt;p&gt;Next, override this value if the current sample window is very, very quiet – that is, the user stopped talking. (If we don’t do this, we’ll amplify background noise between words)&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;if&lt;/span&gt; (MS &amp;lt; X * 0.40 &amp;amp;&amp;amp; MS &amp;lt; 12800.0)
   X = MS;&lt;/pre&gt;

&lt;p&gt;Finally, convert the result into decibels (or a reasonable approximation of a decibel)&lt;/p&gt;

&lt;p&gt;&lt;b&gt;C# 
    &lt;br /&gt;&lt;/b&gt;&lt;/p&gt;

&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;return&lt;/span&gt; 10.0 * Math . Log10 (X * 0.5 + &lt;span class="kwrd"&gt;double&lt;/span&gt; . Epsilon);&lt;/pre&gt;

&lt;p&gt;Note: The logarithm function takes a positive, non-zero floating point number. However, the value we pass to it can be zero; if we pass a zero, though, the Logarithm function would return a bad value. The simplest thing to do is check to see if the value we are passing is “zero” and not call Logarithm. However, I learned a long time ago to just add “epsilon” to the value to whatever we pass. This can really improve performance on number crunching.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;This concludes how to add a little bit feedback and fancy amplification to you Skype phone calls.&lt;/p&gt;

&lt;p&gt;If you want to try this out, the download link for the source code is at the top of the article!&lt;/p&gt;

&lt;p&gt;If you’d like to experiment further, here are ideas of what can be done:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;DirectSound has echo cancellation and noise suppression. These seem desirable, esp. if you wanted to try making your own speakerphone. I was not able to get them to work and I would love to learn how. &lt;/li&gt;

  &lt;li&gt;I’m sure it is possible to trim even more latency off of the side-tone playback, and I would be interested in learning better techniques to do so. &lt;/li&gt;

  &lt;li&gt;Another would be to create the ideal equalizer from Robinson’s Equal Loudness model, and use that filter and amplify the sound. &lt;/li&gt;

  &lt;li&gt;It might be useful for the other party to control the settings, so that they decide when your voice has the right volume. &lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;Resources and References&lt;/h4&gt;

&lt;ul&gt;
  &lt;li&gt;David Robinson (while doing his PhD at University of Essex on human hearing). &lt;a href="http://replaygain.hydrogenaudio.org/equal_loudness.html"&gt;His algorithm&lt;/a&gt; is intended to find the overall loudness of an album. He includes &lt;a href="http://replaygain.hydrogenaudio.org/mfiles/equalloudfilt.m"&gt;MATLAB scripts to compute coefficients&lt;/a&gt; at custom sample rates, as well as some &lt;a href="http://replaygain.hydrogenaudio.org/equal_loud_coef.txt"&gt;pre-computed coefficients&lt;/a&gt;. &lt;/li&gt;

  &lt;li&gt;Mark Heath’s &lt;a href="http://blogs.msdn.com/coding4fun/archive/2009/02/02/9391048.aspx"&gt;Skype Voice Changer&lt;/a&gt; &lt;/li&gt;

  &lt;li&gt;Derek Pierson’s &lt;a href="http://blogs.msdn.com/coding4fun/archive/2006/11/02/938703.aspx"&gt;DirectX tutorial&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;About The Author&lt;/h3&gt;

&lt;p&gt;Randall Maas writes firmware for medical devices, and consults in embedded software. Before that he did a lot of other things… like everyone else in the software industry. You can contact him at &lt;a href="mailto:randym@acm.org"&gt;randym@acm.org&lt;/a&gt;.&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=9583391" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/utility/default.aspx">utility</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/web+miscellaneous/default.aspx">web miscellaneous</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/windows/default.aspx">windows</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Audio/default.aspx">Audio</category></item><item><title>Silverlight Dynamic Video Puzzle</title><link>http://blogs.msdn.com/coding4fun/archive/2008/01/22/7163484.aspx</link><pubDate>Tue, 22 Jan 2008 22:02:00 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:7163484</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>7</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/7163484.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=7163484</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=7163484</wfw:comment><description>&lt;P&gt;My blog title says it all, &lt;A href="http://www.betterthaneveryone.com/" mce_href="http://www.betterthaneveryone.com/"&gt;Monkey see, Monkey Build&lt;/A&gt;.&amp;nbsp; I saw Microsoft Surface's video puzzle and I needed to build it.&amp;nbsp; I took this opportunity to play with Microsoft's new technology, &lt;A href="http://silverlight.net/" mce_href="http://silverlight.net"&gt;Silverlight&lt;/A&gt; and build my own puzzle game.&amp;nbsp; I couldn't find anything out on the Internet regarding dynamic video creation with Silverlight so I took it upon myself to do this.&amp;nbsp; The screen shots in this demo will be in c#, however, everything should hold true for VB.&lt;/P&gt;
&lt;P&gt;Clint Rutkas - Academic Developer Evangelist - Microsoft &lt;BR&gt;&lt;A href="http://www.betterthaneveryone.com/" mce_href="http://www.betterthaneveryone.com/"&gt;Monkey see, Monkey Build&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;B&gt;Difficulty: &lt;/B&gt;Intermediate &lt;BR&gt;&lt;B&gt;Time Required:&lt;/B&gt; 6-10 hours &lt;BR&gt;&lt;B&gt;Cost: &lt;/B&gt;Free &lt;BR&gt;&lt;B&gt;Software: &lt;/B&gt;&lt;B&gt;&lt;A href="http://www.microsoft.com/express/" mce_href="http://www.microsoft.com/express/"&gt;Visual Studio Express&lt;/A&gt;, &lt;A href="http://silverlight.net/GetStarted/" mce_href="http://silverlight.net/GetStarted/"&gt;Silverlight SDK and Runtime for &lt;STRIKE&gt;1.1&lt;/STRIKE&gt; 2.0 beta2&lt;/A&gt;&lt;/B&gt; &lt;BR&gt;&lt;B&gt;Download: &lt;/B&gt;&lt;A href="http://www.peacelovecode.com/code/silverlight/puzzle/1.0.0.0/surfacePuzzleDemo.zip" mce_href="http://www.peacelovecode.com/code/silverlight/puzzle/1.0.0.0/surfacePuzzleDemo.zip"&gt;&lt;STRIKE&gt;Download c#&lt;/STRIKE&gt;&lt;/A&gt;&lt;STRIKE&gt; - &lt;/STRIKE&gt;&lt;A href="http://www.peacelovecode.com/code/silverlight/puzzle/1.0.0.0/surfacePuzzleDemoVB.zip" mce_href="http://www.peacelovecode.com/code/silverlight/puzzle/1.0.0.0/surfacePuzzleDemoVB.zip"&gt;&lt;STRIKE&gt;Download VB&lt;/STRIKE&gt;&lt;/A&gt; Updated to Silverlight 2.0 Beta - &lt;A href="http://www.peacelovecode.com/code/silverlight/puzzle/2.0.0.0/VideoRealTimeBreakUp.zip"&gt;Download c#&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Updates: &lt;/STRONG&gt;&lt;/P&gt;
&lt;UL&gt;
&lt;LI&gt;Fixed the Silverlight.Js, used the new version that is included with the 1.1 Refresh SDK so the proper installer will prompt now.&amp;nbsp; Downloads are corrected also too. &lt;/LI&gt;
&lt;LI&gt;6/20/2008&amp;nbsp;- Verified the solution works with Silverlight 2.0beta2.&lt;/LI&gt;&lt;/UL&gt;
&lt;H2&gt;Spec's, Requirements and headaches&lt;/H2&gt;
&lt;P&gt;So I had a few mental requirements for the application to "entertain" myself.&amp;nbsp; &lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;Be able to rotate the video blocks &lt;/LI&gt;
&lt;LI&gt;Be able to translate &lt;/LI&gt;
&lt;LI&gt;Be able to increase the difficulty of the puzzle on the fly. &lt;/LI&gt;
&lt;LI&gt;Zero interaction with the keyboard&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;Simple, right?&amp;nbsp; You want to see a demo too see some awesomeness?&amp;nbsp; No problem, &lt;A href="http://www.betterthaneveryone.com/archive/2008/01/06/silverlight-ms-surface-puzzle-like-demo.aspx" mce_href="http://www.betterthaneveryone.com/archive/2008/01/06/silverlight-ms-surface-puzzle-like-demo.aspx"&gt;head over to my site&lt;/A&gt; and see it in person.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Microsoft Surface Video Puzzle&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=180 alt=sl_9[1] src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/sl_91.jpg" width=240 border=0 mce_src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/sl_91.jpg"&gt;&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Clint's Silverlight Video Puzzle&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image1.png" mce_href="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image1.png"&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=219 alt=image[1] src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image1_thumb.png" width=240 border=0 mce_src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image1_thumb.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;H2&gt;To the Internet Batman!&lt;/H2&gt;
&lt;P&gt;To help save time building this, I first when out and attempting to see if anything has been done anything close to this before.&amp;nbsp; I found&lt;/P&gt;
&lt;P&gt;Also I need 2 small controls which I found out are in the Silverlight SDK.&amp;nbsp; I needed horizontal slider controls for this app.&amp;nbsp; While I know a text box control would have worked just as well, see requirement 4.&lt;/P&gt;
&lt;P&gt;On the Silverlight community site, there is also a very nice demo showing the &lt;A href="http://silverlight.net/samples/1.1/SilverlightSurface/Run/default.html" mce_href="http://silverlight.net/samples/1.1/SilverlightSurface/Run/default.html"&gt;photo application in Surface with source code&lt;/A&gt;.&amp;nbsp; This is where I learned the majority of what I needed.&amp;nbsp; This application was very close to where I needed to go with mine.&amp;nbsp; However, while it was close, it wasn't perfect.&amp;nbsp; Parts of the photo application code are pretty much copied.&amp;nbsp; This isn't the best way of doing this, but it is one way of doing it.&lt;/P&gt;
&lt;H2&gt;Toolbelt: check, Keyboard: check, Band-aids: check&lt;/H2&gt;
&lt;P&gt;So on to building it.&amp;nbsp; I first started off with a new project and some XAML.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_6.png" mce_href="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_6.png"&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=269 alt=image src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image.png" width=400 border=0 mce_src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image.png"&gt;&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;After clicking "OK", I get a very nice blank project.&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;A href="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_7.png" mce_href="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_7.png"&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=367 alt=image src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_3.png" width=400 border=0 mce_src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_3.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;We'll want to add an additional XAML object for the video blocks.&amp;nbsp; Go to "&lt;STRONG&gt;Project -&amp;gt; Add New Item&lt;/STRONG&gt;", select Silverlight Page, name it "VideoBlock.xaml" and click "OK".&lt;/P&gt;
&lt;P&gt;So now we have everything we need for the most part, grab any video you have, if you don't have one, go to a site like &lt;A href="http://teamxbox.com/" mce_href="http://teamxbox.com"&gt;TeamXbox&lt;/A&gt; and grab one from there.&amp;nbsp; I used Windows Movie Maker and grabbed a snippet from The Office (best show ever).&lt;/P&gt;
&lt;P&gt;In addition to all these files, we need to add in a reference to the Silverlight SDK to get a hold of the Slider controls. Go to "&lt;STRONG&gt;Project -&amp;gt; Add Reference&lt;/STRONG&gt;", and add in the &lt;STRONG&gt;Silverlight.Samples.Controls.dll&lt;/STRONG&gt;.&lt;/P&gt;
&lt;P&gt;While we have a reference in the application, we still need the XAML to know about this also.&amp;nbsp; So we'll add a line to link this in.&amp;nbsp; It is the xmlns line that I bolded, XML name space, real clever, eh?&amp;nbsp; We'll also&amp;nbsp; change the background color to a gray so we can see it more easy.&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;Canvas&lt;/SPAN&gt; &lt;SPAN class=attr&gt;x:Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="parentCanvas"&lt;/SPAN&gt;
        &lt;SPAN class=attr&gt;xmlns&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="http://schemas.microsoft.com/client/2007"&lt;/SPAN&gt; 
        &lt;SPAN class=attr&gt;xmlns:x&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="http://schemas.microsoft.com/winfx/2006/xaml"&lt;/SPAN&gt; 
        &lt;SPAN class=attr&gt;Loaded&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Page_Loaded"&lt;/SPAN&gt; 
        &lt;SPAN class=attr&gt;x:Class&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="c4f_SilverlightVideoDemo.VideoBlock;assembly=ClientBin/c4f_SilverlightVideoDemo.dll"&lt;/SPAN&gt;
        &lt;STRONG&gt;&lt;SPAN class=attr&gt;xmlns:uicontrol&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="clr-namespace:Silverlight.Samples.Controls;assembly=ClientBin/Silverlight.Samples.Controls.dll"&lt;/SPAN&gt;&lt;/STRONG&gt;
        &lt;SPAN class=attr&gt;Background&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="#CCCCCC" &lt;SPAN class=attr&gt;Width&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="640"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Height&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="480"&lt;/SPAN&gt;&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;Canvas&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
	overflow: auto;
}
.csharpcode pre { margin: 0em;  }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;H2&gt;Silverlight 101&lt;/H2&gt;
&lt;P&gt;So in Silverlight, you have brushes which can "painted" onto objects.&amp;nbsp; One of these brushes is called the VideoBrush which I'll talk about later on.&amp;nbsp; For playing videos, one would use the &lt;STRONG&gt;MediaElement&lt;/STRONG&gt;.&amp;nbsp; Lets add this to our canvas.&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;MediaElement&lt;/SPAN&gt; &lt;SPAN class=attr&gt;x:Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="media"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Source&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="theOffice.wmv"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;Now if we run the application at this point, we'll get the video playing.&amp;nbsp; Lets sit back with some popcorn and enjoy this victory for a second or two.&amp;nbsp; Now that we have this, lets hide it since this isn't what we want.&amp;nbsp; We do that by adding in an XML attribute &lt;STRONG&gt;Opacity&lt;/STRONG&gt; and setting it to 0.&lt;/P&gt;
&lt;P&gt;On top of that element, lets add on some TextBlock elements and the sliders.&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;Canvas&lt;/SPAN&gt; &lt;SPAN class=attr&gt;x:Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="parentCanvas"&lt;/SPAN&gt;
        &lt;SPAN class=attr&gt;xmlns&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="http://schemas.microsoft.com/client/2007"&lt;/SPAN&gt; 
        &lt;SPAN class=attr&gt;xmlns:x&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="http://schemas.microsoft.com/winfx/2006/xaml"&lt;/SPAN&gt; 
        &lt;SPAN class=attr&gt;Loaded&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Page_Loaded"&lt;/SPAN&gt; 
        &lt;SPAN class=attr&gt;x:Class&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="VideoCreatedObjectTest.Page;assembly=ClientBin/VideoCreatedObjectTest.dll"&lt;/SPAN&gt;
        &lt;SPAN class=attr&gt;xmlns:uicontrol&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="clr-namespace:Silverlight.Samples.Controls;assembly=ClientBin/Silverlight.Samples.Controls.dll"&lt;/SPAN&gt; 
        &lt;SPAN class=attr&gt;Background&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="#CCCCCC"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;MediaElement&lt;/SPAN&gt; &lt;SPAN class=attr&gt;x:Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="media"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Source&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="theOffice.wmv"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Opacity&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="0"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
    
    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;TextBlock&lt;/SPAN&gt; &lt;SPAN class=attr&gt;x:Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="sliderX"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Canvas&lt;/SPAN&gt;.&lt;SPAN class=attr&gt;Top&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="5"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Canvas&lt;/SPAN&gt;.&lt;SPAN class=attr&gt;Left&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="5"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Text&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="X (01):"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;TextBlock&lt;/SPAN&gt; &lt;SPAN class=attr&gt;x:Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="sliderY"&lt;/SPAN&gt;  &lt;SPAN class=attr&gt;Canvas&lt;/SPAN&gt;.&lt;SPAN class=attr&gt;Top&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="21"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Canvas&lt;/SPAN&gt;.&lt;SPAN class=attr&gt;Left&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="5"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Text&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="Y (01):"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
    
    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;uicontrol:Slider&lt;/SPAN&gt; &lt;SPAN class=attr&gt;x:Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="hSliderX"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Canvas&lt;/SPAN&gt;.&lt;SPAN class=attr&gt;Top&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="8"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Canvas&lt;/SPAN&gt;.&lt;SPAN class=attr&gt;Left&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="55"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN class=html&gt;uicontrol:Slider&lt;/SPAN&gt; &lt;SPAN class=attr&gt;x:Name&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="hSliderY"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Canvas&lt;/SPAN&gt;.&lt;SPAN class=attr&gt;Top&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="25"&lt;/SPAN&gt; &lt;SPAN class=attr&gt;Canvas&lt;/SPAN&gt;.&lt;SPAN class=attr&gt;Left&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;="55"&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;/&amp;gt;&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;&amp;lt;/&lt;/SPAN&gt;&lt;SPAN class=html&gt;Canvas&lt;/SPAN&gt;&lt;SPAN class=kwrd&gt;&amp;gt;&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;So now when we run the application, we get a blank screen but we can hear the audio from the video.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_8.png" mce_href="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_8.png"&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=345 alt=image src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_4.png" width=400 border=0 mce_src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_4.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;Super exciting I know.&amp;nbsp; Now if you resize the browser, you'll notice also the canvas isn't resizing automatically.&amp;nbsp; Lets fix that.&lt;/P&gt;
&lt;P&gt;So in the code behind lets add in a new event on the BrowserHost object with the Resize event.&amp;nbsp; We'll attach the Browser_Resize event to it.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;C#&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; BrowserHost_Resize(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; sender, EventArgs e)
{
    &lt;SPAN class=rem&gt;// Set size to host size&lt;/SPAN&gt;
    Width = BrowserHost.ActualWidth;
    Height = BrowserHost.ActualHeight;
}&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;&lt;STRONG&gt;VB.Net&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;Private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt; BrowserHost_Resize(&lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; sender &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Object&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; e &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; EventArgs)
    &lt;SPAN class=rem&gt;' Set size to host size&lt;/SPAN&gt;
    Width = BrowserHost.ActualWidth
    Height = BrowserHost.ActualHeight
&lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; Sub&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;H2&gt;Video as Paint?&lt;/H2&gt;
&lt;P&gt;So now that we have that small part done, lets get into more of the nitty gritty with video.&amp;nbsp; As I said earlier, you'll use a &lt;STRONG&gt;VideoBrush&lt;/STRONG&gt; to paint on the video.&lt;/P&gt;
&lt;P&gt;We'll use the brush as the Fill for the rectangle we'll be using to show off the clip of the video we want.&lt;/P&gt;
&lt;H3&gt;Still not moving?&amp;nbsp; Try explosives?&lt;/H3&gt;
&lt;P&gt;While doing this project, I discovered an interesting thing when using the VideoBrush and dynamically appending items on.&amp;nbsp; Having items in the XAML rather than programmatically creating everything caused it not to work properly.&amp;nbsp; Nothing would appear.&lt;/P&gt;
&lt;H3&gt;Throwback to how UI's use to be done&lt;/H3&gt;
&lt;P&gt;The XAML for this is a simplified version of the Surface demo Photo.XAML.&amp;nbsp; You have a 3 Rectangles, 1 for the video, 1 for translation and 1 for rotation.&amp;nbsp; Simple, no?&amp;nbsp; Doing all this by hand gets a bit annoying since you need to nest everything properly.&lt;/P&gt;
&lt;P&gt;Here is the more interesting &lt;STRONG&gt;VideoBrush&lt;/STRONG&gt; code.&amp;nbsp; You need the name from the &lt;STRONG&gt;MediaElement &lt;/STRONG&gt;along with the how much of an offset you want the video.&amp;nbsp; Since your moving the "camera" in, this value needs to be negative.&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_10.png" mce_href="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_10.png"&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=395 alt=image src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_5.png" width=654 border=0 mce_src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/image_5.png"&gt;&lt;/A&gt; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;C#&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;delegate&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; SetActiveVideo(VideoBlock videoBlock, ActionType actionType, Point photoCenter, Point lastPosition);
&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; VideoBlock(&lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt; mediaName, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; offsetX, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; offsetY, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; rectWidth, &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; rectHeight, SetActiveVideo functionPointer)
{
    &lt;SPAN class=rem&gt;// additional code here&lt;/SPAN&gt;
    Rectangle video = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; Rectangle();
    VideoBrush vb = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; VideoBrush();
    TranslateTransform videoTransform = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; TranslateTransform();
    videoTransform.X = -1 * offsetX;
    videoTransform.Y = -1 * offsetY;

    vb.SourceName = mediaName;
    vb.Transform = videoTransform;
    vb.Stretch = Stretch.None;
    vb.AlignmentX = AlignmentX.Left;
    vb.AlignmentY = AlignmentY.Top;

    video.Width = Width;
    video.Height = Height;
    video.Fill = vb;
    &lt;SPAN class=rem&gt;// additional code here&lt;/SPAN&gt;
}&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;&lt;STRONG&gt;VB.Net&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;Public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Delegate&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt; SetActiveVideo(&lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; videoBlock &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; VideoBlock, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; actionType &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; ActionType, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; photoCenter &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; Point, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; lastPosition &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; Point)
&lt;SPAN class=kwrd&gt;Public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt; VideoBlock(&lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; mediaName &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;String&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; offsetX &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; offsetY &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; rectWidth &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; rectHeight &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; functionPointer &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; SetActiveVideo)
      &lt;SPAN class=rem&gt;' additional code here&lt;/SPAN&gt;
      &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; video &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; Rectangle = &lt;SPAN class=kwrd&gt;New&lt;/SPAN&gt; Rectangle
      &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; vb &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; VideoBrush = &lt;SPAN class=kwrd&gt;New&lt;/SPAN&gt; VideoBrush
      &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; videoTransform &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; TranslateTransform = &lt;SPAN class=kwrd&gt;New&lt;/SPAN&gt; TranslateTransform
      videoTransform.X = ((1 * offsetX)  * -1)
      videoTransform.Y = ((1 * offsetY)  * -1)
      vb.SourceName = mediaName
      vb.Transform = videoTransform
      vb.Stretch = Stretch.None
      vb.AlignmentX = AlignmentX.Left
      vb.AlignmentY = AlignmentY.Top
      video.Width = Width
      video.Height = Height
      video.Fill = vb
      &lt;SPAN class=rem&gt;' additional code here&lt;/SPAN&gt;
&lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; Sub&lt;/PRE&gt;
&lt;H3&gt;There is a mouse on my object!&lt;/H3&gt;
&lt;P&gt;So now we have our video block element prepped and ready.&amp;nbsp; There are additional events added in, but they are fairly boiler plate.&amp;nbsp; When looking at this code, you see I pass in a delegate, a function pointer if you will.&amp;nbsp; Why do I do this?&amp;nbsp; This is how the mouse position is calculated.&amp;nbsp; I bet this could be redone better, but this is how I did it.&amp;nbsp; The parent element, the canvas, has the mouse position I need to calculate proper translation and rotation, however, mouse events on the VideoBlock object will give me the mouse position only on that element.&amp;nbsp; So I may be at point 150, 150 on the screen, on the VideoBlock object, I'm actually at 10,15.&lt;/P&gt;
&lt;P&gt;Additionally, this approach allows me to move the VideoBlock to the top of the objects.&amp;nbsp; Once again, this could be done other ways, this is how I chose to do it.&lt;/P&gt;
&lt;P&gt;So on all my mouse related all boils down to doing the exact same function.&amp;nbsp; Since events are bubbled, a mouse movement on a VideoBlock is also a mouse movement on the root canvas.&lt;/P&gt;
&lt;P&gt;C#&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; root_MouseLeftButtonDown(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; sender, MouseEventArgs e)
{
    HandleMouseLeftButtonDown(ActionType.Selecting, e);
}

&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; translateControls_MouseLeftButtonDown(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; sender, MouseEventArgs e)
{
    HandleMouseLeftButtonDown(ActionType.Moving, e);
}

&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; rotateScaleControls_MouseLeftButtonDown(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; sender, MouseEventArgs e)
{
    HandleMouseLeftButtonDown(ActionType.RotatingScaling, e);
}

&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; HandleMouseLeftButtonDown(ActionType actionType, MouseEventArgs e)
{
    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (functionPointer != &lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;)
        functionPointer(&lt;SPAN class=kwrd&gt;this&lt;/SPAN&gt;, actionType,
            &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; Point(translateTransform.X + rotateTransform.CenterX,
                  translateTransform.Y + rotateTransform.CenterY), e.GetPosition(&lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;));
}&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;VB.Net&lt;/P&gt;&lt;PRE class=csharpcode&gt;    &lt;SPAN class=kwrd&gt;Private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt; root_MouseLeftButtonDown(&lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; sender &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Object&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; e &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; MouseEventArgs)
        HandleMouseLeftButtonDown(ActionType.Selecting, e)
    &lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt;
    
    &lt;SPAN class=kwrd&gt;Private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt; translateControls_MouseLeftButtonDown(&lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; sender &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Object&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; e &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; MouseEventArgs)
        HandleMouseLeftButtonDown(ActionType.Moving, e)
    &lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt;
    
    &lt;SPAN class=kwrd&gt;Private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt; rotateScaleControls_MouseLeftButtonDown(&lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; sender &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Object&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; e &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; MouseEventArgs)
        HandleMouseLeftButtonDown(ActionType.RotatingScaling, e)
    &lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt;
    
    &lt;SPAN class=kwrd&gt;Private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt; HandleMouseLeftButtonDown(&lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; actionType &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; ActionType, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; e &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; MouseEventArgs)
        &lt;SPAN class=kwrd&gt;If&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;Not&lt;/SPAN&gt; (functionPointer) &lt;SPAN class=kwrd&gt;Is&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Nothing&lt;/SPAN&gt;) &lt;SPAN class=kwrd&gt;Then&lt;/SPAN&gt;
            functionPointer(&lt;SPAN class=kwrd&gt;Me&lt;/SPAN&gt;, actionType, &lt;SPAN class=kwrd&gt;New&lt;/SPAN&gt; Point((translateTransform.X + rotateTransform.CenterX), &lt;BR&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; (translateTransform.Y + rotateTransform.CenterY)), e.GetPosition(&lt;SPAN class=kwrd&gt;Nothing&lt;/SPAN&gt;))
        &lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;If&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; Sub&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;H2&gt;You built a car out of all these parts?&lt;/H2&gt;
&lt;P&gt;So we move back from VideoBlock.xaml.cs to Page.xaml.cs&lt;/P&gt;
&lt;P&gt;We've created our primary object for painting video, lets populate it.&amp;nbsp; First, how do we know how big the media file is?&amp;nbsp; With the &lt;STRONG&gt;MediaOpened&lt;/STRONG&gt; event!&amp;nbsp; And we'll restart the video with the &lt;STRONG&gt;MediaEnded&lt;/STRONG&gt; event.&lt;/P&gt;
&lt;P&gt;So here is the full Page_Load event from Page.xaml.cs&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;C#&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Page_Loaded(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; o, EventArgs e)
{
    &lt;SPAN class=rem&gt;// Required to initialize variables&lt;/SPAN&gt;
    InitializeComponent();

    BrowserHost.Resize +=&lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; EventHandler(BrowserHost_Resize);
    media.MediaOpened += &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; EventHandler(media_MediaOpened);
    media.MediaEnded += &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; EventHandler(media_MediaEnded);
    MouseLeftButtonUp += Page_MouseLeftButtonUpOrLeave;
    MouseLeave += Page_MouseLeftButtonUpOrLeave;
    MouseMove += Page_MouseMove;

    hSliderX.Range = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; ValueRange(1, 20);
    hSliderY.Range = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; ValueRange(1, 20);
    hSliderX.ValueChanged += &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; EventHandler(slider_ValueChanged);
    hSliderY.ValueChanged += &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; EventHandler(slider_ValueChanged);

    hSliderX.SetValue(ZIndexProperty, 500);
    hSliderY.SetValue(ZIndexProperty, 500);
    sliderX.SetValue(ZIndexProperty, 500);
    sliderY.SetValue(ZIndexProperty, 500);
}&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;&lt;STRONG&gt;VB.Net&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class=csharpcode&gt;    &lt;SPAN class=kwrd&gt;Public&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt; Page_Loaded(&lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; o &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Object&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; e &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; EventArgs)
        &lt;SPAN class=rem&gt;' Required to initialize variables&lt;/SPAN&gt;
        InitializeComponent
        &lt;SPAN class=kwrd&gt;AddHandler&lt;/SPAN&gt; BrowserHost.Resize, &lt;SPAN class=kwrd&gt;AddressOf&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Me&lt;/SPAN&gt;.BrowserHost_Resize
        &lt;SPAN class=kwrd&gt;AddHandler&lt;/SPAN&gt; media.MediaOpened, &lt;SPAN class=kwrd&gt;AddressOf&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Me&lt;/SPAN&gt;.media_MediaOpened
        &lt;SPAN class=kwrd&gt;AddHandler&lt;/SPAN&gt; media.MediaEnded, &lt;SPAN class=kwrd&gt;AddressOf&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Me&lt;/SPAN&gt;.media_MediaEnded
        MouseLeftButtonUp = (MouseLeftButtonUp + Page_MouseLeftButtonUpOrLeave)
        MouseLeave = (MouseLeave + Page_MouseLeftButtonUpOrLeave)
        MouseMove = (MouseMove + Page_MouseMove)
        hSliderX.Range = &lt;SPAN class=kwrd&gt;New&lt;/SPAN&gt; ValueRange(1, 20)
        hSliderY.Range = &lt;SPAN class=kwrd&gt;New&lt;/SPAN&gt; ValueRange(1, 20)
        &lt;SPAN class=kwrd&gt;AddHandler&lt;/SPAN&gt; hSliderX.ValueChanged, &lt;SPAN class=kwrd&gt;AddressOf&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Me&lt;/SPAN&gt;.slider_ValueChanged
        &lt;SPAN class=kwrd&gt;AddHandler&lt;/SPAN&gt; hSliderY.ValueChanged, &lt;SPAN class=kwrd&gt;AddressOf&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Me&lt;/SPAN&gt;.slider_ValueChanged
        hSliderX.SetValue(ZIndexProperty, 500)
        hSliderY.SetValue(ZIndexProperty, 500)
        sliderX.SetValue(ZIndexProperty, 500)
        sliderY.SetValue(ZIndexProperty, 500)
    &lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; Sub&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;So now that we have the media loaded, we can use the media.NaturalVideoWidth and media.NaturalVideoHeight properties to find out exactly how big the video is!&amp;nbsp; I have a function that is fired off when the page is first loaded or a slider value has changed.&amp;nbsp; This is how we chop it up.&lt;/P&gt;
&lt;P&gt;&lt;IMG style="MARGIN: 0px 0px 0px 5px" height=180 alt=mince_garlic[1] src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/mince_garlic1.jpg" width=240 border=0 mce_src="http://www.coding4fun.net/images/SilverlightsVideoPuzzle_E3FF/mince_garlic1.jpg"&gt; &lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;C#&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; prepVideoObjects()
{
    &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; totalPhotosX = (&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt;)hSliderX.Value;
    &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; totalPhotosY = (&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt;)hSliderY.Value;

    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (lastX != totalPhotosX || lastY != totalPhotosY)
    {
        lastX = totalPhotosX;
        lastY = totalPhotosY;

        sliderX.Text = &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;.Format(&lt;SPAN class=str&gt;"X ({0}):"&lt;/SPAN&gt;, totalPhotosX.ToString(&lt;SPAN class=str&gt;"D2"&lt;/SPAN&gt;));
        sliderY.Text = &lt;SPAN class=kwrd&gt;string&lt;/SPAN&gt;.Format(&lt;SPAN class=str&gt;"Y ({0}):"&lt;/SPAN&gt;, totalPhotosY.ToString(&lt;SPAN class=str&gt;"D2"&lt;/SPAN&gt;));

        &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; rectWidth = (&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt;)Math.Floor(media.NaturalVideoWidth / totalPhotosX);
        &lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; rectHeight = (&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt;)Math.Floor(media.NaturalVideoHeight / totalPhotosY);
        Random random = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; Random();

        &lt;SPAN class=rem&gt;// remove all old videoblocks&lt;/SPAN&gt;
        &lt;SPAN class=kwrd&gt;for&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; i = Children.Count - 1; i &amp;gt; 0; i--)
        {
            &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (Children[i].GetType() == &lt;SPAN class=kwrd&gt;typeof&lt;/SPAN&gt;(VideoBlock))
                Children.RemoveAt(i);
        }

        &lt;SPAN class=kwrd&gt;for&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; x = 0; x &amp;lt; totalPhotosX; x++)
        {
            &lt;SPAN class=kwrd&gt;for&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;int&lt;/SPAN&gt; y = 0; y &amp;lt; totalPhotosY; y++)
            {
                VideoBlock vb = &lt;SPAN class=kwrd&gt;new&lt;/SPAN&gt; VideoBlock(media.Name, x * rectWidth, y * rectHeight, rectWidth, rectHeight, SetActivePhoto);
                shuffle(vb, random);
                Children.Add(vb);
            }
        }
    }
}&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;&lt;STRONG&gt;VB.Net&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;Private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt; prepVideoObjects()
        &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; totalPhotosX &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt; = &lt;SPAN class=kwrd&gt;CType&lt;/SPAN&gt;(hSliderX.Value,&lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt;)
        &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; totalPhotosY &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt; = &lt;SPAN class=kwrd&gt;CType&lt;/SPAN&gt;(hSliderY.Value,&lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt;)
        &lt;SPAN class=kwrd&gt;If&lt;/SPAN&gt; ((lastX &amp;lt;&amp;gt; totalPhotosX)  _
                    &lt;SPAN class=kwrd&gt;OrElse&lt;/SPAN&gt; (lastY &amp;lt;&amp;gt; totalPhotosY)) &lt;SPAN class=kwrd&gt;Then&lt;/SPAN&gt;
            lastX = totalPhotosX
            lastY = totalPhotosY
            sliderX.Text = &lt;SPAN class=kwrd&gt;String&lt;/SPAN&gt;.Format(&lt;SPAN class=str&gt;"X ({0}):"&lt;/SPAN&gt;, totalPhotosX.ToString(&lt;SPAN class=str&gt;"D2"&lt;/SPAN&gt;))
            sliderY.Text = &lt;SPAN class=kwrd&gt;String&lt;/SPAN&gt;.Format(&lt;SPAN class=str&gt;"Y ({0}):"&lt;/SPAN&gt;, totalPhotosY.ToString(&lt;SPAN class=str&gt;"D2"&lt;/SPAN&gt;))
            &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; rectWidth &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt; = &lt;SPAN class=kwrd&gt;CType&lt;/SPAN&gt;(Math.Floor((media.NaturalVideoWidth / totalPhotosX)),&lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt;)
            &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; rectHeight &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt; = &lt;SPAN class=kwrd&gt;CType&lt;/SPAN&gt;(Math.Floor((media.NaturalVideoHeight / totalPhotosY)),&lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt;)
            &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; random &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; Random = &lt;SPAN class=kwrd&gt;New&lt;/SPAN&gt; Random
            &lt;SPAN class=rem&gt;' remove all old videoblocks&lt;/SPAN&gt;
            &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; i &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt; = (Children.Count - 1)
            &lt;SPAN class=kwrd&gt;Do&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;While&lt;/SPAN&gt; (i &amp;gt; 0)
                &lt;SPAN class=kwrd&gt;If&lt;/SPAN&gt; (Children(i).&lt;SPAN class=kwrd&gt;GetType&lt;/SPAN&gt; = &lt;SPAN class=kwrd&gt;GetType&lt;/SPAN&gt;(VideoBlock)) &lt;SPAN class=kwrd&gt;Then&lt;/SPAN&gt;
                    Children.RemoveAt(i)
                &lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;If&lt;/SPAN&gt;
                i = (i - 1)
            &lt;SPAN class=kwrd&gt;Loop&lt;/SPAN&gt;
            &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; x &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt; = 0
            &lt;SPAN class=kwrd&gt;Do&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;While&lt;/SPAN&gt; (x &amp;lt; totalPhotosX)
                &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; y &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Integer&lt;/SPAN&gt; = 0
                &lt;SPAN class=kwrd&gt;Do&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;While&lt;/SPAN&gt; (y &amp;lt; totalPhotosY)
                    &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; vb &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; VideoBlock = &lt;SPAN class=kwrd&gt;New&lt;/SPAN&gt; VideoBlock(media.Name, (x * rectWidth), (y * rectHeight), rectWidth, rectHeight, SetActivePhoto)
                    shuffle(vb, random)
                    Children.Add(vb)
                    y = (y + 1)
                &lt;SPAN class=kwrd&gt;Loop&lt;/SPAN&gt;
                x = (x + 1)
            &lt;SPAN class=kwrd&gt;Loop&lt;/SPAN&gt;
        &lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;If&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt;&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;Last but not least, lets see how the mouse movements are handled on the page.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;C#&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class=csharpcode&gt;&lt;SPAN class=kwrd&gt;private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;void&lt;/SPAN&gt; Page_MouseMove(&lt;SPAN class=kwrd&gt;object&lt;/SPAN&gt; sender, MouseEventArgs e)
{
    &lt;SPAN class=kwrd&gt;if&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt; != activeVideoBlock)
    {
        &lt;SPAN class=rem&gt;// Perform the appropriate transform on the active photo&lt;/SPAN&gt;
        Point position = e.GetPosition(&lt;SPAN class=kwrd&gt;null&lt;/SPAN&gt;);
        &lt;SPAN class=kwrd&gt;switch&lt;/SPAN&gt; (currentActionType)
        {
            &lt;SPAN class=kwrd&gt;case&lt;/SPAN&gt; VideoBlock.ActionType.Moving:
                &lt;SPAN class=rem&gt;// Move it by the amount of the mouse move&lt;/SPAN&gt;
                activeVideoBlock.Translate(position.X - currentLastPosition.X, position.Y - currentLastPosition.Y);
                &lt;SPAN class=kwrd&gt;break&lt;/SPAN&gt;;
            &lt;SPAN class=kwrd&gt;case&lt;/SPAN&gt; VideoBlock.ActionType.RotatingScaling:
                &lt;SPAN class=rem&gt;// Rotate it according to the angle the mouse moved around the photo's center&lt;/SPAN&gt;
                &lt;SPAN class=kwrd&gt;double&lt;/SPAN&gt; radiansToDegrees = 360 / (2 * Math.PI);
                &lt;SPAN class=kwrd&gt;double&lt;/SPAN&gt; lastAngle = Math.Atan2(currentLastPosition.Y - currentVideoCenter.Y, currentLastPosition.X - currentVideoCenter.X) * radiansToDegrees;
                &lt;SPAN class=kwrd&gt;double&lt;/SPAN&gt; currentAngle = Math.Atan2(position.Y - currentVideoCenter.Y, position.X - currentVideoCenter.X) * radiansToDegrees;
                activeVideoBlock.Rotate(currentAngle - lastAngle);

                &lt;SPAN class=kwrd&gt;break&lt;/SPAN&gt;;
        }
        currentLastPosition = position;
    }
}&lt;/PRE&gt;
&lt;STYLE type=text/css&gt;
.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }&lt;/STYLE&gt;

&lt;P&gt;&lt;STRONG&gt;VB.Net&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE class=csharpcode&gt;    &lt;SPAN class=kwrd&gt;Private&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Sub&lt;/SPAN&gt; Page_MouseMove(&lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; sender &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Object&lt;/SPAN&gt;, &lt;SPAN class=kwrd&gt;ByVal&lt;/SPAN&gt; e &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; MouseEventArgs)
        &lt;SPAN class=kwrd&gt;If&lt;/SPAN&gt; (&lt;SPAN class=kwrd&gt;Not&lt;/SPAN&gt; (activeVideoBlock) &lt;SPAN class=kwrd&gt;Is&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Nothing&lt;/SPAN&gt;) &lt;SPAN class=kwrd&gt;Then&lt;/SPAN&gt;
            &lt;SPAN class=rem&gt;' Perform the appropriate transform on the active photo&lt;/SPAN&gt;
            &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; position &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; Point = e.GetPosition(&lt;SPAN class=kwrd&gt;Nothing&lt;/SPAN&gt;)
            &lt;SPAN class=kwrd&gt;Select&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Case&lt;/SPAN&gt; (currentActionType)
                &lt;SPAN class=kwrd&gt;Case&lt;/SPAN&gt; VideoBlock.ActionType.Moving
                    &lt;SPAN class=rem&gt;' Move it by the amount of the mouse move&lt;/SPAN&gt;
                    activeVideoBlock.Translate((position.X - currentLastPosition.X), (position.Y - currentLastPosition.Y))
                &lt;SPAN class=kwrd&gt;Case&lt;/SPAN&gt; VideoBlock.ActionType.RotatingScaling
                    &lt;SPAN class=rem&gt;' Rotate it according to the angle the mouse moved around the photo's center&lt;/SPAN&gt;
                    &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; radiansToDegrees &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Double&lt;/SPAN&gt; = (360 / (2 * Math.PI))
                    &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; lastAngle &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Double&lt;/SPAN&gt; = (Math.Atan2((currentLastPosition.Y - currentVideoCenter.Y), (currentLastPosition.X - currentVideoCenter.X)) * radiansToDegrees)
                    &lt;SPAN class=kwrd&gt;Dim&lt;/SPAN&gt; currentAngle &lt;SPAN class=kwrd&gt;As&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Double&lt;/SPAN&gt; = (Math.Atan2((position.Y - currentVideoCenter.Y), (position.X - currentVideoCenter.X)) * radiansToDegrees)
                    activeVideoBlock.Rotate((currentAngle - lastAngle))
            &lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;Select&lt;/SPAN&gt;
            currentLastPosition = position
        &lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; &lt;SPAN class=kwrd&gt;If&lt;/SPAN&gt;
    &lt;SPAN class=kwrd&gt;End&lt;/SPAN&gt; Sub&lt;/PRE&gt;
&lt;H2&gt;Wrapping it up&lt;/H2&gt;
&lt;P&gt;So as you can see, Silverlight is pretty powerful once you figure out how to tame it.&amp;nbsp; I used example base code and modified it to suit my own needs to dynamically alter a video in real time.&amp;nbsp; There are a few code tweaks that could happen to improve this code and I'm betting with some additional effort, one could remove the delegate.&amp;nbsp; In addition, you could add in edge detection code and a timer to make this into a true video puzzle game.&amp;nbsp; This was a pet project I worked on while I was at the airport.&amp;nbsp; This demo can be downgraded to Silverlight 1.0 also.&amp;nbsp; I don't believe anything I did was really Silverlight 1.1 (now 2.0) only.&lt;/P&gt;
&lt;P&gt;&lt;STRONG&gt;Clint's Bio:&lt;/STRONG&gt;&lt;/P&gt;
&lt;P&gt;Clint is an academic developer evangelist for Microsoft.&amp;nbsp; His two primary development languages are C# and JavaScript. He has built a &lt;A href="http://msdn.microsoft.com/coding4fun/coolapplications/disco/default.aspx" mce_href="http://msdn.microsoft.com/coding4fun/coolapplications/disco/default.aspx"&gt;Disco Dance Floor&lt;/A&gt; too! In his off time, he whips up other random weird projects and does twenty something activities with his friends.&amp;nbsp; His next two big projects are an automated bartender and a skateboard segway.&amp;nbsp; Clint’s blog is &lt;A href="http://betterthaneveryone.com/" mce_href="http://betterthaneveryone.com/"&gt;betterthaneveryone.com&lt;/A&gt; and can be emailed at &lt;A href="mailto:crutkas@microsoft.com" mce_href="mailto:crutkas@microsoft.com"&gt;crutkas@microsoft.com&lt;/A&gt; if you have any question.&lt;/P&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=7163484" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/media/default.aspx">media</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/mash+up/default.aspx">mash up</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/web+miscellaneous/default.aspx">web miscellaneous</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/puzzle/default.aspx">puzzle</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/web/default.aspx">web</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/Silverlight/default.aspx">Silverlight</category></item><item><title>Silverlight 8-Ball</title><link>http://blogs.msdn.com/coding4fun/archive/2007/09/19/5002772.aspx</link><pubDate>Thu, 20 Sep 2007 03:03:50 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:5002772</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>18</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/5002772.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=5002772</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=5002772</wfw:comment><description>&lt;span id="c4fmetadata"&gt; &lt;table cellspacing="0" cellpadding="1" width="100%" border="0"&gt; &lt;tbody&gt; &lt;tr class="entry_overview"&gt; &lt;td width="50"&gt;&lt;img height="48" src="http://employees.claritycon.com/jpetersen/Silverlight8Ball/8BallSmall.png" width="48"&gt;&lt;/td&gt; &lt;td&gt;&lt;span class="entry_description"&gt;In this article, I will discuss how I have built a 2 player 8-Ball game in Silverlight (&lt;a href="http://employees.claritycon.com/jpetersen/Silverlight8Ball/"&gt;play here&lt;/a&gt;). I will explain how I used the Expression tools to design the graphics and various .NET techniques to enable user control and game animation. &lt;/span&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td colspan="2"&gt; &lt;div class="entry_author"&gt;Justin Petersen&lt;/div&gt; &lt;div class="entry_company"&gt;&lt;a href="http://www.claritycon.com/coding4fun"&gt;Coding4Fun at Clarity&lt;/a&gt;&lt;/div&gt;&lt;br&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Difficulty: &lt;/b&gt;&lt;span class="entry_details_input"&gt;Intermediate&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Time Required:&lt;/b&gt; &lt;span class="entry_details_input"&gt;6-10 hours&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Cost: &lt;/b&gt;&lt;span class="entry_details_input"&gt;Free&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Software: &lt;/b&gt;&lt;span class="entry_details_input"&gt;&lt;a href="http://msdn2.microsoft.com/en-us/vstudio/"&gt;Visual Studio 2008 Beta 2&lt;/a&gt;, &lt;a href="http://msdn2.microsoft.com/en-us/silverlight/"&gt;Silverlight 1.1 Alpha Refresh&lt;/a&gt;, &lt;a href="http://www.microsoft.com/expression/products/overview.aspx?key=design"&gt;Expression Design&lt;/a&gt;, &lt;a href="http://www.microsoft.com/expression/products/features.aspx?key=blend2preview"&gt;Expression Blend 2 Preview&lt;/a&gt; &lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Hardware: &lt;/b&gt;&lt;span class="entry_details_input"&gt;&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Download: &lt;/b&gt;&lt;a href="http://channel9.msdn.com/Photos/ZippedFiles/342985_Silverlight8Ball.zip"&gt;Download&lt;/a&gt; &lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/span&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;In this article, I will discuss how I have built a 2 player 8-Ball game in Silverlight (&lt;a href="http://employees.claritycon.com/jpetersen/Silverlight8Ball/"&gt;play here&lt;/a&gt;). I will explain how I used the Expression tools to design the graphics and various .NET techniques to enable user control and game animation.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The following components must be implemented to complete this game: &lt;/p&gt; &lt;ol&gt; &lt;li&gt;Graphics (pool table, pool ball, and pool stick)  &lt;li&gt;Vector animation and collision physics  &lt;li&gt;User interaction&amp;nbsp;  &lt;li&gt;Game state and control&lt;/li&gt;&lt;/ol&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Silverlight8Ball_D983/Silverlight8Ball18.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="335" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Silverlight8Ball_D983/Silverlight8Ball_thumb12.png" width="439" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Before I continue, I’d like to point out that I did not originate all of the code and XAML for this solution. I came up with the idea of creating a Silverlight 8-Ball game after stumbling upon a 2-D “bouncing bubble” animation here: &lt;a href="http://www.bubblemark.com/"&gt;http://www.bubblemark.com/&lt;/a&gt;&amp;nbsp;created by Alexey Gavrilov.&amp;nbsp; &lt;/p&gt; &lt;p&gt;The original intent for this solution was to compare the performance of the bouncing bubbles across&amp;nbsp;various platforms.&amp;nbsp; I found this very useful, but was personally interested in making something fun and interactive out of it.&amp;nbsp; &lt;/p&gt; &lt;h1&gt;&lt;/h1&gt; &lt;h2&gt;&lt;b&gt;Getting Started&lt;/b&gt;&lt;/h2&gt; &lt;h5&gt;&lt;strong&gt;Prerequisites &lt;/strong&gt;&lt;/h5&gt; &lt;p&gt;The following tools were used to implement this solution:  &lt;ul&gt; &lt;li&gt;Visual Studio 2008 Beta 2  &lt;li&gt;Silverlight 1.1 Alpha Refresh&amp;nbsp;  &lt;li&gt;Expression Design  &lt;li&gt;Expression Blend&lt;/li&gt;&lt;/ul&gt; &lt;h5&gt;&lt;strong&gt;Learning more about game development&lt;/strong&gt; &lt;/h5&gt; &lt;p&gt;If you'd like to learn more about game development, I found a number Coding4Fun posts&amp;nbsp;under Gaming helpful.&amp;nbsp; In particular,&amp;nbsp;the&amp;nbsp;&lt;a href="http://blogs.msdn.com/coding4fun/archive/2007/02/20/1727608.aspx"&gt;2D Game Primer&lt;/a&gt;&amp;nbsp;by "ZMan" gives a good overview of the basics (e.g. GameLoop, Sprites, etc.)&lt;/p&gt; &lt;h2&gt;&lt;b&gt;Graphics&lt;/b&gt; &lt;/h2&gt; &lt;p&gt;I am not much of a&amp;nbsp;graphic&amp;nbsp;designer.&amp;nbsp; In fact, I've spent the majority of my career designing and implementing line of business apps for enterprise customers (typically not a very graphically intensive task).&amp;nbsp; So I believe it is a decent testament to the&amp;nbsp;effectiveness of the Microsoft Expression suite that I could, in short order, create the graphics for this game.&amp;nbsp; &lt;/p&gt; &lt;p&gt;I used Expression Design to build the graphics of the pool table.&amp;nbsp; Modeling my design&amp;nbsp;after the standard dimension of a 9 foot billiards table,&amp;nbsp;I drew the main structure&amp;nbsp;as a rectangle with rounded corners.&amp;nbsp;&amp;nbsp;I drew a smaller green rectangle centered over it for the playing surface (of course following standard dimensions).&amp;nbsp; Next, I created 6 black circles placed one level behind the playing surface to give the impression of pockets.&amp;nbsp; Lastly, I added the wood texture to the outside rectangle (which was super easy as there is a set of wood textures available by default), and drew a simple rounded rectangle beneath the table to serve as a status bar.&amp;nbsp; &lt;/p&gt; &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Silverlight8Ball_D983/image03.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="272" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Silverlight8Ball_D983/image0_thumb1.png" width="437" border="0"&gt;&lt;/a&gt;  &lt;p&gt;I also created the graphics for my pool stick using Expression Design.&amp;nbsp; This consisted of a few tapered polygons and 2 half circles for the butt and tip.  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Silverlight8Ball_D983/image011.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="229" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Silverlight8Ball_D983/image0_thumb5.png" width="433" border="0"&gt;&lt;/a&gt;  &lt;p&gt;After exporting the associated XAML, I imported each element into my project.&amp;nbsp; From here, I could view and refine the design through a scaled down visual editor or the associated XAML.  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Silverlight8Ball_D983/image021.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="271" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Silverlight8Ball_D983/image0_thumb9.png" width="433" border="0"&gt;&lt;/a&gt;  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Silverlight8Ball_D983/image024.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="270" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Silverlight8Ball_D983/image0_thumb10.png" width="433" border="0"&gt;&lt;/a&gt;  &lt;p&gt;Lastly, I inspected the&amp;nbsp;XAML markup for the pool ball I reused from Alexey's Bubblemark solution.&amp;nbsp; I needed to understand the properties of this object so that I could modify the color of the balls later on.  &lt;p&gt;&lt;a href="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Silverlight8Ball_D983/image018.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="272" src="http://blogs.msdn.com/blogfiles/coding4fun/WindowsLiveWriter/Silverlight8Ball_D983/image0_thumb8.png" width="436" border="0"&gt;&lt;/a&gt;  &lt;h2&gt;&lt;b&gt;Vector Animation and Collision Physics&lt;/b&gt; &lt;/h2&gt; &lt;p&gt;The root of Silverlight8Ball is a Storyboard (x:Name=”GameLoop”) that acts as a triggering mechanism for determining ball velocity, direction, and redirection due to collision. Whereas some Storyboards are implemented with predetermined paths and timelines directly in XAML, the action taken at each tick must be determined dynamically in this game. So we simply set the duration to 00:00:0, and handle the Completed event to trigger our positioning logic. This design effectively creates what game developers call a “Game Loop” that triggers continuous processing to determine application state.  &lt;p&gt;The resulting “GameLoop_Completedhandler” becomes the root processing agent for all of the game’s ball movement logic.&amp;nbsp;&amp;nbsp;  &lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt; &lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt; &lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; GameLoop_Completed(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (m_ActionState)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; m_ActionStates.BallsMoving:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;             &lt;span style="color: #008000"&gt;// prep&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;             List&amp;lt;Ball&amp;gt; removeList = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;Ball&amp;gt;();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; someBallsAreMoving = &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;             &lt;span style="color: #008000"&gt;// move each ball&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (Ball ball &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; m_GameBalls)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;             {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;                 ball.Move();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ball.InPocket) removeList.Add(ball);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;else&lt;/span&gt; &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (ball.IsMoving) someBallsAreMoving = &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;             }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;             &lt;span style="color: #008000"&gt;// store balls sunk on shot and update ui &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt; (Ball ball &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; removeList)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt;             {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  22:&lt;/span&gt;                 sunkBalls.Add(ball);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  23:&lt;/span&gt;                 RemoveBall(ball);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  24:&lt;/span&gt;             }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  25:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  26:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (someBallsAreMoving)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  27:&lt;/span&gt;             {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  28:&lt;/span&gt;                 &lt;span style="color: #008000"&gt;// update vectors for ball collisions&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  29:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = 0; i &amp;lt; m_GameBalls.Count; i++)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  30:&lt;/span&gt;                 {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  31:&lt;/span&gt;                     &lt;span style="color: #0000ff"&gt;for&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; j = i + 1; j &amp;lt; m_GameBalls.Count; j++)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  32:&lt;/span&gt;                     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  33:&lt;/span&gt;                         m_GameBalls[i].DoCollide(m_GameBalls[j]);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  34:&lt;/span&gt;                     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  35:&lt;/span&gt;                 }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  36:&lt;/span&gt;             }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  37:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  38:&lt;/span&gt;             {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  39:&lt;/span&gt;                 &lt;span style="color: #008000"&gt;// determine shot results&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  40:&lt;/span&gt;                 ShotResults results = EvaluateShot();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  41:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  42:&lt;/span&gt;                 &lt;span style="color: #008000"&gt;// apply state and ui changes&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  43:&lt;/span&gt;                 UpdateGameState(results);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  44:&lt;/span&gt;             }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  45:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  46:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  47:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  48:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  49:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// restart the storyboard&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  50:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (m_IsRunning)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  51:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  52:&lt;/span&gt;         GameLoop.Begin();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  53:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  54:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  55:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; GameLoop_Completed(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; EventArgs)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Select&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; m_ActionState&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; m_ActionStates.BallsMoving&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;             &lt;span style="color: #008000"&gt;' prep&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; removeList &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(Of Ball) = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; List(Of Ball)()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; someBallsAreMoving &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Boolean&lt;/span&gt; = &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;             &lt;span style="color: #008000"&gt;' move each ball&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Each&lt;/span&gt; ball &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Ball &lt;span style="color: #0000ff"&gt;In&lt;/span&gt; m_GameBalls&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;                 ball.Move()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; ball.InPocket &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;                     removeList.Add(ball)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;ElseIf&lt;/span&gt; ball.IsMoving &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;                     someBallsAreMoving = &lt;span style="color: #0000ff"&gt;True&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt; ball&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt;             &lt;span style="color: #008000"&gt;' store balls sunk on shot and update ui &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  22:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Each&lt;/span&gt; ball &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Ball &lt;span style="color: #0000ff"&gt;In&lt;/span&gt; removeList&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  23:&lt;/span&gt;                 sunkBalls.Add(ball)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  24:&lt;/span&gt;                 RemoveBall(ball)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  25:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt; ball&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  26:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  27:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; someBallsAreMoving &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  28:&lt;/span&gt;                 &lt;span style="color: #008000"&gt;' update vectors for ball collisions&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  29:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; i &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; = 0 &lt;span style="color: #0000ff"&gt;To&lt;/span&gt; m_GameBalls.Count - 1&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  30:&lt;/span&gt;                     &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; j &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; = i + 1 &lt;span style="color: #0000ff"&gt;To&lt;/span&gt; m_GameBalls.Count - 1&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  31:&lt;/span&gt;                         m_GameBalls(i).DoCollide(m_GameBalls(j))&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  32:&lt;/span&gt;                     &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt; j&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  33:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt; i&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  34:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  35:&lt;/span&gt;                 &lt;span style="color: #008000"&gt;' determine shot results&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  36:&lt;/span&gt;                 &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; results &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ShotResults = EvaluateShot()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  37:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  38:&lt;/span&gt;                 &lt;span style="color: #008000"&gt;' apply state and ui changes&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  39:&lt;/span&gt;                 UpdateGameState(results)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  40:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  41:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  42:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Select&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  43:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  44:&lt;/span&gt;     &lt;span style="color: #008000"&gt;' restart the storyboard&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  45:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; m_IsRunning &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  46:&lt;/span&gt;         GameLoop.Begin()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  47:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  48:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  49:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The above code snippets demonstrate the full functionality of our GameLoop.&amp;nbsp; However, the primary animation and collision logic are handled by "ball.Move();" and "m_GameBalls[i].DoCollide(m_GameBalls[j]);" lines&amp;nbsp;(in C# example).&amp;nbsp; The Move() function of each ball applies its current vector (i.e. x and y "velocities") to determine its next position and updates the ball's&amp;nbsp;UI element coordinates.&amp;nbsp; Once the ball is advanced, the DoCollide function checks if two balls have collided.&amp;nbsp; If so, their vectors are adjusted accordingly.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;bool&lt;/span&gt; DoCollide(Ball b)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// calculate some vectors &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; dx = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._x - b._x;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; dy = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._y - b._y;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; dvx = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._vx - b._vx;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; dvy = &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._vy - b._vy;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; distance2 = dx * dx + dy * dy;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;     &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (Math.Abs(dx) &amp;gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._d || Math.Abs(dy) &amp;gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._d)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (distance2 &amp;gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._d2)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// make absolutely elastic collision&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; mag = dvx * dx + dvy * dy;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;     &lt;span style="color: #008000"&gt;// test that balls move towards each other    &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (mag &amp;gt; 0)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  22:&lt;/span&gt;     mag /= distance2;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  23:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  24:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; delta_vx = dx * mag;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  25:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; delta_vy = dy * mag;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  26:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  27:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._vx -= delta_vx;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  28:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._vy -= delta_vy;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  29:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  30:&lt;/span&gt;     b._vx += delta_vx;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  31:&lt;/span&gt;     b._vy += delta_vy;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  32:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  33:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  34:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; DoCollide(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; b &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Ball) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Boolean&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;     &lt;span style="color: #008000"&gt;' calculate some vectors &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; dx &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt; = &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._x - b._x&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; dy &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt; = &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._y - b._y&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; dvx &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt; = &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._vx - b._vx&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; dvy &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt; = &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._vy - b._vy&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; distance2 &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt; = dx * dx + dy * dy&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; Math.Abs(dx) &amp;gt; &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._d &lt;span style="color: #0000ff"&gt;OrElse&lt;/span&gt; Math.Abs(dy) &amp;gt; &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._d &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; distance2 &amp;gt; &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._d2 &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;     &lt;span style="color: #008000"&gt;' make absolutely elastic collision&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; mag &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt; = dvx * dx + dvy * dy&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;     &lt;span style="color: #008000"&gt;' test that balls move towards each other    &lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; mag &amp;gt; 0 &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  22:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  23:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  24:&lt;/span&gt;     mag /= distance2&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  25:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  26:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; delta_vx &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt; = dx * mag&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  27:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; delta_vy &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt; = dy * mag&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  28:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  29:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._vx -= delta_vx&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  30:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._vy -= delta_vy&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  31:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  32:&lt;/span&gt;     b._vx += delta_vx&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  33:&lt;/span&gt;     b._vy += delta_vy&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  34:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  35:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;True&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  36:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Function&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2&gt;User Interaction&amp;nbsp;&lt;/h2&gt;
&lt;p&gt;While the GameLoop Storyboard does a good job at managing ball movement, I didn't think it was the&amp;nbsp;best option for handling pool stick&amp;nbsp;and&amp;nbsp;q-ball control.&amp;nbsp; During times of user control (stick aiming and q-ball "ball in hand"), I chose to use mouse movement and&amp;nbsp;click events to determine object position and angle.&amp;nbsp; I created my own enumeration to manage switching between ball movement and user control&amp;nbsp;states.&amp;nbsp; The rest involves some simple statistics and Silverlight XAML transformations. 
&lt;h5&gt;&lt;strong&gt;Pool Stick Aiming and Ball-In-Hand&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;During a scratch, the MouseMove event allows the affect of moving the q-ball for placement.&amp;nbsp; During aiming, it allows the user to rotate the poolstick around the q-ball.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Page_MouseMove(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, MouseEventArgs e)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     m_MousePoint = e.GetPosition(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (m_ActionState)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; m_ActionStates.Scratch:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;             m_QBall.MoveAbsolute(m_MousePoint.X, m_MousePoint.Y);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; m_ActionStates.Aiming:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;             m_PoolStick.Rotate(m_MousePoint.X, m_MousePoint.Y, m_QBall.BallCenterX, m_QBall.BallCenterY);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;     }      &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;     &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; Page_MouseMove(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; MouseEventArgs)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     m_MousePoint = e.GetPosition(&lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Select&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; m_ActionState&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; m_ActionStates.Scratch&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;             m_QBall.MoveAbsolute(m_MousePoint.X, m_MousePoint.Y)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; m_ActionStates.Aiming&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;             m_PoolStick.Rotate(m_MousePoint.X, m_MousePoint.Y, m_QBall.BallCenterX, m_QBall.BallCenterY)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Select&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h5&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/h5&gt;
&lt;h5&gt;&lt;strong&gt;The RotateTransform Rocks&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;The Silverlight RotateTranform is very powerful in this case.&amp;nbsp; It allows me to simply rotate the pool stick object around a center point (the center of the q-ball) using a relative angle between the mouse point and the ball.&amp;nbsp; 
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Rotate (&lt;span style="color: #0000ff"&gt;double&lt;/span&gt; mouseX, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; mouseY, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; ballX, &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; ballY)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; vx = ballX - mouseX;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; vy = ballY - mouseY;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;     radians = Math.Atan2(vy, vx);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;double&lt;/span&gt; angle = radians * (180/Math.PI);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;     &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;     rootCanvas.RenderTransform = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; RotateTransform &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;     { &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;         CenterX = Model.stickBuffer, &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;         CenterY = Model.stickHeight/2, &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;         Angle = angle &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;     };&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; Rotate(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; mouseX &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; mouseY &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; ballX &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; ballY &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt;)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; vx &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt; = ballX - mouseX&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; vy &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt; = ballY - mouseY&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     radians = Math.Atan2(vy, vx)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; angle &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Double&lt;/span&gt; = radians * (180 / Math.PI)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; transform &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; RotateTransform = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; RotateTransform()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;     transform.CenterX = Model.stickBuffer&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;     transform.CenterY = Model.stickHeight / 2&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;     transform.Angle = angle&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;     rootCanvas.RenderTransform = transform&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre&gt;&lt;strong&gt;&lt;/strong&gt;&amp;nbsp;&lt;/pre&gt;
&lt;h5&gt;&lt;strong&gt;Power Control and Q-Ball Placement&lt;/strong&gt;&lt;/h5&gt;
&lt;p&gt;Based on the ActionState, the mouse up and mouse down events manage user interaction during power adjustment and q-ball placement.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Page_MouseLeftButtonUp(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, MouseEventArgs e)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_ActionState == m_ActionStates.AdjustingPower)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;         m_QBall.Strike(m_PoolStick.power, m_PoolStick.radians);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;         m_PoolStick.StopPowerMovement();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Children.Remove(m_PoolStick);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_ActionState = m_ActionStates.BallsMoving;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt; }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; Page_MouseLeftButtonDown(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, MouseEventArgs e)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (m_ActionState)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; m_ActionStates.Aiming:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;             m_PoolStick.StartPowerMovement();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.m_ActionState = m_ActionStates.AdjustingPower;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; m_ActionStates.Scratch:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  22:&lt;/span&gt;             ResetPoolStick();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  23:&lt;/span&gt;             m_ActionState = m_ActionStates.Aiming;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  24:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  25:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  26:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; Page_MouseLeftButtonUp(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; MouseEventArgs)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.m_ActionState = m_ActionStates.AdjustingPower &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;         m_QBall.Strike(m_PoolStick.power, m_PoolStick.radians)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;         m_PoolStick.StopPowerMovement()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.Children.Remove(m_PoolStick)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.m_ActionState = m_ActionStates.BallsMoving&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; Page_MouseLeftButtonDown(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; MouseEventArgs)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Select&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; m_ActionState&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; m_ActionStates.Aiming&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;             m_PoolStick.StartPowerMovement()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.m_ActionState = m_ActionStates.AdjustingPower&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; m_ActionStates.Scratch&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;             ResetPoolStick()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;             m_ActionState = m_ActionStates.Aiming&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Select&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;pre&gt;&amp;nbsp;&lt;/pre&gt;
&lt;h2&gt;Game State and Control&lt;/h2&gt;
&lt;p&gt;The final component to this application is the "business rules" behind the game.&amp;nbsp; A game of 8-Ball is governed by the results of each player's shot.&amp;nbsp; Whether that shot ends the game or whose shot it is next is based on what balls are sunk.&amp;nbsp; 
&lt;p&gt;I created another enumeration for ShotResults which defines each potential outcome: GoAgain, NextPlayer, Scratch, ScratchOnEight, PrematureEightBall, and Win.&amp;nbsp; 
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; UpdateGameState(ShotResults results)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt; {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; resultText = &lt;span style="color: #006080"&gt;""&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     &lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;switch&lt;/span&gt; (results)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;     {&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;         &lt;span style="color: #008000"&gt;// update game states&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; ShotResults.PrematureEightBall:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; ShotResults.ScratchOnEight:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;             resultText = ProcessGameEnd(&lt;span style="color: #0000ff"&gt;false&lt;/span&gt;, results);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;             m_ActionState = m_ActionStates.GameOver;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; ShotResults.NextPlayer:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;             resultText = &lt;span style="color: #006080"&gt;"Player looses turn"&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;             ChangeCurrentPlayer();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;             ResetPoolStick();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;             m_ActionState = m_ActionStates.Aiming;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; ShotResults.GoAgain:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;             resultText = &lt;span style="color: #006080"&gt;"Nice job. Go again."&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt;             ResetPoolStick();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  22:&lt;/span&gt;             m_ActionState = m_ActionStates.Aiming;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  23:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  24:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; ShotResults.Scratch:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  25:&lt;/span&gt;             resultText = &lt;span style="color: #006080"&gt;"Scratch. Player looses turn."&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  26:&lt;/span&gt;             ChangeCurrentPlayer();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  27:&lt;/span&gt;             AddBall(m_QBall);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  28:&lt;/span&gt;             m_ActionState = m_ActionStates.Scratch;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  29:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  30:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;case&lt;/span&gt; ShotResults.Win:&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  31:&lt;/span&gt;             resultText = ProcessGameEnd(&lt;span style="color: #0000ff"&gt;true&lt;/span&gt;, results);&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  32:&lt;/span&gt;             m_ActionState = m_ActionStates.GameOver;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  33:&lt;/span&gt;             &lt;span style="color: #0000ff"&gt;break&lt;/span&gt;;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  34:&lt;/span&gt;     }&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  35:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  36:&lt;/span&gt;     sunkBalls.Clear();&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  37:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  38:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Text_Status.Text = resultText;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  39:&lt;/span&gt; }&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;
&lt;div style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   1:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; UpdateGameState(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; results &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ShotResults)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   2:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; resultText &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt; = &lt;span style="color: #006080"&gt;""&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   3:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   4:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Select&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; results&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   5:&lt;/span&gt;         &lt;span style="color: #008000"&gt;' update game states&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   6:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; ShotResults.PrematureEightBall, ShotResults.ScratchOnEight&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   7:&lt;/span&gt;             resultText = ProcessGameEnd(&lt;span style="color: #0000ff"&gt;False&lt;/span&gt;, results)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   8:&lt;/span&gt;             m_ActionState = m_ActionStates.GameOver&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;   9:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; ShotResults.NextPlayer&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  10:&lt;/span&gt;             resultText = &lt;span style="color: #006080"&gt;"Player looses turn"&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  11:&lt;/span&gt;             ChangeCurrentPlayer()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  12:&lt;/span&gt;             ResetPoolStick()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  13:&lt;/span&gt;             m_ActionState = m_ActionStates.Aiming&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  14:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; ShotResults.GoAgain&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  15:&lt;/span&gt;             resultText = &lt;span style="color: #006080"&gt;"Nice job. Go again."&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  16:&lt;/span&gt;             ResetPoolStick()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  17:&lt;/span&gt;             m_ActionState = m_ActionStates.Aiming&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  18:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; ShotResults.Scratch&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  19:&lt;/span&gt;             resultText = &lt;span style="color: #006080"&gt;"Scratch. Player looses turn."&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  20:&lt;/span&gt;             ChangeCurrentPlayer()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  21:&lt;/span&gt;             AddBall(m_QBall)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  22:&lt;/span&gt;             m_ActionState = m_ActionStates.Scratch&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  23:&lt;/span&gt;         &lt;span style="color: #0000ff"&gt;Case&lt;/span&gt; ShotResults.Win&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  24:&lt;/span&gt;             resultText = ProcessGameEnd(&lt;span style="color: #0000ff"&gt;True&lt;/span&gt;, results)&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  25:&lt;/span&gt;             m_ActionState = m_ActionStates.GameOver&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  26:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Select&lt;/span&gt;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  27:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  28:&lt;/span&gt;     sunkBalls.Clear()&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  29:&lt;/span&gt; &amp;nbsp;&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  30:&lt;/span&gt;     &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.Text_Status.Text = resultText&lt;/pre&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: white; border-bottom-style: none"&gt;&lt;span style="color: #606060"&gt;  31:&lt;/span&gt; &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This was a fun and educational exercise for me (always a good combination).&amp;nbsp; I learned enough about graphics design to at least fear it less, especially with the use of the Expression suite.&amp;nbsp; It also opened my perspective of Silverlight to understand how it will empower us to implement more rich interactive applications.&amp;nbsp; The most interesting part for me, however, was the change in perspective I had to take in implementing an "always on" game.&amp;nbsp; As simple as a game of 8-ball is, it definitely&amp;nbsp;required an&amp;nbsp;adjustment in thinking from the event-driven model of programming I'm accustomed to using in my every day work.&amp;nbsp; 
&lt;p&gt;If you have any questions about this solution or have suggestions for improvement, feel free to contact me at &lt;a href="mailto:jpetersen@claritycon.com"&gt;jpetersen@claritycon.com&lt;/a&gt;&lt;/p&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=5002772" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/web+miscellaneous/default.aspx">web miscellaneous</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/arcade/default.aspx">arcade</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/web/default.aspx">web</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/gaming/default.aspx">gaming</category></item><item><title>Where am I? What am I doing?</title><link>http://blogs.msdn.com/coding4fun/archive/2007/08/31/4677305.aspx</link><pubDate>Sat, 01 Sep 2007 01:17:53 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4677305</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>5</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/4677305.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=4677305</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=4677305</wfw:comment><description>&lt;span id="c4fmetadata"&gt; &lt;table cellspacing="0" cellpadding="1" width="100%" border="0"&gt; &lt;tbody&gt; &lt;tr class="entry_overview"&gt; &lt;td width="50"&gt;&lt;a href="http://www.coding4fun.net/images/WhereamIWhatamIdoing_FA45/gps.jpg" atomicselection="true"&gt;&lt;img height="32" alt="GPS satellite" src="http://www.coding4fun.net/images/WhereamIWhatamIdoing_FA45/gps_thumb.jpg" width="32" border="0"&gt;&lt;/a&gt; &lt;/td&gt; &lt;td&gt;&lt;span class="entry_description"&gt;Do have a GPS receiver laying around?&amp;nbsp; Do you travel?&amp;nbsp; Do you blog?&amp;nbsp; If you answered yes to these questions, you might be interested in this Windows Live Writer plugin.&amp;nbsp; People who travel and like to blog about it can just click a button to insert their current coordinates along with a Virtual Earth Map.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td colspan="2"&gt; &lt;div class="entry_author"&gt;Arian Kulp&lt;/div&gt; &lt;div class="entry_company"&gt;&lt;a href="http://www.ariankulp.com"&gt;Arian's Blog&lt;/a&gt;&lt;/div&gt;&lt;br&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Difficulty: &lt;/b&gt;&lt;span class="entry_details_input"&gt;Intermediate&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Time Required:&lt;/b&gt; &lt;span class="entry_details_input"&gt;1-3 hours&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Cost: &lt;/b&gt;&lt;span class="entry_details_input"&gt;$50 and up (depending on hardware choice)&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Software: &lt;/b&gt;&lt;span class="entry_details_input"&gt;&lt;a href="http://msdn.com/express/"&gt;Visual Basic or Visual C# Express Editions&lt;/a&gt;, Windows Live Writer&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;span class="entry_details_input"&gt;&lt;b&gt;Hardware: &lt;/b&gt;A GPS receiver that supports the NMEA protocol (they all should...)&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Download: &lt;/b&gt; &lt;ul&gt; &lt;li&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=338811"&gt;C# Download&lt;/a&gt;  &lt;li&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=338812"&gt;VB Download&lt;/a&gt;  &lt;li&gt;&lt;a href="http://channel9.msdn.com/ShowPost.aspx?PostID=338813"&gt;MSI Download&lt;/a&gt;&amp;nbsp;(binary only, ready to install!)&lt;/li&gt;&lt;/ul&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/span&gt; &lt;style type="text/css"&gt;.csharpcode, .csharpcode pre
{
	font-size: small;
	color: black;
	font-family: consolas, "Courier New", courier, monospace;
	background-color: #ffffff;
	/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt 
{
	background-color: #f4f4f4;
	width: 100%;
	margin: 0em;
}
.csharpcode .lnum { color: #606060; }

&lt;/style&gt;  &lt;h2&gt;Introduction&lt;/h2&gt; &lt;p&gt;I've had a yellow Garmin etrex GPS unit in the home for about two years now.&amp;nbsp; My family enjoys geocaching (though we don't go nearly often enough...), and it was a good price.&amp;nbsp; The unit has a small screen, but it lets you enter coordinates, then track your way to them.&amp;nbsp; Really, just having your current coordinates is a pretty cool thing!&lt;/p&gt; &lt;p&gt;I've always enjoyed playing with GPS software, and I've liked the idea of creating my own.&amp;nbsp; Unfortunately, I didn't know how to interface with the hardware, so I was out of luck.&amp;nbsp; After buying a serial/USB cable, I was half-way there, but what to do with the data stream?&lt;/p&gt; &lt;p&gt;In this article, learn how to read the stream of data from (hopefully) any GPS unit, then create a plugin for Windows Live Writer so you can add your current location to any blog entry.&amp;nbsp;&amp;nbsp; Scott Hanselman created a GPS interface in &lt;a href="http://blogs.msdn.com/coding4fun/archive/2006/10/31/912287.aspx" target="_blank"&gt;Where the Heck am I?&amp;nbsp; Connecting .NET 2.0 to a GPS&lt;/a&gt;&amp;nbsp;back in October of 2006.&amp;nbsp; As always with Scott, it was a great article, but I didn't come across it until I'd made it through a lot of roadblocks already!&amp;nbsp; My result at this point works pretty well so I decided to stick with it, plus it integrates with Windows Live Writer.&lt;/p&gt; &lt;p align="center"&gt;&lt;a href="http://www.coding4fun.net/images/WhereamIWhatamIdoing_FA45/image.png" atomicselection="true"&gt;&lt;em&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="381" alt="&amp;quot;Where am I?&amp;quot; GPS plugin for Windows Live Writer" src="http://www.coding4fun.net/images/WhereamIWhatamIdoing_FA45/image_thumb.png" width="295" border="0"&gt;&lt;/em&gt;&lt;/a&gt;&lt;em&gt; &lt;/em&gt;&lt;/p&gt; &lt;p align="center"&gt;&lt;em&gt;Figure 1: The plugin in action&lt;/em&gt;&lt;/p&gt; &lt;p&gt;If you want, download the source code from the links above, or just follow along with the article.&amp;nbsp; If you haven't already, download the appropriate version of &lt;a href="http://msdn.microsoft.com/vstudio/express"&gt;Visual Studio 2005 Express Edition&lt;/a&gt;.&amp;nbsp; The plugin will run on either XP or Vista.&amp;nbsp; &lt;/p&gt; &lt;h2&gt;Choosing your Hardware&lt;/h2&gt; &lt;p&gt;Though my main GPS receiver is the Garmin etrex, I also recently bought an Ambicom unit with no screen -- just a Bluetooth link.&amp;nbsp; It's the perfect device just for obtaining information for a PDA, laptop, or other Bluetooth-connected device if you don't need display on the device.&amp;nbsp; It uses the SPP profile for data exchange, so it's just another COM port as well.&lt;/p&gt; &lt;p&gt;My other unit, the Garmin, has four metal dots hidden under a rubber flap.&amp;nbsp; A number of sites provide information on the pin-outs, or you can buy a cable (serial).&amp;nbsp; I bought a serial-USB interface to avoid the serial port on the back of the machine.&amp;nbsp; My assumption is that all GPS units end up with a serial connection via virtual or physical COM port.&amp;nbsp; If I'm wrong, you may need to do some extra work to get the data.&lt;/p&gt; &lt;h2&gt;Speaking NMEA&amp;nbsp;&lt;/h2&gt; &lt;p&gt;Speaking about data... once you have a connection to the unit (4800 bps, 8-N-1), you will have a continuously updated stream of information flowing in.&amp;nbsp; The format of this data is defined by the National Marine Electronics Association (&lt;a href="http://www.nmea.org/" target="_blank"&gt;NMEA&lt;/a&gt;), and is an older format than most people would expect.&amp;nbsp; Interpreting the information is pretty easy once you understand the format (of course, that's often the case!).&lt;/p&gt; &lt;p&gt;&lt;strong&gt;Sample NMEA Data&lt;/strong&gt;&lt;/p&gt; &lt;div class="csharpcode"&gt;&lt;pre&gt;$GPRMB,V,,,,,,,,,,,,A,N*13&lt;/pre&gt;&lt;pre class="alt"&gt;$GPGGA,,,,,,0,00,,,M,,M,,*66&lt;/pre&gt;&lt;pre&gt;$GPGSA,A,1,,,,,,,,,,,,,,,*1E&lt;/pre&gt;&lt;pre class="alt"&gt;$GPGSV,3,1,10,02,60,&lt;/pre&gt;&lt;pre class="alt"&gt;$GPRMC,,V,,,,,,,210807,0.2,E,N*36&lt;/pre&gt;&lt;pre class="alt"&gt;241,00,04,78,042,00,05,24,314,00,09,20,252,00*7F&lt;/pre&gt;&lt;pre&gt;$GPGSV,3,2,10,10,07,185,00,12,44,307,00,17,36,089,00,20,08,035,00*7A&lt;/pre&gt;&lt;pre class="alt"&gt;$GPGSV,3,3,10,28,05,147,00,30,08,319,00*75&lt;/pre&gt;&lt;pre&gt;$GPGLL,,,,,,V,N*64&lt;/pre&gt;&lt;pre class="alt"&gt;$GPBOD,,T,,M,,*47&lt;/pre&gt;&lt;pre&gt;$PGRME,,M,,M,,M*00&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;There are three things to notice at first glance (four if you're really on the ball!).&amp;nbsp; First, every line starts with a dollar sign.&amp;nbsp; Second, that dollar sign is always followed by five upper-case letters (not all begin with "G" though).&amp;nbsp; Third, the data following the capital letters is comma-delimited.&amp;nbsp; If you looked really close, you might have noticed that every line ends with an asterisk, then two more characters that appear to be in hexadecimal format.&lt;/p&gt;
&lt;p&gt;The capital letters after the dollar sign represent the message ID.&amp;nbsp; All standard NMEA messages start with "G."&amp;nbsp; In this example, the line beginning with "P" is a Garmin-specific message.&amp;nbsp; It's proprietary, but it's also documented and &lt;a href="http://www8.garmin.com/support/commProtocol.html" target="_blank"&gt;freely available from their web site&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;With each line being comma-delimited, processing is pretty easy at a high-level.&amp;nbsp; From the &lt;strong&gt;System.IO.Ports.SerialPort&lt;/strong&gt; class, you can call &lt;strong&gt;ReadLine()&lt;/strong&gt; to get a line of data as a string.&amp;nbsp; Each line of data is called a "sentence" in the standard.&amp;nbsp; From there, the &lt;strong&gt;Split()&lt;/strong&gt; method can be used to return an array for the "words."&lt;/p&gt;
&lt;p&gt;That hexadecimal number is the checksum for the sentence.&amp;nbsp; It's a simple formula too.&amp;nbsp; Take, in order, every character between (not including) the dollar sign and asterisk, and XOR them together.&amp;nbsp; The first character seeds the checksum (in other words, a one-character sentence's checksum would be equal to that one character).&amp;nbsp; The &lt;strong&gt;LocationInterface &lt;/strong&gt;class handles all of the serial I/O and NMEA protocol implementation (the little there is!).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Shared&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; GetChecksum(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sentence &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;) &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;
    &lt;span class="rem"&gt;' A sentence can't be shorter than 9 characters ($XXXXX*0x)&lt;/span&gt;
    &lt;span class="kwrd"&gt;If&lt;/span&gt; sentence.Length &amp;lt; 9 &lt;span class="kwrd"&gt;Then&lt;/span&gt;
        &lt;span class="kwrd"&gt;Return&lt;/span&gt; &lt;span class="str"&gt;""&lt;/span&gt;
    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;

    &lt;span class="rem"&gt;' Seed with the second character (remember, skip the $)&lt;/span&gt;
    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; checksum &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt; = Convert.ToByte(sentence(1))
    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; loc &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt; = 0, [&lt;span class="kwrd"&gt;end&lt;/span&gt;] &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt; = sentence.Length - 3

    &lt;span class="rem"&gt;' Loop through the characters&lt;/span&gt;
    &lt;span class="kwrd"&gt;For&lt;/span&gt; &lt;span class="kwrd"&gt;Each&lt;/span&gt; c &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Char&lt;/span&gt; &lt;span class="kwrd"&gt;In&lt;/span&gt; sentence
        &lt;span class="rem"&gt;' XOR every character between the dollar sign and the asterisk&lt;/span&gt;
        &lt;span class="kwrd"&gt;If&lt;/span&gt; loc &amp;gt; 1 &lt;span class="kwrd"&gt;AndAlso&lt;/span&gt; loc &amp;lt; [&lt;span class="kwrd"&gt;end&lt;/span&gt;] &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            checksum = checksum &lt;span class="kwrd"&gt;Xor&lt;/span&gt; Convert.ToByte(c)
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
        loc += 1
    &lt;span class="kwrd"&gt;Next&lt;/span&gt;

    &lt;span class="rem"&gt;' "X2" is the format string for hexadecimal&lt;/span&gt;
    &lt;span class="kwrd"&gt;Return&lt;/span&gt; checksum.ToString(&lt;span class="str"&gt;"X2"&lt;/span&gt;)
&lt;span class="kwrd"&gt;End&lt;/span&gt; Function&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Visual C#&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="rem"&gt;// Calculates the checksum for a sentence&lt;/span&gt;
&lt;span class="kwrd"&gt;public&lt;/span&gt; &lt;span class="kwrd"&gt;static&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; GetChecksum(&lt;span class="kwrd"&gt;string&lt;/span&gt; sentence)
{
    &lt;span class="rem"&gt;// A sentence can't be shorter than 9 characters ($XXXXX*0x)&lt;/span&gt;
    &lt;span class="kwrd"&gt;if&lt;/span&gt;( sentence.Length &amp;lt; 9 ) &lt;span class="kwrd"&gt;return&lt;/span&gt; &lt;span class="str"&gt;""&lt;/span&gt;;

    &lt;span class="rem"&gt;// Seed with the second character (remember, skip the $)&lt;/span&gt;
    &lt;span class="kwrd"&gt;int&lt;/span&gt; checksum = Convert.ToByte(sentence[1]); &lt;span class="rem"&gt;// Second character&lt;/span&gt;
    &lt;span class="kwrd"&gt;int&lt;/span&gt; loc = 0, end = sentence.Length - 3;

    &lt;span class="rem"&gt;// Loop through the characters&lt;/span&gt;
    &lt;span class="kwrd"&gt;foreach&lt;/span&gt; (&lt;span class="kwrd"&gt;char&lt;/span&gt; c &lt;span class="kwrd"&gt;in&lt;/span&gt; sentence)
    {
        &lt;span class="rem"&gt;// XOR every character between the dollar sign and the asterisk&lt;/span&gt;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (loc &amp;gt; 1 &amp;amp;&amp;amp; loc &amp;lt; end)
        {
            c2 = c2 ^ Convert.ToByte(c);
        }
        loc++;
    }
    &lt;span class="rem"&gt;// "X2" is the format string for hexadecimal&lt;/span&gt;
    &lt;span class="kwrd"&gt;return&lt;/span&gt; checksum.ToString(&lt;span class="str"&gt;"X2"&lt;/span&gt;);
}&lt;/pre&gt;
&lt;p&gt;With&amp;nbsp;this handy method, you can&amp;nbsp;validate&amp;nbsp;every line of data that you have before bothering to process it.&amp;nbsp; If a line's bad, don't make a guess.&amp;nbsp; The nature of NMEA is to repeat&amp;nbsp;data frequently.&amp;nbsp; If you missed it this time, you'll have it a second or&amp;nbsp;so later probably.&amp;nbsp; In my code, when I want to get the next data sentence, I call my &lt;strong&gt;ReadNextGoodLine()&lt;/strong&gt; method.&amp;nbsp; This calls &lt;strong&gt;ReadLine()&lt;/strong&gt; on the &lt;strong&gt;SerialPort&lt;/strong&gt;, and validates the checksum.&amp;nbsp; It will try up to ten times before returning a NULL.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Private&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; ReadNextGoodLine(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; port &lt;span class="kwrd"&gt;As&lt;/span&gt; SerialPort) &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;
    &lt;span class="rem"&gt;' Must read the next line.  This may not be a complete NMEA line&lt;/span&gt;
    &lt;span class="rem"&gt;' (or even not an NMEA line at all!)&lt;/span&gt;
    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; line &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt; = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
    &lt;span class="kwrd"&gt;For&lt;/span&gt; i &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Integer&lt;/span&gt; = 0 &lt;span class="kwrd"&gt;To&lt;/span&gt; 9

        &lt;span class="rem"&gt;' Up to ten tries...&lt;/span&gt;
        line = port.ReadLine()

        &lt;span class="kwrd"&gt;If&lt;/span&gt; &lt;span class="kwrd"&gt;Not&lt;/span&gt; IsSentenceValid(line) &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            line = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
        &lt;span class="kwrd"&gt;Else&lt;/span&gt;
            &lt;span class="kwrd"&gt;Exit&lt;/span&gt; &lt;span class="kwrd"&gt;For&lt;/span&gt;

        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;
    &lt;span class="kwrd"&gt;Next&lt;/span&gt;

    &lt;span class="kwrd"&gt;Return&lt;/span&gt; line
&lt;span class="kwrd"&gt;End&lt;/span&gt; Function&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Visual C#&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;private&lt;/span&gt; &lt;span class="kwrd"&gt;string&lt;/span&gt; ReadNextGoodLine(SerialPort port)
{
    &lt;span class="rem"&gt;// Must read the next line.  This may not be a complete NMEA line&lt;/span&gt;
    &lt;span class="rem"&gt;// (or even not an NMEA line at all!)&lt;/span&gt;
    &lt;span class="kwrd"&gt;string&lt;/span&gt; line = &lt;span class="kwrd"&gt;null&lt;/span&gt;;

    &lt;span class="rem"&gt;// Up to ten tries...&lt;/span&gt;
    &lt;span class="kwrd"&gt;for&lt;/span&gt; (&lt;span class="kwrd"&gt;int&lt;/span&gt; i = 0; i &amp;lt; 10; i++)
    {
        line = port.ReadLine();

        &lt;span class="kwrd"&gt;if&lt;/span&gt; (!IsSentenceValid(line)) line = &lt;span class="kwrd"&gt;null&lt;/span&gt;;
        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;break&lt;/span&gt;;
    }

    &lt;span class="kwrd"&gt;return&lt;/span&gt; line;
}&lt;/pre&gt;
&lt;p&gt;Now that I can read sentences and validate them, I can also create a basic auto-scan GPS search.&amp;nbsp; &amp;nbsp;From the &lt;strong&gt;SerialPort&lt;/strong&gt; class, I can call &lt;strong&gt;GetPortNames()&lt;/strong&gt;.&amp;nbsp; This returns a string array of port names.&amp;nbsp; I can instantiate each port by name, call open, then call &lt;strong&gt;ReadNextGoodLine()&lt;/strong&gt;.&amp;nbsp; If it returns NULL (couldn't find valid NMEA after ten lines), assume it isn't a GPS unit and keep moving to the next port.&amp;nbsp; The &lt;strong&gt;ComPortName&lt;/strong&gt; property saves the name, and can also be set manually to avoid the search.&lt;/p&gt;
&lt;h1&gt;&lt;/h1&gt;
&lt;h2&gt;Of Latitudes and Longitudes...&lt;/h2&gt;
&lt;p&gt;One thing I learned from this&amp;nbsp;project, is just how much math is involved with GPS!&amp;nbsp; You take it for granted when the device shows coordinates, but there is so much more going on in there.&lt;/p&gt;
&lt;p&gt;Recall that GPS is all about geosynchronous satellites sending out time signals.&amp;nbsp; Based on the time delay from satellites with known geostationary locations, you can locate your position.&amp;nbsp; As any experienced GPS user knows, however, when you first turn on the unit, or if you are in a house, underground, or often even wooded areas, the unit will be searching for a signal and won't display anything.&amp;nbsp; The $GPRMC sentence continues to arrive, but the coordinates may be blank, or indicate the lack of a "fix."&lt;/p&gt;
&lt;div class="csharpcode"&gt;&lt;pre class="alt"&gt;$GPRMC,153538,A,4140.5555,N,09100.0000,W,000.0,246.0,310807,,,A*66&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The GPRMC consists of a lot of information, including latitude, longitude, speed, heading, and UTC date/time.&amp;nbsp; If you break up the sentence based on commas, the data words that I concentrate in the sample code are 3 (latitude), 4 (N/S), 5 (longitude), 6 (E/W), and 2 (A means fix, V or blank is no fix).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Visual Basic&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;Public&lt;/span&gt; &lt;span class="kwrd"&gt;Function&lt;/span&gt; ParseGPRMC(&lt;span class="kwrd"&gt;ByVal&lt;/span&gt; sentence &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;) &lt;span class="kwrd"&gt;As&lt;/span&gt; CoordinatePair
    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; loc &lt;span class="kwrd"&gt;As&lt;/span&gt; CoordinatePair = &lt;span class="kwrd"&gt;Nothing&lt;/span&gt;
    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; fix &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;Boolean&lt;/span&gt; = &lt;span class="kwrd"&gt;False&lt;/span&gt;

    &lt;span class="rem"&gt;' Split the sentence into words&lt;/span&gt;
    &lt;span class="kwrd"&gt;Dim&lt;/span&gt; words &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;String&lt;/span&gt;() = sentence.Split(&lt;span class="str"&gt;","&lt;/span&gt;c)

    &lt;span class="rem"&gt;' Not all sentences have data populated&lt;/span&gt;
    &lt;span class="kwrd"&gt;If&lt;/span&gt; words(3) &amp;lt;&amp;gt; &lt;span class="str"&gt;""&lt;/span&gt; &lt;span class="kwrd"&gt;AndAlso&lt;/span&gt; words(4) &amp;lt;&amp;gt; &lt;span class="str"&gt;""&lt;/span&gt; &lt;span class="kwrd"&gt;AndAlso&lt;/span&gt; words(5) &amp;lt;&amp;gt; &lt;span class="str"&gt;""&lt;/span&gt; &lt;span class="kwrd"&gt;AndAlso&lt;/span&gt; words(6) &amp;lt;&amp;gt; &lt;span class="str"&gt;""&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
        &lt;span class="rem"&gt;' NMEA coordinates are in DM (Degrees-Minutes) format &lt;/span&gt;
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; lat &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; Coordinate(&lt;span class="kwrd"&gt;Integer&lt;/span&gt;.Parse(words(3).Substring(0, 2)), _&lt;br&gt;            &lt;span class="kwrd"&gt;Decimal&lt;/span&gt;.Parse(words(3).Substring(2)), _&lt;br&gt;            &lt;span class="kwrd"&gt;DirectCast&lt;/span&gt;([&lt;span class="kwrd"&gt;Enum&lt;/span&gt;].Parse(&lt;span class="kwrd"&gt;GetType&lt;/span&gt;(HemisphereOptions), words(4)), HemisphereOptions))
        &lt;span class="kwrd"&gt;Dim&lt;/span&gt; lng &lt;span class="kwrd"&gt;As&lt;/span&gt; &lt;span class="kwrd"&gt;New&lt;/span&gt; Coordinate(&lt;span class="kwrd"&gt;Integer&lt;/span&gt;.Parse(words(5).Substring(0, 3)), _&lt;br&gt;            &lt;span class="kwrd"&gt;Decimal&lt;/span&gt;.Parse(words(5).Substring(3)), _&lt;br&gt;            &lt;span class="kwrd"&gt;DirectCast&lt;/span&gt;([&lt;span class="kwrd"&gt;Enum&lt;/span&gt;].Parse(&lt;span class="kwrd"&gt;GetType&lt;/span&gt;(HemisphereOptions), words(6)), HemisphereOptions))

        loc = &lt;span class="kwrd"&gt;New&lt;/span&gt; CoordinatePair(lat, lng)

        &lt;span class="rem"&gt;' Does the device currently have a satellite fix?&lt;/span&gt;
        &lt;span class="kwrd"&gt;If&lt;/span&gt; words(2) = &lt;span class="str"&gt;"A"&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            &lt;span class="rem"&gt;' Fix has been obtained&lt;/span&gt;
            loc.Fixed = &lt;span class="kwrd"&gt;True&lt;/span&gt;
        &lt;span class="kwrd"&gt;ElseIf&lt;/span&gt; words(2) = &lt;span class="str"&gt;"V"&lt;/span&gt; &lt;span class="kwrd"&gt;Then&lt;/span&gt;
            &lt;span class="rem"&gt;' Fix has been lost&lt;/span&gt;
            loc.Fixed = &lt;span class="kwrd"&gt;False&lt;/span&gt;
        &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;

    &lt;span class="kwrd"&gt;End&lt;/span&gt; &lt;span class="kwrd"&gt;If&lt;/span&gt;

    &lt;span class="kwrd"&gt;Return&lt;/span&gt; loc
&lt;span class="kwrd"&gt;End&lt;/span&gt; Function&lt;/pre&gt;
&lt;p&gt;&lt;strong&gt;Visual C#&lt;/strong&gt;&lt;/p&gt;&lt;pre class="csharpcode"&gt;&lt;span class="kwrd"&gt;public&lt;/span&gt; CoordinatePair ParseGPRMC(&lt;span class="kwrd"&gt;string&lt;/span&gt; sentence)
{
    CoordinatePair loc = &lt;span class="kwrd"&gt;null&lt;/span&gt;;

    &lt;span class="rem"&gt;// Split the sentence into words&lt;/span&gt;
    &lt;span class="kwrd"&gt;string&lt;/span&gt;[] words = sentence.Split(&lt;span class="str"&gt;','&lt;/span&gt;);

    &lt;span class="rem"&gt;// Not all sentences have data populated&lt;/span&gt;
    &lt;span class="kwrd"&gt;if&lt;/span&gt; (words[3] != &lt;span class="str"&gt;""&lt;/span&gt; &amp;amp;&amp;amp; words[4] != &lt;span class="str"&gt;""&lt;/span&gt; &amp;amp;&amp;amp; words[5] != &lt;span class="str"&gt;""&lt;/span&gt; &amp;amp;&amp;amp; words[6] != &lt;span class="str"&gt;""&lt;/span&gt;)
    {
        &lt;span class="rem"&gt;// NMEA coordinates are in DM (Degrees-Minutes) format &lt;/span&gt;
        Coordinate lat = &lt;span class="kwrd"&gt;new&lt;/span&gt; Coordinate(&lt;span class="kwrd"&gt;int&lt;/span&gt;.Parse(words[3].Substring(0, 2)), &lt;br&gt;            &lt;span class="kwrd"&gt;decimal&lt;/span&gt;.Parse(words[3].Substring(2)), &lt;br&gt;            (HemisphereOptions)Enum.Parse(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(HemisphereOptions), words[4]));
        Coordinate lng = &lt;span class="kwrd"&gt;new&lt;/span&gt; Coordinate(&lt;span class="kwrd"&gt;int&lt;/span&gt;.Parse(words[5].Substring(0, 3)), &lt;br&gt;            &lt;span class="kwrd"&gt;decimal&lt;/span&gt;.Parse(words[5].Substring(3)),&lt;br&gt;            (HemisphereOptions)Enum.Parse(&lt;span class="kwrd"&gt;typeof&lt;/span&gt;(HemisphereOptions), words[6]));

        loc = &lt;span class="kwrd"&gt;new&lt;/span&gt; CoordinatePair(lat, lng);
        
        &lt;span class="rem"&gt;// Does the device currently have a satellite fix?&lt;/span&gt;
        &lt;span class="kwrd"&gt;if&lt;/span&gt; (words[2] == &lt;span class="str"&gt;"A"&lt;/span&gt;) loc.Fixed = &lt;span class="kwrd"&gt;true&lt;/span&gt;; &lt;span class="rem"&gt;// Fix has been obtained&lt;/span&gt;
        &lt;span class="kwrd"&gt;else&lt;/span&gt; &lt;span class="kwrd"&gt;if&lt;/span&gt; (words[2] == &lt;span class="str"&gt;"V"&lt;/span&gt;) loc.Fixed = &lt;span class="kwrd"&gt;false&lt;/span&gt;; &lt;span class="rem"&gt;// Fix has been lost&lt;/span&gt;
    }

    &lt;span class="kwrd"&gt;return&lt;/span&gt; loc;
}&lt;/pre&gt;
&lt;p&gt;The latitude and longitude values in NMEA data are expressed as DM format.&amp;nbsp; DM is short for &lt;em&gt;Degrees-Minutes&lt;/em&gt;, and actually the minutes are expressed in decimal form.&amp;nbsp; In the above example, "4140.5555" is meant to be parsed as 41 degrees and 40.5555 minutes.&amp;nbsp; Longitude uses three digits for degrees, so "09100.0000" is 091 degrees and 00.0000 minutes.&amp;nbsp; Degrees-Minutes is just one of three common ways to express coordinates though.&amp;nbsp; &lt;em&gt;Degrees-Minutes-Seconds&lt;/em&gt; splits the minutes into minutes and seconds.&amp;nbsp; If you think of it like time, it's easier.&amp;nbsp; If the decimal minutes is .50000, then that's half of 60, or 30 minutes.&amp;nbsp; A number like .55555 would spill into the seconds place as well.&amp;nbsp; You can also use &lt;em&gt;Degrees-Decimal &lt;/em&gt;which simply uses one decimal number to express the degrees&amp;nbsp;along with any fractional "extra." &amp;nbsp;Just remember that the source format is Degrees-Minutes, and given any format, you can convert to any other.&amp;nbsp; My &lt;strong&gt;Coordinate &lt;/strong&gt;class provides &lt;strong&gt;ToString() &lt;/strong&gt;methods to return in all three representations, and internally it stores it as &lt;strong&gt;int &lt;/strong&gt;degrees and minutes and &lt;strong&gt;decimal &lt;/strong&gt;seconds.&amp;nbsp; For more information on these numbers, Wikipedia has a &lt;a href="http://en.wikipedia.org/wiki/Geographic_coordinate" target="_blank"&gt;great article&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;Plugging In&lt;/h2&gt;
&lt;p&gt;Functioning as a &amp;nbsp;Live Writer plugin requires that you do several things.&amp;nbsp; First of all, you will need to download and install the Windows Live Writer SDK.&amp;nbsp; This gives you access to an assembly to add a reference to in your project.&amp;nbsp; Your entry point class should import the &lt;strong&gt;WindowsLive.Writer.Api &lt;/strong&gt;namespace, and inherit ContentSource.&amp;nbsp; You'll need to add the &lt;strong&gt;WriterPlugin &lt;/strong&gt;attribute with values for a unique GUID (use the &lt;strong&gt;Tools | Create GUID &lt;/strong&gt;menu item in Visual Studio to help with that), and set a name at least.&lt;/p&gt;
&lt;p&gt;The &lt;strong&gt;EditOptions &lt;/strong&gt;method must be overridden if you provide an Options dialog (in this sample, it's just a message box.&amp;nbsp; The &lt;strong&gt;CreateContent &lt;/strong&gt;method is the meat of the plugin.&amp;nbsp; This can do anything, then assign a string to the &lt;strong&gt;newContent &lt;/strong&gt;ref parameter.&amp;nbsp; It returns a &lt;strong&gt;DialogResult &lt;/strong&gt;to indicate if it was OK'd or Cancel'd.&lt;/p&gt;
&lt;p&gt;The&amp;nbsp;&lt;strong&gt;InsertableContentSource &lt;/strong&gt;attribute&amp;nbsp;lets you set the &lt;strong&gt;SideBar &lt;/strong&gt;text property, and the &lt;strong&gt;WriterPlugin &lt;/strong&gt;attribute has a property for &lt;strong&gt;ImagePath&amp;nbsp;&lt;/strong&gt;to create an image link:&lt;/p&gt;
&lt;p align="center"&gt;&lt;a href="http://www.coding4fun.net/images/WhereamIWhatamIdoing_FA45/image_3.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" alt="Plugin Insert links" src="http://www.coding4fun.net/images/WhereamIWhatamIdoing_FA45/image_thumb_3.png" border="0"&gt;&lt;/a&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="center"&gt;&lt;em&gt;Figure 2: Ready to use&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;When &lt;strong&gt;CreateContent &lt;/strong&gt;is called, the sample plugin shows the &lt;strong&gt;LocationPreviewForm &lt;/strong&gt;dialog.&amp;nbsp; This in turn triggers the &lt;strong&gt;GPSInit &lt;/strong&gt;method in &lt;strong&gt;LocationInterface &lt;/strong&gt;to find and connect to the GPS unit.&amp;nbsp; If it's found, the COM port and coordinates are shown.&amp;nbsp; All GPS activity is performed in a &lt;strong&gt;BackgroundWorker&lt;/strong&gt; to maintain a responsive user interface.&amp;nbsp; The &lt;strong&gt;Title &lt;/strong&gt;and &lt;strong&gt;Description &lt;/strong&gt;fields are used for a pushpin in a Virtual Earth embedded AJAX map.&amp;nbsp; This is a full-blown instance with the scrolling and zooming.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p align="center"&gt;&lt;a href="http://www.coding4fun.net/images/WhereamIWhatamIdoing_FA45/image_4.png" atomicselection="true"&gt;&lt;img height="204" alt="Location Preview dialog" src="http://www.coding4fun.net/images/WhereamIWhatamIdoing_FA45/image_thumb_4.png" width="298" border="0"&gt;&lt;/a&gt; &lt;/p&gt;
&lt;p align="center"&gt;&lt;em&gt;Figure 3: The plugin dialog&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Actually, I would have liked to use a static bitmap, but I'm not sure how to obtain good free mapping images in a small amount of code, other than services like MapPoint which aren't free.&amp;nbsp; Changing this aspect of the code would be very easy in the &lt;strong&gt;GetOutput &lt;/strong&gt;method, and you could remove the image/map altogether and simply show the coordinates or other information.&amp;nbsp; It's not exactly extensible, but it's easy to modify.&lt;/p&gt;
&lt;p&gt;Finally, in order to simplify debugging, I created a post-build event to copy the plugin DLL to the Windows Live Writer Plugins directory:&lt;/p&gt;
&lt;p&gt;XCOPY /D /Y /R "$(TargetPath)" "C:\Program Files\Windows Live Writer\Plugins\"&lt;/p&gt;
&lt;p&gt;I also went into the Debug settings for the project&amp;nbsp;for the project and set the &lt;strong&gt;Start Action&lt;/strong&gt; to &lt;strong&gt;Start external program&lt;/strong&gt;, setting it to the path to the EXE:&lt;/p&gt;
&lt;p&gt;C:\Program Files\Windows Live Writer\WindowsLiveWriter.exe&lt;/p&gt;
&lt;p&gt;Now, when you press F5, it copies the DLL and attaches the debugger to a new instance of Windows Live Writer for Edit-and-Continue and other debugging.&amp;nbsp; It works well!&lt;/p&gt;
&lt;p&gt;One thing to remember, is that Live Writer locks the DLL's when it's running, so you will get an error if you even build while it's running, since the DLL can't be copied.&lt;/p&gt;
&lt;h2&gt;Next Steps&lt;/h2&gt;
&lt;p&gt;At this point, I'd like to create more flexibility on what the plugin does with the coordinates.&amp;nbsp; It could locate images through various sources, include altitude, speed, and heading when available, or just pretty up the embedded information.&amp;nbsp; I'd like to work on the GPS classes a bit to make them more robust, handling some of the other messages, and support raising events to be used in other applications.&amp;nbsp; Developing GPS applications is conceptually pretty easy once you have the data.&amp;nbsp; It's just a matter of exposing the data in a good way.&lt;/p&gt;
&lt;h2&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Working with GPS data was much easier than I expected.&amp;nbsp; I had some Bluetooth/USB issues at first, but working&amp;nbsp;with the data was fun and gave me lots of ideas!&amp;nbsp; See what you can do with location information to enhance some existing application, or think&amp;nbsp;up something&amp;nbsp;entirely&amp;nbsp;new.&amp;nbsp; Have fun with the code and as usual, contact me through &lt;a href="http://www.ariankulp.com"&gt;my blog&lt;/a&gt; for comments, complaints, or questions.&lt;/p&gt;
&lt;p&gt;
&lt;hr&gt;

&lt;p&gt;&lt;/p&gt;
&lt;table cellspacing="0" cellpadding="1" width="100%" border="0" unselectable="on"&gt;
&lt;tbody&gt;
&lt;tr class="author"&gt;
&lt;td class="author_image" width="50"&gt;&lt;a href="http://www.coding4fun.net/images/WhereamIWhatamIdoing_FA45/Avatar80.jpg" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; margin: 5px; border-right-width: 0px" alt="Avatar80" src="http://www.coding4fun.net/images/WhereamIWhatamIdoing_FA45/Avatar80_thumb.jpg" border="0"&gt;&lt;/a&gt; &lt;/td&gt;
&lt;td class="author_bio"&gt;Arian Kulp is an independent software developer and writer working in the Midwest.&amp;nbsp; He has been coding since the fifth grade on various platforms, and also enjoys photography, nature, and spending time with his family.&amp;nbsp; Arian can be reached through his web site at &lt;a href="http://www.ariankulp.com"&gt;http://www.ariankulp.com&lt;/a&gt;.&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;img src="http://blogs.msdn.com/aggbug.aspx?PostID=4677305" width="1" height="1"&gt;</description><category domain="http://blogs.msdn.com/coding4fun/archive/tags/utility/default.aspx">utility</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/web+miscellaneous/default.aspx">web miscellaneous</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/hardware+miscellaneous/default.aspx">hardware miscellaneous</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/windows/default.aspx">windows</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/web/default.aspx">web</category><category domain="http://blogs.msdn.com/coding4fun/archive/tags/hardware/default.aspx">hardware</category></item><item><title>Outlook Webmail Add-in for Windows Home Server</title><link>http://blogs.msdn.com/coding4fun/archive/2007/08/10/4320362.aspx</link><pubDate>Fri, 10 Aug 2007 14:33:56 GMT</pubDate><guid isPermaLink="false">91d46819-8472-40ad-a661-2c78acb4018c:4320362</guid><dc:creator>Coding4Fun</dc:creator><slash:comments>26</slash:comments><comments>http://blogs.msdn.com/coding4fun/comments/4320362.aspx</comments><wfw:commentRss>http://blogs.msdn.com/coding4fun/commentrss.aspx?PostID=4320362</wfw:commentRss><wfw:comment>http://blogs.msdn.com/coding4fun/rsscomments.aspx?PostID=4320362</wfw:comment><description>&lt;table cellspacing="0" cellpadding="1" width="100%" border="0"&gt; &lt;tbody&gt; &lt;tr class="entry_overview"&gt; &lt;td width="50"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" alt="Office_MAIL" src="http://www.coding4fun.net/images/OutlookWebmailAddinforWindowsHomeServer_B4D/Office_MAIL.png" border="0"&gt; &lt;/td&gt; &lt;td&gt;&lt;span class="entry_description"&gt;In this article, Brian Peek will demonstrate how to create an add-in for Windows Home Server that will allow users to view their Outlook mail from a web browser.&lt;/span&gt;&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td colspan="2"&gt; &lt;div class="entry_author"&gt;&lt;a href="http://www.brianpeek.com/" target="_blank"&gt;Brian Peek&lt;/a&gt;&lt;/div&gt; &lt;div class="entry_company"&gt;&lt;a href="http://www.aspsoft.com/"&gt;ASPSOFT, Inc.&lt;/a&gt;&lt;/div&gt;&lt;br&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Difficulty: &lt;/b&gt;&lt;span class="entry_details_input"&gt;Intermediate&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Time Required:&lt;/b&gt; 2&lt;span class="entry_details_input"&gt;-3 hours&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Cost: &lt;/b&gt;&lt;span class="entry_details_input"&gt;Free&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;strong&gt;Software: &lt;/strong&gt;&lt;a href="http://www.microsoft.com/windows/products/winfamily/windowshomeserver/default.mspx" target="_blank"&gt;Windows Home Server&lt;/a&gt;,&amp;nbsp;&lt;a href="http://office.microsoft.com/en-us/outlook/default.aspx" target="_blank"&gt;Microsoft Outlook 2000/XP/2003/2007&lt;/a&gt; (&lt;strong&gt;not&lt;/strong&gt; Outlook Express/Windows Mail),&amp;nbsp;&lt;span class="entry_details_input"&gt;&lt;a href="http://msdn.com/express/"&gt;Visual Basic or Visual C# Express Editions&lt;/a&gt;, &lt;a href="http://msdn.com/express/" target="_blank"&gt;Visual Web Developer Express Edition&lt;/a&gt;, &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=10CC340B-F857-4A14-83F5-25634C3BF043&amp;amp;displaylang=en" target="_blank"&gt;Microsoft .NET Framework 3.0 runtime&lt;/a&gt;, Outlook/Office Primary Interop Assemblies (more on this below),&amp;nbsp;&lt;a href="http://www.microsoft.com/downloads/details.aspx?familyid=4377f86d-c913-4b5c-b87e-ef72e5b4e065&amp;amp;displaylang=en" target="_blank"&gt;Windows SDK&lt;/a&gt; (Vista or later, which includes the .NET 3.0 bits.&amp;nbsp; Note that this installs and works just fine under Windows XP.&amp;nbsp; The SDK can build applications for Windows XP and greater.)&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Hardware: &lt;/b&gt;&lt;span class="entry_details_input"&gt;None&lt;/span&gt;&lt;/div&gt; &lt;div class="entry_details"&gt;&lt;b&gt;Download: &lt;/b&gt;&lt;a href="http://www.codeplex.com/WHSMail" target="_blank"&gt;CodePlex Project&lt;/a&gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;h3&gt;Introduction&lt;/h3&gt; &lt;p&gt;&lt;a href="http://www.microsoft.com/windows/products/winfamily/windowshomeserver/default.mspx" target="_blank"&gt;Windows Home Server&lt;/a&gt;&amp;nbsp;is a new product from Microsoft which allows home users to manage and share data, including photos, documents, videos, music, etc.&amp;nbsp; It also provides a very easy way to backup all computers on your home network to a central storage server.&lt;/p&gt; &lt;p&gt;Windows Home Server can also be extended via add-ins to enhance the experience and provide new and interesting functionality other than what comes in the box.&lt;/p&gt; &lt;p&gt;One&amp;nbsp;feature not present in WHS&amp;nbsp;that I would find useful is the ability to view my Outlook mail box from the web at any time.&amp;nbsp; I have 6&amp;nbsp;or 7 email accounts that are&amp;nbsp;all setup&amp;nbsp;to retrieve via POP3 to Outlook.&amp;nbsp; Most of these accounts do not support IMAP or have a web-based interface.&amp;nbsp; Therefore, Outlook is generally open all day and checking messages.&amp;nbsp;&amp;nbsp;When I'm away from home for work or pleasure,&amp;nbsp;it's&amp;nbsp;very often&amp;nbsp;inconvenient to have to remote desktop into&amp;nbsp;the machine with Outlook running to read my email,&amp;nbsp;so it would be nice to have a web-based version of my current&amp;nbsp;Outlook folders so I can view all email (old and new) at any time simply by browsing to a&amp;nbsp;web server at home.&amp;nbsp; Windows Home&amp;nbsp;Server comes with&amp;nbsp;Internet Information Services&amp;nbsp;6 (IIS6) and&amp;nbsp;one can easily add a new web application to IIS on the server.&lt;/p&gt; &lt;p&gt;So, this article will attempt to show how to build a new web site using ASP.NET that can be added to your Windows Home Server installation that will allow one to view the Outlook folders running on whatever computer contains your current Outlook installation and message store.&lt;/p&gt; &lt;p&gt;If you wish to just use the application, download the sample from above and skip down to the deployment section for installation instructions.&lt;/p&gt; &lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; This application will only work with Microsoft Outlook.&amp;nbsp; It will not work with Outlook Express, Windows Mail, or any other mail client.&lt;/p&gt; &lt;h3&gt;Setup&lt;/h3&gt; &lt;p&gt;Setup can be a bit tricky.&amp;nbsp; Office/Outlook will need to be installed on your development machine.&amp;nbsp; It does not need to be the same machine which contains your store at this point, but that too would help.&amp;nbsp; Once Office/Outlook is installed, the &lt;strong&gt;Primary Interop Assemblies&lt;/strong&gt; for the version of Office you are using need to be installed.&amp;nbsp; For Office 2003/2007, this can be done choosing &lt;strong&gt;.NET Programming Support&lt;/strong&gt; from the list of sub-items in the &lt;strong&gt;Microsoft Office Outlook &lt;/strong&gt;section of the setup program.&lt;/p&gt; &lt;p&gt;&lt;a href="http://www.coding4fun.net/images/OutlookWebmailAddinforWindowsHomeServer_B4D/2003_3.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="426" alt="2003" src="http://www.coding4fun.net/images/OutlookWebmailAddinforWindowsHomeServer_B4D/2003_thumb_3.png" width="490" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;&lt;a href="http://www.coding4fun.net/images/OutlookWebmailAddinforWindowsHomeServer_B4D/pia_3.png" atomicselection="true"&gt;&lt;img style="border-top-width: 0px; border-left-width: 0px; border-bottom-width: 0px; border-right-width: 0px" height="414" alt="pia" src="http://www.coding4fun.net/images/OutlookWebmailAddinforWindowsHomeServer_B4D/pia_thumb_3.png" width="490" border="0"&gt;&lt;/a&gt; &lt;/p&gt; &lt;p&gt;Unfortunately I do not have an earlier copy of Office with which to check, but the procedure should be the same.&amp;nbsp; If anyone happens to try this with Office XP/2000, please let me know if/how it works.&lt;/p&gt; &lt;p&gt;If you will be developing on an OS earlier than Vista,&amp;nbsp;install the &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=10CC340B-F857-4A14-83F5-25634C3BF043&amp;amp;displaylang=en" target="_blank"&gt;.NET Framework 3.0 runtime&lt;/a&gt;.&lt;/p&gt; &lt;p&gt;Finally, install the Windows SDK linked above accepting all defaults.&lt;/p&gt; &lt;h3&gt;Architecture&lt;/h3&gt; &lt;p&gt;The architecture we will be using is very similar that to an N-tier application.&amp;nbsp; The machine running Outlook with the message store to be viewed is, in essence, the server machine.&amp;nbsp; That machine will run a host process that we will develop which will expose several methods via Windows Communication Foundation.&amp;nbsp; These methods will be consumed by an ASP.NET application running on the Windows Home Server.&lt;/p&gt; &lt;h3&gt;The Host&lt;/h3&gt; &lt;p&gt;Let's start by building the host application.&amp;nbsp; This will run on the computer where Outlook is installed and the messages are stored.&amp;nbsp; The application will be written to run in the notification area next to the Windows system clock.&lt;/p&gt; &lt;p&gt;To start, create a new Windows Application project named &lt;strong&gt;WHSMailHost&lt;/strong&gt;.&amp;nbsp; Rename the default &lt;strong&gt;Form1.cs/.vb&lt;/strong&gt; file to &lt;strong&gt;frmMain.cs/.vb&lt;/strong&gt;.&amp;nbsp; Double-click on the file in the Solution Explorer to bring up the design surface.&lt;/p&gt; &lt;p&gt;In order to get the application to run in the notification area, drag and drop a &lt;strong&gt;NotifyIcon&lt;/strong&gt; control from the Toolbox to the design surface, name it &lt;strong&gt;niIcon&lt;/strong&gt;.&amp;nbsp; Also, drag over a &lt;strong&gt;ContextMenuStrip&lt;/strong&gt; to the design surface and name it &lt;strong&gt;cmsMenu&lt;/strong&gt;.&amp;nbsp; This will be used to pop up a context menu when the icon in the notification area is clicked.&amp;nbsp;&amp;nbsp;Finally,&amp;nbsp;set the following properties on the &lt;strong&gt;niIcon&lt;/strong&gt; control:&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="248" border="1" unselectable="on"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="136"&gt;&lt;strong&gt;Text&lt;/strong&gt;&lt;/td&gt; &lt;td valign="top" width="110"&gt;WHS Mail Host&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="138"&gt;&lt;strong&gt;ContextMenuStrip&lt;/strong&gt;&lt;/td&gt; &lt;td valign="top" width="110"&gt;cmsMenu&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="139"&gt;&lt;strong&gt;Visible&lt;/strong&gt;&lt;/td&gt; &lt;td valign="top" width="110"&gt;True&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;Select the &lt;strong&gt;cmsMenu&lt;/strong&gt; control and add a single menu item named &lt;strong&gt;Exit&lt;/strong&gt; to the list.&amp;nbsp; Double-click on that menu item to create a default &lt;strong&gt;Click &lt;/strong&gt;event.&amp;nbsp; In the code for the &lt;strong&gt;Click&lt;/strong&gt; event, simply close the form as follows:&lt;/p&gt; &lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt; &lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; mnuExit_Click(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)
{
    &lt;span style="color: #008000"&gt;// exit the application&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Close();
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; mnuExit_Click(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; EventArgs) &lt;span style="color: #0000ff"&gt;Handles&lt;/span&gt; mnuExit.Click
    &lt;span style="color: #008000"&gt;' exit the application&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.Close()
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Finally, add the following events to &lt;strong&gt;frmMain&lt;/strong&gt; by selecting them from the Event Property window and implementing them with the following code:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; frmMain_Resize(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)
{
    &lt;span style="color: #008000"&gt;// hide the form&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Hide();
}

&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; frmMain_Load(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, EventArgs e)
{
    &lt;span style="color: #008000"&gt;// start the WCF service&lt;/span&gt;
    MyServiceHost.StartService();
}

&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; frmMain_FormClosing(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; sender, FormClosingEventArgs e)
{
    &lt;span style="color: #008000"&gt;// stop the WCF service&lt;/span&gt;
    MyServiceHost.StopService();
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; frmMain_Resize(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; EventArgs) &lt;span style="color: #0000ff"&gt;Handles&lt;/span&gt; &lt;span style="color: #0000ff"&gt;MyBase&lt;/span&gt;.Resize
    &lt;span style="color: #008000"&gt;' hide the form&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.Hide()
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; frmMain_Load(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; EventArgs) &lt;span style="color: #0000ff"&gt;Handles&lt;/span&gt; &lt;span style="color: #0000ff"&gt;MyBase&lt;/span&gt;.Load
    &lt;span style="color: #008000"&gt;' start the WCF service&lt;/span&gt;
    MyServiceHost.StartService()
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; frmMain_FormClosing(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; sender &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; e &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; FormClosingEventArgs) &lt;span style="color: #0000ff"&gt;Handles&lt;/span&gt; &lt;span style="color: #0000ff"&gt;MyBase&lt;/span&gt;.FormClosing
    &lt;span style="color: #008000"&gt;' stop the WCF service&lt;/span&gt;
    MyServiceHost.StopService()
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The code above references a class named &lt;strong&gt;MyServiceHost&lt;/strong&gt;.&amp;nbsp; This is what starts the WCF host and will be discussed next.&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;h4&gt;Windows Communication Foundation (WCF)&lt;/h4&gt;
&lt;p&gt;Windows Communication Foundation (formerly known as Indigo) is a feature of the .NET Framework 3.0 that allows one to build and run connected systems.&amp;nbsp; The simplest definition that fits with what we will be doing here is that it allows an application running on one machine (the client, in this case, the ASP.NET application) to execute a method on another machine (the host, in this case, the application we're currently building).&lt;/p&gt;
&lt;p&gt;First, add a reference to the &lt;strong&gt;System.ServiceModel&lt;/strong&gt; assembly.&amp;nbsp; Then, add a class to the project named &lt;strong&gt;WHSMailService&lt;/strong&gt;.&amp;nbsp; Open the class and add the following code beneath the generated &lt;strong&gt;WHSMailService&lt;/strong&gt; class implementation:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; MyServiceHost
{
    &lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; ServiceHost myServiceHost = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;

    &lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; StartService()
    {
        &lt;span style="color: #008000"&gt;// Instantiate new ServiceHost &lt;/span&gt;
        myServiceHost = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ServiceHost(&lt;span style="color: #0000ff"&gt;typeof&lt;/span&gt;(WHSMailService));
        myServiceHost.Open();
    }

    &lt;span style="color: #0000ff"&gt;internal&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; StopService()
    {
        &lt;span style="color: #008000"&gt;// Call StopService from your shutdown logic (i.e. dispose method)&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt; (myServiceHost.State != CommunicationState.Closed)
            myServiceHost.Close();
    }
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Friend&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; MyServiceHost
    &lt;span style="color: #0000ff"&gt;Friend&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Shared&lt;/span&gt; myServiceHost &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; ServiceHost = &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Friend&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Shared&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; StartService()
        &lt;span style="color: #008000"&gt;' Instantiate new ServiceHost &lt;/span&gt;
        myServiceHost = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; ServiceHost(&lt;span style="color: #0000ff"&gt;GetType&lt;/span&gt;(WHSMailService))
        myServiceHost.Open()
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Friend&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Shared&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; StopService()
        &lt;span style="color: #008000"&gt;' Call StopService from your shutdown logic (i.e. dispose method)&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; myServiceHost.State &amp;lt;&amp;gt; CommunicationState.Closed &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
            myServiceHost.Close()
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This code simply creates a new WCF &lt;strong&gt;ServiceHost&lt;/strong&gt; of the type &lt;strong&gt;WHSMailService&lt;/strong&gt; (which we will implement next) and then opens that host so that it may receive incoming connections.&amp;nbsp; We will look at how this connections are configured later in the article.&lt;/p&gt;
&lt;p&gt;Remember that the code in the form above above called the &lt;strong&gt;StartService&lt;/strong&gt; and &lt;strong&gt;StopService&lt;/strong&gt; methods located here when the main form loads and closes.&amp;nbsp; This very easily allows to immediately start the service host when the application starts and closes the service host when the application exits.&lt;/p&gt;
&lt;h4&gt;Contracts and Entities&lt;/h4&gt;
&lt;p&gt;A contract is an interface that defines which methods are exposed by the service host that can be consumed by the client application.&amp;nbsp; Both the client application and the server application will need to know what is in this interface, so we will need to create a second project that will contain the interface definition.&amp;nbsp; Additionally, we will need a way to pass folder and email information to and from each application, so we will define some custom classes to encapsulate those objects.&lt;/p&gt;
&lt;p&gt;Create a new &lt;strong&gt;Class Library&lt;/strong&gt; project in the current solution named &lt;strong&gt;WHSMailCommon&lt;/strong&gt;.&amp;nbsp; In this new project, create a directory named &lt;strong&gt;Contracts&lt;/strong&gt; and a directory named &lt;strong&gt;Entities&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;Inside the &lt;strong&gt;Entities&lt;/strong&gt; directory, create a new class named &lt;strong&gt;Folder&lt;/strong&gt;.&amp;nbsp; This will represent an Outlook message folder.&amp;nbsp; The class should look like the following:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections.Generic;

&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; WHSMailCommon.Entities
{
    &lt;span style="color: #008000"&gt;// entity object representing an Folder&lt;/span&gt;
    [Serializable]
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Folder : IComparable
    {
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _entryID;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _name;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; List&amp;lt;Folder&amp;gt; _folders;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; _unreadMessages;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; _totalMessages;

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Folder(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; entryID, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; name, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; unreadMessages, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; totalMessages)
        {
            _entryID = entryID;
            _name = name;
            _unreadMessages = unreadMessages;
            _totalMessages = totalMessages;
        }

        &lt;span style="color: #008000"&gt;// MAPI unique identifier&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; EntryID
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _entryID; }
            set { _entryID = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #008000"&gt;// subfolders of this folder&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; List&amp;lt;Folder&amp;gt; Folders
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _folders; }
            set { _folders = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Name
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _name; }
            set { _name = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; UnreadMessages
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._unreadMessages; }
            set { &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._unreadMessages = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; TotalMessages
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._totalMessages; }
            set { &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;._totalMessages = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #008000"&gt;// used so we can sort the folders alphabetically later on&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; CompareTo(&lt;span style="color: #0000ff"&gt;object&lt;/span&gt; obj)
        {
            &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.Compare(&lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.Name, ((Folder)obj).Name);
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; Microsoft.VisualBasic
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.Collections.Generic

&lt;span style="color: #0000ff"&gt;Namespace&lt;/span&gt; WHSMailCommon.Entities
    &lt;span style="color: #008000"&gt;' entity object representing an Folder&lt;/span&gt;
    &amp;lt;Serializable&amp;gt; _
    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; Folder
        &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IComparable
        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _entryID &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _name &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _folders &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(Of Folder)
        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _unreadMessages &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _totalMessages &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; entryID &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; name &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; unreadMessages &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; totalMessages &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;)
            _entryID = entryID
            _name = name
            _unreadMessages = unreadMessages
            _totalMessages = totalMessages
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

        &lt;span style="color: #008000"&gt;' MAPI unique identifier&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; EntryID() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _entryID
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
                _entryID = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

        &lt;span style="color: #008000"&gt;' subfolders of this folder&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; Folders() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(Of Folder)
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _folders
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(Of Folder))
                _folders = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; Name() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _name
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
                _name = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; UnreadMessages() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._unreadMessages
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;)
                &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._unreadMessages = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; TotalMessages() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._totalMessages
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;)
                &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;._totalMessages = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

        &lt;span style="color: #008000"&gt;' used so we can sort the folders alphabetically later on&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; CompareTo(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; obj &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Object&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IComparable.CompareTo
            &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.Compare(&lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.Name, (&lt;span style="color: #0000ff"&gt;CType&lt;/span&gt;(obj, Folder)).Name)
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Namespace&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This class defines several properties to describe the folder (EntryID, Name, etc.) and additionally implements the &lt;strong&gt;IComparable &lt;/strong&gt;interface's &lt;strong&gt;CompareTo&lt;/strong&gt; method&amp;nbsp;so that we can easily sort the folders alphabetically later on.&lt;/p&gt;
&lt;p&gt;Next, create a class named &lt;strong&gt;Email&lt;/strong&gt;.&amp;nbsp; The code for this class looks like the following:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Text;

&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; WHSMailCommon.Entities
{
    &lt;span style="color: #008000"&gt;// entity object representing an Email&lt;/span&gt;
    [Serializable]
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; Email
    {
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _entryID;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _from;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _fromName;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _subject;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; DateTime _received;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; _size;
        &lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; _body;

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Email(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; entryID, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; from, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; fromName, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; subject, DateTime received, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; size)
        {
            _entryID = entryID;
            _from = from;
            _fromName = fromName;
            _subject = &lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(subject) ? &lt;span style="color: #006080"&gt;"(no subject)"&lt;/span&gt; : subject;
            _received = received;
            _size = size;
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; Email(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; entryID, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; from, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; fromName, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; subject, DateTime received, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; size, &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; body) :
            &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;(entryID, from, fromName, subject, received, size)
        {
            _body = body;
        }

        &lt;span style="color: #008000"&gt;// MAPI unique ID&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; EntryID
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _entryID; }
            set { _entryID = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #008000"&gt;// email address of sender&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; From
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _from; }
            set { _from = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #008000"&gt;// name of sender&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; FromName
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _fromName; }
            set { _fromName = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Subject
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _subject; }
            set { _subject = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;string&lt;/span&gt; Body
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _body; }
            set { _body = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; DateTime Received
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _received; }
            set { _received = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }

        &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; Size
        {
            get { &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; _size; }
            set { _size = &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;; }
        }
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; Microsoft.VisualBasic
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.Collections.Generic
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.Text

&lt;span style="color: #0000ff"&gt;Namespace&lt;/span&gt; WHSMailCommon.Entities
    &lt;span style="color: #008000"&gt;' entity object representing an Email&lt;/span&gt;
    &amp;lt;Serializable&amp;gt; _
    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; Email
        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _entryID &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _from &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _fromName &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _subject &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _received &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; DateTime
        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _size &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; _body &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; entryID &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; From &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; fromName &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; subject &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; received &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; DateTime, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; size &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;)
            _entryID = entryID
            _from = From
            _fromName = fromName
            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.IsNullOrEmpty(subject) &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                _subject = &lt;span style="color: #006080"&gt;"(no subject)"&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;
                _subject = subject
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
            _received = received
            _size = size
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; entryID &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; From &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; fromName &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; subject &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; received &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; DateTime, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; size &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; body &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
            &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.&lt;span style="color: #0000ff"&gt;New&lt;/span&gt;(entryID, From, fromName, subject, received, size)
            _body = body
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;

        &lt;span style="color: #008000"&gt;' MAPI unique ID&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; EntryID() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _entryID
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
                _entryID = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

        &lt;span style="color: #008000"&gt;' email address of sender&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; From() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _from
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
                _from = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

        &lt;span style="color: #008000"&gt;' name of sender&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; FromName() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _fromName
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
                _fromName = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; Subject() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _subject
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
                _subject = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; Body() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _body
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;)
                _body = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; Received() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; DateTime
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _received
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; DateTime)
                _received = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;

        &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt; Size() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; _size
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Get&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; value &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;)
                _size = value
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Set&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Property&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Namespace&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This class simply contains properties to describe an email message.&lt;/p&gt;
&lt;p&gt;You will note that both of these classes have the &lt;strong&gt;[Serializable]&lt;/strong&gt; attribute attached to them.&amp;nbsp; When objects are passed through WCF, they are serialized at the source and deserialized at the destination.&amp;nbsp; By marking the objects with the &lt;strong&gt;[Serializable]&lt;/strong&gt; attribute, the .NET CLR can do this for us automatically&amp;nbsp; since we are not using any complex data types in our entities.&lt;/p&gt;
&lt;p&gt;With our entities out of the way, we can define our contract.&amp;nbsp;&amp;nbsp;Inside&amp;nbsp;the &lt;strong&gt;Contracts&lt;/strong&gt;&amp;nbsp;directory, create a new &lt;strong&gt;Interface&lt;/strong&gt; file named &lt;strong&gt;IWHSMailService&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;This interface/contract will define three methods:&amp;nbsp; one method to return a tree of objects which represent the folder tree in Outlook (&lt;strong&gt;GetFolders&lt;/strong&gt;), one method to return a list of messages inside that folder (&lt;strong&gt;GetMessages&lt;/strong&gt;), and one method to return the contents of a specific message (&lt;strong&gt;GetMessages&lt;/strong&gt;).&amp;nbsp; The interface will look like the following:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.Collections.Generic;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; System.ServiceModel;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; WHSMailCommon.Entities;

&lt;span style="color: #0000ff"&gt;namespace&lt;/span&gt; WHSMailCommon.Contracts
{
    &lt;span style="color: #008000"&gt;// list of methods of the WHSMailService service&lt;/span&gt;
    [ServiceContract()]
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; IWHSMailService
    {
        [OperationContract]
        List&amp;lt;Folder&amp;gt; GetFolders();

        [OperationContract]
        List&amp;lt;Email&amp;gt; GetMessages(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; entryID, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; numPerPage, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; pageNum);

        [OperationContract]
        Email GetMessage(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; entryID);
    }
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; Microsoft.VisualBasic
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.Collections.Generic
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; System.ServiceModel
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; WHSMailCommon.Entities

&lt;span style="color: #0000ff"&gt;Namespace&lt;/span&gt; WHSMailCommon.Contracts
    &lt;span style="color: #008000"&gt;' list of methods of the WHSMailService service&lt;/span&gt;
    &amp;lt;ServiceContract()&amp;gt; _
    &lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Interface&lt;/span&gt; IWHSMailService
        &amp;lt;OperationContract&amp;gt; _
        &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; GetFolders() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(Of Folder)

        &amp;lt;OperationContract&amp;gt; _
        &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; GetMessages(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; entryID &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; numPerPage &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; pageNum &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(Of Email)

        &amp;lt;OperationContract&amp;gt; _
        &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; GetMessage(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; entryID &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Email
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Interface&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Namespace&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;As with the entities, this interface is also decorated with several attributes.&amp;nbsp; First, any WCF contract interface must be tagged with the &lt;strong&gt;[ServiceContract()]&lt;/strong&gt; attribute to define it as a contract to WCF.&amp;nbsp; Additionally, all methods which will be exposed for consumption by a client must be marked with the &lt;strong&gt;[OperationContract]&lt;/strong&gt; attribute.&lt;/p&gt;
&lt;p&gt;The implementation and description of these methods will come later when we write the contract implementation.&lt;/p&gt;
&lt;h4&gt;&lt;/h4&gt;
&lt;h4&gt;Configuration&lt;/h4&gt;
&lt;p&gt;The final thing to setup on the WCF server is the configuration file.&amp;nbsp; The service can very easily be configured using an application configuration file.&amp;nbsp; Add an &lt;strong&gt;Application Configuration&lt;/strong&gt; file to the project named &lt;strong&gt;App.config&lt;/strong&gt;.&amp;nbsp; Set the contents of the file to the following:&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;&amp;lt;?&lt;/span&gt;&lt;span style="color: #800000"&gt;xml&lt;/span&gt; &lt;span style="color: #ff0000"&gt;version&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="1.0"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;encoding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="utf-8"&lt;/span&gt; ?&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;bindings&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;netTcpBinding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;binding&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="NewBinding0"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;security&lt;/span&gt; &lt;span style="color: #ff0000"&gt;mode&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="None"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;binding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;netTcpBinding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;bindings&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;services&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;service&lt;/span&gt; &lt;span style="color: #ff0000"&gt;name&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="WHSMailHost.WHSMailService"&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;&amp;lt;&lt;/span&gt;&lt;span style="color: #800000"&gt;endpoint&lt;/span&gt; &lt;span style="color: #ff0000"&gt;address&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="net.tcp://localhost:12345/IWHSMailService"&lt;/span&gt;
                    &lt;span style="color: #ff0000"&gt;binding&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="netTcpBinding"&lt;/span&gt; &lt;span style="color: #ff0000"&gt;bindingConfiguration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="NewBinding0"&lt;/span&gt;
                    &lt;span style="color: #ff0000"&gt;contract&lt;/span&gt;&lt;span style="color: #0000ff"&gt;="WHSMailCommon.Contracts.IWHSMailService"&lt;/span&gt; &lt;span style="color: #0000ff"&gt;/&amp;gt;&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;service&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;services&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;system.serviceModel&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;
&lt;span style="color: #0000ff"&gt;&amp;lt;/&lt;/span&gt;&lt;span style="color: #800000"&gt;configuration&lt;/span&gt;&lt;span style="color: #0000ff"&gt;&amp;gt;&lt;/span&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The &lt;strong&gt;&amp;lt;services&amp;gt;&lt;/strong&gt; section defines the services that the WCF host will enable.&amp;nbsp; This creates a single &lt;strong&gt;&amp;lt;service&amp;gt;&lt;/strong&gt; named &lt;strong&gt;WHSMailHost.WHSMailService&lt;/strong&gt;, which is the full name of the service class that we will implement shortly.&amp;nbsp; Inside the &lt;strong&gt;&amp;lt;service&amp;gt;&lt;/strong&gt; tag an endpoint is defined.&amp;nbsp; And endpoint is essentially the "port" on which the client connects.&amp;nbsp; The endpoint defined here is using the &lt;strong&gt;net.tcp&lt;/strong&gt; protocol and is set to listen on the &lt;strong&gt;localhost&lt;/strong&gt; on port &lt;strong&gt;12345&lt;/strong&gt; at the name &lt;strong&gt;IWHSMailService&lt;/strong&gt;.&amp;nbsp; The next thing defined is a binding.&amp;nbsp; This sets protocol by which the service will communicate, its configuration,&amp;nbsp;and the contract it implements.&amp;nbsp; The binding configuration named &lt;strong&gt;NewBinding0&lt;/strong&gt; (a default name) can be found above inside the &lt;strong&gt;&amp;lt;bindings&amp;gt;&lt;/strong&gt; tag.&amp;nbsp; The only configuration item that is specified is that security will be turned off for communication between the client and server.&amp;nbsp; Given that these two machines will be connecting to each other on your own local network, security is not a great concern.&amp;nbsp; If you were to use this over a real internet connection where the client and server were open to the outside world, you would definitely not want to do this.&lt;/p&gt;
&lt;p&gt;There are around several billion other options, protocols, bindings, etc. etc. etc. that can be configured here.&amp;nbsp; At the end of the article you will find several links to WCF documentation that you can explore to learn more about the WCF internals.&amp;nbsp; Also note that you can configure WCF with a windows UI by selecting the &lt;strong&gt;Service Configuration Editor&lt;/strong&gt; application installed with the Windows SDK.&amp;nbsp; You'll find this in the &lt;strong&gt;Microsoft Windows SDK&lt;/strong&gt; program group off your Start menu.&lt;/p&gt;
&lt;h3&gt;Outlook and MAPI&lt;/h3&gt;
&lt;p&gt;MAPI (Messaging Application Programming Interface) is what allows one to develop applications and plugins for Microsoft Outlook and other messaging applications which support it (Exchange, Windows Messaging, etc.).&amp;nbsp; We will be using MAPI to get the data we require from Outlook for our application.&lt;/p&gt;
&lt;p&gt;Earlier we created a contract named &lt;strong&gt;IWHSMailService&lt;/strong&gt;.&amp;nbsp; This contract will be implemented by the &lt;strong&gt;WHSMailService&lt;/strong&gt; class that was also created earlier.&amp;nbsp; To do this, set a reference to the project's &lt;strong&gt;WHSMailCommon&lt;/strong&gt; assembly.&amp;nbsp; Then, bring the &lt;strong&gt;Contracts&lt;/strong&gt; and &lt;strong&gt;Entities&lt;/strong&gt; namespaces into the &lt;strong&gt;WHSMailService&lt;/strong&gt; class with the following:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; WHSMailCommon.Contracts;
&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; WHSMailCommon.Entities;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; WHSMailCommon.Contracts
&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; WHSMailCommon.Entities&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Then, setup the class to implement the interface as follows:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;class&lt;/span&gt; WHSMailService : IWHSMailService&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Class&lt;/span&gt; WHSMailService
    &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IWHSMailService
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Visual Studio will then create the 3 methods that must be implemented according to the interface (&lt;strong&gt;GetFolders&lt;/strong&gt;, &lt;strong&gt;GetMessages&lt;/strong&gt;, &lt;strong&gt;GetMessage&lt;/strong&gt;).&amp;nbsp; We will fill those in shortly.&amp;nbsp; But first, we must implement our constructor.&amp;nbsp; When WCF calls the service, a new instance of the object will be created on each call.&amp;nbsp; Therefore, it is easy to setup any initialization code for the service in the default constructor method.&amp;nbsp; In this case, we will initialize the MAPI layer and logon to the default instance.&lt;/p&gt;
&lt;p&gt;First, set a reference to the &lt;strong&gt;Microsoft Outlook XX.0 Object Library&lt;/strong&gt; which you will find under the COM tab assuming Outlook is installed as per the instructions above.&amp;nbsp; Note that the version will depend on what version of Outlook you have installed on your local machine.&amp;nbsp; I'm using Outlook 2007, so version 12 is what the sample code above is referencing.&amp;nbsp; If you are using a different version, reference the appropriate version before continuing.&lt;/p&gt;
&lt;p&gt;Once the reference is set, bring the namespace into the &lt;strong&gt;WHSMailService&lt;/strong&gt; class with the following line which will import the namespace and setup an alias named &lt;strong&gt;Outlook&lt;/strong&gt; to save some typing:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;using&lt;/span&gt; Outlook = Microsoft.Office.Interop.Outlook;&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Imports&lt;/span&gt; Outlook = Microsoft.Office.Interop.Outlook&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Now the constructor can be implemented.&amp;nbsp; We need to get an instance of the Outlook &lt;strong&gt;ApplicationClass&lt;/strong&gt;.&amp;nbsp; From there we can get an instance of the &lt;strong&gt;MAPI&lt;/strong&gt; namespace.&amp;nbsp; All methods that we will be using hang off that namespace object.&amp;nbsp; The code for the constructor follows:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;readonly&lt;/span&gt; Outlook.NameSpace _nameSpace = &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;;

&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; WHSMailService()
{
    &lt;span style="color: #008000"&gt;// get an instance of the MAPI namespace and login&lt;/span&gt;
    Outlook.Application app = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Outlook.ApplicationClass();
    _nameSpace = app.GetNamespace(&lt;span style="color: #006080"&gt;"MAPI"&lt;/span&gt;);
    _nameSpace.Logon(&lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;false&lt;/span&gt;);
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;ReadOnly&lt;/span&gt; _nameSpace &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Outlook.&lt;span style="color: #0000ff"&gt;NameSpace&lt;/span&gt; = &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;

&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; &lt;span style="color: #0000ff"&gt;New&lt;/span&gt;()
    &lt;span style="color: #008000"&gt;' get an instance of the MAPI namespace and login&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; app &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Outlook.Application = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Outlook.ApplicationClass()
    _nameSpace = app.GetNamespace(&lt;span style="color: #006080"&gt;"MAPI"&lt;/span&gt;)
    _nameSpace.Logon(&lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;False&lt;/span&gt;)
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;With a handle to the namespace, we can write our &lt;strong&gt;GetFolders&lt;/strong&gt; method.&amp;nbsp; This method will get the default Inbox folder in the default Outlook message store, look at the parent node, recursively enumerate from there, pulling out only folders that contain mail items, and finally sort them alphabetically (recall the &lt;strong&gt;CompareTo&lt;/strong&gt; method of the &lt;strong&gt;IComparable&lt;/strong&gt; interface we implemented earlier).&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; List&amp;lt;Folder&amp;gt; GetFolders()
{
    List&amp;lt;Folder&amp;gt; list = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;Folder&amp;gt;();

    &lt;span style="color: #008000"&gt;// get the inbox and then go up one level...that *should* be the root of the default store&lt;/span&gt;
    Outlook.MAPIFolder root = (Outlook.MAPIFolder)_nameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox).Parent;

    &lt;span style="color: #008000"&gt;// add root folder&lt;/span&gt;
    Folder folder = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Folder(root.EntryID, root.Name, root.UnReadItemCount, root.Items.Count);
    list.Add(folder);

    &lt;span style="color: #008000"&gt;// Enumerate the sub-folders&lt;/span&gt;
    EnumerateFolders(root.Folders, folder);

    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; list;
}

&lt;span style="color: #0000ff"&gt;private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; EnumerateFolders(Outlook.Folders folders, Folder rootFolder)
{
    &lt;span style="color: #0000ff"&gt;foreach&lt;/span&gt;(Outlook.MAPIFolder f &lt;span style="color: #0000ff"&gt;in&lt;/span&gt; folders)
    {
        &lt;span style="color: #008000"&gt;// ensure it's a folder that contains mail messages (i.e. no contacts, appointments, etc.)&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(f.DefaultItemType == Outlook.OlItemType.olMailItem)
        {
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(rootFolder.Folders == &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
                rootFolder.Folders = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;Folder&amp;gt;();

            &lt;span style="color: #008000"&gt;// add the current folder and enumerate all sub-folders&lt;/span&gt;
            Folder subFolder = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Folder(f.EntryID, f.Name, f.UnReadItemCount, f.Items.Count);
            rootFolder.Folders.Add(subFolder);
            &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(f.Folders.Count &amp;gt; 0)
                &lt;span style="color: #0000ff"&gt;this&lt;/span&gt;.EnumerateFolders(f.Folders, subFolder);
        }
    }

    &lt;span style="color: #008000"&gt;// alphabetize the list (Folder implements IComparable)&lt;/span&gt;
    rootFolder.Folders.Sort();
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; GetFolders() &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(Of Folder) &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IWHSMailService.GetFolders
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; list &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(Of Folder) = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; List(Of Folder)()

    &lt;span style="color: #008000"&gt;' get the inbox and then go up one level...that *should* be the root of the default store&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; root &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Outlook.MAPIFolder = &lt;span style="color: #0000ff"&gt;CType&lt;/span&gt;(_nameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox).Parent, Outlook.MAPIFolder)

    &lt;span style="color: #008000"&gt;' add root folder&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; folder &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Folder = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Folder(root.EntryID, root.Name, root.UnReadItemCount, root.Items.Count)
    list.Add(folder)

    &lt;span style="color: #008000"&gt;' Enumerate the sub-folders&lt;/span&gt;
    EnumerateFolders(root.Folders, folder)

    &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; list
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;

&lt;span style="color: #0000ff"&gt;Private&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Sub&lt;/span&gt; EnumerateFolders(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; folders &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Outlook.Folders, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; rootFolder &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Folder)
    &lt;span style="color: #0000ff"&gt;For&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Each&lt;/span&gt; f &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Outlook.MAPIFolder &lt;span style="color: #0000ff"&gt;In&lt;/span&gt; folders
        &lt;span style="color: #008000"&gt;' ensure it's a folder that contains mail messages (i.e. no contacts, appointments, etc.)&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; f.DefaultItemType = Outlook.OlItemType.olMailItem &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; rootFolder.Folders &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                rootFolder.Folders = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; List(Of Folder)()
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;

            &lt;span style="color: #008000"&gt;' add the current folder and enumerate all sub-folders&lt;/span&gt;
            &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; subFolder &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Folder = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Folder(f.EntryID, f.Name, f.UnReadItemCount, f.Items.Count)
            rootFolder.Folders.Add(subFolder)
            &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; f.Folders.Count &amp;gt; 0 &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
                &lt;span style="color: #0000ff"&gt;Me&lt;/span&gt;.EnumerateFolders(f.Folders, subFolder)
            &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Next&lt;/span&gt; f

    &lt;span style="color: #008000"&gt;' alphabetize the list (Folder implements IComparable)&lt;/span&gt;
    rootFolder.Folders.Sort()
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; Sub&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;This code will return a generic hierarchal list of our &lt;strong&gt;Folder&lt;/strong&gt; entity objects which&amp;nbsp;will be displayed in the web application.&amp;nbsp; Note that one of the items assigned to the &lt;strong&gt;Folder&lt;/strong&gt; entity is the &lt;strong&gt;EntryID&lt;/strong&gt; property from the &lt;strong&gt;MAPIFolder&lt;/strong&gt; object.&amp;nbsp; All MAPI items, be they email messages, folders, appointments, etc. have a unique identifier which is stored in the &lt;strong&gt;EntryID&lt;/strong&gt; field.&amp;nbsp; We will need this unique value later on to retrieve messages from that folder.&lt;/p&gt;
&lt;p&gt;Next, let's implement the &lt;strong&gt;GetMessages&lt;/strong&gt; method.&amp;nbsp; This method will return a list of messages (minus the bodies) from&amp;nbsp;the folder specified using the &lt;strong&gt;GetFolderFromID&lt;/strong&gt; method, sorted by the received date with the most current first.&amp;nbsp; It will also handle paging so that the entire folder is not returned at once.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; List&amp;lt;Email&amp;gt; GetMessages(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt; entryID, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; numPerPage, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; pageNum)
{
    List&amp;lt;Email&amp;gt; list = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; List&amp;lt;Email&amp;gt;();

    Outlook.MAPIFolder f;

    &lt;span style="color: #008000"&gt;// if no ID specified, open the inbox&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;string&lt;/span&gt;.IsNullOrEmpty(entryID))
        f = _nameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox);
    &lt;span style="color: #0000ff"&gt;else&lt;/span&gt;
        f = _nameSpace.GetFolderFromID(entryID, &lt;span style="color: #006080"&gt;""&lt;/span&gt;);

    &lt;span style="color: #008000"&gt;// to handle the sorting, one needs to cache their own instance of the items object&lt;/span&gt;
    Outlook.Items items = f.Items;

    &lt;span style="color: #008000"&gt;// sort descending by received time&lt;/span&gt;
    items.Sort(&lt;span style="color: #006080"&gt;"[ReceivedTime]"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;true&lt;/span&gt;);

    &lt;span style="color: #008000"&gt;// pull in the correct number of items based on number of items per page and current page number&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; i = (numPerPage*pageNum)+1; i &amp;lt;= (numPerPage*pageNum)+numPerPage &amp;amp;&amp;amp; i &amp;lt;= items.Count; i++)
    {
        &lt;span style="color: #008000"&gt;// ensure it's a mail message&lt;/span&gt;
        Outlook.MailItem mi = (items[i] &lt;span style="color: #0000ff"&gt;as&lt;/span&gt; Outlook.MailItem);
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(mi != &lt;span style="color: #0000ff"&gt;null&lt;/span&gt;)
            list.Add(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Email(mi.EntryID, mi.SenderEmailAddress, mi.SenderName, mi.Subject, mi.ReceivedTime, mi.Size));
    }

    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; list;
}
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;VB&lt;/strong&gt;&lt;/p&gt;
&lt;div style="border-right: gray 1px solid; padding-right: 4px; border-top: gray 1px solid; padding-left: 4px; font-size: 8pt; padding-bottom: 4px; margin: 20px 0px 10px; overflow: auto; border-left: gray 1px solid; width: 97.5%; cursor: text; max-height: 200px; line-height: 12pt; padding-top: 4px; border-bottom: gray 1px solid; font-family: consolas, 'Courier New', courier, monospace; background-color: #f4f4f4"&gt;&lt;pre style="padding-right: 0px; padding-left: 0px; font-size: 8pt; padding-bottom: 0px; margin: 0em; overflow: visible; width: 100%; color: black; border-top-style: none; line-height: 12pt; padding-top: 0px; font-family: consolas, 'Courier New', courier, monospace; border-right-style: none; border-left-style: none; background-color: #f4f4f4; border-bottom-style: none"&gt;&lt;span style="color: #0000ff"&gt;Public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt; GetMessages(&lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; entryID &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; numPerPage &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;ByVal&lt;/span&gt; pageNum &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt;) &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(Of Email) &lt;span style="color: #0000ff"&gt;Implements&lt;/span&gt; IWHSMailService.GetMessages
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; list &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; List(Of Email) = &lt;span style="color: #0000ff"&gt;New&lt;/span&gt; List(Of Email)()

    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; f &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Outlook.MAPIFolder

    &lt;span style="color: #008000"&gt;' if no ID specified, open the inbox&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;String&lt;/span&gt;.IsNullOrEmpty(entryID) &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
        f = _nameSpace.GetDefaultFolder(Outlook.OlDefaultFolders.olFolderInbox)
    &lt;span style="color: #0000ff"&gt;Else&lt;/span&gt;
        f = _nameSpace.GetFolderFromID(entryID, &lt;span style="color: #006080"&gt;""&lt;/span&gt;)
    &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;

    &lt;span style="color: #008000"&gt;' to handle the sorting, one needs to cache their own instance of the items object&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; items &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Outlook.Items = f.Items

    &lt;span style="color: #008000"&gt;' sort descending by received time&lt;/span&gt;
    items.Sort(&lt;span style="color: #006080"&gt;"[ReceivedTime]"&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;True&lt;/span&gt;)

    &lt;span style="color: #008000"&gt;' pull in the correct number of items based on number of items per page and current page number&lt;/span&gt;
    &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; i &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; = (numPerPage*pageNum)+1
    &lt;span style="color: #0000ff"&gt;Do&lt;/span&gt; &lt;span style="color: #0000ff"&gt;While&lt;/span&gt; i &amp;lt;= (numPerPage*pageNum)+numPerPage &lt;span style="color: #0000ff"&gt;AndAlso&lt;/span&gt; i &amp;lt;= items.Count
        &lt;span style="color: #008000"&gt;' ensure it's a mail message&lt;/span&gt;
        &lt;span style="color: #0000ff"&gt;Dim&lt;/span&gt; mi &lt;span style="color: #0000ff"&gt;As&lt;/span&gt; Outlook.MailItem = (&lt;span style="color: #0000ff"&gt;TryCast&lt;/span&gt;(items(i), Outlook.MailItem))
        &lt;span style="color: #0000ff"&gt;If&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Not&lt;/span&gt; mi &lt;span style="color: #0000ff"&gt;Is&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Nothing&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Then&lt;/span&gt;
            list.Add(&lt;span style="color: #0000ff"&gt;New&lt;/span&gt; Email(mi.EntryID, mi.SenderEmailAddress, mi.SenderName, mi.Subject, mi.ReceivedTime, mi.Size))
        &lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;If&lt;/span&gt;
        i += 1
    &lt;span style="color: #0000ff"&gt;Loop&lt;/span&gt;

    &lt;span style="color: #0000ff"&gt;Return&lt;/span&gt; list
&lt;span style="color: #0000ff"&gt;End&lt;/span&gt; &lt;span style="color: #0000ff"&gt;Function&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;The method takes a string parameter named &lt;strong&gt;entryID&lt;/strong&gt; which is the unique identifier of the folder (from the code above) from which to return the messages.&amp;nbsp; If no ID is specified, messages are returned from the Inbox.&amp;nbsp; This code also handles paging by indexing into the array of &lt;strong&gt;Items&lt;/strong&gt; of the &lt;strong&gt;MAPIFolder&lt;/strong&gt; object at the specified position and counting out &lt;strong&gt;numPerPage&lt;/strong&gt; records to be returned.&amp;nbsp; A list of &lt;strong&gt;Email&lt;/strong&gt; entity objects is returned from this method to be displayed on the web interface.&lt;/p&gt;
&lt;p&gt;Finally, let's implement the &lt;strong&gt;GetMessage&lt;/strong&gt; method.&amp;nbsp; This will return a specific message based on the MAPI &lt;strong&gt;EntryID&lt;/strong&gt; using the &lt;strong&gt;GetItemFromID&lt;/strong&gt; method and format the body for plain text or HTML display.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;C#&lt;/strong&gt;&lt;/p&gt;