Skip to content

Iloggable

Silverlight, Moonlight and a true VM for your browser

Considering my previous rant about RIA platforms, I'm a bit slow out the gate with my Silverlight comments. But there was a lot to digest before making half-baked comments.

While I was at MEDC, Mix07 was going on next door. I didn't even hear the cool Silverlight announcements until I got back from Vegas. But now that i've played with it, it's exactly what I had hoped for (minus a disconnected use model): We have a true VM to code against on the client side. That means the full breadth of .NET languages to control the reduced WPF presentation layer, plus with the DLR true scripting support at near-compiled performance.

As I expected, there was no linux support announced by MS and neither does it appear that they've opened a channel to the mono team. But Miguel de Icaza has addressed this issue independently with the Moonlight project and listening to the chatter on the dev list and following the wiki updates, that project is getting serious attention. I may even be better this way. I think a firefox plug-in coming from the mono team would be more willingly installed by linux users than something coming directly from MS.

We'll have to see how much more of the WPF set of Xaml gets supported by Silverlight as 1.1 moves to beta and RTM. Obviously, the way custom controls are done is not ideal right now--the way properties are acting against implementationRoot (haven't gotten deep enough to understand why it's not using the DependencyObject/Property pattern) and the shadowing of inherited properties just make for a strange experience compared to Controls in WPF, Windows Forms or even ASP.NET. Hopefully that morphs into a better model as we move along. If nothing else, the development of the promised suite of UI controls provide internal motivation to refine the model. Not that I think that DependencyObject/Property is an elegant coding pattern (at least not until that legwork moves into code generation).

But while everyone is busy committing the same UI crimes that many Flash developers have been guilty of for years, I think the real significance of Silverlight is not it's Xaml and rich media support. In my opinion the most amazing feat of Silverlight is its DOM interoperation. The Silverlight VM is accessible in both directions, complete with object serialization across boundaries. This means you can have managed code attached to DOM events, and managed code modifying the DOM itself or calling javascript in the page. With a minimum of glue, you could move all your code inside of Silverlight and even if you don't care about C# et al., you'd at least get a much higher performance javascript out of the deal. Then add the rich communications infrastructure and the hinted at socket level networking in future versions and suddenly you can have very fast, very interactive web applications that could be truly stateful and have better event handling for asynchronous operation etc.

Right now, you need some 1x1 pixel Silverlight object that everything gets channeled through, but MS has already promised that that dependency is going away. So what you really have is a VM and rich framework addressable with bytecode compiled from a huge number of potential languages in the browser. Whether you use that VM to drive your HTML, Silverlight's presentation layer or even the canvas tag is up to you. It's what I hoped that the browser manufacturers would do themselves, but as a plug-in, the chance of this capability becoming ubiquitous is even better, imho.

Silverlight 1.1 alpha is clearly a very early peek into the tech, but it works just great already. I'm curious what it will look like by the time it's an official release. And I certainly hope that by that time, MS has given the disconnected, self-hosted option some consideration. After all, when competing with Flash/Flex, one shouldn't ignore Apollo.

Running third party vmware images

Trying to reconfigure mail once again (a rant for another time) and trying out a couple of VMware Virtual Appliances. But every appliance I tried on my server would just appear to hang. Black screen, no bios, no nothing. Finally found a post on the VMware forums talking about permissions, so I compared my working images to the non-working ones and the problem was simply that the .vmx file needed to have execute permissions.

Reading a resource in eclipse or jar

Disclaimer: I've been trying to store some text resources in my jar so that i can easily package uncompiled content with my executable. This course of action seemed like the natural thing to do. However what I had to do to actually access this file and allow for different environments like running from eclipse vs. executing the jar makes me wonder if I'm missing some essential facilities. I.e. can eclipse build the jar and execute it instead of running it's class files, so that you can test jar stored executions as part of eclipses normal debug and excution? And is there some facility that let's you just say InputStream res = App.GetResourceStream()?. Well, in the meantime here's what i cobbled together to get this working, since my googling didn't come up with a single source that put it all together.

First thing, we need to determine where we are executing, both because its the base for finding our resource and because it tells us whether we're dealing with a directory hierarchy or a jar file:

ProtectionDomain protectionDomain = this.getClass().getProtectionDomain();
CodeSource codeSource = protectionDomain.getCodeSource();
URL location = codeSource.getLocation();
File f = new File(location.getFile());

Now we get an InputStream, depending on what environment we're in:

