Sunday, July 19, 2009

Historical Debugging in VSTS 2010

One more of the very cool features that is coming with Visual Studio Team System 2010 is Historical Debugging. This is just one of those things that makes me go WOW! What this gets us is the ability to debug code that has already run. Perhaps it was even run by a tester. On another computer!

There are a few things that take a bit of poking at to get the hang of but once you learn the twists and turns of where to configure everything the technology does work exceptionally well. And this is on Beta 1!!!

The settings for the historical debugger are found within the Visual Studio options off of the Tools –> options menu selection. Scroll down until you see the root level Historical Debugging menu as shown in the screenshot below. Most of the options are reasonably straight forward. On the General settings tab is the option to enable or disable Historical Debugging as well as the option of how much information to track. The default settings enable Historical Debugging and track events only. To really see the power of Historical Debugging select the Events, Methods and Parameters option.


To test these features I have created a simple sample application using a single project that compiles to one assembly, however this process works just as well with larger applications that consist of multiple assemblies. Once you have set the options to meet your needs run your application. To demonstrate some of the interesting aspects my application creates a simple data transfer object in the UI class that is populated from user supplied data, passes the object to a controller class that then passes the object to a validation method on another class and based on the validation results passes the object to a data access layer for persistence. Not an uncommon scenario in a simple business application.

Running my application I enter and submit data however after I click the Save button all of the input textboxes are cleared. The application should have populated the fields with the values of the object after saving but instead a null reference exception is thrown and caught by Visual Studio.



The screenshot shows Visual Studio after it has caught the breakpoint. The Debug History window is displayed. The default view shows the significant events that the historical debugger has tracked ending with the Exception event that was thrown, the break that the debugger implemented and finally the option to return to the live debugging session. To view the details of the methods and parameters rather than just the events click the icon second from the left on the debugging window toolbar (Show Tree View).

A couple of things to note is the view of the call stack in the Historical Debugging window. The last entry in the window shows that the Person parameter that was passed to the DisplayPerson method was null. On the code editor window you can see the navigation gutter that displays the VCR style controls for navigating back through the code. Using the navigation controls we can navigate up the call stack to the point where we call the Controller.SavePerson method. From here we can step into the SavePerson method and inspect that values of the properties of the Person object that was supplied to the method. We can use the navigation icons in the gutter or the typical debug step commands (step into, step over, etc) to navigate about our code to determine what the problem is and where it occurred, all without restarting our application. There is no need to set breakpoints within the application to start a fresh debug session to find where the problem is, the Historical Debugger takes care of everything for us as we ran through the application the first time.

This is a great time saver that will make debugging problems much faster and easier. In my next post I will demonstrate how to leverage the new testing tools to capture historical debug logs that can then be passed from a tester to a developer to determine exactly what values were supplied by the tester as well as the exact path that they took through the code.
[Update: Oct 20, 2009: Historical Debugging has been renamed Intellitrace]

Saturday, July 18, 2009

Detailing Use Cases (part 5 of 5)

In this final post in my VSTS 2010 Use Cases series I have a few parting words about use cases and what this process is meant to achieve.  I hope you have enjoyed these posts and find some value in them.

User stories provide a concise and agile means for understanding the high level desires of the user community. Expanding user stories into use cases and actors provides a means for examining the user stories from another perspective. Increasing the perspectives of observation will generally bring greater understanding to a problem space. By expanding the user stories it becomes easier to combine and re-arrange them into manners that add meaning to other actors than initially defined as well as see how use cases can relate to each other. The approach of combining user stories and use case modeling enables a robust and wide view of the system functionality. However it is rarely sufficient.

Each use case defined within the model should also include a text based use case. The recognized standard use case has been defined by Alistair Cockburn (Cockburn, 2001). The document form of a use case expands upon an individual UML use case by detailing the steps that are exchanged between the system and the user as well as alternate steps and exception cases as well as pre-conditions and post-conditions. A use case template should be established using MS Word and used to provide consistency. Each individual use case in the model should have a matching document which is stored in the SharePoint Portal site of the TFS project. Use case documents provide a depth view of an individual use case. Of course, expanding UML use cases and their corresponding user stories into use case documents does not need to happen completely up front prior to any development effort. In an agile approach the use case document is often the result of the conversation with the user about the user story.

