Get a VS2010 Ultimate Experience for Less

As of writing this blog post, there are thousands of developers converging in Las Vegas for the official release of Visual Studio 2010. I’ve been using Visual Studio 2010 for the a while now and it has been a generally positive experience. While as was exploring the VS2010 site I saw this question posed. “What Edition is Right for Me?” That prompted me to look through the editions. Microsoft has planned to sell for commercial versions: Professional, Premium, Ultimate, and Test Professional. A much smaller selection that the VS2008 editions, but that is a good thing. What shocked me was the outrageous price jump from Professional to Ultimate, from $799 to $11,899; that is over $11,000 difference for one copy of Visual Studio. So this blog post is to show you how to get an Ultimate experience for less, so that you can utilize that extra money for pizza and beers for you development staff.

1.) Visual Studio Professional ($799)

you are going to need this right? So what is missing from Professional that is in Ultimate?

  • Intellitrace (Historical Debugger)
  • Static Code Analysis
  • Code Metrics
  • Profiling

image

a.) Intellitrace ( $0 no alternative )

sadly I couldn’t find something that replaced this feature. It is very cool. Look at it this way though, the fact that Microsoft moved it up to the premium edition makes me think that they feel the common developer probably doesn’t need it. I also rarely used this feature in my own development.

b.)Static Code Analysis & Code Metrics ($410)

so what is static code analysis? Wikipedia defines it as the analysis of computer software that is performed without actually executing programs built from that software. Hmm… this sounds familiar, I think I’ve done that before. Oh wait I have! NDepend is a great static analysis tool that has been around for a while now.

c.) Profiling ( $0 – $500 )

There are a ton of profilers for the .Net framework, and some of them are FREE! In this post I chose the two that a company might buy ANTS Memory Profiler and JetBrains ReSharper.

2.) Testing

So you are a testing kind of developer, that’s great but you want all the extras that ultimate offers.

  • Code Coverage
  • Test Impact Analysis
  • Coded UI Test
  • Web Performance Testing
  • Load Testing
  • etc…

a.) Code Coverage ($479)

NCover is a mature and great tool for code coverage.

b.) Web Performance Testing and Load Testing($0)

The web has been around long before VS2010, so this problem has been solved a million times. Realizing that there are a ton of tools out there to do this and I won’t list each of them. Just Google and prepare to be overwhelmed by the possibilities.

c.) Coded UI Test ($0)

Watin allows you to code tests for UI interaction of web applications, which is probably the hardest interaction to test for.

d.) Resharper ($349)

I have to mention this tool just because it is so good and it improves the unit testing experience inside of visual studio, regardless of your framework.

3.)Database Development

the dreaded database…. how do we handle this stuff?

  • Database Deployment
  • Database Change Management
  • Database Unit Testing
  • Data Generation

a.) Database Deployment ($0 – not needed)

In theory this sounds great, but the majority of companies have a company structure that forbids any developer from making database pushes; the job of pushes are usually left to a Database Administrator. They will probably want to execute SQL that they have crafted and labored over.

b.) Database Change Management ($0 – code option)

again this is probably left up to your DBA with a combination of your source control (SVN, Hg, Git, TFS). I recommend looking into a migration framework if you really want to control the versioning of a database.

c.)Database Unit Testing (Whaaaaat? $0)

this troubles me on two fronts. First off you probably shouldn’t be unit testing enough of your database to have a whole project dedicated to it. Secondly, this is what developers refer to as integration tests and you don’t need any other tools other than your  favorite unit testing package to do this. Granted, VS2010 probably has some nice UI tools to make this more pleasurable, but in my opinion tests are about results and not how pretty the UI is.

d.) Data Generation ($0)

This is a problem that isn’t that complicated to solve, and again has been solved. Check out AutoPoco which allows you to generate a ton of data easily through a fluent interface. After generation, just go ahead and pump this data into your database with your favorite ORM or DAL.

4.)Architecture and Modeling ($100)

Buy a whiteboard for modeling and get your team involved. There is nothing worse than an Ivory tower architect that pushes his architectural will on the team without discussion.

5.)Source Control ($300)

Unfuddle is a great online source control provider and in my opinion gives you a lot of things your business will use from Team Foundation Server. When I quote the $300, I am talking about for your whole company and not per developer. This is a huge cost savings. There are also a ton of other online source control providers that are similar to Unfuddle.