String resourcePath = "resources/xsl/register.xsl";
InputStream resourceStream = null;
if (f.isFile()) {
    // it's a file, so we assume it's a jar and look for our
    // resource as a JarEntry
    JarFile jar = new JarFile(f);
    JarEntry xslEntry = jar.getJarEntry(resourcePath);
    resourceStream = jar.getInputStream(xslEntry);
} else {
    // it's a directory, so we just append our relative resource
    // path
    resourceStream = new FileInputStream(f.getAbsolutePath() + "/"
            + resourcePath);
}

Now we have an InputStream and can ingest the file anyway we like.

Are delegates the reason we have C#?

This may be ancient news, but I just came across an article that strongly implied that the reason .NET came about was because Sun didn't like Microsoft's addition of delegates to J++. That surely is a condensation of events, but it's certainly an interesting yarn.

I got into this whole subject because I needed an object to subscribe to the state change of another object in my java project. And I didn't want to create a tight coupling between otherwise unrelated objects. In C#, I would have created an event for the state change and have the second object subscribe to it. Done.

Alas, I'm in java and don't have delegates, e.g. no events in the way i'm used to. I remembered dealing with creating lots of anonymous inner classes during some long ago experiences with swing programming, which I always found to be less than transparent in presentation. So I figured I'd do some digging to see how delegation and events should be handled in java. I don't like seeing getFoo()/setFoo() from someone not used to C# properties, and I don't want to subject someone else to my C#-ing of java code in return.

I started googling java, delegates and inner classes and came across a plethora of interesting articles, including the obligatory C# is better better than java because it has delegates and java kicks C#'s ass because isn't littered with atrocious syntactic sugar like delegates when inner classes will do variety. Of these, the most entertaining was a rather testy condemnation of delegates in J++ in the form of a white paper on Sun's site. Considering the stance Sun has taken over the years on java, i.e. binding the language, runtime and philosophy into a single indivisible unit, having MS try subvert the language with what to many looks like a procedural programming throwback certainly could have been a significant motivator for the lawsuit that revoked Microsoft's java license. Looking at C# and the CLR, Microsoft obviously saw a lot of things it liked in the java language and the jvm. So the result that .NET came about because Sun rejected delegates doesn't seem too far fetched and my favorite version of the story so far.

Now, back to the problem at hand, how does one do delegation in java and the answer does appear to be with inner classes functioning as callbacks. This certainly does the trick. But that's a bunch of code and interfaces to create which in the end doesn't improve the readability of the code. As an illustration, here is the C# code and the java code I created to get the same effect. Note: I didn't need the extra information that C# events provide, i.e. the event source and event arguments, so I left them out of the java version to keep the code more concise. I also didn't do any checking if there are subscribers, etc -- read: this is an illustration not production code :)

Publisher

/ C# Publisher
public class Publisher
{
  // create the event, which implicitly gives us add/delete subscribers
  public event EventHandler someAction;

  public void DoAction()
  {
    Console.WriteLine("Start action");
    //implictly call all subscribers
    someAction(this, EventArgs.Empty);
    Console.WriteLine("End action");
  }
}
// java Publisher
public class Publisher {

    private List<EventHandler> subscribers = new ArrayList<EventHandler>();

    public void subscribeToAction(EventHandler notifier)
    {
        subscribers.add(notifier);
    }

    public void doAction()
    {
        System.out.println("Start action");
        for( EventHandler subscriber : subscribers ) {
            subscriber.handle(this);
        }
        System.out.println("End action");
    }
}

Subscriber

//C# Subscriber
public class Subscriber
{
  private string name;

  public Subscriber(string name)
  {
    this.name = name;
  }

  public void AttachToPublisher(Publisher publisher)
  {
    // subscribe to the event. This creates a closure for this particular
    // instance of Subscriber.
    publisher.someAction += new EventHandler(RespondToAction);
  }

  void RespondToAction(object sender, EventArgs e)
  {
    Console.WriteLine("Responding to action for '" + name + "'");
  }
}
// java Subscriber
public class Subscriber {

    private String name;

    public Subscriber(String name) {
        this.name = name;
    }

    public void attachToPublisher(Publisher publisher) {
        // create a new anonymouse instance of the EventHandler
        // as a closure for this instance of Subscriber
        publisher.subscribeToAction(new EventHandler() {
            public void handle(Publisher publisher) {
                respondToAction();
            }
        }
        );

    }

