Wednesday, September 30, 2009
Deep Fried Bytes – Workflow Part 2 is up
Part 2 of my interview on workflow foundation, past, present, future, and focus on workflow services is up and available for your listening pleasure (or torture as the case may be). 
Monday, September 21, 2009
Deep Fried Bytes episode Part 1 live
A couple months ago I recorded an interview on the state of affairs of Windows Workflow Foundation, with the focus on Workflow Services, on Deep Fried Bytes. The recording has been broken into two parts because we talked for quite a while and part one has gone live. You can check it out here: 
Saturday, September 05, 2009
Supporting Graceful Shutdown and Saving on Close From a WPF Prism App
When you start building applications the Prism way, your UI logic can be spread out across any number of loosely-coupled, independent modules and their supporting code. This is a good thing in terms of breaking up the functionality of your application into reusable components and being able to distribute the work across multiple developers or teams. However, the decentralizing of the UI logic can lead you to scratch your head frequently when you need to implement some piece of functionality that sort of naturally feels like the main window has to handle it all. A common requirement that is one of these common head scratchers is what to do when you want to prevent the application from shutting down until all work in progress (unsaved documents, pending downloads, etc.) is complete. This came up (again) with a customer the other day, so I figured it would make a good post (thanks for the idea John :) ). In a Prism app, the code that performs those actions and manages the state associated with them should be implemented within the modules that are loading into the application, and that code probably belongs in a ViewModel or Controller that is supporting the associated views. So when the user clicks on the red X to close the application, or invokes some other command from the menu or toolbar that indicates it is time to close the application, you need a clean communication path from the shell down to all chunks of code that may need to vote on whether the application should be allowed to shut down right now. Picking a Communication Option Prism offers two loosely-coupled communication mechanisms: Prism events and commands. One approach that might occur to you is to use Prism events and have the shell publish a shutdown event, and have the module code subscribe and handle it. This could work, but part of the pattern of pub-sub events is that the publisher should not know or care if there are any subscribers out there, nor should it care what the subscribers do if they are there. So if you just wanted to notify the module code that shutdown is happening, you could use a Prism event, but the problem is that you probably need to block the shutdown until they have all done their clean up, and you often need to be able to cancel shutdown if there is unsaved state or incomplete tasks. One of the key differentiators between events and commands in my mind is that commands represent an action taking place for which there is an expectation that there will be some handling code out there. So for a shutdown communication to the modules, a command is a better way to go. And the way Prism CompositeCommands work, all of the contained command handlers will be invoked before the execution of the command is complete. In general, a command invoker is not expecting any results back from the handlers. However, to support the cancellation of shutdown, we would need to effectively pass arguments back to the invoker to let it know whether to complete the shutdown. To do this, we can just piggy back on a well-established pattern in WPF and Windows Forms – pass a CancelEventArgs argument as the command parameter, and allow the handlers set the Cancel property of that parameter to true if they don’t want shutdown to happen. Putting it Together To demonstrate one way to put this together, I’ve put together a simple Prism application that is like a simple Wordpad of sorts. You can fire it up, open multiple documents in tabs, edit them, and save them independently. You can see the app running below. A few minor bells and whistles include setting the tab header to the document title, and showing “dirty” documents by making their tab header bold/italic. The New command in the toolbar is always enabled, but the Save command is only enabled if the currently active document is dirty. I’ll do a follow on post about this aspect, which uses the IActiveAware facility of Prism. The logic code for supporting an individual instance of an editor views is fully implemented in the ViewModel class for the view, DocumentEditorViewModel. There is also a controller class that takes care of creating the instances of the view when the New command is invoked. I’m not going to drill into all aspects of the application architecture, but you can take a look at it as a fairly well organized example of a Prism app if you download the sample code. The basic project structure is shown below. I have a ShellApp that is the WPF application project. It contains a bootstrapper like most Prism apps that gets things going by presenting the shell. The MainWindow class is the shell window, and has two regions in it: a MainToolbarRegion and a DocumentRegion. The toolbar is (not surprisingly) a Toolbar, and the document region is just a TabControl. There is also a StatusBar at the bottom to show an indication of why close is not happening if one of the documents needs to be saved. The SomeApp.Common is just a class library that contains the shared types between the shell and the modules – specifically some constants and the commands in this case. The SomeDocumentModuleLib is the only module in this example, and contains the SomeDocumentModule, the DocumentController, the DocumentEditorViewModel, and its supporting DocumentEditorView. The view class (DocumentEditorView) is very simple, just a TextBox and the IActiveAware implementation I’ll talk about in a subsequent post. The controller is called by the module’s Initialize method to get things going, and it populates the toolbar with the New and Save command buttons using Prism regions, and also has the handling code for New, which simply creates a new instance of a view and a viewmodel and marries them (sets the view’s DataContext = viewmodel). The ViewModel is where the action is at for both the Save command and the Shutdown command that I am really trying to focus on here. Notifying ViewModels of Shutdown To get the word out to the ViewModel instances for open documents when someone goes to close the application, you have to first start with the WPF Window.Closing event that is fired. That event passes a CancelEventArgs allowing you to prevent the closing of the Window. But first off we don’t want to do logic handling in a view (the Shell), and second, the Shell is supposed to be fairly stupid about what the app components want to do about the event anyway. So we need a clean way to dispatch the event out as a command and get results back to decide whether to let the close happen or not. The way I chose to approach it is to use a Prism CompositeCommand as the form of communication. Each ViewModel (or other interested background code) can provide a command implementation for that command, and in that implementation they can decide and modify the argument that is passed to indicate whether they are OK with the shutdown or not. So starting at the source, we first have to handle the Closing event at the Window level: <Window x:Class="ShellApp.MainWindow"
...
Closing="OnWindowClosing"
>
To dispatch the command to others, we need a command definition.
public static class Commands
{
...
public static readonly CompositeCommand ShutdownCommand = new CompositeCommand();
}
The ShutdownCommand is the one we are focusing on here.
The code behind handler for the Closing event basically needs to execute the Shutdown event and pass along the CancelEventArgs as a command parameter, allowing the handlers of the command to potentially set Cancel to true:
private void OnWindowClosing(object sender, CancelEventArgs e)
{
if (Commands.ShutdownCommand.CanExecute(e))
Commands.ShutdownCommand.Execute(e);
if (e.Cancel)
m_StatusText.Text = "One or more documents need saving before you can shutdown";
}
The way the CompositeCommand works in Prism, it will go out to all command handlers that register with the command and invoke their handling code.
The DocumentEditorViewModel provides the implementation of that command, one for each instance of an open document:
public DocumentEditorViewModel()
{
...
ShutdownCommand = new DelegateCommand<CancelEventArgs>(OnShutdown);
Commands.ShutdownCommand.RegisterCommand(ShutdownCommand);
}
public DelegateCommand<CancelEventArgs> ShutdownCommand { get; set; }
private void OnShutdown(CancelEventArgs args)
{
if (IsDirty)
{
args.Cancel = true;
}
}
The view model also maintains the dirty state of the document and uses it to drive both the enablement of the Save command, as well as to decide whether to allow shutdown. If the document is dirty, it simply sets the CancelEventArgs.Cancel property to false. Since the same argument is passed by reference to all the handlers of the command, if any one sets it to true, Closing will not happen.
That’s all there is to it. Piece of cake, right? Clean, simple, loosely coupled communications that achieves the end goal. Shell doesn’t have to have any knowledge of what it takes to allow the app to shut down, and the individual chunks of code that care don’t have to know about each other.
Any questions or comments, please post a comment and I’ll get back to you.
You can download the full sample app code here.
Sunday, August 16, 2009
INETA UG Talks This Week
I gave two talks in SoCal this week, one at the San Diego .NET User Group Connected Systems SIG in San Diego and one at the South Bay .NET User Group in Torrance. The San Diego talk was titled Exercise WCF Best Practices and was a collection of practices with context and explanation on employing features and capabilities in the WCF stack in the best way. I talked about server side considerations including interface and layer separation, instancing model, exception handling, security model, and hosting, as well as client side considerations such as proxy creation, caching of proxies, and exception handling on the client side. The slides and demos for this talk can be downloaded here: Slides Demos The Torrance talk was A First Look at WF 4, which covered all the new features coming in WF 4. I covered the new designer, declarative XAML workflows, new activities in the base activity library, the flowchart workflow model, hosting of workflows, arguments, variables, and expressions, workflow services, and runtime improvements to name a few things. The slides and demos for this talk can be downloaded here: Slides Demos
Tuesday, August 04, 2009
TechEd Africa Sessions and Demos
This week I had the pleasure of speaking at TechEd Africa in Durban South Africa. It was a great venue, great attendees with insightful questions, and generally just a lot of fun to get to see a part of the world I’ve never been to while still teaching people about the cool capabilities of the .NET Framework and the best ways to employ those capabilities. I did 5 sessions, briefly outlined here: WUX303: New Tools and Controls for Building Rich WPF Line of Business Apps The real title was something else, horrendously long and un-pronounceable in one breath, but that covers the gist of it. I showed how to use the DataGrid, DatePicker, and Calendar controls that are available for .NET 3.5 development today with the WPF Toolkit. If there are any WPF developers out there that don’t have that as part of their standard development machine set up after installing VS 2008, they are selling WPF short and hindering the user experience for their user (unless they have a third party control library that gives them similar and more functional versions of those kinds of controls). Those controls will also be incorporated as part of the framework in .NET 4.0, so I also demoed their use in VS 2010 along with the great new data binding features in the designer, which closely mimic the capabilities in Windows Form 2.0 that I covered extensively in my data binding book. I also talked about the new WPF Ribbon control and showed its use, and briefly talked about the MVVM pattern, showed an implementation in the demos, and mentioned the MVVM Toolkit that is in development that will make it easier to do. SOA305: Exercise WCF Best Practices In this session, I went through a bunch of best practices for WCF, along with their context, to help people identify practices they should be following regularly when implement WCF services and clients. I covered things like starting your services as PerCall rather than the default of sessionful, exception management on the server and client side, implementing and attaching error handlers, picking a hosting model from IIS, WAS, self-hosting, and eventually Dublin, self-hosting coding patterns, proxy creation and management patterns, and a brief touch on REST vs SOAP at the end. It was a jam packed session and I unfortunately did not have enough time with a 1 hour session to show as many code samples of the practices I was covering as I wanted. SOA401: Developing Service Oriented Workflows This was pretty much the same session I gave at TechEd US, with the exception that I had to cut some content and do less coding from scratch because the session here was only an hour vs 1:15 in the states. SOA201: New Features in WCF and WF 4.0 This was a packed session, standing room only, so obviously a lot of people want to know what is coming down the pike. I covered the new features in WCF 4.0 including simplified configuration, Discovery, Router Service, REST features, and a few others. Then I switched to WF 4.0 since the changes are even more sweeping there and covered the new declarative workflow model, data flow with variables and arguments, workflow services and more. Fun session, just wish I could have twice as much time to give all the great new features better coverage. Whiteboard Session: Are WCF and WF for Mere Mortal Developers? Had good attendance and some great questions and discussions with the attendees about the barriers to adoption with WF, what are some of the scenarios where you should just not bother with WF, where those scenarios change with WF 4 compared to 3, and what some of the pain points are with WF in terms of adoption. There was also a fair amount of discussion on WCF, talking about challenges and solutions as far as managing configuration of services, diagnostics and tracing capabilities, factoring of service interfaces and moving to WCF from other technologies and architectures. For those that attended, thanks! For them and others who want the demo code, here is one zip with all session demos in it.
Thursday, July 23, 2009
Obscure WCF Exception – Mislaid Blame
I lost a couple hours today to perhaps the most obscure WCF error message I have encountered yet. I do tons of WCF and have been working with WCF extensively since 2003 timeframe when I had access to the private betas. I would consider myself a top expert on WCF, and yet this one really was kicking me in the butt. Without a methodical approach to troubleshooting it, I never would have sorted it out. Most WCF errors, after developing a good experience base with the technology, you can rapidly solve. You will either get to know some common ones and know where to jump in your configuration to sort it out, or you can Bing/Google the error message and you will usually find some forum posts where someone suggests the right configuration fix. I was putting together a very simple WCF call from a client to a service, using username security with the WsHttpBindiing. When I got everything set up the way I had done hundreds of times before, I was getting an exception whenever I tried to make the method call on the client. The error I got stuck on was telling me this: Outer exception: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail. Inner Exception: An error occurred when verifying security for the message. OK, fine. I’ve seen those many times before. Went back and quadruple checked all my security settings on both the client and server. All seemed well there. Time to search. Lots of people have apparently had this error, and every solution I found had to do with making sure the clock on the client and server were matched up. Hmm, I’m running client and server localhost. I’m no time-space continuum expert, but I’m relatively certain when two parties reference the same clock, they are in sync. So then it became an exercise in eliminating variables. Change the service method to return null to eliminate some kind of serialization error. No, not it. Snap back to a default WsHttpBinding with no modifications. All works well there. Gotta be the binding. So I look closer at what I had hacked together for a server binding: <wsHttpBinding>
<binding name="MyBinding" maxReceivedMessageSize="20000000">
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
<!--Remove the readerQuota or increase its size, problem goes away-->
<readerQuotas maxArrayLength="2000"/>
</binding>
</wsHttpBinding>
Thanks to the fact that I had just observed a conversation on a connected systems email alias regarding maxBufferSize and why it doesn’t exist on WsHttpBinding, it occurred to me that it could be my (arbitrarily chosen) message size or array length.
Sure enough, if I removed the readerQuotas maxArrayLength altogether, or just bump it up by one extra zero, the problem disappeared. I know that there is some coupling between maxReceivedMessageSize and maxArrayLength, but don’t know the specific rules off the top of my head. But I just wanted to get this out there that if you have those errors indicating security problems and you are convinced your security is configured correctly, try tinkering with your sizes in the binding. That could very well be the cause as it was for me.
You can download a sample application that demonstrates the problem here.
Wednesday, July 22, 2009
Implementing Plug-Ins with a DI Container
If you are building a highly extensible application, the right answer these days seems to be to look into MEF. It is a very flexible approach to extensibility and plug ins that works for 3.5 and will become part of the .NET Framework in 4.0. However, sometimes you just need a simple plug in capability to load some components provided by others. If there is any chance those plug ins will depend on each other and need to talk to each other, bite the bullet and learn and use MEF. But if they just need to be loaded up and called, you can use a simple factory to get the job done. About 4 years ago, I put together a little sample of doing this with a generic factory class here. A similar requirement came up with a customer this week, but with one twist: we were already using a DI container (Unity) and the plug ins that were going to load were going to have dependencies on some objects and services that the DI container already knew about. Since the container is really a generic factory itself, I decided to put together a little sample of using Unity as a plug-in factory and thought I would share it here. Defining the Plug-ins The first step to a plug-in architecture is to define the common interface(s) that the plug-ins themselves will implement. Say you have this interface definition in a common library: public interface IPlugIn
{
void DoSomething();
}
Then you define some implementations of that interface in other class libraries (the plug in libraries):
public class PlugIn1 : IPlugIn
{
public PlugIn1(ILogger logger) { }
public void DoSomething()
{
Console.WriteLine("PlugIn1 called");
}
}
Note that this plug in has a dependency on some service (ILogger) that our DI container will know about.
Using the Container As the Plug-In Factory
Now all you need to do is use the ability to configure the Unity container through a config file to have the construction of those plug ins loosely coupled from the code.
Define the config info to configure the container with the plug in types, as well as the dependent types:
<configuration>
<configSections>
<section name="unity"
type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection,
Microsoft.Practices.Unity.Configuration, Version=1.2.0.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<unity>
<typeAliases>
<!-- Lifetime manager types -->
<typeAlias alias="singleton"
type="Microsoft.Practices.Unity.ContainerControlledLifetimeManager,
Microsoft.Practices.Unity" />
</typeAliases>
<containers>
<container>
<types>
<type type="Common.IPlugIn, Common" mapTo="PlugIns.PlugIn1, PlugIns" name="PlugIn1"/>
<type type="Common.IPlugIn, Common" mapTo="PlugIns.PlugIn2, PlugIns" name="PlugIn2"/>
<type type="SomeDependencyLibrary.ILogger, SomeDependencyLibrary"
mapTo="SomeDependencyLibrary.Logger, SomeDependencyLibrary" >
<lifetime type="singleton" />
</type>
</types>
</container>
</containers>
</unity>
</configuration>
Then just configure the container and resolve the plug-ins through a call to ResolveAll:
IUnityContainer container = new UnityContainer();
UnityConfigurationSection section =
(UnityConfigurationSection)ConfigurationManager.GetSection("unity");
section.Containers.Default.Configure(container);
IEnumerable<IPlugIn> plugIns =
container.ResolveAll<IPlugIn>();
foreach (IPlugIn plugin in plugIns)
{
plugin.DoSomething();
}
And viola. you have a simple plug-in factory using the container.
Sunday, July 12, 2009
Comments on The Myth of Developer Productivity
Scott Bellware put together a great post emphasizing the importance of organizational productivity over developer productivity that I wanted to point people to and make some additional comments on. In his post, Scott points out the pitfalls of focusing only on developer productivity as a way to ship your product faster. He elaborates on the fact that if you don’t have a good quality-focused process and organization, the short term gains (or local optima as he describes them) created by developer productivity or efficiency tools may actually compound your problem in several ways. Organizational Productivity I totally agree with several things Scott points out in his post. First, a lot of the customers I deal with in consulting do have immature processes and organizations, so they need to fix those first and foremost if they really want to ship higher quality products faster. Following agile practices including the following are some of the minimum bars I think development teams should be targeting for most business applications: - Practicing Scrum or having daily stand up meetings to facilitate team communications and collaboration
- Practicing Pair Programming or at a minimum having diligent code reviews on all production code
- Practicing TDD/BDD/DDD or at a minimum having a high degree of unit test coverage combined with a good loosely coupled design
- Documenting requirements in a light weight, but easy to understand and location form (user stories, bullet lists, work items all suffice if done coherently)
- Having a good CM process including good source control tools
- Having an automated build process that runs nightly at a minimum, or better yet trending to continuous integration
There is a lot more to having a good agile process in place than I can document here, but the point is that too many teams recognize that these are things they should be doing, but they never get around to establishing as a repeatable part of their process. Then they hear about developer productivity tools and think that just by using those, they will somehow overcome the organization-level lack of productivity with the micro-productivity enhancements that developer productivity tools can often have. The Hazard of Developer Productivity Tools Also as Scott points out, when used blindly, some developer productivity tools can actually cause grave damage to product-level productivity. One example of this includes some of the developer productivity tools in Visual Studio, specifically some of the code produced by designers and code generation. This has gotten better from version to version, but there is still the tendency to put things into Visual Studio that demo well and might be OK for toy applications, but should never be used for serious applications. For example, the SqlDataSource in ASP.NET encourages developers to drag and drop their way to a functional data driven page. Looks great, and you are done in minutes. Developer productivity nirvana. But what happens after that? You end up with hundreds of these scattered across your project, each with embedded markup tightly coupling the page to the database schema. Bad, bad, bad for overall productivity in developing a product because it is a maintenance nightmare. But these kind of features are often hyped in the VS demos as if it will make you able to ship your product so much faster. It might let you get a simple first version out the door faster. But even the first version of a moderately complex app will suffer in timeline as the schema changes throughout the development cycle and you have to keep tracking down the resulting breakage in the tightly coupled pages. The remedy is taking the time up front to put a good layered design in place, and use the right developer productivity tools in the right way (i.e. bind an ObjectDataSource to the domain objects coming out of a repository) to speed up the coding process slightly, but not end up with messy un-maintainable code from using them. Another hazard I see with developer productivity tools (VS ones in particular) are that especially for less experienced developers, it tends to teach them that if they can’t do it through the tool, it can’t be done. I had this at a customer site the other day. We were using a mapping component, and the developer came in complaining something that we needed to do wasn’t supported by the component. After drilling into the problem, it turned out that what the developer really meant is “my Visual Studio integration for that component is not working, and if I can’t drag and drop it and hook things up in the designer, I have no clue how to code against the component itself”. If you are going to use any developer productivity tool, the developers have an absolute responsibility for understanding what the generated code does, and how to write that code themselves if the tool is not available or is not doing things quite right. If they are going to use features that produce code that is not great for long-term productivity, they need to fix the code to make it more maintainable as soon as the code is generated. If fixing the generated code right then takes them longer than it would have to code it all by hand, then they shouldn’t be using the tool in the first place. Another example is the WCF proxy generation in Visual Studio. While it is great for quickly the code in place to make calls to a service that exposes metadata, the proxy code that it generates is usually much more verbose than it needs to be, and it can totally garbage up your app.config or web.config file with unnecessary configuration elements that become your maintenance burden. It is usually more productive from an overall productivity perspective to do what we call “hand coding” the proxy. The Benefit of Developer Productivity Tools and Why You Should Still Use Them - Correctly However, that being said, I am a firm believer in not wasting developers time, as well as trying to keep developers focused on the logic they are implementing, instead of spending too much time banging on the keyboard and worrying about the structure of the code instead of its content. So even when I say “hand coding” above, I would prefer to use a developer productivity tool such as CodeRush + Refactor, ReSharper, or just Code Snippets in Visual Studio to output clean, templated code for those places where repetitive coding patterns are required. If possible, I would then look for opportunities to refactor some of that repetitive code into base classes or helpers, but that is not always possible. So I actually often say that I firmly believe that every developer should have a copy of CodeRush+Refactor or ReSharper on their machine, and should spend a little time learning how to use the basic features of those products right. As Scott points out, doing so is not going to affect your overall timeline one bit if you don’t already have a highly efficient and streamlined organizational process. And if the developers don’t understand the code that is being spit out or when it is appropriate, it is again a liability , but that again comes back to professional responsibility of being a good developer. But at a minimum, I do think the tools mentioned above save the developers tons of time in terms of not wasting time banging out snippets of code character by character, but instead lets them spit out the right code with minimal keystrokes. This frees their time and their mind to focus more on the logic of the code instead of the structure. It also lets them blaze through throw away implementation of prototypes and spikes much faster than if they didn’t have those tools, and if done right, that code is getting dumped once you figure out what you are going to do and how to do it anyway. Using CodeRush/Refactor or ReSharper also tend to produce better consistency in the code, because if the tool templates are spitting the small structural elements out, those elements are more likely to be coded consistently across developers. Finally, both of those tools have great features for continuous refactoring of code to clean up things like redundant/unused declarations, replacing string concatenation with string.Format, and hundreds of other things that might otherwise be missed, or just take more time to do manually than they do using the tool. Wrap Up So bottom line, I agree with almost everything Scott says in his post. I just think in some places it paints an overly negative picture of developer productivity tools and could lead someone like a product manager to say “I don’t need to buy my developers these tools because they won’t help anyway”. If you don’t focus first at the process level, you still won’t ship your products any faster by using developer productivity tools. But I think with the right tools and the right approach to using them, you will still improve the quality of the code the developers are producing by using these tools, and that is worth it in its own right. And you may get through the experimentation implementation portions of your lifecycle a little faster as well. But don’t fool yourself into thinking that just throwing these tools at the developer is all you need to do. And also approach any developer productivity tool with jaded optimism and get a real understanding of what it is producing and what the long term impact of that code is before you think it is really going to save you any time before committing to using it for production coding.
|