Tools I have to mention: TortoiseSVN, MsysGit, TortoiseHg, AnkhSVN (all free)

Conclusion and Total Price: $2637 ($2832 less than Premium and $9262 less than Ultimate)

That savings per developer is nothing to joke about. You could save over $9000 dollars but just looking around more. So what is the downside? Well you will have a hodgepodge of tools to use and many of these options might lack UI tools and possibly Visual Studio integration. Do your homework and see if the benefits of buying these tools outweigh your desire to have a all in one tool like VS2010. If you have a team of five developers, I just saved you over $45k. Your welcome.

C4MVC Presentation on Database Migrations

Hello everybody. It has been about a week since I gave my C4MVC presentation on database migrations. The video is below, and the code is also downloadable below.

Migrations Example (VS2010)

Asp.Net MVC 2 Quick and Simple Site – v1

*Note: Asp.Net MVC 2 project in Visual Studio 2010

I sat down last night and was thinking about how I could get a simple starter site up and running for a client, until I could design something more tailored to their needs. There is nothing worse than having a “under construction” page or a “coming soon” page. It doesn’t really say much about what is happening or what might be coming. So I sat down and came up with the basics of what a client might want right from the start, here were my requirements.

  • Set a Logo, Name, and Subtitle
  • Be able to quickly edit a small about section (Content)
  • Quickly add some of the more important social networks (Twitter, YouTube, FeedBurner, Delicious, MySpace, and Facebook).
  • Be able to add Google Analytics (Optional)
  • A dynamic image gallery (drop images in a directory and everything is done for you).
  • Basic contact information. Email, Phone, and Website.
  • No external libraries to install (this hurts but is helpful).

So I sat down and started writing. I wanted someone to be able to push this site without editing a lot of files or having to setup a database. I opted to put a lot of the client’s settings in configuration. Yes configuration sections are not the new hotness but they can still serve a powerful purpose.

My first iteration had me using controller actions for each part of the site, but I slowly realized it was overkill. I opted to have one controller action from my index, and then break sections up into partial views that would be all rendered at the same time. Then those sections would be hidden and made visible using JQuery. After a little design, I ended up with this.

image

Let’s look at how to set this up.

Step 1 – Setup the Configuration

There are some pretty simple configuration sections in the web.config included with this project. You will see two App settings: WorkImagesDirectory and GoogleAnalyticsCode. The WorkImagesDirectory is used to find all the images in your gallery. Thumbnails for all your images will be automatically created if they are missing. The GoogleAnalyticsCode setting should be set to your Google Analytics code UA-XX-XXXX (or something like that). If you leave out the Google Analytics code then the script won’t be output to the page.

Next you will see a ContactInformation section. In this section you can set the name, site subtitle, email, phone, and website.

Finally, you will see a SocialNetworks section. Only the social network usernames you set will show up on the page. You can set Twitter, Facebook, YouTube, Delicious, MySpace, and FeedBurner(a blog maybe).

Step 2 – Setup Content

Once the configuration is done, then you probably want to change some of the content to reflect some good information.

All tabs are separated into partial views: About, Contact, Work, Social. Just replace the HTML content in here with what you want, leaving the nested RenderPartials.

Step 3 – Modify Colors and Images

All the images and style sheets you need to modify are under the Content directory. If you like the color and just want to modify the avatar at the top, just overwrite the avatar.png under Content/img.

Step 4 – Deploy It

Just publish what is there to your hosting provider and you are ready to go.

Conclusion

This is a good little site to get up and running for your clients, but it isn’t anything ground breaking. The code is straight forward, so even a novice can get in there and change things. The point here was not to over complicate the solution with third party libraries. It is to get a site up with in minutes, while still giving some great functionality to the people that need it.

AquaBird.StarterSite

Aqua Bird Consulting has moved to CoolHandle Web Hosting

Aqua Bird Consulting has just finished its move from its old hosting company to its new location at CoolHandle Web Hosting. I can honestly say that I am 100 times happier with the move and the service that CoolHandle offers. For those who have been reading our blog posts, we apologize for the long wait. In an effort to get back into blogging you can expect to see a lot of helpful blog posts in the up coming weeks.