    private void respondToAction() {
        System.out.println("Responding to action for '" + name + "'");
    }
}

EventHandler

In C# this is just built in plumbing. In java we create a simple interface that our anonymous inner class will implement:

public interface EventHandler {
    void handle(Publisher publisher);
}

Now we exercise the code:

Publisher p = new Publisher();
Subscriber s1 = new Subscriber("abc");
Subscriber s2 = new Subscriber("xyz");
s1.AttachToPublisher(p);
s2.AttachToPublisher(p);
p.DoAction();

The java code is virtually identical just with different casing for code style and both produce this output:

Start action
Responding to action for 'abc'
Responding to action for 'xyz'
End action

Now add lost of different events and unsubscribing of events, plus more complex EventHandlers and the amount of code you end up writing quickly becomes significant. If there is one thing object oriented programming encourages us to do is to take repetitive code patterns and formulate reusable objects. Plenty of people in the java community have created delegate-like helpers that make delegation easier to read and maintain than simple inner classes, my favorite so far being Alex Winston's strongly typed approach.

So are delegates just syntactic sugar or a throw-back to procedural coding? For those with only a cursory understanding of delegates, they do just look like function pointers, like C, or at best, type-safe function pointers. But just like inner classes they create instance specific closures, plus they throw in functionality for handling multi-casting and handling synchronous and asynchronous invocation of the closure. I, at least, think delegates as a first-class citizen of the runtime make life easier, improve readability and do not detract from the object oriented nature of the surrounding code.

Asus Vintage 2 & Ubuntu

I just built a new linux dev machine and decided to go Ubuntu this time around to see what all the excitement is about. I had been a Redhat/Fedora Core desktop user since 1999 and only recently switched to Centos for my servers.

On the hardware side, I've been a big fan of the Asus Vintage line of barebone machines and have a number of them doing simulator duty for Full Motion Racing. They're a great machine for the money. The box I ended up with was the Asus Vintage V2-P5945G. Another clean and simple design.

I had everything assembled in no time and popped in the Ubunto 6.10 CD. It booted into the Ubuntu Live desktop, i.e. a fully functional distro running straight off CD without any HD requirements. On the desktop was an "install Icon" which ran a very simple wizard to take care of installation. All around a slick, easy and trouble-free process. Well, almost. I had no network connectivity. It didn't even see the network device nor did I get a link light.

