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

LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2

This post is the second part of the VSXtra presentation on September 15, 2008 at VSX Developer Conference. You can find the first part here.

Menus and Commands

As you could see from demos VSXtra provides a totally new pattern for handling commands within packages. This pattern uses a declarative approach through attributes and as a result developers do not need to write explicit initialization code for binding the commands with all the methods handling related events. The pattern I use is applicable for all IOleCommandTarget implementers, so you can easily use it in your own classes.

Actually, I provide two ways to declare command handler entities.

The first way is to declare command handler methods; you could see them in my demos. They are very simple to use, the approach is similar than in the case of WinForms applications. The other way is to use command handler classes and this is even more powerful than handler methods. In this case all the functions, data and events related to a command are encapsulated into a separate class. Of course, inheritance is supported. Also another new mechanism I call command mapping is also supported. Later in my demo I will show you what it means.

If you have ever tried to use VS combo boxes you know that it is like painting the room through the doorway. VSXtra makes it much easier as I can demonstrate it later. Also, working with tool window toolbars is easy, as VSXtra knows what a toolbar is.

Services

For services VSXtra uses the same old pattern as implemented everywhere in the VS SDK. However, it provides no-code initialization through the declarative approach. Let’s see an example:

public interface IMyService   // --- Service behavior

{

  void MyServiceMethod(string firstParam);

}

 

public interface SMyService { } // --- Service address

 

[AutoCreateService]

[Promote]

public MyService: VsxService<OwnerPackage, SMyService>, IMyService

{

  public void MyServiceMethod(string firstParam) { ... }

}

The service behavior is defined by a simple interface. The service address is provided by a so-called address interface that is actually a markup interface without any members.

The implementation of the service derives from the VsxService<,> generic type and implements the behavior interface. The generic type accepts a package as the first type parameter and the address service as the second one.

The attributes decorating the implementation class are used instead of the explicit initialization code. By using them the PackageBase class automatically creates an instance of the service class and promotes it to be a global service.

VSXtraCommands implementation demo

My next demo uses an alternative implementation of Pablo Galiano’s PowerCommands utility, so I’d like to say thank you to Pablo who inspired me a lot! I use this demo to show you different aspects of command handling. In previous demos we saw a few examples of command handling methods, now we look after command handler classes.

Each Visual Studio command has an ID composed from two parts. The first part is a GUID that acts as a logical container for commands. The second part is an integer as a unique ID within the container.

The CommandGroup class in VSXtra is about representing the logical container:

[Guid(GuidList.guidVSXtraCommandsCmdSetString)]

public partial class VSXtraCommandGroup: CommandGroup<VSXtraCommandsPackage>

{

}

The Guid attribute designates the identifier of the command group, in our case it is set to the command set identifier of VSXtraCommands. This class also acts a physical container to nest in command handler classes.

Here is an example:

public partial class VSXtraCommandGroup

{

  [CommandId(CmdIDs.ClearAllPanesCommand)]

  [DisplayName("Clear All Panes")]

  public sealed class ClearAllPanes: CommandHandlerBase

  {

    protected override void OnExecute(OleMenuCommand command)

    {

      OutputWindow.OutputWindowPanes.ForEach(pane => pane.Clear());

    }

  }

}

We nested the ClearAllPanes class into VSXtraCommandGroup. Due to the nesting we must specify only the integer part of the Command ID, because the GUID part is taken from the logical container, in our case the VSXTraCommandGroup. The overridden OnExecute method defines what to do when the command is executed.

You may say we could do this with the menu command handler methods in the previous demos. However, command handler methods support inheritance. As you can see, all commands derive from CommandHandlerBase. This type is defined by our package and not directly by VSXtra. It is intended to be the base class of all other command handler classes:

public abstract class CommandHandlerBase : MenuCommandHandler

{

  protected override void OnQueryStatus(OleMenuCommand command)

  {

    var commandsPage = Package.GetDialogPage<CommandsPage>();

    bool canExecute =

      commandsPage.DisabledCommands.SingleOrDefault(

        cmd => cmd.Guid.Equals(command.CommandID.Guid) &&

            cmd.ID.Equals(command.CommandID.ID)) == null;

    if (canExecute)

    {

      canExecute = CanExecute(command);

    }

    command.Enabled = command.Visible = command.Supported = canExecute;

  }

 

  protected virtual bool CanExecute(OleMenuCommand command)

  {

    return true;

  }

}

This class derives from MenuCommandHandler that is the base class of all command handlers in VSXtra. Our class overrides OnQueryStatus method to decide if the specific command instance is enabled or not. All command handler classes deriving from CommandHandlerBase inherit this behavior.

