Static Classes And The HasShutdownStarted Property#

During the pre-conference session on Framework Design Guidelines, Brad Abrams was kind enough to share the story behind the infamous HasShutdownStarted property on the Environment class with us. If you're unfamiliar with that property, take a look at its original definition below:

public sealed class Environment
{
private Environment() {}
public bool HasShutDownStarted { get { /*...*/ } }
}

Now see if you can spot the "minor issue" with this property...

The funny thing is, this code actually shipped in the initial release of the .NET Framework, but obviously it needed to be QFE'd (Quick Fix Engineered). So Brad did a little investigation to see how it could have happened that an effectively uncallable property made it into the framework. Running through the engineering callstack, he found out that:

  • The property was implemented and unit tested by the developer.
  • It was subsequently tested and approved by the tester.
  • It was documented along with "working" sample code.
  • And finally it was reviewed and accepted by the Program Manager who owned the feature (in his defense, he had originally specified that it should be static).

According to the story, this incident triggered the static classes feature that is new in C# 2.0 (which declares a class as having only static members) to prevent this from happening again.

By the way, declaring a class as static makes the compiler mark the class both sealed (so it cannot be inherited) and abstract (so it cannot be instantiated) under the covers; furthermore, the compiler checks that everything on the class is effectively static. It doesn't create a private constructor, as you might think, because there's no real point to do that anymore (instantiation is already prevented by defining the class as abstract) and to avoid the small metadata overhead induced by the additional constructor.

Blog | General | Programming | .NET | Quirks | Whidbey | PDC05
Friday, September 16, 2005 5:15:49 PM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

PDC05 Pre-Con: The Art Of Building A Reusable Class Library#

Attending a pre-conference session is a bit like foreplay for the brain: it's not about going ahead and diving into the action, it's gearing up the body to prepare for the main dish.

In that sense, I decided to cheat on the wife a little. So last Monday, in stead of going to the SOA pre-con I originally planned, I followed my instinct and went to one about a pet peeve of mine: API design. So I spent the entire day exploring "The Art Of Building A Reusable Class Library" by Brad Abrams and Krzysztof Cwalina, who are both very knowledgeable on the subject in their roles at Microsoft where they review the public API's of the entire .NET Framework. In fact, they just have a book out on the subject called "Framework Design Guidelines" and - lucky me - they handed out free copies for their attendees. Nice!

The reason I chose this session, is that I'm quite passionate about building reusable libraries which have a clear, consistent and self-explaining API. I've been involved in designing reusable components and frameworks before, and it's indeed quite challenging to meet these goals.

There are quite some factors to take into account when designing a framework, and they've been summarized in the session in four key topics:

  • The Power Of Sameness
  • Framework Design Matters
  • Tools For Communication
  • The Pit Of Success

The Power Of Sameness

When driving a new type of car, there's no point in reading the owner's manual: you just know how to operate a car, the seatbelt, the turn signals, ... because they all work the same way. This principle should be applied as much as possible to software as well: if your users know how to use previous versions or other parts of your program or framework, they will easily get started with a new version or with an undiscovered part of your framework.

In framework design, this means that you must adhere to consistent naming guidelines, patterns (like prefixes and suffixes, take the "I"-suffix for interfaces and the standard Exception and Attribute suffixes for example), to lower the learning curve of your API.

One important point of attention is to "optimize globally" in stead of locally, which means that even a justified deviation from the guideline shouldn't always be allowed, even if there are very good reasons to do so. In other words: you should dare to make one part "less good" to keep the overall system consistent and thus better. A practical example of a violation of this principle is the ArgumentNullException: the general pattern is that all exceptions take the message as their first parameter, but the ArgumentNullException takes the parameter name as its first (because that makes much more sense in this case). In retrospect, this shouldn't have been allowed, since it breaks the common usage scenario that developers are used to.

Framework Design Matters

A well-designed framework must, above all, be simple. To achieve this simplicity, you need to think like your users. A very convenient way of getting in their heads is to actually write code samples for the main scenarios first, and then defining the object model to support these code samples. Another way to make sure your framework is simple to use is to factor the namespaces to only include the most used types and move the advanced types into their specialized namespace so they don't clutter the view for the most commonly used scenarios.

A well-designed framework must be explicitly designed. This means that you should create an API specification, review the scenarios with expected users, peers and non-experts, and finally review the API design.