For each use case document you may choose to create an artifact entity on a diagram and provide the path to the document in the SharePoint site. Since artifacts appear in the UML Model Explorer they become an integral part of the model and provide instant traceability between the model and the document. In addition to adding a reference to the use case document as an Artifact element in the model a hyperlink should also be created in the user story work item by adding a hyperlink in the links tab to the same SharePoint location.

So What Does This Get Us?

It may seem as though we are duplicating effort and information by creating use case diagrams and user stories since they both capture the same information. Creating use cases using UML Diagrams provides a very quick and easy way to view the functionality of the system in a visual manner. These diagrams can be printed and posted or copied into other documents for ease of reference. UML Diagrams are a concise format for conveying a significant amount of information as well as providing a means of relating user stories together to see how they relate. Diagrams can be created that reuse use cases that are displayed on other diagrams to provide distinct perspectives of the system under development. For example, creating a diagram that focuses on a specific actor provides users that fulfill that role a view of the system as it is relevant to them whereas a diagram that focuses on functionality as it spans multiple actors can provide a view into gaps in a process or missing steps.

Having the model tied to the user stories incorporates a link to an increased detail level that also provides links and traceability to the work that is performed to deliver the requested functionality. Since the user stories are Team Foundation Server work items they have all of the capabilities and integration that make work items such a powerful means for tracking, monitoring and managing a project while still providing a tie to the model and diagrams.

The benefits of tying these types of things (UML Model elements and work items) together is at the core of the integrated lifecycle tooling provided by Visual Studio Team System bringing traceability, flexibility and integration in a cohesive and powerful product.

 

Bibliography

Cockburn, A. (2001). Writing Effective Use Cases. Addison-Wesley.

Thursday, July 16, 2009

Expanding on Use Cases and User Stories (part 4 of 5)

As the development team begins to investigate the user stories they have conversations with the business users uncovering more details about how the system is expected to work. As the conversations uncover details the user stories expand and often result in new stories being created that help divide the initial story into more manageable pieces of work. These expanded user stories result in more use cases as well. Dependencies begin to evolve as more and more of the system needs are understood. For example the use case “Look up Order” when used by a “Call Center Worker” requires that the “Call Center Worker” has previously performed the “Lookup Customer Data” use case. As conversations are had about the “Lookup Customer Data” user story it may be determined that the initial user story can be broken down into the following two stories:
  • Search for Customer
  • Retrieve Single Customer Data (formerly Lookup Customer Data)
Once the Call Center Worker has performed the search they are able to retrieve the single customer’s specific data. There is a dependency between the two user stories. In addition to this relationship the “Retrieve Single Customer Data” may be intended to retrieve information about the customer’s contacts and primary address information as well as a list of the orders that they have currently active. This can create a relationship between “Retrieve Single Customer Data” and “Look up Order”. Understanding these relationships between user stories can be difficult. When user stories are created using index cards defining relationships between them is a challenge, especially as the relationships become more complex. Using Team Foundation Server work items the relationships can be managed using work item links but this is not ideal as the work item links are not displayed in a convenient graphical format for navigating that type of information. If you are mapping your user stories to sue cases using the UML Model Explorer creating and defining these relationships becomes very easy as this is one of the purposes of the UML. Let’s look at a more complex diagram and dissect the parts to fully understand both the capabilities of the use case diagram in Visual Studio Team Architect as well as the expressive capabilities of the UML

The above diagram includes all of the elements available for use cases within Visual Studio Team Architect as depicted in the screenshot of the toolbox below. We have seen examples of the most rudimentary elements the use case, actors and associations. The Subsystem is perhaps as common as the actor, use case and association elements. It is rare when a use case diagram is created without also including a subsystem element. This element denotes the boundaries of systems. There may be zero or more subsystems on a given diagram. The example above is using the subsystem element to denote the application that is to be developed.

Notice the actor to the right of the subsystem boundary, the Identity Management System. Although this is an external application that is called by the system under development since it is not part of the system that is being built it is represented as another actor that the Transportation system interacts. The association relationship between the Logon use case and the Identity Management System actor has a cardinality indicating that a single instance of the Identity Management System can interact with multiple instances of the Logon use case at once. The association relationships between the Customer actor and the Logon use case has a cardinality of 1 on both ends indicating that a single Customer may only interact with a single instance of the Logon use case at any given time.