Topics you can expect to see are business oriented, development oriented, and technology rants. To be specific, I have been personally working on a presentation for C4MVC  regarding database migration frameworks. Expect to see a downloadable solution for the migration presentation. For those of you the commented on previous posts, if you do not see your comments then you may have been lost in the transfer (probably a strong argument to use Disqus here). Please comment again and I will try to reply to your question.

We have been up to some really exciting things and can’t wait to share some of them with you. So anyways, the point is the Aqua Bird Consulting Blog is back! Be sure to tune in and keep reading.

Thank You,

Khalid Abuhakmeh

New Year – New Developer

So we are sitting on what is the precipice of a new year. We can either choose to change and evolve with the times, or we can stay stuck in our ways. I have decided to make some new year’s resolutions to make me a better person and developer.

1. Get Into Shape

As developers we can spend a lot of our time on our butts, up to 8 hours a day. That is why I need to make a strong effort to be active. My definition of active is a solid hour of exercise five to six days a week. Exercise is only part of the solution. Did you know your body expends more calories digesting food then it does when you exercise? That is why I have to make an effort to eat less calories. Now that the holiday season is over, the temptation of gorging is gone with it. And finally, cut out all high-sugar drinks. Developers live off of energy drinks but each can of energy drink can be as much as 400 calories. That is equivalent to the calories found in a bagel! Replacing those drinks with water can cut out a lot of unnecessary calories.

2. Work On My Communication Skills

I can talk to people, but sometimes I don’t fully get my idea across. This can cause frustration on both my part and the listener. That is why I have to work on my communication skills. I will do this by being more conscious of the words I say, listen deeply to my counterpart, and being less abrupt with my answers. I will also be working on my vocabulary. Adding words to my vocabulary can give me a more diverse set of words to express my ideas and intentions.

3. Swear Less

Swearing is a powerful tool when used properly. It can express frustration, anger, and happiness all in a couple words. There have also been studies that show swearing can lead to better rapport between co-workers. That being said, I have to remember that there is a place and time to use certain words and phrases. For example, a holy place is no place to start dropping the F-Bomb.

4. Be More Systematic

I am trying more and more to depend on systems to make me more efficient and dependable. This will help me reduce times where I am just thinking of what to do instead of doing what I need to do.

5. Be More Assertive

Over my life I’ve learned that people can take advantage of you if you let them. They can also mistake your kindness for weakness. Letting the other party know why I won’t do something, or the conditions on what I’ll do given a task will make my life much simpler.

6. Give Love to the People that Deserve It

There are a lot of important people in my life, and some not that important. Giving more preference to those I love will make everyone happier.

7. Read, Read, Read

It’s surprising how much more knowledgeable you get by just reading what other people are doing. So I am dedicating 2010 to reading more.

The year is early and things could change, but for right now these are my resolutions. Do you have any?

Main Site Now iPhone Enabled

Have I pronounced my love for ASP.NET MVC yet? Well if I haven’t then let me do it now. I love you ASP.NET MVC! With very minimal effort, about 3 hours, I was able to create an iPhone version of the main site of Aqua Bird Consulting. I used JQTouch for the iPhone functionality, and used a new view engine to determine whether your coming in through an iPhone. Check out the pictures below. I’ll be pushing this nice feature out pretty soon. I still need to delve deeper into JQTouch, but I am confident that most ASP.NET MVC applications can be converted to an iPhone version with no effort at all.

photo photo 2photo 3

Zeep Mobile – SMS Gateways

A good application is ubiquitous, it is everywhere you need it and never in your way. That is probably why applications like Twitter and Facebook have been so successful. So how do you add more of that ubiqutous goodness into your applications? SMS of course! Text messaging is a powerful tool for many people. I text more than I talk, and I think that is becoming the status quo.  That in mind, I have been looking for a good SMS gateway provider so that I can give texting capabilities to my clients. I still haven’t stumbled on the best solution, but there is one worth talking about: Zeep Mobile.

Zeep Mobile is a Free SMS Gateway for use without any limitations, but there is a catch. The catch is with each message you send  your users, a small text based ad will be placed in your at the end of the message. If you don’t want ads, you can pay for an ad free service. So I signed up for the beta and decided to figure out how well it works.

Step 1 – Sign Up For Beta

Go to the Zeep Mobile site and sign up for the Beta, you should get an invitation almost instantly. This is a Beta, so I didn’t expect everything to work or have a super refined service.

