Dotneteers.net
All for .net, .net for all!

LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1

After I had held my presentation on September 16 on the VSX Developer Conference in Redmond I downloaded the presentation file just to check it again. Going through these slides are recognized that they do not tell too much without commentary. So I decided to publish it in commented form.

This blog post is the first part from the two, the second is coming soon.

Objectives

In this presentation my main objective is to show you how I think about the possibilities to improve the Managed Package Framework. I will demonstrate a bunch of implementation patterns I created in the frame of the VSXtra project.

Of course, I am hungry for your feedback, and I hope I can influence Microsoft guys responsible for the next major version of MPF.

My Personal Story

However, I deal with .NET framework from the first beta of the 1.0 version and Visual Studio from its first public release, Visual Studio Extensibility is a new field for me. To be honest I tried to create VSPackages since I have the first SDK for VS 2005 but I always got frustrated mainly because of the relatively high initial cost of getting into the world of VSX.

With the release of VS 2008 SDK I decided to pay that high cost and started to learn how VSX works and what is behind the scenes. I also decided to share the experience learned and created the LearnVSXNow project just at the beginning of this year.

I know I am relatively new in the community of seniors dealing with VSX and do not have so much knowledge and experience about extensibility details than the old guys from all around the world. However, being new in this field maybe allows me looking at the whole extensibility story with a fresh eye not dimmed by my former implementation experiences.

About Developer Experience

In order to treat why I think the current MPF experience can be improved, let me tell you a few thoughts about what I mean by DX.

“User Experience” and “Developer Experience” are among the most frequently used buzzwords today. We have heard very much about what user experience is, but a bit less about developer experience. I guess, developer experience is a kind of user experience where the “user” itself is a developer. I think there are many factors determining what the something we call developer experience is.

—  The Development Environment makes the first impression about DX. What kind of editors and designers we have there? What are the tools we can use in the environment? Can we customize or extend it?

—  Majority of developers opts for the Programming Model as a primary DX factor. What kind of object model is used there? Does is mirror the real world in a natural or intuitive way? What kind of programming paradigm is used? Imperative, functional or something else? Is the code using the model compact or verbose?

—  There is another important factor that best can be described with the word Guidance. What is the learning curve of a specific development product or technology? What is the quality of documentation and help provided? Are there any FAQs or samples to help developers’ perception?

I think, when we are talking about developer experience related to Visual Studio Extensibility, we face these primary factors.

The Role of Managed Package Framework

Let’s put the Managed Package Framework into the picture through the layered architecture of VSX components!

At the back we have the core services of the Visual Studio IDE. We can take it into account just like the Win32 API for the Windows operating systems. At the top we have applications for Visual Studio as Macros, Add-ins and Packages. There is a stack of components between the core services and the application layer. In my presentation I focus on the managed VSPackage development. In this area our VSPackages actually use COM interop assemblies over the Package and Automation APIs. The Managed Package Framework provides a great help to use an object model over the COM interop assemblies.

By its position we can say MPF is a primary factor for DX! Developers wanting to create extensions for Visual Studio qualify their experience according to how they feel when using MPF.

Demo: Feelings about MPF

To point out why I think the current MPF can be improved, let us see a few VSPackages created by the VSPackage wizard of Visual Studio. The first package is created with a simple menu command displaying a message box on the screen. Here I show the essential source code of the package, I omitted all comments to improve the readability:

using System;

using System.Diagnostics;

using System.Globalization;

using System.Runtime.InteropServices;

using System.ComponentModel.Design;

using Microsoft.VisualStudio.Shell.Interop;

using Microsoft.VisualStudio.Shell;

 

namespace MyCompany.SimpleMenuCommand

{

  [PackageRegistration(UseManagedResourcesOnly = true)]

