T4 Preprocessed Text Templates in Visual Studio 2010

October 30, 2009

The best kept secret in Redmond, WA are the new T4 Preprocess Text Templates that shipped in Visual Studio 2010 Beta1 and Beta2.  In just a few minutes you’ll be in the know and using them.

Background – Condensed

T4 = text template transformation toolkit

T4 templates have been available since Visual Studio 2005 and are part of DSL (Domain Specific Languages) documentation.

In Visual Studio 2010 the templates are MUCH easier to use because they are preprocessed.  When you save your T4 template, it is compiled.  The T4 template is now “processed” at compile time.  This was not the case in previous releases.

Your compiled template is just another type in an assembly that you can now instantiate and call its single method, TransformText.  The only run-time requirement to use T4 templates is the .NET 2.0 Framework.

Prerequisites

  • Visual Studio 2010
  • T4 Editor Plug In 
    • Visual Studio 2010 does not provide any editing assistance when editing T4 templates (.tt files).  You can search the Internet for T4 Editor and you’ll find some information and products.
    • I’m currently using the Tangible T4 Editor (free) that you can get on the Visual Studio Gallery here: 

Our Scenario

We have been tasked with creating some code that we can pass data fields to and that code will create a VB.NET property.  This code will be part of a larger program that is fed information and creates class files.

Before T4 Preprocessed templates we had several options available to us.  Write code to spit out the required property, buy a 3rd party product, use CodeDom, etc.

Since we just installed Visual Studio 2010 Beta2, we are going for the productive, inexpensive, simple and out of the box solution, T4 Preprocessed Text Template.

Our Test Bench

This simple application simulates the data harness that will ultimately feed our T4 template and consume its output.  Set a few data fields and press Generate Code.

demoApplicaiton

Code Generation – It’s all about the data

Code generation requires metadata to drive the output.  With the new T4 templates, getting metadata into your T4 template is a simple matter of a partial class.  The members in the partial class are available at design time and run-time.  I know this seems so simple, but T4 did not always work this way.  Now you have full design time strong typing and instant compile time verification of your template and code.

To keep this example as simple as possible, I’ve exposed the metadata directly as properties and passed values for them in the constructor of our Partial Class PropertyTemplate.  For simple scenarios this totally fine.  For a larger or multi-language code generation applications, a better solution is to expose the metadata through an Interface.  The Interface type can contain metadata and helper methods that can be used in your T4 template.

Kathleen Dollard and I have spoken a good bit about this and think using Interfaces for metadata and helper methods makes the most sense.  I’m sure Kathleen will write more on this subject and I know I will.

In the below T4TemplateLibrary project you can see how I’ve set up the project.  I had to turn on “Show All Files” to see the hidden file, “PropertyTemplate.vb” below the “PropertyTemplate.tt” file.

Open the hidden “PropertyTemplate.vb” file up and you will see the type of code you and I used to have to write to generate code.  Now T4 does it for us!

T4Project

The below partial class is overly simple and exposes metadata that will be consumed by the T4 template.

Namespace My.Templates

  Partial Public Class PropertyTemplate

    Public Property PropertyName As String = String.Empty
    Public Property BackingField As String = String.Empty
    Public Property TypeName As String = String.Empty
    Public Property IsShared As Boolean = False
    Public Property RaisePropertyChangedMethodName As String = String.Empty
    Public Property IsReadOnly As Boolean = False
    Public Property Scope As String = String.Empty
    Public Property IsSetterPrivate As Boolean = False

    Public Sub New(ByVal strScope As String, ByVal bolIsShared As Boolean,
                   ByVal bolIsReadOnly As Boolean, ByVal bolIsSetterPrivate As Boolean,
                   ByVal strPropertyName As String, ByVal strBackingField As String,
                   ByVal strTypeName As String, ByVal strRaisePropertyChangedMethodName As String)
      Me.Scope = strScope
      Me.IsShared = bolIsShared
      Me.IsReadOnly = bolIsReadOnly
      Me.IsSetterPrivate = bolIsSetterPrivate
      Me.PropertyName = strPropertyName
      Me.BackingField = strBackingField
      Me.TypeName = strTypeName
      Me.RaisePropertyChangedMethodName = strRaisePropertyChangedMethodName
    End Sub

  End Class

End Namespace

T4 Template