We can even use inheritance for some other situations.

For example, in VSXtraCommands there are two commands related to delete items from the list of recent projects or files. The internal logic of these commands is very similar. So we can extract the common behavior into a base class and define derived classes to designate the differences. Here is the solution:

public partial class VSXtraCommandGroup

{

  public abstract class ClearRecentListBase : CommandHandlerBase

  {

    protected override bool CanExecute(OleMenuCommand command)

    {

      return VsRegistry.GetFileEntryList(RecentListKey).Count > 0;

    }

 

    protected override void OnExecute(OleMenuCommand command)

    {

      var view = new ClearListView();

      VsRegistry.GetFileEntryList(RecentListKey).

        ForEach(item => view.Model.ListEntries.Add(item));

      if ((bool)view.ShowDialog())

      {

        VsIde.File.SaveAll();

        DeleteRecentFileList(view.Model.SelectedListEntries);

        VsIde.RestartVS();

      }

    }

 

    protected abstract RegistryKey RecentListKey { get; }

 

    private void DeleteRecentFileList(List<FileEntry> entriesToDelete)

    {

      using (var key = RecentListKey)

      {

        entriesToDelete.ForEach(entry => key.DeleteValue(entry.Key));

        var valueNames = key.GetValueNames();

        if (valueNames.Length <= 0) return;

        var fileCounter = 1;

        valueNames.ForEach(

          valueName =>

          {

            key.SetValue(string.Concat(valueName, "_"), key.GetValue(valueName));

            key.DeleteValue(valueName);

          });

        key.GetValueNames().ForEach(

          valueName =>

          {

            key.SetValue(string.Format("File{0}", fileCounter++),

              key.GetValue(valueName));

                key.DeleteValue(valueName);

          });

      }

    }

  }

 

  [CommandId(CmdIDs.ClearRecentFileListCommand)]

  [DisplayName("Clear Recent Files")]

  public sealed class ClearRecentFileList : ClearRecentListBase

  {

    protected override RegistryKey RecentListKey

    {

      get { return VsRegistry.GetRecentFilesListKey(true); }

    }

  }

 

  [CommandId(CmdIDs.ClearRecentProjectListCommand)]

  [DisplayName("Clear Recent Projects")]

  public sealed class ClearRecentProjectList : ClearRecentListBase

  {

    protected override RegistryKey RecentListKey

    {

      get { return VsRegistry.GetRecentProjectsListKey(true); }

    }

  }

}

The two commands do almost the same operation, the only difference is the registry key used to pick up the information about the recent lists. Projects and files use separate registry keys.

So, the implementation encapsulates this logic into the abstract ClearRecentListBase command handler class and defines the RecentListKey abstract property. The concrete command handler classes derive from this abstract base class and override the RecentListKey property and add attributes to specify command binding.

When we use command handler methods, we cannot use this technique. Due to the fact that in case of command handler methods binding attributes are related to classes, we can use such useful techniques like command handler inheritance.

Just like command handler methods, command handler classes do not need explicit initialization code. When we install our package the logical container of menu commands are a package-scoped class and so command handler bindings automatically can be done leveraging on the metadata attributes.

Before going on to detail how services are implemented in VSXtraCommands, let me show you another feature of VSXtra command handling called declarative actions. In order to make the declaration of frequently used action types easier, VSXtra allows defining so-called declarative actions. For example, the Close All Documents command in VSXtraCommands uses the following way to define declarative actions:

public partial class VSXtraCommandGroup

{

  [CommandId(CmdIDs.CloseAllDocumentsCommand)]

  [DisplayName("Close All Documents")]

  [ExecuteCommandAction("Window.CloseAllDocuments")]

  public sealed class CloseAllDocuments : CommandHandlerBase

  {

  }

}

Here the ExecuteCommandAction is a declarative command its result is that activating the command executes the Visual Studio’s Window.CloseAllDocuments command. You can define your own actions by deriving an attribute from ActionAttibute. Instead of going into deep details, let me show you how ExecuteCommandAction is implemented:

public sealed class ExecuteCommandActionAttribute : ActionAttribute

{

  private readonly string _CommandName;

  private readonly string _Args;

 

  public ExecuteCommandActionAttribute(string commandName, string args)

  {

    _CommandName = commandName;

    _Args = args;

  }

 

  public ExecuteCommandActionAttribute(string commandName)

  {

    _CommandName = commandName;

    _Args = string.Empty;

  }

 

  public override void ExecuteAction(PackageBase package, CommandID id)

  {

    VsIde.ExecuteCommand(_CommandName, _Args);

  }

}