  [DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0")]

  [InstalledProductRegistration(false, "#110", "#112", "1.0",

    IconResourceID = 400)]

  [ProvideLoadKey("Standard", "1.0", "SimpleMenuCommand", "MyCompany", 1)]

  [ProvideMenuResource(1000, 1)]

  [Guid(GuidList.guidSimpleMenuCommandPkgString)]

  public sealed class SimpleMenuCommandPackage : Package

  {

    public SimpleMenuCommandPackage()

    {

      Trace.WriteLine(string.Format(CultureInfo.CurrentCulture,

      "Entering constructor for: {0}", this.ToString()));

    }

 

    protected override void Initialize()

    {

      Trace.WriteLine(string.Format(CultureInfo.CurrentCulture,

        "Entering Initialize() of: {0}", this.ToString()));

      base.Initialize();

      OleMenuCommandService mcs = GetService(typeof(IMenuCommandService))

        as OleMenuCommandService;

      if (null != mcs)

      {

        CommandID menuCommandID =

          new CommandID(GuidList.guidSimpleMenuCommandCmdSet,

          (int)PkgCmdIDList.cmdidMyCommand);

        MenuCommand menuItem = new MenuCommand(MenuItemCallback, menuCommandID);

        mcs.AddCommand(menuItem);

      }

    }

 

    private void MenuItemCallback(object sender, EventArgs e)

    {

      IVsUIShell uiShell = (IVsUIShell)GetService(typeof(SVsUIShell));

      Guid clsid = Guid.Empty;

      int result;

      Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(uiShell.ShowMessageBox(

                 0,

                 ref clsid,

                 "SimpleMenuCommand",

                 string.Format(CultureInfo.CurrentCulture,

                   "Inside {0}.MenuItemCallback()", this.ToString()),

                 string.Empty,

                 0,

                 OLEMSGBUTTON.OLEMSGBUTTON_OK,

                 OLEMSGDEFBUTTON.OLEMSGDEFBUTTON_FIRST,

                 OLEMSGICON.OLEMSGICON_INFO,

                 0,

                 out result));

    }

  }

}

This source code does not seem too complicated but for the functionality it offers, it seems too long. The Initialize method contains more than ten lines dealing with preparing a handler method that responds to the event when the command behind our menu item is executed (the user click on the menu item). The MenuItemCallback method simple shows up a message box on the screen, however, it seems to do some more complicated task by the number of lines.

Let’s see another example with a VSPackage implementing a simple tool window! Here is the source code for the package body:

using System;

using System.Diagnostics;

using System.Globalization;

using System.Runtime.InteropServices;

using System.ComponentModel.Design;

using Microsoft.VisualStudio.Shell.Interop;

using Microsoft.VisualStudio.Shell;

 

namespace MyCompany.SimpleToolWindow

{

  [PackageRegistration(UseManagedResourcesOnly = true)]

  [DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0")]

  [InstalledProductRegistration(false, "#110", "#112", "1.0",

    IconResourceID = 400)]

  [ProvideLoadKey("Standard", "1.0", "SimpleToolWindow", "MyCompany", 1)]

  [ProvideMenuResource(1000, 1)]

  [ProvideToolWindow(typeof(MyToolWindow))]

  [Guid(GuidList.guidSimpleToolWindowPkgString)]

  public sealed class SimpleToolWindowPackage : Package

  {

    public SimpleToolWindowPackage()

    {

      Trace.WriteLine(string.Format(CultureInfo.CurrentCulture,

        "Entering constructor for: {0}", this.ToString()));

    }

 

    private void ShowToolWindow(object sender, EventArgs e)

    {

      ToolWindowPane window = this.FindToolWindow(typeof(MyToolWindow), 0, true);

      if ((null == window) || (null == window.Frame))

      {

        throw new NotSupportedException(Resources.CanNotCreateWindow);

      }

      IVsWindowFrame windowFrame = (IVsWindowFrame)window.Frame;

      Microsoft.VisualStudio.ErrorHandler.ThrowOnFailure(windowFrame.Show());

    }

 

    protected override void Initialize()

    {

      Trace.WriteLine(string.Format(CultureInfo.CurrentCulture,

        "Entering Initialize() of: {0}", this.ToString()));

      base.Initialize();

 

      OleMenuCommandService mcs = GetService(typeof(IMenuCommandService))

        as OleMenuCommandService;

      if (null != mcs)

      {

        CommandID toolwndCommandID =

          new CommandID(GuidList.guidSimpleToolWindowCmdSet,

          (int)PkgCmdIDList.cmdidMyTool);

        MenuCommand menuToolWin =

          new MenuCommand(ShowToolWindow, toolwndCommandID);

        mcs.AddCommand(menuToolWin);

      }

    }

  }

}

The situation is very similar to the package we have seen before. The ShowToolWindow method has about 8 lines to display the tool window. The tool window declaration looks like this:

using System.Windows.Forms;

using System.Runtime.InteropServices;

using Microsoft.VisualStudio.Shell;

 

namespace MyCompany.SimpleToolWindow

{

