context: using System;
  
  namespace NetChris
  {
  
      // TODO R1.000 - Consider removing this.  Not used in our system.
      // From http://www.codeproject.com/csharp/base36.asp
      // Highly-modified
      /// <summary>
      /// Class representing a Base36 number
      /// </summary>
      public struct Base36
      {
  
          #region Constants (and pseudo-constants)
  
          /// <summary>
          /// Base36 containing the maximum supported value for this type
          /// </summary>
          public static readonly Base36 MaxValue = new Base36(long.MaxValue);
  
          /// <summary>
          /// Base36 containing the minimum supported value for this type
          /// </summary>
          public static readonly Base36 MinValue = new Base36(long.MinValue + 1);
  
          #endregion
  
          #region Fields
  
          private long _numericValue;
  
          #endregion
  
          #region Constructor
  
          /// <summary>
          /// Instantiate a Base36 number from a long value
          /// </summary>
          /// <param name="numericValue">The long value to give to the Base36 number</param>
          public Base36(long numericValue)
          {
              _numericValue = 0; //required by the struct.
              NumericValue = numericValue;
          }
  
  
          /// <summary>
          /// Instantiate a Base36 number from a Base36 string
          /// </summary>
          /// <param name="value">The value to give to the Base36 number</param>
          public Base36(string value)
          {
              _numericValue = 0; //required by the struct.
              Value = value;
          }
  
          #endregion
  
          #region Properties
  
          /// <summary>
          /// Get or set the value of the type using a base-10 long integer
          /// </summary>
          /// <value>
          /// The value of the type using a base-10 long integer
          /// </value>
          public long NumericValue
          {
              get
              {
                  return _numericValue;
              }
              set
              {
                  //Make sure value is between allowed ranges
                  if (value <= long.MinValue || value > long.MaxValue)
                      throw new ArgumentOutOfRangeException("value",
                        value + " is out of range. It must be larger than the minumum value of a long " +
                        "or less-than-or-equal-to the maximum value of a long.");
  
                  _numericValue = value;
              }
          }
  
          /// <summary>
          /// Get or set the value of the type using a Base36 string
          /// </summary>
          /// <value>
          /// The value of the type using a Base36 string
          /// </value>
          public string Value
          {
              get
              {
                  return NumberToBase36(_numericValue);
              }
              set
              {
                  _numericValue = Base36ToNumber(value);
              }
          }
  
          #endregion
  
          #region Public Static Methods
  
          /// <summary>
          /// Static method to convert a Base36 string to a long integer (base-10)
          /// </summary>
          /// <param name="base36Value">The number to convert from</param>
          /// <returns>The long integer</returns>
          /// <exception cref="ArgumentNullException">The value passed into <paramref name="base36Value"/> was null</exception>
          /// <exception cref="ArgumentOutOfRangeException">The value passed into <paramref name="base36Value"/> was an empty string</exception>
          /// <exception cref="FormatException">The value passed into <paramref name="base36Value"/> was not in a correct Base36 format: all numbers and letters with an optional '-' at the beginning</exception>
          public static long Base36ToNumber(string base36Value)
          {
  
              // Make sure we have passed something
              if (base36Value == null)
                  throw new ArgumentNullException("base36Value", "Base36ToNumber requires that the value passed not be null");
              if (base36Value.Trim() == String.Empty)
                  throw new ArgumentOutOfRangeException("base36Value", "Base36ToNumber requires that the value passed not be empty");
  
              // TODO R1.000 - Place a length limit on base36Value as long will only be able to hold ...
              // 36^x where x <= 12 (?)
  
              // Make sure the number is in upper case & trimmed:
              base36Value = base36Value.ToUpper().Trim();
  
              // Account for negative values:
              bool isNegative = false;
  
              if (base36Value[0] == '-')
              {
                  base36Value = base36Value.Substring(1);
                  isNegative = true;
              }
  
              // This check was done a digit at a time in base36DigitToNumber
              // By checking all digits before we start doing work, we can provide
              // a quick answer to whether this is formatted correctly
              for (int charIndex = 0; charIndex < base36Value.Length; charIndex++)
                  if (!char.IsLetterOrDigit(base36Value[charIndex]))
                      throw new FormatException("The value (base36Value) passed to Base36ToNumber is not in a correct Base36 format.");
  
              //Loop through our string and calculate its value
              long result = 0;
  
              // Loop through the character in the string (right to left) and add
              // up increasing powers as we go.
              for (int i = 0; i < base36Value.Length; i++)
                  result += ((long)Math.Pow(36, i) *
                    base36DigitToNumber(base36Value[base36Value.Length - (i + 1)]));
  
              // Do negative correction if required:
              if (isNegative)
              {
                  return result * -1;
              }
  
              return result;
          }
  
          /// <summary>
          /// Public static method to convert a long integer (base-10) to a Base36 number
          /// </summary>
          /// <param name="numericValue">The base-10 long integer</param>
          /// <returns>A Base36 representation</returns>
          public static string NumberToBase36(long numericValue)
          {
              //Handle negative values:
              if (numericValue < 0)
              {
                  return string.Concat("-", positiveNumberToBase36(Math.Abs(numericValue)));
              }
  
              return positiveNumberToBase36(numericValue);
          }
  
          #endregion
  
          #region Private Static Methods
  
          private static string positiveNumberToBase36(long numericValue)
          {
              //This is a clever recursively called function that builds
              //the base-36 string representation of the long base-10 value
              if (numericValue < 36)
              {
                  // The get out clause; fires when we reach a number less than 
                  // 36 - this means we can add the last digit.
                  return numberToBase36Digit((byte)numericValue).ToString();
              }
              // Add digits from left to right in powers of 36 (recursive)
              return string.Concat(positiveNumberToBase36(numericValue / 36), numberToBase36Digit((byte)(numericValue % 36)).ToString());
          }
  
          private static byte base36DigitToNumber(char base36Digit)
          {
              if (char.IsDigit(base36Digit))
              {
                  // Handles 0 - 9
                  return byte.Parse(base36Digit.ToString());
              }
  
              // Handles A - Z
              return (byte)(base36Digit - 55);
          }
  
          private static char numberToBase36Digit(byte numericValue)
          {
              // Converts a number to it's base-36 value.
              // Only works for numbers <= 35.
              if (numericValue > 35)
                  throw new ArgumentOutOfRangeException("numericValue", "must be <= 35");
  
              // Numbers:
              if (numericValue <= 9)
              {
                  return numericValue.ToString()[0];
              }
  
              return (char)(numericValue + 55);
          }
  
          #endregion
  
          #region Operator Overloads
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="lhs"></param>
          /// <param name="rhs"></param>
          /// <returns></returns>
          public static bool operator >(Base36 lhs, Base36 rhs)
          {
              return lhs._numericValue > rhs._numericValue;
          }
  
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="lhs"></param>
          /// <param name="rhs"></param>
          /// <returns></returns>
          public static bool operator <(Base36 lhs, Base36 rhs)
          {
              return lhs._numericValue < rhs._numericValue;
          }
  
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="lhs"></param>
          /// <param name="rhs"></param>
          /// <returns></returns>
          public static bool operator >=(Base36 lhs, Base36 rhs)
          {
              return lhs._numericValue >= rhs._numericValue;
          }
  
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="lhs"></param>
          /// <param name="rhs"></param>
          /// <returns></returns>
          public static bool operator <=(Base36 lhs, Base36 rhs)
          {
              return lhs._numericValue <= rhs._numericValue;
          }
  
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="lhs"></param>
          /// <param name="rhs"></param>
          /// <returns></returns>
          public static bool operator ==(Base36 lhs, Base36 rhs)
          {
              return Equals(lhs, rhs);
          }
  
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="lhs"></param>
          /// <param name="rhs"></param>
          /// <returns></returns>
          public static bool operator !=(Base36 lhs, Base36 rhs)
          {
              return !(lhs == rhs);
          }
  
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="lhs"></param>
          /// <param name="rhs"></param>
          /// <returns></returns>
          public static Base36 operator +(Base36 lhs, Base36 rhs)
          {
              return new Base36(lhs._numericValue + rhs._numericValue);
          }
  
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="lhs"></param>
          /// <param name="rhs"></param>
          /// <returns></returns>
          public static Base36 operator -(Base36 lhs, Base36 rhs)
          {
              return new Base36(lhs._numericValue - rhs._numericValue);
          }
  
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="value"></param>
          /// <returns></returns>
          public static Base36 operator ++(Base36 value)
          {
              return new Base36(value._numericValue++);
          }
  
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="value"></param>
          /// <returns></returns>
          public static Base36 operator --(Base36 value)
          {
              return new Base36(value._numericValue--);
          }
  
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="lhs"></param>
          /// <param name="rhs"></param>
          /// <returns></returns>
          public static Base36 operator *(Base36 lhs, Base36 rhs)
          {
              return new Base36(lhs._numericValue * rhs._numericValue);
          }
  
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="lhs"></param>
          /// <param name="rhs"></param>
          /// <returns></returns>
          public static Base36 operator /(Base36 lhs, Base36 rhs)
          {
              return new Base36(lhs._numericValue / rhs._numericValue);
          }
  
  
          /// <summary>
          /// Operator overload
          /// </summary>
          /// <param name="lhs"></param>
          /// <param name="rhs"></param>
          /// <returns></returns>
          public static Base36 operator %(Base36 lhs, Base36 rhs)
          {
              return new Base36(lhs._numericValue % rhs._numericValue);
          }
  
  
          /// <summary>
          /// Implicitly converts type Base36 to a base-10 long
          /// </summary>
          /// <param name="value">The Base36 object</param>
          /// <returns>The base-10 long integer</returns>
          public static implicit operator long(Base36 value)
          {
              return value._numericValue;
          }
  
          /// <summary>
          /// Implicitly converts type Base36 to a base-10 integer
          /// </summary>
          /// <param name="value">The Base36 object</param>
          /// <returns>The base-10 integer</returns>
          public static implicit operator int(Base36 value)
          {
              // Throw for overflows
              if (value._numericValue > int.MaxValue)
              {
                  throw new OverflowException("Overflow: Value too large to return as an integer");
              }
              if (value._numericValue < int.MinValue)
              {
                  throw new OverflowException("Overflow: Value too small to return as an integer");
              }
  
              return (int)value._numericValue;
          }
  
          /// <summary>
          /// Implicitly converts type Base36 to a base-10 short
          /// </summary>
          /// <param name="value">The Base36 object</param>
          /// <returns>The base-10 short</returns>
          public static implicit operator short(Base36 value)
          {
              // Throw for overflows
              if (value._numericValue > short.MaxValue)
              {
                  throw new OverflowException("Overflow: Value too large to return as a short");
              }
              if (value._numericValue < short.MinValue)
              {
                  throw new OverflowException("Overflow: Value too small to return as a short");
              }
  
              return (short)value._numericValue;
          }
  
          /// <summary>
          /// Implicitly converts a long (base-10) to a Base36 type
          /// </summary>
          /// <param name="value">The long to convert</param>
          /// <returns>The Base36 object</returns>
          public static implicit operator Base36(long value)
          {
              return new Base36(value);
          }
  
          /// <summary>
          /// Converts type Base36 to a string; must be explicit, since
          /// Base36 > string is dangerous!
          /// </summary>
          /// <param name="value">The Base36 type</param>
          /// <returns>The string representation</returns>
          public static explicit operator string(Base36 value)
          {
              return value.Value;
          }
  
          /// <summary>
          /// Converts a string to a Base36
          /// </summary>
          /// <param name="value">The string (must be a Base36 string)</param>
          /// <returns>A Base36 type</returns>
          public static implicit operator Base36(string value)
          {
              return new Base36(value);
          }
  
          #endregion
  
          #region Public Override Methods
  
          /// <summary>
          /// Returns a string representation of the Base36 number
          /// </summary>
          /// <returns>A string representation</returns>
          public override string ToString()
          {
              return NumberToBase36(_numericValue);
          }
  
  
          /// <summary>
          /// A unique value representing the value of the number
          /// </summary>
          /// <returns>The unique number</returns>
          public override int GetHashCode()
          {
              return _numericValue.GetHashCode();
          }
  
  
          /// <summary>
          /// Indicates whether this instance and a specified object are equal.
          /// </summary>
          /// <param name="obj">The object to compare</param>
          /// <returns>
          /// <b>true</b> if <paramref name="obj"/> and this instance are the same type and represent the same value; otherwise, <b>false</b>.
          /// </returns>
          public override bool Equals(object obj)
          {
              if (!(obj is Base36))
              {
                  return false;
              }
  
              return Equals((Base36)obj);
          }
  
          /// <summary>
          /// Indicates whether this instance and a specified object are equal.
          /// </summary>
          /// <param name="other"></param>
          /// <returns>true if <paramref name="other"/> and this instance represent the same value; otherwise, false.</returns>
          public bool Equals(Base36 other)
          {
              return Equals(this, other);
          }
  
          /// <summary>
          /// Indicates whether two instances of Base36 are equal
          /// </summary>
          /// <param name="a"></param>
          /// <param name="b"></param>
          /// <returns><b>true</b> if variables <paramref name="a"/> and
          /// <paramref name="b"/> are equal to each other; otherwise, <b>false</b>.</returns>
          public static bool Equals(Base36 a, Base36 b)
          {
              if ((((object)a) == null) || (((object)b) == null))
              {
                  return false;
              }
  
  
gt:             return a._numericValue == b._numericValue;