To add a T4 template to your project, select Add New Item, then type “preprocessed” in the search box.  Select the Preprocess Text Template.

If you used classic ASP, then T4 template editing is a skill you already have.  In classic ASP we used <% and <%=.  In T4 we use <# and <#=.  The reason for this change is so that T4 can be used to generate classic ASP and ASP.NET code.  If you didn’t have the joy of shipping classic ASP web sites, no worries.  15 minutes of trail and error and you’ll be fully qualified.

The below image shows the free Tangible T4 Editor Plug-In IntelliSense in action.  It provides IntelliSense for T4 directives and template specific constructs like <#.  It also colorizes the template code.  Colorizing makes editing the template much easier too.  One current limitation is that its IntelliSense engine does list member properties defined in the partial class for the template.

T4IntelliSense 

The below code block is the T4 template.  It has a language directive at the top followed by static text and code blocks.

<#@ template language="VB" #>

<#= Me.Scope #><#= IIF(Me.IsShared, " Shared","") #><#= IIF(Me.IsReadOnly, " ReadOnly", "") #> Property <#= Me.PropertyName #> As <#= Me.TypeName #>
    Get
        Return <#= Me.BackingField #>
    End Get
<# If Not Me.IsReadOnly Then #>
    <#= IIF(Me.IsSetterPrivate, " Private ","") #>Set(ByVal value As <#= Me.TypeName #>)
<# If String.IsNullOrEmpty(Me.RaisePropertyChangedMethodName) Then #>    
        <#= Me.BackingField #> = value
<# Else #>
        <#= Me.BackingField #> = value
        <#= String.Format("{0}(""{1}"")", Me.RaisePropertyChangedMethodName, Me.PropertyName) #>
<# End If #>
    End Set
<# End If #>
End Property

<#=  is the same as the ASP Response.Write.  It writes the result of the expression into the template.  For example, if the Scope is Public, <#= Me.Scope #> would yield Public when the template is transformed at run-time.

<# is the beginning of a code block.  Notice how the IsReadOnly property is tested.  Basic on the result, an entire block of code can either run or be by-passed.  This feature is so cool when you bring loops from LINQ queries into the picture.

One thing you’ll notice is that all the code blocks are left justified.  Yes, this makes reading the template a little harder.  However, if you don’t do this, the resulting code will be indented the same amount as the code block indentation.

So what I do when editing my templates is to indent everything to make it easier to edit the template.  When I”m done, I go back and move the code to the left.

Run-Time Rendering of T4 Templates

Dim t As New PropertyTemplate(
    Me.cboScope.SelectedItem.ToString,
    Me.chkIsShared.IsChecked.Value,
    Me.chkIsReadOnly.IsChecked.Value,
    Me.chkIsSetterPrivate.IsChecked.Value,
    Me.txtPropertyName.Text,
    Me.txtBackingField.Text,
    Me.cboTypeName.SelectedItem.ToString,
    Me.cboRaisePropertyChangedMethodName.SelectedItem.ToString)

'How cool is this?  Instantiate, call a single method, get the code!
Dim strResult As String = t.TransformText

Instantiate the template, call the TransformText method.  Not very sexy, but powerful!

Download

Get Your T4 On Demo Application (33KB)

Alternate Download Site

Some corporate firewalls do not allow access to Windows Live Sky Drive. You can download the installer here. Remember to rename the file from .doc to .zip. This is a requirement of WordPress.

Get Your T4 On Demo Application (33KB)

Links

Gareth Jones blog  Gareth works on the DSL Team at Microsoft and works with the Microsoft T4 product.

Kathleen Dollard’s blog Kathleen has been doing code generation for a very long time and is an industry expert in this space.

Kathleen Dollard’s work blog post on why T4 Templates are the best thing since sliced bread.

Oleg Sych very nice blog post on T4 Preprocessed Text Templates

Pablo Galiano T4 Preprocessing Part 1

Pablo Galiano T4 Preprocessing Part 2

Close

There is a fair amount of information on Visual Studio 2005/2008 T4 templates.  When reading these blog posts, magazine articles and MSDN Documentation, keep in mind that the new T4 templates do not have wide spread documentation yet.  Most of what you will find is applicable to editing of the templates and directives used in the templates.  Beyond that, just filter the information and you’ll stay on course.

