namespace Util {
    public class Optional<T> {
        private T _Value;
        public T Value {
            get {
                if (HasValue) {
                    return _Value;
                } else {
                    throw new System.InvalidOperationException("Value of the Optional is null.");
                }
            }
            set {
                _Value = value;
            }
        }

        public Optional(T val) {
            Value = val;
        }

        public static implicit operator Optional<T>(T val) {
            return new Optional<T>(val);
        }

        public static implicit operator T(Optional<T> opt) {
            return opt.Value;
        }

        public void Clear() {
            _Value = default(T);
        }

        public bool HasValue { get { return _Value != null; } }
        public bool isEmpty { get { return !HasValue; } }
        public bool Equals(Optional<T> opt) {
            if (opt.HasValue == HasValue) { return Equals(opt.Value, Value); }
            else { return opt.HasValue == HasValue; }
        }
    }
}