  [Guid("5f180713-6959-402b-a2f7-63f85b925675")]

  public class MyToolWindow : ToolWindowPane

  {

    private MyControl control;

 

    public MyToolWindow() :

      base(null)

    {

      this.Caption = Resources.ToolWindowTitle;

      this.BitmapResourceID = 301;

      this.BitmapIndex = 1;

      control = new MyControl();

    }

 

    override public IWin32Window Window

    {

      get

      {

        return (IWin32Window)control;

      }

    }

  }

}

This declaration does not do anything else but sets up the user control representing the user interface of the tool window. None of the codes above is complex, but all of them seem “noisy”; we have to type much more then we feel optimal.

When looking at the source codes above, we can ask the following question from ourselves: Should the code be so noisy?

As a last sample, create a custom editor with the VSPackage wizard and look for the code! You’ll see the code generated is quite long, about 4,500 lines containing about 3,000 code lines when omitting comments. Even if we know it contains complex functionality, this code seems too complex for the first sight!

Major Issues with MPF

Let me summarize the major issues I have with MPF, the demo before highlighted only a few of them.

The current MPF adds value only to a small portion of the core IDE services. As you remember for my demo, actually there is no real value added for developers of custom editors. MPF does not use the newest .NET technologies like generics and LINQ. If you looked at VSPackage source codes from Pablo Galiano’s (PowerCommands is one of them), you can see good examples how these technologies can use developers perception about VSX.

I feel and I suppose you could feel the same after the demos: We must still write too much plumbing code in our programs to access and use majority of core services.

If you have created WinForms applications before, you can see that it is much easier to create an event handler method for responding a menu item click than doing the same for a VSPackage. Would not it be nice to use the same approach for VSPackage command handlers?

I guess the right position for MPF would be the same for VSX as the Base Class Library for the .NET Framework.

VSXtra in a NutShell

At the end of May I started an experimental project called VSXtra and published it on CodePlex at the end of June. My main objective was to demonstrate many ways how DX can be improved by a new MPF. I wanted to create something that helps in making the first steps in creating a VSPackage. I handle VSXtra like if it were a new Base Class Library for VSX and hope it will provide more readable and straightforward VSPackages. The current release of this runtime library provides a few dozen types and about 15 samples.

VSXtra Component Stack

To have you understand how VSXtra does its work, let me show you where it is located in the stack of service components between the core IDE services and a Managed VSPackage.

Right now VSXtra is build over the Managed Package Framework; however, it changes many MPF core types in the Microsoft.VisualStudio.Shell namespace. Examples of these types are the most-known Package class, but WindowPane, ToolWindowPane and many others belong to this category. In my imagination VSXtra is going to change the whole MPF.

The current VSXtra implementation uses all the lower layers. My aim is that Managed VSPackages use only the VSXtra objects to implement their functionality, but of course VSPackages can consume all the lower layers.

Demo: Creating a Simple Menu Command with VSXtra

First I show you how to create a simple menu command with VSXtra. The Package (VSXtraMenuCommand) I am going to create implements the same functionality as the package created by the VSPackage wizard. To spare a couple of minutes I have already created the package and removed comments and whitespaces to improve readability. I did not make any changes in the package semantics.

I run the package, and as you can see, on the Tools menu there is the VSXtra Menu Command function that pops up a message box when activated.

OK, now let us change this package to use VSXtra. As the first step I add the VSXtra runtime to the referenced assemblies. I comment out the old package code and then I change the package class to derive from the PackageBase class. PackageBase in VSXtra replaces the Package class in Microsoft.VisualStudio.Shell namespace and adds a lot of power to the package.

As the next step I create an instance method of the package to respond to the menu command execution:

[CommandExecMethod]

[CommandId(GuidList.guidVSXtraMenuCommandCmdSetString,

  CmdIDs.cmdidVSXtraMenuCommand)]

private void MyMenuCommand()

{

  VsMessageBox.Show("Inside VSXtra Menu Command");

}

The CommandExecMethod attribute signs this method defines a menu command execution method. The CommandId attribute defines the GUID and ID pair to bind this method to the corresponding command. As you see VSXtra provides an easy way to pop up a Visual Studio message box.

We can even display the message box using the CommandAction attribute feature of VSXtra:

[CommandExecMethod]

[CommandId(GuidList.guidVSXtraMenuCommandCmdSetString,

  CmdIDs.cmdidVSXtraMenuCommand)]

[ShowMessageAction("Inside VSXtra Menu Command")]

private void MyMenuCommand()

{

}

The ShowMessageAction attribute does exactly what its name suggests.

I suppose, you agree that this code is compact enough and expresses the developer’s intention.

Demo: Implementing a Simple Tool Window with VSXtra

Now, let’s see an example with a tool window. As before I have pre-created a package with the VSPackage wizard, removed to comments and also added the VSXtra reference to the project. The wizard created a very simple tool window for me, now I refactor it using VSXtra features. I do not change the user interface; I only build up the so-called window frame responsible for hosting the UI of the tool window:

[InitialCaption("$ToolWindowTitle")]

[BitmapResourceId(301)]

public class MyToolWindow: ToolWindowPane<VSXtraToolWindowPackage, MyControl>

{

}

As you see, the definition of the tool window pane is very simple using the generic ToolWindowPane<> generic class. The first type parameter sets the type of the package owning the tool window frame; the second type defines the type responsible for the UI of the window. The initial window properties can be set through attributes.

Now, let’s change the package class definition. I create a package leaving the default registration attributes:

public sealed class VSXtraToolWindowPackage : PackageBase

{

}

I add a menu command handler method to the package just like I did it in the previous demonstration sample:

[CommandExecMethod]

[CommandId(GuidList.guidVSXtraToolWindowCmdSetString, CmdIDs.cmdidShowToolWindow)]

private void ShowToolWindow()

{

}

Our menu command handler should display the tool window pane I have created. I can tell it to the method by simply declaring a command action using the ShowToolWindowAction attribute:

[ShowToolWindowAction(typeof(MyToolWindow))]

This attribute specifies the type of the tool window pane to display. In order VSXtra could support all tool window features, we must change the ProvideToolWindow attribute to XtraProvideToolWindow attribute:

[XtraProvideToolWindow(typeof(MyToolWindow))]

Now, I can run the VSPackage. When I click on the appropriate menu item the tool window pops up. By clicking on the button I can check that it works.

I hope these two samples convinced you that there are great opportunities to improve the DX with some good implementation patterns.

Coping with GUIDs

In this slide I show you a simple VSPackage that automatically loads into the VS IDE at startup time and is intended to display a simple message into the Output window:

[PackageRegistration(UseManagedResourcesOnly = true)]

[DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0")]

[InstalledProductRegistration(false, "#110", "#112", "1.0",

  IconResourceID = 400)]

[ProvideLoadKey("Standard", "1.0", "SimpleMenuCommand", "MyCompany", 1)]

[ProvideMenuResource(1000, 1)]

[ProvideAutoLoad("ADFC4E64-0397-11D1-9F4E-00A0C911004E")]

[Guid(GuidList.guidSimpleMenuCommandPkgString)]

public sealed class SimpleMenuCommandPackage : Package

{

  protected override void Initialize()

  {

    // --- Here we write a message to the Output window

  }

}

This package compiles without any warnings or errors but does not work. Can you guess what is wrong with it? I tell you, as you can guess it from the title of the slide it is because of the highlighted GUID of the ProvideAutoLoad attribute is wrong. How can a GUID be wrong? It has no syntax error, it got compiled! The GUID is wrong because it has no meaning in the specified context, VS IDE cannot interpret it as a UI context GUID. Eventually, the last “E” of the GUID should be “F”.

With this sample I wanted to demonstrate that we have many fields where we have to struggle with GUIDs. Using constants instead of literal values would not help in this situation. Nobody will prevent me to use a wrong constant (a constant in a wrong place)!

“Typed GUID” Pattern

VSXtra uses a simple pattern to avoid the issues with GUIDs. I call it “Typed GUID” pattern, because the base idea is to wrap a GUID into a type as you can see the definition in the slide:

[Guid("The GUID value")]

public sealed class IdeaBehindTheGUID: ISemantics { }

We assign the GUID to the class through the Guid attribute. The class implements a markup interface (an empty “name-only” interface). We can use this interface to add semantics to to GUID. Let me show you concrete example:

[Guid("ADFC4E64-0397-11D1-9F4E-00A0C911004F")]

public sealed class NoSolution: IUIContextGuidType { }

This class defines a GUID representing the UI context where no solution is loaded into Visual Studio. The IUIContextGuidType markup interface has the meaning “Hey guys, this GUID represents a UI context; use only where a UI Context is expected”. How can we live with it?

public sealed class XtraProvideAutoLoadAttribute : RegistrationAttribute

{

  public XtraProvideAutoLoadAttribute(Type type)

  {

    if (!typeof(IUIContextGuidType).IsAssignableFrom(type))

      throw new ArgumentException();

    // ...

  }

}

We use the typed GUID, for example here in the definition of XtraProvideAutoLoad attribute we use a Type in the constructor instead of a GUID. In the body we can check if the type provided represents a UI context or not. When we use this attribute to decorate a package, we use it like this:

[XtraProvideAutoLoad(typeof(NoSolution))]

Demo: Using Typed GUIDs

Let me demo this concept with a small package that automatically loads a package when Visual Studio is started and writes a message to the Output window:

[PackageRegistration(UseManagedResourcesOnly = true)]

[DefaultRegistryRoot("Software\\Microsoft\\VisualStudio\\9.0")]

[InstalledProductRegistration(false, "#110", "#112", "1.0", IconResourceID = 400)]

[ProvideLoadKey("Standard", "1.0", "TypedGuid", "DeepDiver", 1)]

[XtraProvideAutoLoad(typeof(UIContext.NoSolution))]

[Guid(GuidList.guidTypedGuidPkgString)]

public sealed class TypedGuidPackage : PackageBase

{

  protected override void Initialize()

  {

    Console.WriteLine("This package uses a Typed GUID.");

  }

}

Here we use the XtraProvideAutoLoad attribute on the same way as I presented in the previous slide, passing a typed GUID as an attribute. By the way, look at just another feature of VSXtra: you can use the System.Console class to write to the Output window.

When I run the application, it works as expected.

Now let’s make a wrong decision and change the typed GUID to one invalid in this context, for example let’s use System.Int32:

[XtraProvideAutoLoad(typeof(int))]

Now, when we want to run our application, we get a build time message telling we are using an invalid typed GUID. Actually this is not a compile-time message but a message coming from the RegPkg.exe, but it is a sign that we did something wrong! Should we use a simple GUID, we would never get such kind of message. We could only perceive that out package does not do what we expect!

Packages

The most important change VSXtra introduces is a completely rewritten form of the original Package class of the Microsoft.VisualStudio.Shell namespace. VSXtra names that new class PackageBase. I have rewritten the original Package class to add more power to the new class. My aim was to create a smart type that uses the declarative model to avoid unnecessary and long initialization code. So, with the new PackageBase type no explicit code should be written for services, command handler and factories. I added new properties and methods to the class, most of them leverages on the values of generics. Of course, the new package abstraction uses the typed GUID pattern.

Package-Scoped Objects

I’d like to show you another pattern used widely in VSXtra, this is related to the so-called package-scoped objects. Just to introduce you what am I talking about, let me show you a brief overview of objects used within Visual Studio packages. This time I classify objects according to their service access opportunities.

As all of us know VSPackages are loaded into the memory space of the VS IDE through on on-demand mechanism. They are sited and so can access a service provider to request objects for various services. VS loads packages into the memory the first when we want to use one of its objects.

So, there are objects owned by the package, I call them package-scoped objects. Commands, services and tool windows are good examples. These objects can directly access the packages’ service providers to access package level and global services.

Packages can be related to other objects. A part of them like tool window UIs can sited in the VS IDE and so these objects can access the IDE’s global services. Some of them are just in relation with the package but because they are not package-scoped and not sited in the IDE they cannot access any services directly.

In VSXtra I treat all package-scoped objects with generic types having a package type as their first type parameter.

Package Instance Propagation

In the current implementation of MPF when you want to use a package-scoped object you must pass explicitly pass the package instance to this object in order to access package services from within the object. You can do it either in the constructor or through a property.

VSXtra has a very simple mechanism to avoid the need to explicitly pass a package instance. The mechanism is based on fact that we have exactly one instance of a certain package type sited within one Visual Studio process.

Because the PackageBase class keeps track of loaded package instances we can access a particular instance by its type. The next source code extract shows how it works:

public class MyPackageScopedClass<TPackage>

{

  public MyPackageScopedClass() // --- No need to pass package instance

  {

    // ...

  }

 

  public TPackage Package

  {

    get { return PackageBase.GetPackageInstance<TPackage>(); }

  }

}

Using the GetPackageInstance<> generic method of the PackageBase class we can access the specified package instance by its type. We can close it into a property (of course you’d better cache the property value). By doing this we do not need to pass the package or service provider instance to the constructor. I suppose, I do not have to tell that it makes the code simpler.

Demo: Listing Sited VSXtra Packages

I show you a short demo about package features. In later demos I will illustrate many PackageBase features; here I only show you how to access package metadata with VSXtra.

[CommandExecMethod]

[CommandId(GuidList.guidDisplayLoadedPackagesCmdSetString,

  CmdIDs.cmdidDisplayPackages)]

private static void DisplayPackageInfo()

{

  var sitedPackages = SitedVSXtraPackages;

  Console.WriteLine("There are currently {0} sited VSXtra packages:",

    sitedPackages.Count);

  foreach (var package in sitedPackages)

  {

    Console.WriteLine("  {0}", package.GetType().FullName);

    var registeredHandlers = GetCommandHandlerInstances(package.GetType());

    if (registeredHandlers.Count() > 0)

    {

      Console.WriteLine("    Registered command handlers:");

      foreach (var command in registeredHandlers)

      {

        Console.WriteLine("      {0}", command.GetType().FullName);

      }

    }

  }

}

The essence of the code is encapsulated into the DisplayPackageInfo method. This method responds to a menu command and as you can see there is no explicit code binding this method to the corresponding command. What you can see is a few attributes expressing the intention of the developer. All the work is done behind the scenes by the PackageBase class. The SitedVSXtraPackages property retrieves a collection of packages sited. We can even retrieve the menu command classes registered by a VSXtra package using the GetCommandHandlerInstances method.

What’s Next

In the next part I will treat the part of the presentation treating menus, commands, services, tool windows and my imaginations about the future of VSXtra.


Posted Sep 18 2008, 03:32 PM by inovak
Filed under:

Comments

DiveDeeper's blog wrote LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Tue, Sep 23 2008 11:37

This post is the second part of the VSXtra presentation on September 15, 2008 at VSX Developer Conference

Lars wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Sep 24 2008 9:04

Very nice! Really a proper way to go. I'm really interested in the project and custom editor/designer stuff. Will the project simplify hierarchy implementations as well ?

inovak wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Sep 24 2008 9:19

Hi Lars, if you download the VSXtra source code, you'll find the starting points for custom editors. I started working on simplifying the hierarchies. I suppose the first results can be expected in about 6-8 weeks.

Topsoil Supplies wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Feb 16 2013 14:16

I really like and appreciate your blog.Really thank you! Really Great.

buy generic cialis online wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Feb 23 2013 21:59

NSaDTW Thanks so much for the article post.Thanks Again.

Advertising in Austin, TX wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Mon, Feb 25 2013 2:01

Major thankies for the article post.Really thank you! Great.

Austin SEO Company wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Mon, Feb 25 2013 3:54

Thanks a lot for the article.Thanks Again. Really Great.

advertising agencies austin wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Mon, Feb 25 2013 9:36

Great blog.Thanks Again. Want more.

Los Angeles Video Production wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Mon, Feb 25 2013 11:09

Great, thanks for sharing this post. Really Cool.

Beverly Hills Liposuction wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Mon, Feb 25 2013 15:32

Thank you ever so for you blog post.Much thanks again. Cool.

Yorba Linda Invisalign wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Mon, Feb 25 2013 15:44

A round of applause for your blog. Fantastic.

Beverly Hills Augmentation wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Mon, Feb 25 2013 17:00

A big thank you for your blog article.Really looking forward to read more. Will read on...

Liposuction in Los Angeles wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Mon, Feb 25 2013 18:23

I appreciate you sharing this blog article.Thanks Again. Great.

Body Contouring Riverside wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Mon, Feb 25 2013 18:36

I really enjoy the blog post.Really looking forward to read more. Really Great.

Los Angeles Rhinoplasty wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Mon, Feb 25 2013 19:44

Very good post. Awesome.

Buccal Fat Removal wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Mon, Feb 25 2013 21:05

Looking forward to reading more. Great blog post.Thanks Again. Will read on...

California Document shredding wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Mon, Feb 25 2013 22:52

Thanks a lot for the article post.Really looking forward to read more. Really Cool.

Tissue Packaging Paper wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 0:07

I appreciate you sharing this post.Really thank you! Really Cool.

Shred It Orange County wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 0:18

I loved your blog.Much thanks again. Will read on...

collins elite diary wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 1:35

Very informative blog article.Really looking forward to read more. Keep writing.

san diego shredding wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 1:45

I really like and appreciate your article post.

clipboards wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 3:03

Thank you for your article.Really looking forward to read more. Much obliged.

membrane switch manufacturers wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 3:12

Very neat article. Will read on...

Mobile Application Development wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 4:42

Very neat article post.Really thank you! Will read on...

a4 box files wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 6:06

Major thankies for the blog article. Really Cool.

Los Angeles Facelift wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 6:29

I am so grateful for your article.Really looking forward to read more. Want more.

office diary wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 7:40

Say, you got a nice blog post.Thanks Again. Much obliged.

Plastic Surgeon Inland Empire wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 8:18

A round of applause for your article.Really thank you! Fantastic.

hard back envelope wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 9:19

I really like and appreciate your blog article.Thanks Again. Will read on...

over 50 life insurance wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 10:55

A big thank you for your article. Fantastic.

cultural business wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 11:59

Hey, thanks for the blog post.Really looking forward to read more. Want more.

T Cards wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 12:57

Thanks a lot for the blog.Really thank you! Fantastic.

How To Get Fans Online wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 13:53

wow, awesome post.Much thanks again. Keep writing.

office supplies wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 14:36

I truly appreciate this article.Really looking forward to read more.

Crest Media Inc. wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 15:52

Thanks again for the article.Really looking forward to read more. Awesome.

Day to Page diary wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 16:19

Thanks so much for the blog post. Much obliged.

Injury Lawyer Los Angeles wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 17:51

I cannot thank you enough for the blog article.Much thanks again. Fantastic.

ring binders wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 18:06

Great article post.Really thank you!

application get more twitter followers wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 18:24

I think this is a real great article.Much thanks again. Keep writing.

buy Phen375 wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 19:24

I cannot thank you enough for the blog.Thanks Again.

liposuction pasadena wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 19:52

Wow, great blog article.Thanks Again. Really Great.

make your hair grow faster wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 20:00

Major thankies for the blog post. Want more.

mar jennings wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 20:54

Thanks a lot for the blog article.Much thanks again. Really Great.

earned money wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 21:45

I truly appreciate this blog article.Really looking forward to read more. Fantastic.

Creative Domain Names wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 21:56

Very good article post.Really looking forward to read more. Fantastic.

who unfollowed me on instagram wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 23:06

Enjoyed every bit of your blog post.Much thanks again. Fantastic.

Best Priced Home Audio and Video wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 23:21

Im thankful for the blog article.Thanks Again. Much obliged.

colonie de vacances wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Tue, Feb 26 2013 23:51

I loved your blog article. Keep writing.

vagas wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 0:56

I appreciate you sharing this article post.Thanks Again. Really Cool.

card index box wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 0:58

I think this is a real great blog.Thanks Again. Cool.

buy instagram followers wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 1:00

I cannot thank you enough for the article.Thanks Again. Will read on...

empower network system wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 1:42

Wow, great blog.Really thank you! Fantastic.

Bisley filing cabinets wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 2:17

Muchos Gracias for your post.Really looking forward to read more. Keep writing.

Real Estate Brokers wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 2:31

I truly appreciate this blog post. Awesome.

kim kardashian youtube wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 2:51

I value the blog post.Much thanks again.

Kardashian Superstar wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 3:35

Im grateful for the article post.Much thanks again. Really Cool.

Paper Trimmer wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 3:40

Fantastic article post.Thanks Again. Fantastic.

evan sharboneau trick photography and special effects wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 4:08

I cannot thank you enough for the blog.

date chinese women wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 5:28

I value the post. Much obliged.

marketing tips financial advisors wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 5:48

I cannot thank you enough for the blog article.Much thanks again. Cool.

white tack wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 6:19

Thanks again for the blog post.Really thank you! Really Great.

wood working wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 7:23

Awesome blog.Really thank you! Awesome.

cheap nikon d3100 lenses wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 7:26

Wow, great article post.Much thanks again. Really Great.

idaniko varos wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 9:06

Really enjoyed this post.Really looking forward to read more. Cool.

office stationary wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 10:12

Fantastic blog. Will read on...

tourism in kerala wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 10:32

Thanks-a-mundo for the post.Thanks Again.

cheap facebook likes wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 10:45

Really appreciate you sharing this blog.Much thanks again. Want more.

Mobile service wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 11:18

Muchos Gracias for your blog article. Awesome.

online jobs from home wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 12:26

Hey, thanks for the blog article.Much thanks again. Much obliged.

power supply wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 17:04

Thank you for your article post.Thanks Again. Really Great.

Jesusita Maxson wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 22:09

Im thankful for the blog.Really looking forward to read more. Keep writing.

Big Bear Wedding wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Wed, Feb 27 2013 23:40

Great, thanks for sharing this blog article.Really looking forward to read more. Want more.

ginny simon wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Thu, Feb 28 2013 0:09

Looking forward to reading more. Great blog post. Really Great.

guillotine wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Thu, Feb 28 2013 17:12

Thanks for the article. Cool.

guillotine wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Thu, Feb 28 2013 17:57

Thanks for sharing, this is a fantastic blog post.Thanks Again.

Vpn wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Thu, Feb 28 2013 19:21

Appreciate you sharing, great blog.Really looking forward to read more. Awesome.

ourmeds wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Thu, Feb 28 2013 20:58

Very informative blog article.Thanks Again. Great.

buy clomid no prescription wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 0:00

UmkSCm I really liked your post.Thanks Again. Really Cool.

atlasjet ucak bileti|atlasjet ucak bileti wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 10:46

I value the article post.Really looking forward to read more. Really Cool.

GeForce GTX 690 wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 11:24

Very neat blog article.Really thank you! Will read on...

london escort wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 12:59

wow, awesome article post.Really looking forward to read more. Cool.

adjustable dumbbell review wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 14:34

Appreciate you sharing, great article. Awesome.

robe de soiree wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 14:54

Hey, thanks for the article post.Much thanks again. Keep writing.

social bookmarking wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 15:44

Looking forward to reading more. Great article post.Really looking forward to read more. Want more.

article generator tool wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 15:54

I cannot thank you enough for the article post.Much thanks again. Will read on...

mode grande taille wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 16:03

Thanks again for the blog post. Keep writing.

steals and deals wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 16:10

Thanks again for the blog. Keep writing.

magazine pour femme ronde wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 17:11

Awesome article.Much thanks again. Keep writing.

dublins sightseeing card wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 17:42

I really like and appreciate your article post.Thanks Again. Great.

make money online wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 17:45

Great, thanks for sharing this article post. Keep writing.

mannequin grande taille wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 19:27

I truly appreciate this article.Thanks Again. Keep writing.

cardiology equipment wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 19:28

Wow, great article post.Much thanks again. Much obliged.

network marketing wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 19:53

I appreciate you sharing this blog article.Thanks Again. Great.

Ferienwohnung cuxhaven wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 21:11

I value the article.Thanks Again. Keep writing.

halovar wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Fri, Mar 1 2013 22:54

Thanks a lot for the blog. Awesome.

what women wants wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 0:03

Thank you ever so for you article post.Really thank you! Cool.

oxyelite usplabs wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 0:37

Im thankful for the article post.Thanks Again. Much obliged.

lipo 6 black wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 2:21

Thank you for your blog.Much thanks again. Awesome.

make your own website wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 4:04

Very good blog post.Really thank you! Cool.

kitchens wimlsow wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 4:54

I really liked your blog article.Thanks Again.

cheap auto insurance wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 5:49

I loved your blog article.Really looking forward to read more. Will read on...

Digital camera picture recovery wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 6:56

Looking forward to reading more. Great blog article. Keep writing.

Get A Payday Loan wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 7:32

Great, thanks for sharing this article.Really thank you! Fantastic.

personal injury attorney houston wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 8:24

Awesome blog post.Really looking forward to read more. Cool.

seo services adelaide wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 9:17

I think this is a real great article post.Really looking forward to read more.

kim kardashian sex tape wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 10:31

Im grateful for the post.Really thank you! Keep writing.

gold buyers wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 11:04

Really enjoyed this blog.Really thank you! Great.

Get Twitter followers wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 11:53

I cannot thank you enough for the article.Really looking forward to read more. Keep writing.

green coffee beans for weight loss wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 12:51

Major thanks for the post.Thanks Again.

Brandable Domains wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 13:30

Enjoyed every bit of your blog post.Really looking forward to read more. Want more.

how to find the right guitar for your wrote re: LearnVSXNow! Part #32 - VSXtra at DevCon - Part 1
on Sat, Mar 2 2013 15:07

I loved your article.Thanks Again. Awesome.