Visual Studio 2010 T4 Preprocessed Text Templates are a great tool for your toolbox.  Hope to see you use the best kept secret in Redmond.

Have a great day,

Just a grain of sand on the worlds beaches.


Updated Code: Visual Studio 2010 Beta2 Sample Data Project Templates

October 28, 2009

I have updated the project templates Visual Studio 2010 Beta2 Sample Data Project Templates

The Silverlight template needed an update to the .proj file.

Please download the templates from the above post.

Sorry for the problem.

Close

Have a great day,

Just a grain of sand on the worlds beaches.


Updated Code: XAML Power Toys for Visual Studio 2010 Beta2 Cider Designer

October 28, 2009

I was working on a post for T4 Preprocessed Text Templates (I’ll post it tonight) and found a bug in the XAML Power Toys for Visual Studio 2010 Beta2 Cider Designer grid parsing code. 

Chances are you won’t hit it, but I did so I’ve corrected the code and posted a new update.  The code didn’t properly handle a null value in the CheckBox.Content property.  I’ve correct it and added additional null checks.

Please visit this page XAML Power Toys for Visual Studio 2010 Beta2 Cider Designer and get the latest version v1.0.1.

You can go to the above page, download the install files and install overtop as it will remove the previous version and install the new one.

Sorry for the bug. 

Close

Hope you use and enjoy XAML Power Toys for Visual Studio 2010 Beta2 for Cider.

Have a great day,

Just a grain of sand on the worlds beaches.


d:DesignInstance, d:DesignData in Visual Studio 2010 Beta2

October 28, 2009

The WPF and Silverlight Designer for Visual Studio 2010 shares several new design time (d:) properties and design time MarkupExtensions with Expression Blend 3 that provide necessary information for the WPF and Silverlight Designer to deliver a great editing experience.

I have explained the d:DesignData MarkupExtension in detail in this blog post:  Visual Studio 2010 Beta2 Sample Data Project Templates.

In this post I’ll cover the d:DataContext property and the d:DesignInstance MarkupExtension.

d:DataContext

d:DataContext gives developers the ability to set a design time d:DataContext that is separate and independent of the run-time DataContext property.

This feature solves the problem of developers wanting to set their DataContext programmatically but also wanting design time data.

All d: properties are ignored during compilation and are not part of any run-time assemblies.

d:DesignInstance

Purpose:  Provides a design time shape to the d:DataContext its applied to.

Example:  In the below snippet the Person class is the shape provided by d:DesignInstance to the Grid’s d:DataContext.

<Grid d:DataContext="{d:DesignInstance local:Person}">

Note: In the above example, the Person class is actually a faux type (fake or substitute type).  This faux type enables types that are not creatable to be created and their properties exposed as a shape.  See the below section on creating creatable types.

Usage:  So, now that the d:DataContext has shape, what can I do with it?

The shape is used by the new Binding Builder to expose the properties of the type in d:DataContext.  You can see in the below image, the four properties exposed by the Person class.

BindingBuilder

The Binding Builder is opened by clicking or right clicking on the Property Marker in the Properties Window.  The Property Marker is the icon to the right of the property name.  The Binding Builder is a GUI for editing bindings in WPF and Silverlight.  This is a super feature

The Cider Team has a great explanation of the new features on WindowsClient.net that you can read here: Setting Up Visual Studio for WPF and Silverlight Development.  There is an article and video.

You can read additional Cider Team Online material here:  WPF and Silverlight Designer for Visual Studio 2010.  We are in the process of adding many more articles.  While the material is initially geared for developers coming from other platforms to WPF or Silverlight, it has a lot of great information even for the seasoned XAML Head.  Yea, I said it.  I’m a XAML Head too and proud of it.  (LOL)

Without d:DesignInstance, d:DesignData or d:Source applied to a CollectionViewSource the Binding Builder would have no way to determine shape and provide a list of properties.

Note:  If d:DataContext is not set, but DataContext is set and has a created type assigned to it, this will also supply shape that the Binding Builder can use for listing properties.

Creating Creatable Types

 <Grid d:DataContext="{d:DesignInstance local:Person, IsDesignTimeCreatable=True}">

d:DesignInstance provides a technique for creating a non-faux type.  Setting the property IsDesignTimeCreatable to True on the d:DesignInstance MarkupExtension enables this.

Links