After some research I discovered that this mobo (along with a bunch of other Asus mobos uses an Attansic Gigabit Ethernet device that isn't supported by the current Ubuntu. For that matter it only made it into the general kernel in January. So I tried again with Ubuntu "Feisty Fawn" and this time everything went of without a hitch.

We'll see how I like Ubuntu in time, but the install experience is certainly one of the slickest I've seen to date, more newbie friendly than Windows or Mac. Granted, the inability to find my ethernet adapter should have been handled a bit better, if only to give a warning that none was found. Really, if you can't find an ethernet device, chances are it's a sign that something is up.

Eclipse & referencing JARs

Being an eclipse newbie, setting up third party JARs was a bit painful to figure out. Well, not painful as such, just painful once i tried to move the project across platforms.

See, I was using the External JARs... option in the Build Path dialog. But that set up absolute paths, which is a bad idea even if you stay on the same platform. Going across platforms C:\.. just wasn't an option. So i tried editing the .classpath by hand. That just created tied the path to the root. Finally I figure out that if i added a lib directory to the project, the JARs I put inside of it, were now browsable by the Add JARs option. Now everything build happily across Mac and Windows. Joy.

Simple Java XML Serialization

Last time I used Java, JAXB was just being released. At least at the time, it was all about Schema definition and code generation. I loved the concept of serializing straight into XML and back, but code generation always is a bit of a nasty beast, imho. Plus, adding custom code to your class was also annoying. You basically had to extend your generated class to add anything custom to it.

When I started working with .NET, I was pleasantly surprised by their Attribute driven approach. Now the code and the XML definition was in one place and no post processing was required.

Back in Java land, I thought that with Java 5.0's addition of Annotations, maybe the meta-data code-markup method had been picked up as well. Sure enough there is JAXB 2.0 Reflection. However, if all I want to do is some config files and maybe some data serialization without the full Web Services juggernaut, that seems like a heavy handed way of doing it.

A little further digging brought me to Simple. One tiny jar and you are ready to define, serialize and deserialize your classes. Woot. Sure, my .NET bias is showing, but I really like this approach so much better than starting at the XSD/DTD and generating code. And creating code that let's you move objects from one side to the other is dead simple:

java

@Root(name="example")
public class Example {

   @Element(name="message")
   private String text;

   @Attribute(name="id")
   private int index;

   public Example() {
      super();
   }  

   public Example(String text, int index) {
      this.text = text;
      this.index = index;
   }

   public String getMessage() {
      return text;
   }

   public int getId() {
      return index;
   }
}

C#

[XmlRoot("example")]
public class Example
{

  private string text;
  private int index;

  public Example()
  {
  }

  public Example(string text, int index)
  {
    this.text = text;
    this.index = index;
  }

  [XmlElement("message")]
  public String Message
  {
    get { return text; }
    set { text = value; }
  }

  [XmlAttribute("id")]
  public int Id
  {
    get { return index; }
    set { index = value; }
  }
}

XML

<?xml version="1.0" encoding="UTF-8"?>
<example id="123">
  <message>Example message</message>
</example>

The main difference is that the Simple approach doesn't require there to be a public setter on the data, which is actually kind of strange. How does deserialization set the field? Does it use reflection Regardless, two pieces of code, looking quite similar, allowing you to serialize a class from C# to Java and back without a lot of work.

throws NobodyCaresException

I've been doing java again for a project for the last few weeks and it's been fun. You do get spoiled from the clean syntax C# Properties give you over the getter/setter pattern. And talk about notation differences. I'm so used to Pascal Case on everyting except for fields and parameters that writing Camel Case on methods is taking some getting used to again. And don't even get me started on switching back and forth between Eclipse and VS.NET several times a day. My muscle memory is in shock. But once you get your mind in the right frame for the idiosyncracies, everything else is so similar is scary, especially with the Java 5.0 additions.

The difference, however, between the two platforms that I was always on the fence about is Checked Exceptions:

In Java, I love that I can declare what exceptions a method may throw and the IDE can pick this up and let you make intelligent decisions. In C#, you have to hope there are some mentions in the docs and otherwise you just find out at runtime and either have a catch all or add individual catches as you find exceptions.

But then, checked exceptions are in my mind the single most responsible party for the good old catch {} gem. And it's unavoidable. There are a number of cases where a non-type-safe argument is required, which, if it was wrong, would throw an exception. However, most of the time that argument isn't dynamic, but some constant you define. Really you know that the exception you are forced to handle will never be thrown and you put a catch {} in there, feeling justified. Soon enough the guilt is gone and you start using it when you just don't feel like dealing with that exception right now. Suddenly you're swallowing exceptions that someone up the chain might have cared about or that should have legitimately bubbled to the top. Bah.

Being a rabid fan of anything that makes code requirements machine discoverable, not being able to declare my exceptions feels dirty. And even for human discovery, documentation isn't sufficient, since it only covers the surface level, i.e. what I throw. Now, if i use someone else's code in there, i need to hope they were also diligent and I have to add any exceptions they may throw and I don't handle to the ones i may throw. Yeah, thatdocumentation is highly likely to fall behind the reality of the code.

Wouldn't it be nice if we could declare our exceptions as informational. Like throws but you don't have to deal with it. Huh, wouldn't that be meta-data about your code, i.e. a perfect candidate for Attributes ne Annotations? I've seen rumblings here and there about this, but nobody's ever picked it up seriously, that I could find. I for one, would love it if I could say

[Throws("InvalidOperationException,FooBarException")]
public void SomeMethod() { ... }

and have the IDE pick up on it to let me know and optionally generate warnings about things I'm not catching. I think that would be the best of both worlds.

Rich Internet App Development

If you've had the misfortune of mentioning AJAX in my presence, then you've heard me rant about the crappy user experience we are all willing to accept in the name of net connectness. This really is a lamentation about the state of Rich Internet Application Frameworks and my dislike for coding in Javascript. Well, it looks like there are more choices than I'd been aware of (the choice of google search terms makes all the difference). Still not what I'd hope, but at least its getting more digestible.

Running in the Browser

Programming based on the AJAX technique has certainly done much to elevate the quality of web apps, but I still feel they are always just a pale facsimile of good old desktop apps. Even the best webapp UI is generally great "for a webapp". However lots of libraries are emerging, as are s number of widget sets, so that's definitely improving. While most toolkits let you extend them, you're always doing your server in one language and your custom UI in javascript.

What I personally have hoped for was a VM in the browser that was addressable by a number of compilers creating bytecode. Everytime I see a platform that runs a VM underneath and doesn't let you address that VM directly, I feel like a great opportunity has been missed. Oddly, MS' CLR is the best example of a VM that lets you address it in virtually any language. They certainly didn't invent the concept but they've promoted it. I think Sun did a major disservice to itself and VMs in general when they married Java the language, the Virtual Machine and the Religion into a single marketing entity. I mean who even knows that there are lots of languages that can be used to target the JVM?

Compile to Javascript

A while ago I found a post by Brendan Eich talking about the future of the Mozilla VM and mentioned mono and the jvm as options. Yesterday, he posted about open web standards and I seized the opporunity to ask about bytecode addressability of JS2's VM. His answer about legal issues is likely a big reason why mono was abandoned as an option:

"there won't be a standard bytecode, on account of at least (a) too much patent encrustation and (b) overt differences in VM architectures. We might standardize binary AST syntax for ES4 in a later, smaller ECMA spec -- I'm in favor."

But as he also pointed out there is always compiling to Javascript instead of bytecode. The options he and another poster mentioned were:

Of the three I initially liked the Morfik approach the best, but doing a bit more research, they seem to be well on the path of propagating the same patent issues that Brendan Eich attributes the lack of standard VMs to. Pity.

Looking around for Javascript compiler's I noticed that this approach is also under development at MS as Script# although it hasn't yet moved up to an official MS project. Interestingly this does pit MS vs. Google once again, framed in a C# vs. Java context with ASP.NET AJAX w/ Script# and GWT. And if there's anything that's just as great for innovation as open standards, in my opinion, it's competition between giants. I look forward to seeing them try to outdo each other.

Looking forward to Rich Apps

So far, we're stuck in the browser, and even with tabs, I sure hope this isn't the future of applications. If we are to move beyond browser, what are our options?

Apollo

Clearly, Adobe is leading the RIA platform wars with Flash and with Flex, SWF certainly looks more like a platform than an animation tool forced to render User Interfaces.

And Apollo certainly looks to push Flash as a platform as well as making it a stand-alone app platform. I certainly think this is going to be the juggernaut to beat. Given my dislike for the syntax of (Java|Ecma|Action)Script, it's unlikely to be my platform of choice. And i don't see a Adobe supporting cross-language compilation and support for Eclipse or Visual Studio at the expense of their Dev suite.

WPF

I really like the concept of WPF. It's philosophy is what I want the future to look like. Mark-up and code separate, common runtime addressable in many languages on client and server, well developed communications framework. Ah, it warms my heart.

But, a) it's closed, b) it's only Windows (i'll get to WPF/E in a sec) and c) boy, is it over-architected. Now, it's at 1.0 release and if there's anything about MS releases, they seldomly get it right in 1.0. We'll see what 2.0 looks like.

WPF/E looks like a combination of simplifying WPF (is this 2.0?) and going after Adobe. And with Script# and recent admissions of some type of CLR on Mac for WPF/E, we're looking at a trojan horse to get Rich Internnet Application Development in .NET established in both the browser and the desktop across platforms. Unfortunately, "across platforms" for MS still means Windows and Mac, while Adobe's Flash 9 has demonstrated their dedication to encompass the linux sphere as well. I don't think that's going to change... I just don't see MS going to linux with the CLR and I find the likelyhood of them leveraging mono's efforts just as unlikely. I wouldn't mind being wrong.

XUL & Canvas

This isn't a platform per se, but I've seen a lot of cool tech demo's using XUL and/or the canvas tag. Also looking at the work that Micheal Robertson's AJAX13 has done, I think there are the makings of a stand-alone app platform here. If your runtime requirements are "install firefox, but you don't even have to use it as your browser if you don't want to", that's a pretty small barrier for a platform that runs everywhere. Personally, I hope someone straps mono or the recently liberated jvm to XUL and builds a platform out of it (you'd get mature WS communication for free with either), because of all the options that looks the most appealing to me personally.