Step 2 – Understanding the Flow

You can’t start sending messages to anyone you want. This is a subscription based system. So you have to follow these steps to get started.

  1. Create  an application key within Zeep Mobile
  2. Copy a provided HTML Snippet onto your site
  3. Sign up through the provided widget with a valid number or test number (provided by Zeep Mobile).
  4. Confirm on that number that you want text messages from said application.
  5. The Application is now ready to send that number text messages.

Step 3 – Following Their API

Zeep Mobile is a REST based API, which means all your interactions will be facilitated through the HTTP protocol; mainly posting your data to them. Also, their authorization scheme is based on a secret key and hashing your content along with the current date of the request. See the diagram below.

authentification_step_2

In addition to sending text messages, Zeep Mobile can make calls to an endpoint of yours and pass you data. This is so your application can store and maintain the latest users. I’ll show you how to send text messages to Zeep, but I won’t show the callback because that is trivial to implement once I show you how to call Zeep Mobile.

Creating Your Zeep Authorization Token

Zeep Mobile requires you have your authorization token in the header. It follows the following format.

Zeep [API Key]:[HMAC+SHA1 Encoded Canonical]

Being a nice guy, the following code to do that is directly below. One note, before you pass the message into the method below, make sure to Url Encode the string. This can be done by using the HttpUtility class. I’ve also provided extension methods to do this.

        public string GetZeepAuthorization(string message, DateTime date)
        {
            // product HTTP Date
            var httpDate = date.ToString("r");
            string canonicalString = ApiKey + httpDate + message;

            // Compute the Base64 HMACSHA1 value
            HMACSHA1 hmacsha1 = new HMACSHA1(SecretAccessKey.ToByteArray());

            // Compute the hash of the input file.
            byte[] hashValue = hmacsha1.ComputeHash(canonicalString.ToByteArray());

            string b64Mac = hashValue.ToBase64String();
            return string.Format("Zeep {0}:{1}", ApiKey, b64Mac);
        }
 public static class Extensions
    {
        public static byte[] ToByteArray(this string input)
        {
            UTF8Encoding encoding = new UTF8Encoding();
            return encoding.GetBytes(input);
        }

        public static string ToBase64String(this byte[] input)
        {
            return Convert.ToBase64String(input);
        }

        public static string ToUrlEncoded(this string input)
        {
            return HttpUtility.UrlEncode(input, Encoding.UTF8);
        }
    }

Posting Your Text Message

You have two options here: Send a message to a particular user or send the message to everyone. The code below shows you how to send to everyone, but this code is easily adapted to send to a single user. The quirk below is that you have to set the date on your request or Zeep will complain. Zeep uses the date to calculate the hash on their side, if the date is missing then you can’t get your request through. Read the documentation on Zeep Mobile for more detailed information.

  public string SendZeepMessage(string message, string authorization, DateTime date)
        {
            HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(BlastMessage);

            request.Date = date;
            request.Method = "POST";
            request.Headers.Add("Authorization", authorization);
            request.ContentType = "application/x-www-form-urlencoded";

            // send the Post
            var messageBytes = message.ToByteArray();
            request.ContentLength = messageBytes.Length;

            using (var os = request.GetRequestStream())
                os.Write(messageBytes, 0, messageBytes.Length);

            try
            { // get the response
                WebResponse webResponse = request.GetResponse();

                using (var stream = new StreamReader(webResponse.GetResponseStream()))
                    return stream.ReadToEnd().Trim();
            }
            catch (WebException wex)
            {
                // This exception will be raised if the server didn't return 200 - OK
                // Try to retrieve more information about the network error
                using (HttpWebResponse errorResponse = (HttpWebResponse)wex.Response)
                {
                    // get descriptive message
                    using (StreamReader sr = new StreamReader(errorResponse.GetResponseStream()))
                        return sr.ReadToEnd().Trim();
                }
            }
        }

That’s all the code you need to start sending text messages to subscribers. Now all you need to do is write a way to handle callbacks, possibly through an HttpHandler, ASP.NET Web Form Page, or ASP.NET MVC.

Get Your Message (err… Sorta)