A well-designed framework is part of an ecosystem. Your API won't only show up in code, it should also be designed to look well in IntelliSense, in the Debugger, in the Properties Window, ... Also take care to make your framework CLS Compliant, since there are other languages in the ecosystem that might want to consume it.

A well-designed framework must be integrated. Special points of attention here are to apply the proper abstractions (e.g. something I do a lot: don't explicitly declare fields and arguments as a Hashtable when an IDictionary is enough for your needs), and watch out for type name conflicts (it's not because it's in a separate namespace that a generic type name such as "Message" won't get in the way of your users).

A well-designed framework must be designed to evolve. This is particularly hard, since versioning and building for the future means taking into account the unknown. In this sense, you should favor using classes (likely abstract classes) over interfaces since they are easier to version: adding members is a non-breaking change for classes, but not for interfaces. Also make sure to control your extensibility points, such as virtual methods, and only open them up if there is a good reason to do so.

A well-designed framework must be consistent. This, of course, relates to the Power Of Sameness mentioned before, and is key to a good user experience. Specific rules include having consistent naming guidelines and using common patterns and idioms (like the Async pattern, the Dispose pattern, ...).

Tools For Communication

Consumers of your framework can't read your mind, so you have to communicate your intent. This can take the classical form of documentation, of course, but even if you have 500 pages worth of documentation, your API can still reek royally and your customers won't be happy. The layout of your namespaces, the naming patterns in your types, the exceptions you define, ... all form a common vocabulary that allows your consumers to feel familiar with your API (and of course, if your API adheres to the guidelines published by Microsoft, they'll feel right at home right away if they know their way around the .NET Framework).

A few interesting highlights out of the different artifacts of that vocabulary:

  • Namespaces are just an organizational element, they have nothing to do with implementation (so there doesn't have to be a one-on-one link between the namespace name and the assembly name, for example).
  • Classes are a conceptual model for a thing so they should represent something with one single semantic meaning.
  • A struct is a domain specific extension of the intrinsic type system, so typically they should be smaller than 16 bytes and, quite importantly, immutable.
  • Exceptions should be defined wisely, and a new type should only be defined if the user would like to differentiate the way to handle this exception versus other exceptions you've defined.
  • An enum is a container for named constants; you should take care to explicitly assign the enum values and make their name singular, e.g. Color for a list of colors (except when they're [Flags] type of enum, in which case their name should be plural, e.g. AnchorStyles).
  • A constructor should be lazy and only capture state, make sure not to do too much work in the constructor.
  • A method exposes an action or operation, it doesn't return instance state as such.
  • A property is a logical backing field for instance state, but take care that it's not retrieved using an expensive operation (like going to the database), in which case you're better of with an explicit method.
  • A field is just an implementation detail, and it should never be exposed anyway.
  • An event is raised (not fired or triggered) to inform a subscriber of something that happened, and you should carefully follow the common event naming pattern to avoid confusion.

The Pit Of Success

The final part talked about a very interesting concept: you should guide the consumers of your framework into just "doing the right thing" if they don't really know what to do in a given situation. Doing the right thing shouldn't be hard as climbing a mountain or running through a desert - instead it should be as easy as just falling into a pit. Enabling this Pit Of Success can be accomplished by avoiding the Perilous Summit Of Complexity and the Desert Of Confusion. The first can be summarized as "making the simple things simple, and the hard things possible". The second means making consumers fall into doing things the right way by avoiding leading them down confusing and possibly wrong paths. A good way to put this into practice could be to provide easy-to-discover convenience methods for the most common scenarios (e.g. the new File.ReadAllLines method in the .NET Framework 2.0 that hides all the filestream plumbing in one simple method call).

Finally, one other way to achieve the Pit Of Success is to remove unnecessary features - thereby reducing the surface area and the accompanying room for mistakes, which, in the end, adds value to your framework. Or to put it another way: you can actually reduce the value of your framework by adding features. So you should do as little as possible now (but no less) to ensure room for extensibility in the future.

So this is the compressed takeaway I got out of this excellent pre-conference session. If you found this interesting (I sure do), I can highly recommend the book "Framework Design Guidelines" which is full of practical guidelines, do's and don'ts, along with their reason and additional annotations. Learn from it, and apply the guidelines to your own API's so your consumers will be happy to use what you've built.

Blog | General | Programming | .NET | PDC05
Friday, September 16, 2005 5:01:58 PM (Romance Standard Time, UTC+01:00) #    Comments [1]  | 

 

PDC05: The Third Keynote#

In the third and final keynote, Bob Muglia talked about the server side of things in the roadmap that matters for developers. This was a much shorter session, but covered some interesting topics such as management, Monad, WinFX, Active Directory, ...

Some interesting notes from the keynote:

Management

  • WS-Management, which I've also seen in action at TechEd, has been defined as a unification of remote management of hardware, operating systems and application. It even enables remote management of WMI services cross-platform.
  • MMC 3.0 has been announced to host managed components, so you can finally write MMC Snap-Ins in .NET!

Monad

As you might already know, Monad is the codename of a new object-based command line language.

  • It has been created in .NET.
  • It works with thin commandlets.
  • In integrates the command line, COM and .NET

Active Directory

Active Directory has been around for a few years providing identity management and single sign-on across the enterprise. Now with Federation Services it will extend this single sign-on principle to work between different enterprises.

Longhorn Server

The server edition of Windows Vista should be ready in 2007. Of course, there are a lot of interesting enhancements and new features but a few highlights were pointed out:

  • Terminal Services will be accessible through firewalls, and it will support USB device redirection. Nice!
  • TxF is the codename for the Transactional Filesystem, which adds transaction support to an NTFS filesystem. This means you can finally have atomic changes to filesets (which can be very handy for certain Source Control scenarios and, why not, Transactional FTP?)
  • IIS 7, but this actually deserves a point of its own :-)

IIS 7

One of the most common problems with IIS to date has been the centralized and opaque nature of the IIS Metabase (which holds all the configuration data for the IIS server). It required an administrator to update the settings, and you were in serious problems if the metabase ever got corrupted. So it was very exciting to hear that the metabase is now officially dead. All configuration is now persisted in XML configuration files, and this even trickles down to the web.config files of the individual websites. Take for example the task of adding a default document to be served for a website, which can now be defined in its own web.config as such:

<configuration>
  <system.webServer>
    <defaultDocument>
      <files>
        <add value="MyHomePage.aspx" />
      </files>
    </defaultDocument>
  </system.webServer>
</configuration>

Furthermore, IIS7 is completely modular, so you can remove modules that you don't use (e.g. CGI) and rewrite modules that you're not happy with (e.g. the DirectoryListingModule) - and all of this on an individual website basis and without restarting the server or IIS! This is very powerful and opens up a lot of interesting scenarios.

So that concludes the last keynote, I'm off to some more in-depth sessions!

Blog | General | Programming | .NET | PDC05
Thursday, September 15, 2005 7:06:49 PM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

PDC05: The Second Keynote#

Introduction

Although the first keynote on Tuesday already ran way over time, Eric Rudder still found plenty more to talk about in the second keynote today. The main announcements were:

  • Windows Workflow Foundation: this natural extension to the .NET Framework enables developers to incorporate both System Workflow as Human Workflow into their applications. Microsoft is actually using this themselves in their next versions of SharePoint and Office "12".
  • Microsoft Expression: this is a suite of designer tools (codenamed Acrylic, Sparkle and Quartz) aimed at graphics and web designers.
  • Visual Studio Tools for Applications (VSTA): think of this as the next version of Visual Basic for Applications (VBA), but of course now within the managed .NET runtime. So this technology enables application customization in .NET, and it's already committed to by its integration into Office InfoPath "12".

Windows Workflow Foundation

The main statement that caught my attention was that "Workflow is everywhere": every "if" statement you write is a branch that effectively represents a lightweight workflow step; every webpage transition is a choice you make and can be modeled in a workflow.

So Windows Workflow Foundation sets out to capture complex workflows, expose them to developers and enable on-the-fly extensions to them for added flexibility. Although this sounds impressive, in the end, all it is is "just another .NET namespace": you can execute all of this through managed classes. Furthermore, you can design the workflows right in Visual Studio, very much like you can model Biztalk orchestrations right now.

As a small remark (but I think this is quite big news), it was noted that Microsoft will be providing the tools to embed these workflow designers inside your own applications, so your end users will also benefit from this runtime.

As a demo, we were shown how this currently works: there's a new project type in Visual Studio, you can define the state machine in a visual designer which is persisted as a .xoml file and you can program the individual activities through managed classes. Furthermore, the entire development experience supported since you can visually set breakpoints in your workflow designer and it will just work in the debugger. Incredibly powerful!

Microsoft Expression

Acrylic is a tool that allows you to create vector-based graphics and export them as XAML.

Quartz Web Designer allows a web designer to create ASP.NET ASPX and master pages in a rich designer environment that supports XML/XSLT and even ASP.NET controls with their full design-time power (such as smart tags). It even features a built-in web server that runs your website locally.

Sparkle is basically a XAML designer that uses the same project and MSBuild system as Visual Studio.

The last two tools actually make me wonder how large the overlap is with Visual Studio: since they share so many features (designers, web server, project system, build system, ...), I would think that the tools are just customized and "skinned" versions of Visual Studio, but targeted at non-developers...

Visual Studio Tools for Applications

The VSTA platform looks promising, and we were shown a demo that showed the runtime in action in a special build of AutoCAD, but there wasn't really much info available on the runtime or on the capabilities of the platform. I'm sure we will hear much more about this in the near future, since VBA is still one of the most used extension platforms for a lot of applications.

Office 12

During the second part of the keynote, more time was dedicated to showcasing the upcoming Office "12" release. The user experience seems much improved, but unfortunately, we won't be able to get our hands on it for a few months yet. For PDC attendees, this is truly a shame, since we're all quite thrilled about it and they're hyping it all up, but we need to wait a few months before we can actually start using it...

Some random notes from the Office 12 part:

  • SharePoint (Windows SharePoint Services as well as SharePoint Portal Server) is positioned as the core element of the entire Office System.
  • Office 12 will have blogs and wiki's as part of the collaboration framework. You heard it right, blogs and wiki's!
  • You can think of the new FrontPage as a designer or management tool for SharePoint, e.g. you can use it to define new workflows (which are of course also persisted as .xoml files).
  • You can finally use InfoPath forms over the web! Another cool feature was that you can now store and share design snippets for reusable parts of your InfoPath forms. Nice!

So that wrapped up the second keynote, less interesting (apart from the Windows Workflow Services) but nevertheless lots of promise for the future.

Blog | General | Programming | .NET | PDC05
Thursday, September 15, 2005 12:07:23 AM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

PDC05 Keynote#

Introduction

The keynote for this year's PDC traditionally started off with a roadmap of the Microsoft platform from the times of yore. In waves of 10 years, we received new foundations to build upon:

  • In 1975, the software industry really took off as a consumer-oriented market.
  • In 1985, there was MS-DOS and the PC that we could take for granted.
  • In 1995, Windows '95 established the new GUI capabilities that we still use today.
  • In 2005, we can really depend on the internet, .NET, XML and WebServices to build connected applications.

Windows Vista

The keynote went on to talk about the three C's of Windows Vista: Clear, Confident and Connect. Things that caught my attention in those areas were:

Clear

  • The ALT-TAB window looks much nicer, with live previews of the windows in a sort of carroussel mode.
  • You can also get a very nice 3D view of the open windows.
  • If you hover over a taskbar item, you get a nice little live preview of the associated window (a bit like the little inline Windows Media Player toolbar).
  • Search is embedded everywhere, also in the Start Menu, where you can quickly filter all items collected from your start menu, your applications, your favorites, ...
  • A virtual folder in Windows Explorer is actually just a persisted query stored in an XML file, so you can actually open the virtual folder in notepad and see the XML.
  • The sidebar is back! I heard some rumors that it would disappear but it's there and still looking as nice as before. The individual panels on it are now called "gadgets" (I don't think that was how they were called before.)
  • There's also a little something called "Sideshow", which looked kind of like a PDA built into the case of a laptop where you get quick access to your email, calendar, ... without booting your laptop.

Confident

  • There's built-in support for Parental Control, so you can define which games can be played by who for example.
  • A lot of work has been put into anti-phishing. For example, there's a new Dynamic Protection Service, which blocks websites which have been marked as phishing sites. You can easily mark sites as phishing, so they will be blocked for everyone automatically; you can also request to unblock sites you believe are falsely blocked. A team is actively maintaining the list, so if they can keep this up-to-date, it could be a viable solution to the problem.

Connect

  • IE7 supports tabbed browsing, as we already knew. The pretty cool extra feature is that you can get a PowerPoint-like slide overview of all your open windows and manage them through there.
  • IE7 has built-in support for discovering RSS feeds and subscribing to them. The only problem I have with it, is that it heavily uses the orange XML icon we all know now, but I wouldn't want this to become too mainstream. XML does so much more than RSS that it's just stupid to use it as a "marketing icon" for it. Why not just use an orange RSS icon?
  • Microsoft is also anticipating RSS to be used for much more than just subscribing to feeds: businesses will depend on a syndication format more and more as they connect to their partners and suppliers. One example was the new version of their CRM solution, Microsoft Dynamics CRM, which uses RSS to let a user subscribe to changes in the backend CRM system.

Office 12

After touring Windows Vista, Office 12 was next up. The target of Office has always been to "Get Better Results Faster" and there sure seem to be a lot of productivity enhancements. As a fun fact, Word 1.0 had 100 commands (in the menu bars and toolbars), Word 2003 has over 1500! So with that in mind, we basically got a quick tour of Word, Excel and PowerPoint running under Vista and it truly looks wonderful.

Windows Vista and Office 12 are both scheduled for release the second half of 2006, so that's getting pretty close already. I'm actually very much looking forward to getting all this power, so I might start really using Windows Vista as my main OS. I'll keep you posted if it works out :-)

Pillars Of Longhorn

In the second part of the keynote, Jim Allchin came out to revisit the four pillars of Longhorn as they were originally set out at the PDC two years ago (Indigo, Avalon and WinFS on top of a common Core). They still seem to be in the current version of Vista although, for a long time, I thought they were gone: Indigo and Avalon were backported to Windows XP SP2 and Windows 2003, and WinFS seemed to be postponed to Longhorn Server. Here's how they look today:

Core

  • The security system has been adapted so that users can more easily run in least-privilege accounts.
  • SuperFetch is a service that monitors your application usage over time (seconds, hours, days, ...) to see which applications you use most and pre-loads them so they start up much faster.
  • If you stick in a USB drive, the system will notice this and start using it as extra RAM. Funky!
  • Another attempt has been made to reduce the number of reboots by 50%. In fact, it seems they can now shut down part of the system to replace dll's while the rest of the system keeps running.

Presentation (formerly Avalon)

  • They've officially announced the Atlas technology, which is basically an AJAX framework integrated into ASP.NET 2.0 and Visual Studio 2005.
  • The Windows Presentation Foundation consists of both the engine (allowing applications to run on screen real estate varying from devices to laptops to 21" screens to wall-sized video screens) and the framework (the managed classes you can use to build your application).
  • Newly announced is WPF/E, which stands for Windows Presentation Foundation/Everywhere. This is a lightweight stripped subset of the WPF runtime for use on devices, and is based on XAML and JScript (so no support for C# or other managed languages to code your application in).

Communication (formerly Indigo)

  • Relatively new to the Windows Communication Foundation (for me anyway) is InfoCards, which is a federated claims-based identity system. Important to note is that the OS manages all your identities and use one type of window and thus one user experience to log you on to different remote systems.
  • Another feature shown is People Near Me (PNM), which seems to have locality-based information about the people you know.

If you think both these features seam a little vague, I can't blame you: they weren't really explained very much yet and I'm not sure what they do exactly or how to use them (but there will be plenty of sessions to explain later this week).

WinFS

Actually, this part wasn't covered today, so I'm assuming the "Windows Storage Foundation" (wild guess on the future official name) will still only appear in the Longhorn Server timeframe.

Lap Around Vista

By far the coolest new feature that was announced today is LINQ, or .NET Language Integrated Query. This means you can write SQL-like selects with filtering and sorting as first-class citizens in the C# language. I'll definitely be spending time exploring this feature but in short, it means that you can query any object that implements IEnumerable<T>. Look at Dan Fernandez's blog for more info on LINQ and a code sample. Really, really cool!

Another surprise was the return of ObjectSpaces (once again). This time, using this long-awaited Object/Relational Mapping framework looked very similar to XML serialization in some way: you can decorate your types with attributes that define their mapping onto the database and you're pretty much done.

To conclude, Don Box, Anders Hejlsberg, Chris Anderson and Scott Guthrie came out to run a lap around Vista. The demo started with Anders Hejlsberg building a LINQ query doing a cross select of the currently running processes with an ObjectSpaces-fronted database containing process description. So that was one query, in native C#, that did an in-memory join between objects and the database in a very easy and recognizable format.

After that, Don Box exposed this information as an RSS stream through an Indigo service. A custom PoxBinding stripped off the SoapEnvelope at the top and as such, just doing an HTTP/GET on the service returnd a valid RSS stream, which was consumeable from IE7 out of the box.

To go even further, Scott Guthrie made ASP.NET consume this feed through an Atlas client, which means that it was queried asynchronously and with a pretty slick UI.

Chris Anderson concluded by showing the new Avalon rendering in action to show the items in the feed through fancy 2D and 3D views with minimal amounts of code and XAML.

All in all, this was a very impressive demo, although some parts were obscure and highly customized (the PoxBinding, the special plumbing to consume the Indigo service from JScript, some of the XAML formatting, ...).

Wrap-up

At the very end, Hillel Cooperman showed us a demo application called Project Max that was built to showcase all these different components: it's a photo-sharing app that you can actually use and download at the Project Max Homepage. Looks good!

As a sidenote, the live transcript that was running while the speakers were talking was pretty cool, especially the fact that the person typing the transcript was pretty fast but apparently not very technical. While trying to keep up with the speaker, things like WinFS were consistently transcribed as WinFX (understandeable but critical mistake in this case), RSS became RSF and lots of other small mistakes. But the funniest one was where "things like RSS" was transcribed as "things like our asses" :-)

Anyway, that pretty much concludes the keynote. A great start for a promising conference!

Blog | General | Programming | .NET | PDC05
Wednesday, September 14, 2005 12:45:03 AM (Romance Standard Time, UTC+01:00) #    Comments [1]  | 

 

Themes for dasBlog#

I get quite some questions about the theme for dasBlog I'm currently using, it's always nice to hear you like it :-)

The bad news is: you can't have it :-p It's a pretty customized theme to suit my "special needs" so it wouldn't do you any good anyway.

The good news is: I've created a more generic version of it, which you should be able to use just fine. I dubbed it "essence" since I believe it's quite back-to-the-essentials without too much distraction and chaos (I hope so anyway). The even better news is: it ships by default with the recently released dasBlog 1.8!

BlogXP, a theme I created a while ago, is also in the package by default, and it seems people really dig that theme since I've seen quite a lot of sites using it already. Nice!

If you haven't downloaded dasBlog 1.8 yet, you can also get the themes here:

dasblog-blogxp.zip (15,79 KB)

dasblog-essence.zip (6,76 KB)

Sunday, September 11, 2005 4:59:17 PM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

PDC05: Ready To Rumble!#

Just like the rest of us who flew in on the special EMEA@PDC charter yesterday (check out David's blog for the list of Belgians), I arrived in L.A. without problems, all ready and geared up for the PDC 2005! The community is looking good, the vibe is definitely here, and I'm looking forward to spending a week in braincooking mode.

Here are some of my pictures from the first day (check out the other blogs for much better ones):

Departure in Amsterdam

Flying over Greenland

Flying over L.A.

Arrival at LAX

Downtown L.A. seen from the bus to the hotel

The welcome reception at the pool

And I fully intend to keep making this kind of crappy pictures with my phone so stay tuned for some more low-res fuzzy images of PDC05 - because that's how it feels over here anyway ;-)

Blog | General | Programming | .NET | PDC05
Sunday, September 11, 2005 4:26:54 PM (Romance Standard Time, UTC+01:00) #    Comments [0]  | 

 

All content © 2010, Jelle Druyts
On this page
Static Classes And The HasShutdownStarted Property
PDC05 Pre-Con: The Art Of Building A Reusable Class Library
PDC05: The Third Keynote
PDC05: The Second Keynote
PDC05 Keynote
Themes for dasBlog
PDC05: Ready To Rumble!

Recent Photos
www.flickr.com
This is a Flickr badge showing public photos from Jelle Druyts. Make your own badge here.
Advertising
Top Picks
Statistics
Total Posts: 350
This Year: 4
This Month: 2
This Week: 2
Comments: 526
Archives
Sitemap
Disclaimer
This is my personal website, not my boss', not my mother's, and certainly not the pope's. My personal opinions may be irrelevant, inaccurate, boring or even plain wrong, I'm sorry if that makes you feel uncomfortable. But then again, you don't have to read them, I just hope you'll find something interesting here now and then. I'll certainly do my best. But if you don't like it, go read the pope's blog. I'm sure it's fascinating.

Powered by:
newtelligence dasBlog 2.0.7226.0

Sign In