There's got to be more

Considering that GWT and Script# had eluded my radar up until today, I'm sure there's even more options for RIA's out there. I just hope that people developing platforms take the multi language lessons of the legacy platforms to heart. All the successful OS's of the past offered developers many ways of getting things done. You looked at your task, picked the language that was the best fit to the task and your style of programming and you delivered your solution. VMs have shown that supporting many languages in an OS independent way is viable, so if you're building a platform now, why would you choose to mandate a language and programming model. I sure hope that the reason for not going this route isn't going to be "because the patent system is stopping me" -- that would be the ultimate crime of a system that was supposed to foster innovation.

Discoverable RangeValidation (revisited)

The RangeValidation code I created turned out to be of limited usefulness because Attributes are pretty picky about what they can take as arguments. This meant that I couldn't even create the decimal version, which was the original motivator. Revisiting the design I refactored the range validation code into a generic Attribute paired with a Helper class using generics to be type-safe. This also changed the usage to the following:

/// <summary>
/// Valid from 0 to 10
/// </summary>
[ValidateRange(0, 10)]
public decimal Rating
{
  get { return rating; }
  set
  {
    ValidateRange<decimal>.Validate(value);
    rating = value;
  }
}

/// <summary>
/// Valid from 0 to Int.MaxValue
/// </summary>
[ValidateRange(Min = 0)]
public int Positive
{
  get { return positive; }
  set
  {
    ValidateRange<int>.Validate(value);
    positive = value;
  }
}