We simply set up the command parameters in the constructor and store them. The overridden ExecuteAction method is responsible to carry out the action; here we simply execute the defined VS command.

Now, let’s go back to services. The VSXtraCommands package uses a service to manage registered commands. Here is the definition of the service:

[Promote]

internal class CommandManagerService :

  VsxService<VSXtraCommandsPackage, SCommandManagerService>,

  ICommandManagerService

{

}

As I showed you on the slides, ICommandManagerService defines the behavior interface, while SCommandManager is the address. The key of the service declaration is the VsxService<,> generic type which defines a package-scoped object type and so its first type parameter is the package providing the service.

The Promote attribute signs that this service should be made available by third party packages.

When our package is sited, the PackageBase class automatically searches for services to register. Using .NET metadata it recognizes service types and initializes them accordingly. In our case the CommandManager service is initialized for on-demand instantiation and global service promotion.

Window Panes, Tool Windows

As I have already mentioned PackageBase is one of the classes that has been totally changed in VSXtra. Well, tool window implementation has also changed a lot. In VSXtra window panes and tool windows are represented by generic classes with two type parameters. Because window panes and tool windows are package-scoped objects, their first type parameter describes the package owning them. The second parameter tells the type representing the UI of the window.

To follow the declarative approach, tool windows can be decorated with attributes to set up their initial state, like their caption, toolbar and bitmaps, etc. Tool windows can have their own toolbars that are assigned with the tool window through attributes.

Tool windows can handle their related commands through the mechanisms I have shown to you in previous demos. We do not need to write explicit code for the command binding just as we do not need to write for VSPackages.

Right now there are two additions that are not available in case of the MPF tool windows:

—  There is an explicit managed WindowFrame type that can be accessed through the Frame property of a pane.

—  Windows are associated with a SelectionTracker  object

I think the best way to dive into details is to have a closer look to a few demos.

Tool Windows Demo

In the introduction of VSXtra I have already showed you a very simple demo about creating a tool window. Here I demonstrate some more details. The first examples are taken from the Tool Window Reference Sample of the VS SDK.

The first sample I want to demo is an implementation of a tool window that logs events received by the window frame.

I can move, resize, dock or float the tool window and all of these events are caught and logged to a custom output window frame. Let’s have a look into the code. The UI of the tool window is very simple; it is defined by a WinForms user control. In order Visual Studio could display our UI in a tool window we have define a tool window pane object. VSXtra makes it simply like that:

class DynamicWindowPane :

  ToolWindowPane<DynamicToolWindowPackage, DynamicWindowControl> { ... }

As you see the ToolWindowPane base class used here is different from the one we use in MPF. This class is a generic class having two type parameters. The first is the package owning the tool window; the second is the control implementing the UI of the tool window. There are attributes decorating the class definition. These attributes here set up the initial visual state of the window.

In the OnToolWindowCreated method we can set up event listeners for the window frame hosting our tool window. Each event simply logs the event type and parameters in a custom window pane.

Custom window panes are defined by a class deriving from the OutputPaneDefinition type that is decorated with attributes to define the characteristics of the pane. We can use the GetPane method of the OutputWindow to obtain an instance for this custom pane. All tasks are done behind the scenes. You simply get the output pane and can write to it like to the Sytem.Console in a console application.

My other example demonstrates how easy is to use a toolbar for a window and to cooperate with the properties window. It is quite easy to add a toolbar to a Tool window in a declarative way:

[InitialCaption("Persisted Tool Window")]

[BitmapResourceId(301)]

[Toolbar(typeof(PersistedToolWindowCommandGroup.PersistedWindowToolbar))]

class PersistedWindowPane :

  ToolWindowPane<PersistedToolWindowPackage, PersistedWindowControl>

{

}

The Toolbar attribute tells VSXtra that this tool window has a toolbar. This attribute takes one type parameter that must be a toolbar definition. Toolbar definition as actually a simple markup class:

[Guid(GuidList.guidPersistedToolWindowCmdSetString)]

public sealed class PersistedToolWindowCommandGroup :

  CommandGroup<PersistedToolWindowPackage>

{

  [CommandId(CmdIDs.IDM_PersistedWindowToolbar)]

  public sealed class PersistedWindowToolbar : ToolbarDefinition {}

}

As soon as you defined a toolbar you can add command handler methods for toolbar commands:

[CommandExecMethod]

[Promote]

[CommandId(CmdIDs.cmdidRefreshWindowsList)]

private void RefreshList()

{

  UIControl.RefreshData();

}

Other Utility Types

VSXtra has much more features I could show you in this presentation. Here in this slide I simply call them utility types, but actually they are much more than just single utilities.