At the time I wrote this code, everything was working fine on Zeep Mobile but something must have broken on their side. How can I be certain it is on their side and not my code? Well messages are getting through. This means that hash on my messages are being calculated and are successful on Zeep Mobile’s side, but the messages coming through are blank. Hopefully this is just a small hiccup in the Beta. Below you will see the test phone that Zeep Mobile Provides.

image

Step 4 – Thoughts About Zeep Mobile

It is definitely a winning idea, but it is still in beta. As you saw above things are still being worked out with the API and the API lacks a lot of the calls needed to really make it something great. Essentially the API was designed to facilitate text messaging, but has left out  administration features that would allow you to manage your subscribers. The good side to that lack of functionality is that you could code it yourself due to the nature of the callback service Zeep Mobile provides. Essentially, Zeep Mobile is saying that they want to facilitate communication between you and your subscribers, but doing anything more is up to you.

Zeep Mobile is worth checking out and trying, but as of right now I would look for a stronger SMS Gateway Provider for any serious application. The downside to using other SMS Gateway providers is that they are expensive. If anybody knows any good ones please let me know, because I am always interested.

Coding With My Voice

I was exploring some screen casting software the other day and I noticed that Windows 7 has speech recognition. It probably was there in Vista, but I never really played around with it. I wondered how easy it would be to program a “hello world” program while keeping mouse and keyboard strokes to a minimum. I started by starting my voice recognition on my instance of Windows 7 machine.

image image

The next step is to announce to my computer to start Microsoft visual studio 2010. That command is “Open Microsoft Visual Studio 2010”

This is where it goes down hill for me. Visual Studio 2010 doesn’t have voice support for actions. I tried to say something like “File > New> New Project” but Voice recognition just ignored me. The second approach was to remember what the shortcut was to start a new project. Since I know it, I said to my computer “Control Shift N.” Soon after, I was presented with the New Project dialog. Another painful experience. I had to tab my way to a new project, and tabbing with your voice is not fun. Below is a play by play of my tabs.

image

Not exactly fun. The next step was to get into the code. I cheated here and had to click into my code. After some painful, painful, painful yelling at my computer I got this code. It took me about 10 minutes of backspacing, and fixing things to get a simple application.

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World");
            Console.Read();
        }
    }

So you might be thinking, why would anybody do this?

Well I started thinking about scenarios where programmers could leverage their voice to program. Before we know where we want to go, we have to know where we are. Obviously we are not very far when it comes to programming with your voice. Below are some things that need to change for developers to start programming with their voices.

Context Switching

Programming languages are created to crudely mimic human language. A phrase could mean two different things to a word processing application and a development environment. Theoretically, when I enter Visual Studio my voice context should be switched to a developer context. This means that voice recognition is listening for different keywords to perform functions. Below are some examples of actions that could be present in a developer context.

  • “Add New Class”
  • “Add New Project”
  • “Lambda x comma s executes s equals x”  (x,s) => s = x
  • “Console Write Line String Hello World End String”
  • “Select Current Method”
  • “Select Class”
  • “Rename Function/Class/variable”
  • “Comment Above Line  ….”

In addition to knowing actions in this context, the voice recognition could know you programming preference and make appropriate decisions for you. This is primarily for casing variables, functions, and classes. When you say “Calculator Service,” The voice recognition should know that you mean CalculatorService.

Programming Language Hooks

The voice recognition software should be able to recognize keywords and namespaces of the programming language you are using. So if you say a class name, the voice recognition software should know if you are creating a new class or talking about an existing class. This approach could be achieved two ways: create an API that the voice recognition can call in an IDE, or create a dictionary that you could place into a location for the voice recognition. Either way, you are building an API to allow developers to extend the voice recognition for their particular programming language.

Fingers-Voice Hybrid

Right now you are able to type while you talk to your computer. I would expect that you could do the same when programming with your voice. Some things just might be faster using your fingers.

Conclusion

These are the first step to voice recognition for developers, they are obviously large steps to take. Clearly the current voice recognition in Windows is made to server the greater population of users, who are interested in word processing, email, and chat applications. It would be great if you could take the voice recognition in Windows and specialize it to be used with Visual Studio and other IDEs to boost the efficiency of developers. Microsoft, I hope you are listening.

Jumping Development Niches – Realizing Learning