The ValidateRange class now simply takes the values and stores them as objects, leaving interpretation to the generic class ValidateRange<T>.

[AttributeUsage(AttributeTargets.Property)]
public class ValidateRange : Attribute
{
  object min = null;
  object max = null;

  /// <summary>
  /// Validation with both an upper and lower bound
  /// </summary>
  /// <param name="min"></param>
  /// <param name="max"></param>
  public ValidateRange(object min, object max)
  {
    this.min = min;
    this.max = max;
  }

  /// <summary>
  /// Validation with only upper or lower bound.
  /// Must also specify named parameter Min or Max
  /// </summary>
  public ValidateRange()
  {
  }

  public object Min
  {
    get { return min; }
    set { min = value; }
  }

  public object Max
  {
    get { return max; }
    set { max = value; }
  }
}

The generic class ValidateRange<T> still has the static Validate accessor which has to be used in the property that is tagged with the ValidateRange attribute, since it divines the property from the StackTrace. But given a PropertyInfo instance, the class can also be instantiated independently, so that Validation code can inspect the range requirements and communicate them to the enduser, rather than only reacting to the exceptions thrown by the Property in question.`` ```

public class ValidateRange<T> where T : IComparable
{
  /// <summary>
  /// Must be used from within the set part of the Property.
  /// It divines the Caller to perform validation.
  /// </summary>
  /// <param name="value"></param>
  static public void Validate(T value)
  {
    StackTrace trace = new StackTrace();
    StackFrame frame = trace.GetFrame(1);
    MethodBase methodBase = frame.GetMethod();
    // there has to be a better way to get PropertyInfo from methodBase
    PropertyInfo property
      = methodBase.DeclaringType.GetProperty(methodBase.Name.Substring(4));
    ValidateRange<T> validator = new ValidateRange<T>(property);
    validator.CheckRange(value);
  }

  bool hasMin = false;
  bool hasMax = false;
  T min;
  T max;
  PropertyInfo property;

  public ValidateRange(PropertyInfo property)
  {
    this.property = property;
    ValidateRange validationAttribute = null;
    try
    {
      // we make the assumption that if the caller is using
      // this object, they defined the attribute on the passed property
      validationAttribute
        = (ValidateRange)property.GetCustomAttributes(typeof(ValidateRange), false)[0];
    }
    catch (Exception e)
    {
      throw new InvalidOperationException(
        "ValidateRange Attribute not defined", e);
    }
    if (validationAttribute.Min != null)
    {
      hasMin = true;
      min = (T)Convert.ChangeType(validationAttribute.Min, min.GetType());
    }
    if (validationAttribute.Max != null)
    {
      hasMax = true;
      max = (T)Convert.ChangeType(validationAttribute.Max, max.GetType());
    }
  }

  public bool HasMin
  {
    get { return hasMin; }
  }

  public bool HasMax
  {
    get { return hasMax; }
  }

  public T Min
  {
    get { return min; }
  }

  public T Max
  {
    get { return max; }
  }

  private void CheckRange(T value)
  {
    if (HasMax && value.CompareTo(max) == 1)
    {
      throw new ArgumentOutOfRangeException(
        property.Name,
        "Value cannot be greater than " + max);
    }
    else if (HasMin && value.CompareTo(min) == -1)
    {
      throw new ArgumentOutOfRangeException(
        property.Name,
        "Value cannot be less than " + min);
    }
  }
}