The logon use case demonstrates many of the relationships that are possible with a use case diagram. The first type of relationship of interest is the Generalization. The Logon to Mobile and the Logon to Website use cases are both generalizations of the Logon use case. This indicates to the development team that there will be common functionality that can be reused between the mobile and web based logon use cases while also indicating the logging on to the system from either a mobile device or a website will require some specific details for each. The next relationship demonstrated by the Logon use case is the Dependency. The Logon use case is dependent on the Retrieve Permissions use case. Although the Retrieve Permissions use case is distinct without being able to retrieve a user’s permissions the logon will not be able complete. In comparison the Logon use case includes the Retrieve Customer Data use case. This demonstrates that the logon functionality will also include retrieving the customer’s data as part of the logon procedure. It is useful to break the Retrieve Customer Data out from the logon use case for a couple of reasons;
  1. including it with the logon functionality would place too much functionality within a single use case to be developed in a meaningful manner
  2. the logon and customer data retrieval are distinct capabilities and can be developed separately
  3. the customer data retrieval will also be used by other actors as part of other processes that are not associated with the logon

The last relationship type is the extends relationship type. The Search for Customer Order use case extends the Search for Customer use case by adding an extends relationship with the arrow end of the relationship pointing to the use case that is being extended. The Search for Customer Order functionality will use the functionality of the Search for Customer use case while adding some functionality of its own to also find orders for customers at the same time.
The last two elements on the diagram are comments and artifacts. Comments can be associated with other elements as shown in the diagram or they can simply float on a diagram without a comment link. Comments are not a part of the UML model and do not show up in the UML Model Explorer. Comments are used to add short notes to the diagram. Artifacts are convenient elements to add to a diagram when it is helpful to provide a link to further documents. Looking at the properties for the artifact demonstrates the File Name property that can be configured to point to a file on a local file share. When working with Team Foundation Server it is helpful to have this location reference a document stored in one of the SharePoint document libraries that is part of the portal for the Team


Once the use cases have been created link them to the user stories. Link the Logon use case to the “As a user I want to logon to the application” user story by performing the following steps:
  1. Right click the Logon use case and select “Link to Work item”
  2. The standard Team Foundation Server “Work Items Picker” dialog is displayed. Expand the dropdown list by the Saved Query option and select “Open User Stories” from the “Team Queries” list.
  3. Click the “Find” button and select the correct user story from the list and click the OK button

The next time you right click the Logon user story from any diagram the additional “View Work Items” option will be available. Clicking this option will display a list of all of the worked items that have been linked to this use case. You will have noticed that there is also the option to create a new work item from the context menu as well. This is particularly helpful as it is very common to identify new use cases and user stories as you work with the models. Unfortunately this is not a bi-directional link. There is no link back to the use case created from the work item and currently there is no way to create a link to a specific use case within the model. The best option available is to create a new link in the work item to a “Versioned Item” and reference the model file, a diagram or both.

Friday, July 10, 2009

Helping the Rangers

The Rangers are a very interesting and cool bunch of guys that work for Microsoft as sort of evangelist/consultants. They work on creating guidance as well as help customers effectively utilize Microsoft products.