MSDN d:DesignInstance Walkthrough

Video showing d:DesignData and d:DesignInstance can be viewed from this blog post:  Visual Studio 2010 Beta2 Sample Data Project Templates.

The above post also has source code for sample data templates.  There four of the templates are tutorial walkthroughs on this topic and sample data.

The two .xaml files in the DesignInstance Samples folder are the walkthroughs.  You can create this project in VB.NET or C# by using one of the below templates when creating your project.

  • VB WPF Application DesignData Sample – VB.NET Sample WPF Application that demonstrates consuming sample data.
  • CS WPF Application DesignData Sample – C# Sample WPF Application that demonstrates consuming sample data.

DesignInstanceExamples

Close

Hope you find d:DesignInstance and d:DesignData Sample Data in Visual Studio 2010 Beta2 a productive feature for your application development.

Have a great day,

Just a grain of sand on the worlds beaches.


New Options for Visual Studio 2010 Beta2 WPF and Silverlight Projects

October 27, 2009

ToolOptions

To get to this Options dialog, use the Tools menu, selected Options, select Text Editors, select XAML, select Miscellaneous.

MarkupExtension IntelliSense and Editing

The most requested feature for the WPF & Silverlight XAML Editor was MarkupExtension IntelliSense.  This feature has been added to Visual Studio 2010 Beta2.

In addition to IntelliSense you also get some entry helpers.

1.  When you type a { (left curly brace) Visual Studio will automatically insert the } (right curly brace) for you. 

You can disable this feature by un-checking the above option, “Closing braces for MarkupExtensions.”

2.  When you press the SPACEBAR inside {} (curly braces) Visual Studio will automatically insert a comma for you to the left of the space added by pressing the SPACEBAR. 

You can disable this feature by un-checking the above option, “Commas to separate MarkupExtension parameters.”

Toolbox Auto-Population

Visual Studio 2010 Beta2 now adds all Custom Controls and UserControls in the Solution to the Toolbox when you build the solution.  Control’s are added to a separate Toolbox tab for each project. 

You can disable this feature by un-checking the above option, “Automatically populate toolbox items.”

How Auto-Population Works

When you build a project, its corresponding tab in the Toolbox is cleared and then all types that derive from FrameworkElement are added to the Toolbox tab for that project.  (see Fine Print below for more details)

When you build the solution, all projects Toolbox tabs are updated as explained above.

If you want to prevent an item from appearing in the Toolbox during the Auto-Population processing decorate the class with the System.ComponentModel.DesignTimeVisible attribute and pass False in the constructor.

The following code snippet shows the DesignTimeVisible attribute decorating the CustomView UserControl.  The CustomView UserControl will not appear in the Toolbox.

Imports System.ComponentModel

<DesignTimeVisible(False)>
Public Class CustomerView
    Inherits UserControl

End Class

Fine Print

To appear in the Auto-Population Toolbox process a type must derive from FrameworkElement and:

1.  Are public and have a default public or internal constructor or are internal and have either a default public or internal constructor

3.  Types deriving from Window or Page are ignored

4.  FrameworkElements in other .exe projects are ignore

5.  Internal classes will only be displayed when the active designer is for an item in the same project

6.  Friend Assemblies are not taken into account for Toolbox Auto-Population

Close

Have a great day,

Just a grain of sand on the worlds beaches.


XAML Power Toys for Visual Studio 2010 Beta2 Cider Designer

October 25, 2009

Current Version 1.0.1, Last Update 28 October 2009

v1GridToo

These last few weeks I’ve been writing control designers for Visual Studio 2010 Beta2 WPF and Silverlight controls.

Turns out this is much easier than I expected and is a lot of fun too!

This application is an example for writing a globalized WPF & Silverlight platform neutral control designer.  Both WPF & Silverlight applications use the same Design library.  You can check out the source code to see how this is done.  This source code is in VB.NET.  Later this week, I’ll be posting another full featured article and code example in C# and VB.NET for writing a platform neutral control designer for WPF & Silverlight custom controls.  The project also includes two controls you can use in your projects.  (Yes, Karl now speaks C#.  Took about 2 days to pick it up.  Still have to lookup some syntax but pretty fluent now.)