There are many singleton objects in Visual Studio that can be accessed through the MPF object model as instances, even we can have virtually more than one instance for the same singleton object. Most of them have well-defines services.

In VSXtra I implemented these objects as static classes representing the singleton service objects. Here I list a few of them.

—  ActivityLog can be used to log your packages’ activity in the standard Visual Studio activity log.

—  VsDebug is like the standard .NET Debug diagnostic class but it is lightweight and uses the Debug output window pane for output.

—  We have a static SolutionEvents class to subscribe for solution level events.

—  RunningDocumenTable can be used to access RDT functionality.

—  Instead of using the good old DTE and DTE2 interfaces, the VsIde static class can be used.

I created a few utility classes for output window and pane handling.

You could see the concept of typed GUIDs; I have a few utility classes declaring them.

And VSXtra has many other types to make our life easier; in the future I plan to add many more…

Future Directions

After telling you where VSXtra is right now, let me tell you a few sentences about its future.

In my vision, VSXtra totally replaces the current MPF and managed packages are build over VSXtra they very rarely use lower levels to access VS IDE core services.

In the future I plan to add support for custom editors and designers. This is an area where MPF does not do too much. I have already started to examine how a Managed Project System could be implemented in VSXtra. I started examinations with the MPFProj project on CodePlex and I also implemented some very basic integration with VSXtra.

Language Services and code generation are those areas in my list to improve the related developer experience.

I also have some imaginations about how to add DSL tools to support the design and creation of VSPackages. I have also some imaginations about how to replace the whole VSCT stuff.

The VSXtra project is very young. It van evolve in many directions. The future of Visual Studio determines how VSXtra goes on. While Visual Studio does not have a new MPF that is something like a Base Class Library for Visual Studio, VSXtra tries to fill the gap.

Summary

During this hour I could show you only the top features of the Framework what I call VSXtra.

I hope, in my presentation I managed to give the message to you there are many opportunities to improve the developer experience related to Visual Studio Extensibility. I showed you patters that make VSX more easy to use, less error-prone to use. VSXtra right now is only an experimental project, I suggest you trying it. In the slides you can see that the project is hosted on CodePlex. I also share my experiences on my blog on the Dotneteers site.

I hope the example and demos shown represented the VSXtra uses the state-of-the-art .NET technologies like generics, LINQ, intensive use of metadata and so on.

I made this presentation not just for telling you what in VSXtra but rather to open my ears for your feedback and I am also looking for contributors.

Thank you for your attention, and if you have any questions, it’s the time to ask them.


Posted Sep 23 2008, 11:29 AM by inovak
Filed under:

Comments

buy generic cialis online wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sun, Feb 24 2013 10:02

YGuuB4 Appreciate you sharing, great article post.Really looking forward to read more. Really Cool.

how to get more twitter followers wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Tue, Feb 26 2013 19:21

Awesome blog article.

how to make hair grow faster and longer wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Tue, Feb 26 2013 21:02

Really appreciate you sharing this article post. Awesome.

stay at home parents wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Tue, Feb 26 2013 22:42

Thanks so much for the article.Really looking forward to read more. Fantastic.

Domain Names wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Tue, Feb 26 2013 23:05

Looking forward to reading more. Great post.Really looking forward to read more. Cool.

instagram search user name wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 0:15

Say, you got a nice post.Really looking forward to read more. Much obliged.

Best Priced Home Audio and Video wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 0:17

Awesome article post.Really looking forward to read more.

colonie de vacances wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 0:59

Really informative post.Much thanks again. Keep writing.

rio vaga wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 1:52

Fantastic blog.Really looking forward to read more. Fantastic.

free instagram followers wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 2:06

Thanks a lot for the blog post. Really Cool.

empower network top earner wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 2:50

I loved your blog article.Thanks Again.

selling Ontario properties wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 3:29

Im obliged for the post.Much thanks again. Will read on...

pictures of kim kardashian wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 3:59

Wow, great blog article.Really thank you! Really Cool.

Kardashian wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 4:43

Very neat blog article.Really thank you! Really Cool.

trick photography book and special effects wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 5:07

Very good blog.Thanks Again. Great.

real twitter followers wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 5:53

Thank you for your article.Really thank you! Keep writing.

personal dating wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 6:38

Thanks for the blog post.Much thanks again. Great.

marketing secrets wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 6:47

Very neat article post.Thanks Again. Really Great.

nikon d3200 price in chennai wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 8:25

Im obliged for the blog article.Really thank you! Awesome.

woodworking bench plans wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 8:35

Looking forward to reading more. Great article post.Thanks Again. Great.

travel agency wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 9:46

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