.Net is one of those great platforms that gives you so much value without having to re-learn everything. I recently decided to jump back into Windows Presentation Foundation, to keep my skills there sharp. What I was surprised to find is that it is evolving at break neck speeds, almost to the point of giving me migraines. Obviously Microsoft isn’t moving at this speed to overwhelm developers, but instead to give value to those developer niches. About  5 – 10 years ago Microsoft thought of a developer as a windows developer, creating applications solely for use on their platform. Everything Microsoft made was centered around rapid application development or drag and drop development. This is clearly evident when you look at Asp.Net Web Forms. Since that time the world has evolved, and so has Microsoft’s view of those developers.

Microsoft is developing niches, and although they don’t mind you jumping around from niche to niche, they want to make sure to help those loyal to those niches by continually providing new value in shorter release iterations. This can make it tough, but not impossible, to catch up in a niche like WPF or Silverlight development. So what are these niches? Well they aren’t officially defined, but there are strong lines. There is obviously some overlap, so you might see some things repeated.

p_790886.Net Niches

  • Web Development
    • ASP.NET MVC
    • ASP.NET Web Forms
    • Windows Communication Foundation (WCF)
    • Cloud Computing (Windows Azure)
  • Windows Applications
    • Windows Forms
    • WPF
    • Silverlight
  • Rich Internet Applications (RIA)
    • Silverlight
  • Enterprise Systems
    • Windows Workflow Foundation
    • Office Development
    • Cloud Computing (Windows Azure)
    • SharePoint
    • Reporting
  • Simulation and Games
    • XNA Framework
    • Microsoft Simulators
    • Robotics

These are the major niches as identified by Aqua Bird Consulting. I’m sure there are smaller niches that we’ve missed, but these are the ones that the majority of developers are involved in. So the question is, can you get one developer to know all this stuff off the top of their heads? No, of course not, these frameworks are dynamic and with shorter and shorter release cycles it would be a 24 hour a day job learning it all. So what can a developer do?

I’m No Tabula Rasa

This sadly is what some developers do, they throw up their arms and say they don’t need to learn that new stuff. They believe that Microsoft writes everything sub-standard and that they know better. This usually means these developers are entrenched in building new frameworks and systems and not leveraging the work of external developers. Building frameworks is great for developers because they get to nerd out, but terrible for the business (unless the business intends to sell this framework, but you’ll find few willing to buy). A business needs to perform its business functionality, and the longer a developer can’t provide that the longer the business losses critical revenue.

Jack of All Trades, Master of None

The second approach is to learn a little about every topic and know that it exists. In fears of sounding like a G.I. Joe public service announcement, “knowing is half the battle!” If you know something exists, you won’t spend weeks or months home rolling your own solution. This can be critical to saving time and money. The best place to start is Microsoft Developer Network (MSDN). This approach requires a lot of time surfing the internet and reading blogs. With this approach, when presented with a project, you can make the best decision about what technologies to use and learn more about it during the process of development. This approach has its ups and downs, but can help make sure that your solution is on the latest platform.

Bring in the Specialist

Pick two or three technologies and go deep. Learn everything about these few technologies and be able to talk critically and intelligently about them. This approach can work well for developers when they know what is expected of them. If you are a web developer, then you probably don’t need to read about XNA for your job (although you could read about the XNA framework for fun). This can be a double edged sword for the obvious reason that the only thing that never changes is that everything changes. Your company might be entrenched in web development one year, but decide to go into game development the next year; your skills don’t fit the job description anymore (nothing that drastic will probably happen, just making a point).

Conclusion

Doctors have used a similar approach in their profession. You will first go see a family doctor and he will attempt to diagnose your problem and treat it. If he has diagnosed your problem but cannot treat it, he then goes ahead and refers you to a specialist. Microsoft .Net is growing, both in depth and width. You can either go shallow and wide or deep and slim. You, as a developer know what’s best for you. Also you as a business owner, if you are one, know what you want your developers to be. Keep in mind that it is never too late to jump from one niche to another, but to be effective in any niche you need to do your time and pay your dues; these dues come in the form of long hours reading, learning, and doing.

Aqua Bird Consulting Blog On iPhone

Now you can read the latest from Aqua Bird Consulting on your iPhone. No more gesturing to shrink, zoom, and pan across the blog. As you can see from the screenshots below it is readable and syntax highlighter is supported. Oh Jeez!! I should really charge my phone.

photophoto 3photo 2