class Version implements Comparable<Version> {

   @Override
   public int compareTo(Version o) {
      if(o == null) {
         return 1;
      }
      int major1 = getMajor(), major2 = o.getMajor();
      if(major1 != major2) {
         return major2 - major1;
      }
      int minor1 = getMinor(), minor2 = o.getMinor();
      if(minor1 != minor2) {
         return minor2 - minor1;
      }

      int patch1 = hasPatch() ? getPatch() : 0;
      int patch2 = o.hasPatch() ? o.getPatch() : 0;
      if(patch1 != patch2) {
         return patch2 - patch1;
      }

      int build1 = hasBuild() ? getBuild() : 0;
      int build2 = o.hasBuild() ? o.getBuild() : 0;

      if(build1 != build2) {
         return build2 - build1;
      }

      String q1 = hasQualifier() ? getQualifier() : null;
      String q2 = o.hasQualifier() ? o.getQualifier() : null;
      // this is a bit weird, since we would like 'beta' to be greater
      // than 'alpha' we reverse the comparison here.
      // of course no qualifier means production ready, so null out no qualifier
      // and always sort it to the front
      return ObjectUtils.compare(q2, q1, true);
   }

   public  Version(int major);
   public  Version(int major, int minor);
   public  Version(int major, int minor, @Nullable String qualifier);
   private  Version(int major, int minor, @Nullable String qualifier, String representation);
     Version(int major, int minor, @Nullable Integer patch, @Nullable Integer build, @Nullable String qualifier, String representation);

}