I must give credit where credit is due.  I got a good bit of feedback and suggestions from my teammates on the Cider Team (WPF & Silverlight Designer Team).  Thanks Mark, Zhanbo, Bin, Pav, Marco, Ben  and Ray.  My great friend Josh Smith also came over one day for some pair programming activities.  Thanks Josh!

For those that care, the above designer is an MVVM application that is completely data driven from the ViewModel.

Grid Layout Tool

The Grid Layout Tool provides an abstract view of the selected Grid control in the designer that enables editing the Rows and Columns of the selected Grid.

The above image is the Grid Layout Tool that allows you to:

  • Move (reorder) rows and columns
  • Move (reorder) multiple rows and columns (when multi-selected with CTRL+click)
  • Insert row or column before or after any row or column
  • Delete row or column
  • Set all row or all columns sizes using the TextBoxes at the top.  Enter value and press ENTER.
  • Set individual row or column size by clicking the text value the Azure row or column headers and then editing them.  Enter value and press ENTER.
  • To set size to auto type “a” or “auto” and press ENTER.
  • Designer is updated real time as you make your changes.
  • Clicking the “Save” button commits the changes into one Undo Transaction.
  • Clicking the “Cancel” button cancels all changes and puts the designer back in its original state.

Menu Options

v1Menu

This menu is only available when you have selected a GRID control in the WPF or Silverlight designer.

Chainsaw – Leaves Alignment

The chainsaw will remove all Margins, MinHeights, MinWidths and from CheckBox, RadioButton, Label, TextBlock will remove height and widths and on TextBox will remove height.  Will set all Grid Rows to Auto.  Will remove Name and x:Name if enabled.

Use this command if you do not have styles defined that determine layout for your form.  (see video)

Chainsaw – Clears Alignments

The chainsaw will remove all HorizontalAlignments, VerticalAlignments, Margins, MinHeights, MinWidths and from CheckBox, RadioButton, Label, TextBlock will remove height and widths and on TextBox will remove height.  Will set all Grid Rows to Auto.  Will remove Name and x:Name if enabled.

Use this command is you have a styles defined that determines layout for your form.  (see video)

Modify Control Tags on Create

If this option is checked the following controls will be affected when you create the control using the ToolBox.

StackPanel and Grid – Alignments and Name cleared  (note: when the StackPanel is created inside a GroupBox or Expander, the tag modifications are ignored and overridden by the designer.)

TextBox, TextBlock, Label, CheckBox, RadioButton – smaller sizes than the Visual Studio defaults and Named is cleared.  The smaller sizes widths were 120, now 80, except TextBox which is 100.  You can play around with control creation to see if this makes sense for you.

Modify Control Tags and Chainsaw Clears Name

If you want control names cleared by the Chainsaw or the control Modify Control Tags on Create feature check this menu option.  To turn off name clearing, uncheck this menu option.

Video

PLEASE view this short tutorial video.  You will get a full and quick understanding of this great feature.

This video is on my SkyDrive.  Silverlight Streaming is being discontinued and won’t let me upload any more video files.  Like many others, I’m trying to find an alternate location to host all my training videos.  Relocating and re-pointing all my videos will be a huge PIA.  Any suggestions for hosting would be greatly appreciated.

The below video can be downloaded and viewed.  Click the link to be taken to my SkyDrive.

  XAML Power Toys 2010 Beta2 for Cider Tutorial Video (13 minutes)

Downloads – Visual Studio 2010 Beta2 ONLY

This software will not work in the final release of Visual Studio 2010.  That includes RC/RTM releases.  I will release a new version when RC (release candidates) are published.

Remember – Please build your projects before attempting to create forms, ViewModels or using the Field List.

Please set your Control Defaults after installing, new options have been added.

Download now comes from my Windows Live Sky Drive.

Microsoft employees please read this:

If you are using the final Beta2 release these links and this software will work for you.

If not please  email me and I’ll send you an internal drop location you can get this software from.  (Just look me up in the Global address book.)

XAML Power Toys 2010 for Cider – for Visual Studio 2010 Beta2 v1.0.1 Release (459 KB)

XAML Power Toys 2010 for Cider – for Visual Studio 2010 Beta2 v1.0.1 Source Code not required (85 KB)

Alternate Download Site

Some corporate firewalls do not allow access to Windows Live Sky Drive.  You can download the installer here.  Remember to rename the file from .doc to .zip.  This is a requirement of WordPress.