Grigores sintages wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 10:05

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

get instagram followers wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 10:32

I really enjoy the post.Much thanks again. Keep writing.

cheap facebook likes wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 11:45

Looking forward to reading more. Great article.Much thanks again. Great.

Mobile service wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 12:28

Thanks a lot for the blog post.Thanks Again. Cool.

agen bola wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 14:22

Thanks a lot for the blog.Really looking forward to read more. Great.

how to reduce armpit sweat wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 16:17

I value the blog article. Really Great.

oil paintings sale online wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 19:23

Fantastic blog.Really looking forward to read more. Really Great.

how to be a personal assistant wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 21:22

Great article post.Really thank you! Cool.

pianists nyc wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 22:13

Major thankies for the blog article.Really thank you! Really Cool.

Roberta Gant wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Wed, Feb 27 2013 23:22

Im grateful for the blog post. Great.

advertising speaker wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Thu, Feb 28 2013 9:26

Thanks so much for the blog article.Much thanks again. Really Great.

Vpn wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Thu, Feb 28 2013 20:19

Great post.Really thank you!

ourmeds wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Thu, Feb 28 2013 21:56

I value the article.Much thanks again. Awesome.

thy ucak bileti|thy ucak bileti wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 12:01

Muchos Gracias for your blog post.Much thanks again. Will read on...

GeForce GTX 690 wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 12:21

I truly appreciate this article post.Really thank you! Cool.

sex treffen wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 12:51

Thanks-a-mundo for the article.Much thanks again. Cool.

london escorts wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 13:56

I am so grateful for your post.Much thanks again. Awesome.

artificii pentru firme wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 14:05

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

galerie hamburg kunst wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 14:55

wow, awesome blog.Thanks Again.

adjustable dumbbells wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 15:32

This is one awesome article.Really thank you! Want more.

social bookmarking wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 16:59

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

article writing software wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 17:00

Really informative blog article.Really thank you! Fantastic.

daily steals wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 17:08

Looking forward to reading more. Great article.Really thank you! Cool.

make money online wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 18:43

wow, awesome post.Really looking forward to read more. Great.

dublin pass discount wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 18:44

I really like and appreciate your article post.Much thanks again. Great.

how to light video wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 19:04

I appreciate you sharing this article.Really looking forward to read more. Awesome.

ekg blog wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 20:31

Muchos Gracias for your article post.Thanks Again. Fantastic.

Network marketing italiano wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 21:10

I really enjoy the article post.Thanks Again. Fantastic.

Ferienwohnung cuxhaven wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 22:13

Really informative blog.Really thank you! Awesome.

bus in Peru wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 23:14

Thanks a lot for the article. Much obliged.

Riu Hotels Special wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 23:55

I really enjoy the blog.Thanks Again. Cool.

halovar wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Fri, Mar 1 2013 23:56

Thanks for sharing, this is a fantastic blog.Thanks Again. Keep writing.

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

Thanks so much for the blog. Cool.

best seo link wheel service wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 2:01

Awesome blog.Much thanks again. Want more.

lipo 6 black wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 3:23

Im thankful for the post.Thanks Again. Fantastic.

Ai Kurosawa wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 3:26

A round of applause for your post.Much thanks again. Fantastic.

apothecary pharmacy wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 4:05

I am so grateful for your article.Much thanks again. Awesome.

how to website wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 5:07

Very neat article. Much obliged.

download wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 5:30

I cannot thank you enough for the blog post. Fantastic.

cheap auto insurance wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 6:52

Im obliged for the article post.Really thank you! Much obliged.

Social Bookmarking wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 7:34

Great post. Much obliged.

Photo data Recovery wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 8:12

wow, awesome article post.Really thank you! Much obliged.

No Faxing Payday Loans wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 8:35

I really like and appreciate your blog post.Much thanks again. Want more.

die cutting machines wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 10:18

Thanks again for the blog post. Really Great.

seo services adelaide wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 10:21

Im obliged for the blog. Really Great.

kim kardashian sex tape wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 11:48

Major thanks for the article.Really looking forward to read more. Great.

gold buyers wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 12:09

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

Get Twitter followers wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 12:52

I really liked your blog article. Much obliged.

instagram app for ipad wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 13:54

Major thankies for the blog article.Much thanks again.

green coffee bean wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 13:56

I am so grateful for your article post.Really looking forward to read more. Keep writing.

Business Domain Names wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 14:29

I really enjoy the blog. Fantastic.

guitar online wrote re: LearnVSXNow! Part #33 - VSXtra at DevCon - Part 2
on Sat, Mar 2 2013 16:07

Thanks for the blog article.Thanks Again.