| February, 2012 (1) |
| January, 2012 (1) |
| November, 2011 (4) |
| October, 2011 (1) |
| September, 2011 (2) |
| August, 2011 (1) |
| July, 2011 (1) |
| May, 2011 (5) |
| March, 2011 (4) |
| February, 2011 (2) |
| January, 2011 (3) |
| November, 2010 (4) |
| October, 2010 (1) |
| September, 2010 (5) |
| August, 2010 (5) |
| July, 2010 (6) |
| June, 2010 (8) |
| May, 2010 (2) |
| April, 2010 (2) |
| January, 2010 (1) |
| December, 2009 (3) |
| November, 2009 (2) |
| October, 2009 (3) |
| September, 2009 (3) |
| August, 2009 (2) |
| July, 2009 (3) |
| May, 2009 (3) |
| April, 2009 (2) |
| March, 2009 (1) |
| February, 2009 (2) |
| January, 2009 (2) |
| December, 2008 (1) |
| November, 2008 (2) |
| October, 2008 (5) |
| September, 2008 (4) |
| August, 2008 (2) |
| July, 2008 (1) |
| June, 2008 (2) |
| May, 2008 (2) |
| April, 2008 (3) |
| February, 2008 (6) |
| January, 2008 (3) |
| December, 2007 (1) |
| November, 2007 (1) |
| October, 2007 (5) |
| September, 2007 (1) |
| July, 2007 (3) |
| June, 2007 (8) |
| April, 2007 (2) |
| March, 2007 (4) |
| February, 2007 (1) |
| December, 2006 (2) |
| November, 2006 (9) |
| October, 2006 (5) |
| September, 2006 (3) |
| August, 2006 (2) |
| July, 2006 (4) |
| June, 2006 (5) |
| May, 2006 (10) |
| April, 2006 (4) |
| March, 2006 (2) |
| February, 2006 (12) |
| January, 2006 (7) |
| December, 2005 (2) |
| November, 2005 (15) |
| October, 2005 (6) |
| September, 2005 (7) |
| August, 2005 (3) |
| July, 2005 (10) |
| June, 2005 (11) |
| May, 2005 (7) |
| April, 2005 (8) |
| March, 2005 (6) |
| February, 2005 (2) |
| January, 2005 (6) |
| December, 2004 (3) |
| November, 2004 (5) |
| October, 2004 (2) |
| September, 2004 (5) |
| August, 2004 (13) |
| July, 2004 (6) |
| June, 2004 (14) |
| May, 2004 (17) |
| April, 2004 (12) |
| March, 2004 (8) |
| February, 2004 (10) |
| January, 2004 (14) |
| December, 2003 (9) |
| November, 2003 (13) |
| October, 2003 (3) |


Sign In
|