I have been very fortunate to be involved in one of their projects as they will occasionally reach out to the MVP community to assist them. Willy-Peter Schaub is a former South African MVP turned Ranger and has been kind enough to post a blog entry thanking the MVP and other non-Microsofties that have been helping out with the various projects on the go. I always like to see my name in print by someone else (especially when it's in a favourable way)!

If you don't currently follow Willy's blog it is a great read on the happenings in the Ranger camp at Microsoft as well as a general good read. Willy creates the best graphics and post quite frequently. I don't know where he gets the time!

Building out Use Cases from User Stories (part 3 of 5)

The next step is to catalog into the model the user stories that we have captured as work items in Team Foundation Server. To begin each user story will be mapped to a use case. We will see how the model and the stories evolve as more information is learned in conversations with the users. For now simply map each user story to a use case by performing the following steps for each user story:
  1. From the UML Model Explorer window right click the model project and select Add -> Use Case
  2. Name the use case in a similar manner to the user story. For example the user story “As a customer I want to be able to look up my order to see if it has shipped” may become the use case “Look up orders” or perhaps “Look up shipped orders”

After entering several user stories, adding the roles from the user stories as actors and the actions and goals of the user stories as use cases a view of the UML Model Explorer and the user story list might look like the following:

Note that now the use cases match the user stories. For example the use case “Add New User” maps to the user story “As an application admin I want to add new users”. Coupling the use case with the “Application Administrator” actor provides the full fidelity of the user story. We will see how this is accomplished in a diagram shortly. One of the benefits of splitting the roles and actions apart into actors and use cases provides for the ability to demonstrate how multiple roles may benefit from the same use case as well as identify the common use cases between multiple roles.

The next step is to create use case diagrams to capture the user story intent between roles and actions as found in the title of the user stories. Do this by performing the following steps:
  1. Select the We Transport modeling project in the Solution Explorer
  2. Right click the We Transport project and select Add -> New Item…
  3. In the Add New Item dialog window select “Use Case Diagram”
  4. Name it “Orders.ucd” and click the OK button.
Visual Studio should now look similar to the following screenshot:



Now is a good time to check all of the artifacts that have been created into source control

  1. Right click the solution icon in the Solution Explorer and choose “Check In…”
  2. If asked, save any items that have not been saved
  3. Enter a comment noting the actions that have been performed since the last check in and click the Check In button
  4. Create the “As a customer I want to look up my order to see if it has shipped” as a diagram by first dragging the “Lookup Order” use case from the UML Model Explorer onto the middle of the use case diagram.
  5. Next drag the Customer actor from the UML Model Explorer onto the diagram to the left of the use case
  6. From the toolbox select the Association icon by clicking it.
  7. Note that the cursor indicates the invalid symbol until it is moved over the actor at which point it becomes an endpoint connection icon. Click on the Customer actor on the diagram
  8. Move the cursor over the use case on the diagram and click to associate the other end of the association with the use case.Your diagram should now look like the following:

Note the “+” icons that now appear beside the Customer actor and the Look up Order use case in the Model Explorer. Expand the “+” icons to see the relationships that were created in the diagram are reflected in the model.


You can add a comment to the use case diagram by either right clicking on the diagram surface or dragging a comment icon from the toolbox onto the diagram. You can association the comment with either an actor or a use case if the comment applies specifically to one of them. Associate a comment with an actor or a use case by adding a comment to the diagram and adding a comment link from the toolbox between the two or you can right click on either actor or use case and select Add -> Comment. This will create both the comment and the comment link association automatically. Although comments do not appear in the UML Model Explorer they are still added to the model xml file.

A benefit of presenting user stories as UML use cases in Visual Studio Team Architect is the easy view the UML Model Explorer provides to the list of available actors. As a use case is created using a single actor, such as the Look up Order example above it becomes easy to review the other roles to see if the same use case applies to any of them as well. In this example it is easy to see that the Call Center Worker is also likely to need to look up an order. When additional roles are identified that would leverage the same use case they should be added to the diagram.

Consider a user story titled “As a Driver I want to be able to log on to the application” this might translate into a use case called “Logon to Application” with an association between the use case and the actor “Driver”. It should become clear when this user story is defined that the same story will apply to each of the roles identified. Regardless of which role a user may belong the same user story would apply. To accommodate this situation a generic “user” role would be defined and the user story would read “As a User I want to be able to log on to the application”. “User” becomes an actor in the model of which all of the other actors inherit. This makes defining use cases that apply to all users of the application more concise and easier to read. Add a generic “User” actor to the system by performing the following steps:
  1. Right click the UML Model Explorer and select Add -> Actor
  2. Name the Actor “User”
  3. Set the “Abstract” property for the “User” actor to “true”

As noted in the text at the bottom of the screen setting the abstract property to true indicates that this actor or element, “does not provide a complete declaration and can typically not be instantiated”. This means that further refinement is required to fully flesh it out and provide sufficient meaning.
The next step is to add a diagram to visually layout the associations between the various actors within the system. A new use case diagram will be used to hold this representation.
  1. Right click the model project in Solution Explorer and select Add -> New Item…
  2. Select Use Case Diagram and name it “Roles Relations.ucd”
  3. Add all of the actors onto the diagram
  4. Place the User actor towards the top center of the diagram with the remaining actors in a single row towards the middle of the diagram
  5. Select the Generalization icon from the toolbox and click first one of the specific actors and then the abstract “User” actor creating a generalization between the two starting with the more specific actor
  6. Repeat this association for all of the remaining actors. Your diagram should resemble the one below.

Note that the name of the “User” actor is in italics denoting that this element is abstract. The generalization associations are denoted by a line with an open arrow head at the end closest to the abstract, or parent, element. The end of the association without the arrowhead denotes the specialized element.

This generalization is also indicated in the UML Model Explorer by expanding the individual actor elements and further expanding the Relationships folder underneath each. Once the generalizations have been created a use case diagram can be created showing the abstract “User” actor associated with the “Logon to Application” use case. This shows that each of the actors in the system can log on to the system without cluttering the diagram with each of the specialized actors. Generalization is very useful for keeping the intent of a diagram clear by not cluttering it with all of the specialized actors that are users of the use case.


That's it for this entry. Next time I will explore ways of expanding on these ideas for greater depth and detail.

Sunday, July 5, 2009

Beginning Use Cases – Identifying the Actors (part 2 of 5)

Every project must understand, to some degree, what is to be built, at least at a conceptual level. There are many techniques that have been used over the years ranging from formal, lengthy requirements specifications to short concise user stories. To be successful one of the fundamental goals of requirements is the need to bring value to all members of the team including the project stakeholders. Requirements must convey the requested functionality of the users in a means that the development team can use as a starting point to create and validate software. So far in this series we have looked at establishing requirements using work items and SharePoint portals as they are incorporated with a Team Foundation Server MSF for Agile Software Development v5.0 based project. Using the user story work items established previously we will look at how the process can proceed by taking advantage of use cases and their support in Visual Studio Team Architect 2010.

As this series of posts is all about making the most effective use of VSTS Architect a very specific approach will be used for evolving requirements with use cases. Use cases have two distinct facets; one is the graphical notation as defined by the UML while the other is a textual format that describes the interactions between an actor and a system. The approach taken here will utilize both techniques and show how to leverage Team Foundation Server to tie the pieces together building upon the techniques discussed earlier.

We started our project by establishing the user stories that are currently known and have been identified as the features and capabilities that the application should support to meet the needs and desires of the users. The next step once the user stories have been entered into Team Foundation Server is to create a new Visual Studio solution to contain our models. Starting the project by creating a model in Visual Studio Team Architect first is also a very viable option. Building a model first can be a very quick and easy way to visualize the relationships between requirements ensuring that there is consistent view of the proposed solution. User stories can easily be created from the use cases as we will see.

1. Begin by open Visual Studio Team Architect 2010

2. Select File -> New -> New Project

3. Select Modeling Project from the list of available project types. In the sample the project is named Models, the solution is named WeTransport and both the “Create directory for solution” and “Add to Source Control” options are selected.


4. Once the project is created the “Add Solution to Source Control” dialog window is presented

5. Select the WeTransport project from the list of projects in source control and click the OK button.

6. Check your files into source control

Open your list of user stories that have been created for the project and list each of the roles that have been identified. If you have been creating titles for your user stories of the form “As a «role» I want to «action» to achieve «goal»” you will be able to easily identify the majority of the roles by simply reading the titles of the stories. As an example the user story “As a customer I want to be able to look up my order to see if it has shipped” identifies the role “customer”. Watch for user stories that have identified the role as “user”, this is too generic as all roles that interact with your software will be users. Look for more specific roles such as Administrator, Customer, Call Center Operator, etc. For each role create a new Actor in the model. Using “Customer” as an example, perform the following steps:

1. Open the UML Model Explorer window. View -> Other Windows -> UML Model Explorer

2. Right click the model project “We Transport” within the model explorer

3. Select Add -> Actor

4. Name the new actor element “Customer”

Your model should now contain a single element of type Actor named Customer as shown below.

Continue adding the rest of the roles identified in your user stories as actors to the model.

Once you have added all of the roles identified in the user stories to the model you have a concise single location to review the actors that are involved in your application development effort. Each of the actors within the model represents a role that an end user can assume as they use the software. A single person may easily assume multiple roles, for example a call center worker may also be a supervisor. The specifics behind each of the actors/roles should be captured and documented within the SharePoint portal site for the team project. A common technique for defining the roles and to bring them to life for the team is to use personas. Not only do personas define the responsibilities and duties of an actor but they also provide a personality with a background, name and description that bring the persona to life. Teams commonly provide pictures to go with the personas and hang them in the team room to help remind the team who they are designing the software for.

Thursday, July 2, 2009

Use Cases and Visual Studio 2010 (part 1 of 5)

The Beginning

I would like to introduce an approach to developing software in an agile manner that leverages some of the new capabilities introduced with Visual Studio Team System 2010 and in particular focusing on the Architect Edition to add modeling into the software development process while still maintaining an agile methodology. This first post is about setting the stage for the project and the initial setup that will drive a series of posts on use cases.

The Company

The fictional company that we will be dealing with in this series is the We Transport transportation company. We Transport is a company that provides logistics and shipping information for their clients. Their clients are any other company that needs to move goods from one location to another in an ongoing manner. We Transport owns and operates a fleet of trucks and warehouses and operates throughout North America. They employ drivers, warehouse workers and clerical staff as well as hold contracts with individual contract drivers. We Transport also provides expedited shipping on an as needed basis for their clients by acting as a broker for the top three courier services available today. We Transport can also coordinate and broker shipments that include rail transportation and some ship based transportation although that portion of their business not considered a profit center and so is only offered to their larger customers in certain situations.

We Transport’s customers are typically either retail based enterprises that require consumer goods to supply their stores or are the manufacturers themselves that provide and store large quantities of goods from off shore locations to distribution warehouses throughout the continent. We Transport maintains and negotiates contracts with their customers that establish shipping rates based on frequency and quantity as well as storage fees to provide warehousing services. Although there are standard contract types that are used, each customer can request specific deals as part of the negotiated contract and as such each contract will have some degree of variation with all others.

The Project

We Transport has recently identified a need for a new application to provide increased services to their clients and increases operational efficiencies. An exhaustive build versus buy initiative was embarked upon with the end result being an identified need for a custom developed solution. We Transport has decided to embrace Visual Studio Team System for their initiative. We will examine how Team Foundation Server and Visual Studio Team System Architect can fit into the software development lifecycle.

To begin the endeavor a new project is created in the We Transport Team Foundation Server. We Transport is using Visual Studio Team System 2010 and they work in an agile manner, therefore the new project in Team Foundation Server is created using the MSF for Agile Software Development v5.0 template.

One of the work item types created as part of the MSF for Agile Software Development v5.0 project template is the “User Story”. A user story is a light weight artifact that is used by several of the more popular agile methodologies and is well documented and described by Mike Cohn (Cohn, 2004). In most organizations a user story is nothing more than a very short description written by a business focused team member, preferably a target user of the application but it can be an analyst or user proxy. The user story is written on a 3x5 index card and posted on a cork board where it is managed and tracked throughout its lifecycle. The user story represents nothing more than conversation that must take place between the business user and the developer of the story or development team. An accepted form of a user story is a sentence structured like: “As a <role> I want to perform <action> to achieve <goal>”.

The user story work item type as defined within the MSF for Agile Software Development v5.0 template tracks much more information than just the sentence as defined above. I recommended that you continue to use the index card approach along with the cork board for tracking if that is what you are comfortable with and as long as the method has been successful for you. However, you should also duplicate the index card in Team Foundation Server as a user story work item using the sentence on the card as the title of the work item.

Writing quality and meaningful user stories is a book unto itself and the definitive resource is Mike Cohn’s (Cohn, 2004), it is highly recommended that you get a copy of Mike’s book for further details on user stories. Identifying and cataloging the user stories for the system under development should be your first action when starting a new project. In fact this step almost always happens well before the project team has been assembled because these light weight requirements generally need to be identified to determine if there is even a need for a project and more often than not, these same user stories are used for initial estimation to determine target budgets, team size, and other resources required to bring together the rest of the project team. Once you have created your user stories and entered them into the Team Foundation Server project you can start to track and use them to drive the development of your project. Using the MSF for Agile Software Development v5.0 template to track and manage projects is not the topic of this series. Using Visual Studio Team System Architect is though, so we will switch gears in the next post to look at how to leverage Team Arch as part of the SDLC.

Bibliography

Cohn, M. (2004). User Stories Applied: For Agile Software Development. Addison-Wesley Professional.

Wednesday, July 1, 2009

MVP Award!

Today I was fortunate to be awarded the Microsoft Most Valuable Professional title. This is a fantastic award that I am very excited about.

I want to thank everyone that has helped me get to this position. I hope to continue to bring great value to the community regarding VSTS.