XAML Power Toys 2010 for Cider – for Visual Studio 2010 Beta2 v1.0.1 Release (459 KB)

Your Feedback

I can’t not over emphasize the the importance and the weight of your feedback on this block post.  My team (Cider Team that delivers the WPF & Silverlight Designer) is eager to hear from customers on features you need in the WPF & Silverlight Designer and XAML Editor.

Close

Hope you use and enjoy XAML Power Toys for Visual Studio 2010 Beta2 for Cider.

Have a great day,

Just a grain of sand on the worlds beaches.


XAML Power Toys for Visual Studio 2010 Beta2

October 25, 2009

This post is the home page for XAML Power Toys for Visual Studio 2010 Beta2.  Please post all comments and suggestions for this version on this post.

XAML Power Toys for Visual Studio 2010 has all the same features as XAML Power Toys for Visual Studio 2008 except as noted below.  Please use the XAML Power Toys for Visual Studio 2008 page as a reference for how the the features work.  Please download this version of the software below.

During development of XAML Power Toys for Beta2 I ran into some bugs that are being corrected for the final release of Visual Studio 2010.  As a result I had to cut a few features for this release.

The below image displays the menu for XAML Power Toys for Visual Studio 2010 Beta2.  Users of the 2008 version will notice the “Group Into” submenu is gone; the “Tools” submenu is gone and that “Create ViewModel for Class” is displayed in the this submenu but it shouldn’t.

The bottom line is, submenus are broken in Beta2 and there is no known workaround.

Notice I have moved “Set Control Defaults” and “About” features from the “Tools” submenu to this submenu.

XPT2010Menu

The other grayed out menu options are not enabled because no XAML was selected when the screen shot was taken.  All features on this menu work as advertised.  “Create ViewModel for Class” just displays here in error and will never be enabled.  It does work correctly in the C# and VB.NET Code Windows.

The good news is, the above software has been updated and works great in Visual Studio 2010 Beta2.

When the final release of Visual Studio 2010 is public I will release a new version without these limitations.

Downloads – Visual Studio 2010 Beta2 ONLY

Remember – Please build your projects before attempting to create forms, ViewModels or using the Field List.

Please set your Control Defaults after installing, new options have been added.

Download now comes from my Windows Live Sky Drive.

Download XAML Power Toys for Visual Studio 2010 Beta2 v5.1.0001 Release Installer (809 KB)

Download XAML Power Toys for Visual Studio 2010 Beta2 v5.1.0001 Source Code not required (594 KB)

Alternate Download Site

Some corporate firewalls do not allow access to Windows Live Sky Drive.  You can download the installer here.  Remember to rename the file from .doc to .zip.  This is a requirement of WordPress.

Download XAML Power Toys for Visual Studio 2010 Beta2 v5.1.0001 Release Installer (809 KB)

Visual Studio 2010 Beta2 Known Issues

The below issues are known, being worked on and will be fixed for the RC/RTM milestone.

1.  Can’t Add Menu inside an AddIn

This problem was first reported on MS Connect. 

https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=462766&wa=wsignin1.0

  ReferencesBug

The workaround for this bug is to set the “Embod Interop Types” property to False for the “Microsoft.VisualStudio.CommandBars 8.0 Reference”

2.  Submenus keep repeating

When adding a submenu to a menu you have added in an AddIn, the submenus will repeat the entire menu tree instead of just showing the submenu items.

This is why I had to remove the “Group Into” submenu and features.  The submenus were simply unusable.

3.  Setup project “Client Framework” problems

When I first compiled the Setup project for this release, upon installation I kept getting a message that I had to install the .NET 4.0 Framework.  Obviously the full .NET framework was installed on the machine.

The only way I could get the message to not show up when running the Setup.exe, was to remove all references to the “Client Framework” within the solution.

Remember, in Visual Studio 2010 Beta2 all WPF and Class Library projects will by default target the “.NET 4.0 Client Framework.”  This is a good thing as it makes application distribution and installation easier for customers of your applications.

However, in this Beta2 release, to get the files to install from the output of the Setup project I had to remove all references to the “Client Framework.”

Close

Hope you use and enjoy XAML Power Toys for Visual Studio 2010 Beta2.

Have a great day,

Just a grain of sand on the worlds beaches.


Follow

Get every new post delivered to your Inbox.

Join 244 other followers