using System;

#if WHIDBEYwithGenerics
#if CCINamespace
namespace Microsoft.Cci{
#else
namespace System.Compiler{
#endif
  /// <summary>
  /// Tells a sympathetic compiler that the name of the entity bearing this attribute should be suppressed. When applied to a class or enum,
  /// this means that the members of the class or enum should be injected into the same scope as would have contained the class/enum name.
  /// When applied to a field or property, it means that the members of structure of the type of the field/property should be visible
  /// without qualification by the field/property name.
  /// </summary>
  [AttributeUsage(AttributeTargets.Field|AttributeTargets.Property|AttributeTargets.Class|AttributeTargets.Enum)]
  public sealed class AnonymousAttribute: Attribute{
    private Anonymity type;
    public AnonymousAttribute(){
      this.type = Anonymity.Structural;
    }
    public Anonymity Anonymity{
      get {return this.type;}
    }
  }  
  public enum Anonymity{
    Unknown,
    None,
    Structural,
    Full
  }
  public enum CciMemberKind {
    Unknown,
    Regular,
    Auxiliary,
    FrameGuardGetter,
  }
  [AttributeUsage(AttributeTargets.All)]
  public class CciMemberKindAttribute : Attribute {
    public CciMemberKind Kind;
    public CciMemberKindAttribute(CciMemberKind kind) {
      this.Kind = kind;
    }
  }
  [AttributeUsage(AttributeTargets.Class)]
  public sealed class ComposerAttribute: Attribute{
    public string AssemblyName = null;
    public string TypeName = null;
    public ComposerAttribute(){
    }
  }
  [AttributeUsage(AttributeTargets.Assembly|AttributeTargets.Module, AllowMultiple=true)]
  public sealed class CustomVisitorAttribute : Attribute{
    public string Assembly;
    public string Class;
    public string Phase;
    public bool Replace;
    public CustomVisitorAttribute(){
    }
  }
  [AttributeUsage(AttributeTargets.Class|AttributeTargets.Field|AttributeTargets.Property|AttributeTargets.Method)]
  public sealed class ElementTypeAttribute: Attribute{
    public Type ElementType = null;
    public ElementTypeAttribute(){
    }
  }  
  public interface ITemplateParameter{
  }
  [AttributeUsage(AttributeTargets.Interface|AttributeTargets.Class|AttributeTargets.Struct)]
  public sealed class TemplateAttribute : System.Attribute{
    public Type[] TemplateParameters;
    public TemplateAttribute(params Type[] parameters){
      this.TemplateParameters = parameters;
    }
  }
  [AttributeUsage(AttributeTargets.Interface|AttributeTargets.Class|AttributeTargets.Delegate|AttributeTargets.Interface|AttributeTargets.Struct)]
  public sealed class TemplateInstanceAttribute : System.Attribute{
    public Type Template;
    public Type[] TemplateArguments;
    public TemplateInstanceAttribute(Type template, params Type[] arguments){
      this.Template = template;
    }
  }
  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct)]
  public sealed class TemplateParameterFlagsAttribute : System.Attribute {
    public int Flags;
    public TemplateParameterFlagsAttribute(int flags) {
      this.Flags = flags;
    }
  }

  namespace Diagnostics{
    public sealed class Debug{
      public static void Assert(bool condition){
        System.Diagnostics.Debug.Assert(condition);
      }
    }
  }
}
#if !NoData
namespace System.Data{
  public interface IDbTransactable{ //TODO: move to Query namespace
    IDbTransaction BeginTransaction();
    IDbTransaction BeginTransaction(IsolationLevel level);
  }
}
#endif
namespace StructuralTypes{
#if CCINamespace
  using Microsoft.Cci;
#else
  using System.Compiler;
#endif
  using System.Collections;
  using System.Collections.Generic;
  using SCIEnumerator = System.Collections.IEnumerator;
 
  public interface IConstrainedType{}
  public interface ITupleType{}
  public interface ITypeUnion{}
  public interface ITypeIntersection{}
  public interface ITypeAlias{}
  public interface ITypeDefinition{}

  public struct Boxed<ElementType> : IEnumerable<ElementType>, IEnumerable{
    private ElementType[] box;
    public Boxed(ElementType value){
      this.box = new ElementType[]{value};
    }
    public ElementType GetValue(){
      return this.box[0];
    }
    public void SetValue(ElementType value){
      this.box[0] = value;
    }
    public object ToObject(){
      if (this.box == null) return null;
      return this.box[0];
    }
    public bool IsNull(){
      return this.box == null;
    }
    IEnumerator IEnumerable.GetEnumerator() {
      return new BoxedEnumerator<ElementType>(this.box);
    }
    IEnumerator<ElementType> IEnumerable<ElementType>.GetEnumerator(){
      return new BoxedEnumerator<ElementType>(this.box);
    }
    public BoxedEnumerator<ElementType> GetEnumerator(){
      return new BoxedEnumerator<ElementType>(this.box);
    }
    public void Clear(){
      this.box = null;
    }
    public static implicit operator Boxed<ElementType>(ElementType value){
      return new Boxed<ElementType>(value);
    }
    public static explicit operator ElementType(Boxed<ElementType> boxed){
      return boxed.GetValue();
    }
    public static bool operator == (Boxed<ElementType> a, Boxed<ElementType> b){
      if (a.box == null || b.box == null) return false;
      return a.box[0].Equals(b.box[0]);
    }
    public static bool operator == (Boxed<ElementType> a, object o){
      return a.Equals(o);
    }
    public static bool operator != (Boxed<ElementType> a, object o){
      return !a.Equals(o);
    }
    public static bool operator == (object o, Boxed<ElementType> b){
      return b.Equals(o);
    }
    public static bool operator != (object o, Boxed<ElementType> b){
      return !b.Equals(o);
    }
    public static bool operator != (Boxed<ElementType> a, Boxed<ElementType> b){
      if (a.box == null || b.box == null) return false;
      return !a.box[0].Equals(b.box[0]);
    }
    public override bool Equals(object o){
      if (this.box == null) return o == null;
      if (!(o is Boxed<ElementType>)) return false;
      Boxed<ElementType> b = (Boxed<ElementType>) o;
      if (this.box == null || b.box == null) return this.box == b.box;
      return this.box[0].Equals(b.box[0]);
 
    }
    public override int GetHashCode(){
      return this.box[0].GetHashCode();
    }
  }
  public struct BoxedEnumerator<ElementType>: IEnumerator<ElementType>, IEnumerator{
    private ElementType[] box;
    private int index;
    internal BoxedEnumerator(ElementType[] box){
      this.box = box;
      this.index = -1;
    }
    object IEnumerator.Current{
      get{
        return this.box[0];
      }
    }
    public ElementType Current{
      get{ 
        return this.box[0];
      }
    }
    void IEnumerator.Reset() {
      this.index = -1;
    }
    void IDisposable.Dispose(){
    }
    public bool MoveNext(){
      if (this.box == null) return false;
      return ++this.index == 0;
    }
  }
  public struct Invariant<ElementType>{
    private ElementType value;
    public Invariant(ElementType value){
      if (value == null) throw new ArgumentNullException();
      if (value.GetType() != typeof(ElementType)) throw new ArgumentException();
      this.value = value;
    }
    public ElementType GetValue(){
      return this.value;
    }
    public object ToObject(){
      return this.value;
    }
    public static implicit operator ElementType(Invariant<ElementType> invariantValue){
      return invariantValue.value;
    }
    public static implicit operator NonNull<ElementType>(Invariant<ElementType> invariantValue){
      return new NonNull<ElementType>(invariantValue.value);
    }
    public static explicit operator Invariant<ElementType>(ElementType value){
      return new Invariant<ElementType>(value);
    }
  }
  public struct NonNull<ElementType>: IEnumerable<ElementType>, IEnumerable{
    private ElementType value;
    public NonNull(ElementType value){
      if (value == null) throw new ArgumentNullException();
      this.value = value;
    }
    public ElementType GetValue(){
      return this.value;
    }
    public object ToObject(){
      return this.value;
    }
    IEnumerator IEnumerable.GetEnumerator(){
        return new ValueEnumerator<ElementType>(this.value);
    }
    IEnumerator<ElementType> IEnumerable<ElementType>.GetEnumerator(){
      return new ValueEnumerator<ElementType>(this.value);
    }
    public ValueEnumerator<ElementType> GetEnumerator(){
      return new ValueEnumerator<ElementType>(this.value);
    }
    public static implicit operator ElementType(NonNull<ElementType> nonNullValue){
      return nonNullValue.value;
    }
    public static explicit operator NonNull<ElementType>(ElementType value){
      return new NonNull<ElementType>(value);
    }
  }
  public struct NonEmptyIEnumerable<ElementType>: IEnumerable<ElementType>, IEnumerable{
    IEnumerable<ElementType> enumerable;
    public NonEmptyIEnumerable(IEnumerable<ElementType> enumerable){
      this.enumerable = enumerable;
      if (enumerable == null) 
        throw new ArgumentNullException();
      if (!(enumerable is IEnumerable))
        throw new ArgumentException();
      IEnumerator<ElementType> enumerator = enumerable.GetEnumerator();
      if (enumerator == null || !enumerator.MoveNext())
        throw new ArgumentException();
    }
    public NonEmptyIEnumerable(ElementType element){
      this.enumerable = new NonNull<ElementType>(element);
    }
    public ElementType GetValue(){
      IEnumerator<ElementType> e = this.enumerable.GetEnumerator();
      if (e.MoveNext()){
        ElementType result = e.Current;
        if (!e.MoveNext()) return result;
      }
      throw new ArgumentOutOfRangeException();
    }
    public object ToObject(){
      if (this.enumerable is NonNull<ElementType>){
        NonNull<ElementType> nnull = (NonNull<ElementType>)this.enumerable;
        return nnull.ToObject();
      }
      if (this.enumerable is Boxed<ElementType>){
        Boxed<ElementType> boxed = (Boxed<ElementType>)this.enumerable;
        return boxed.ToObject();
      }
      return this.enumerable;
    }
    IEnumerator IEnumerable.GetEnumerator() {
        return ((IEnumerable)this.enumerable).GetEnumerator();
    }
    public IEnumerator<ElementType> GetEnumerator(){
      return this.enumerable.GetEnumerator();
    }
    public static implicit operator NonEmptyIEnumerable<ElementType>(NonNull<ElementType> element){
      return new NonEmptyIEnumerable<ElementType>((IEnumerable<ElementType>)element);
    }
    public static explicit operator NonEmptyIEnumerable<ElementType>(ElementType element){
      return new NonEmptyIEnumerable<ElementType>(element);
    }
    public static explicit operator NonEmptyIEnumerable<ElementType>(Boxed<ElementType> element){
      return new NonEmptyIEnumerable<ElementType>((IEnumerable<ElementType>)element);
    }
    public static explicit operator NonEmptyIEnumerable<ElementType>(ElementType[] array){
      return new NonEmptyIEnumerable<ElementType>(array);
    }
    public static explicit operator NonEmptyIEnumerable<ElementType>(List<ElementType> list){
      return new NonEmptyIEnumerable<ElementType>(list);
    }
    public static explicit operator ElementType(NonEmptyIEnumerable<ElementType> nonEmptyIEnumerable){
      return nonEmptyIEnumerable.GetValue();
    }
  }
  public sealed class Unboxer<ElementType>{
    public static object ToObject(IEnumerable<ElementType> collection){
      if (collection is NonNull<ElementType>)
        return ((NonNull<ElementType>)collection).ToObject();
      if (collection is Boxed<ElementType>)
        return ((Boxed<ElementType>)collection).ToObject();
      return collection;
    }
  }
  public struct ArrayEnumerator<ElementType>: IEnumerator<ElementType>, SCIEnumerator{
    private ElementType[] array;
    private int index;
    public ArrayEnumerator(ElementType[] array){
      this.array = array;
      this.index = -1;
    }
    public ElementType Current{
      get{
        return this.array[this.index];
      }
    }
    object SCIEnumerator.Current{
      get{
        return this.array[this.index];
      }
    }
    void IDisposable.Dispose(){
    }
    public bool MoveNext(){
      return ++this.index < this.array.Length;
    }
    void SCIEnumerator.Reset(){
      this.index = -1;
    }
  }
  public sealed class GenericIEnumerableToGenericIListAdapter<ElementType>: IList<ElementType>, IEnumerable{
    private List<ElementType> list;
    private IEnumerable<ElementType> collection;
    public GenericIEnumerableToGenericIListAdapter(IEnumerable<ElementType> collection){
      if (collection == null) 
        throw new ArgumentNullException();
      if (!(collection is IEnumerable))
        throw new ArgumentException();
      this.collection = collection;
    }

    private List<ElementType>/*!*/ List{
      get{
        List<ElementType> result = this.list;
        if (result == null){
          result = new List<ElementType>();
          this.list = result;
          if (this.collection != null){
            IEnumerator<ElementType> enumerator = this.collection.GetEnumerator();
            if (enumerator != null){
              while (enumerator.MoveNext()){
                //result.Add(enumerator.Current);
                ElementType curr = enumerator.Current;
                result.Add(curr);
              }
            }
          }
        }
        return result;
      }
    }
    IEnumerator IEnumerable.GetEnumerator() {
      if (this.list != null)
        return this.list.GetEnumerator();
      else
        return ((IEnumerable)this.collection).GetEnumerator();
    }
    public IEnumerator<ElementType> GetEnumerator(){
      if (this.list != null)
        return this.list.GetEnumerator();
      else
        return this.collection.GetEnumerator();
    }
    public int Count{
      get{
        return this.List.Count;
      }
    }
    public bool IsSynchronized{
      get{
        return false;
      }
    }
    public object SyncRoot{
      get{
        return this;
      }
    }
    void ICollection<ElementType>.CopyTo(ElementType[] array, int index){
      this.List.CopyTo(array, index);
    }

    public bool IsFixedSize{
      get{
        return false;
      }
    }
    public bool IsReadOnly{
      get{
        return false;
      }
    }
    public ElementType this[int index]{
      get{
        return this.List[index];
      }
      set{
        this.List[index] = value;
      }
    }
    public void Add(ElementType value){
      this.List.Add(value);
    }
    public void Clear(){
      this.List.Clear();
    }
    public bool Contains(ElementType value){
      return this.List.Contains(value);
    }
    public int IndexOf(ElementType value){
      return this.List.IndexOf(value);
    }
    public void Insert(int index, ElementType value){
      this.List.Insert(index, value);
    }    
    public bool Remove(ElementType value){
      return this.List.Remove(value);
    }
    public void RemoveAt(int index){
      this.List.RemoveAt(index);
    }
  }
  public struct ValueEnumerator<ElementType>: IEnumerator<ElementType>, IEnumerator{
    private ElementType value;
    private int index;

    public ValueEnumerator(ElementType value){
      this.value = value;
      this.index = -1;
    }

    object IEnumerator.Current{
        get{
            return this.value;
        }
    }
    public ElementType Current{
      get{
        return this.value;
      }
    }
    void IEnumerator.Reset(){
        this.index = -1;
    }
    void IDisposable.Dispose(){
    }
    public bool MoveNext(){
      return ++this.index == 0;
    }
  }

  public sealed class StreamUtility<ElementType>{
    private StreamUtility(){}
    public static bool IsNull(IEnumerable<ElementType> stream){
      if (stream == null) return true;
      IEnumerator<ElementType> enumerator = stream.GetEnumerator();
      while (enumerator.MoveNext())
        if (enumerator.Current != null) return false;
      return true;
    }
  }
}
#if !NoData
namespace System.Query{ //TODO: rename to Microsoft.Cci.Query
#if CCINamespace
  using Microsoft.Cci;
#else
  using System.Compiler;
#endif
  using System.Collections.Generic;
  using System.Data.SqlTypes;
  using System.Text;

  //TODO: this class should derive from SystemException and it should not contain a string
  //The message, if any, should be obtained from a resource file
  public class StreamNotSingletonException: Exception{
    public StreamNotSingletonException(): base("Stream not singleton"){
    }
  }
  
  public interface IAggregate{
  }
  public interface IAggregateGroup{
  }

  public class Min: IAggregateGroup{
    public struct MinOfByte: IAggregate{
      byte value;
      bool hasValue;
      public void Add(byte value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value){
          this.value = value;
        }
      }
      public byte GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfInt16: IAggregate{
      short value;
      bool hasValue;
      public void Add(short value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value){
          this.value = value;
        }
      }
      public short GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfInt32: IAggregate{
      int value;
      bool hasValue;
      public void Add(int value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value){
          this.value = value;
        }
      }
      public int GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfInt64: IAggregate{
      long value;
      bool hasValue;
      public void Add(long value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value)
          this.value = value;
      }
      public long GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfSingle: IAggregate{
      float value;
      bool hasValue;
      public void Add(float value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value){
          this.value = value;
        }
      }
      public float GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfDouble: IAggregate{
      double value;
      bool hasValue;
      public void Add(double value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value)
          this.value = value;
      }
      public double GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfDecimal: IAggregate{
      decimal value;
      bool hasValue;
      public void Add(decimal value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value)
          this.value = value;
      }
      public decimal GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfString: IAggregate{
      string value;
      public void Add(string value){
        if (value != null){
          if (this.value == null || value.CompareTo(this.value) < 0)
            this.value = value;
        }
      }
      public string GetValue(){
        string result = this.value;
        this.value = null;
        return result;
      }
    }
    public struct MinOfDateTime: IAggregate{
      DateTime value;
      bool hasValue;
      public void Add(DateTime value){
        if (!this.hasValue || value < this.value){
          this.value = value;
          this.hasValue = true;
        }
      }
      public DateTime GetValue(){
        DateTime result = this.value;
        this.value = new DateTime();
        this.hasValue = false;
        return result;
      }
    }
    public struct MinOfSqlByte: IAggregate{
      byte value;
      bool hasValue;
      public void Add(SqlByte value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (byte)value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = (byte)value;
          }
        }
      }
      public SqlByte GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlByte.Null;
      }
    }
    public struct MinOfSqlInt16: IAggregate{
      short value;
      bool hasValue;
      public void Add(SqlInt16 value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (short)value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = (short)value;
          }
        }
      }
      public SqlInt16 GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlInt16.Null;
      }
    }
    public struct MinOfSqlInt32: IAggregate{
      int value;
      bool hasValue;
      public void Add(SqlInt32 value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (int)value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = (int)value;
          }
        }
      }
      public SqlInt32 GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlInt32.Null;
      }
    }
    public struct MinOfSqlInt64: IAggregate{
      long value;
      bool hasValue;
      public void Add(SqlInt64 value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (long)value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = (long)value;
          }
        }
      }
      public SqlInt64 GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlInt64.Null;
      }
    }
    public struct MinOfSqlSingle: IAggregate{
      float value;
      bool hasValue;
      public void Add(SqlSingle value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = value.Value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = value.Value;
          }
        }
      }
      public SqlSingle GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlSingle.Null;
      }
    }
    public struct MinOfSqlDouble: IAggregate{
      double value;
      bool hasValue;
      public void Add(SqlDouble value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (double)value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = (double)value;
          }
        }
      }
      public SqlDouble GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlDouble.Null;
      }
    }
    public struct MinOfSqlDecimal: IAggregate{
      SqlDecimal value;
      bool hasValue;
      public void Add(SqlDecimal value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = value;
          }
        }
      }
      public SqlDecimal GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlDecimal.Null;
      }
    }
    public struct MinOfSqlMoney: IAggregate{
      SqlMoney value;
      bool hasValue;
      public void Add(SqlMoney value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = value;
          }
        }
      }
      public SqlMoney GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlMoney.Null;
      }
    }
    public struct MinOfSqlString: IAggregate{
      SqlString value;
      bool hasValue;
      public void Add(SqlString value){
        if (!value.IsNull){
          if (!this.hasValue || (bool)SqlString.LessThan(value, this.value)){
            this.value = value;
            this.hasValue = true;
          }
        }
      }
      public SqlString GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlString.Null;
      }
    }
    public struct MinOfSqlDateTime: IAggregate{
      SqlDateTime value;
      bool hasValue;
      public void Add(SqlDateTime value){
        if (!value.IsNull){
          if (!this.hasValue || (bool)SqlDateTime.LessThan(value, this.value)){
            this.value = value;
            this.hasValue = true;
          }
        }
      }
      public SqlDateTime GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlDateTime.Null;
      }
    }
  }
  public class Max: IAggregateGroup{
    public struct MaxOfByte: IAggregate{
      byte value;
      bool hasValue;
      public void Add(byte value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public byte GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfInt16: IAggregate{
      short value;
      bool hasValue;
      public void Add(short value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public short GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfInt32: IAggregate{
      int value;
      bool hasValue;
      public void Add(int value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public int GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfInt64: IAggregate{
      long value;
      bool hasValue;
      public void Add(long value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public long GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfSingle: IAggregate{
      float value;
      bool hasValue;
      public void Add(float value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public float GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfDouble: IAggregate{
      double value;
      bool hasValue;
      public void Add(double value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public double GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfDecimal: IAggregate{
      decimal value;
      bool hasValue;
      public void Add(decimal value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public decimal GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfString: IAggregate{
      string value;
      public void Add(string value){
        if (value != null){
          if (this.value == null || value.CompareTo(this.value) > 0)
            this.value = value;
        }
      }
      public string GetValue(){
        string result = this.value;
        this.value = null;
        return result;
      }
    }
    public struct MaxOfDateTime: IAggregate{
      DateTime value;
      bool hasValue;
      public void Add(DateTime value){
        if (!this.hasValue || value > this.value){
          this.value = value;
          this.hasValue = true;
        }
      }
      public DateTime GetValue(){
        DateTime result = this.value;
        this.value = new DateTime();
        this.hasValue = false;
        return result;
      }
    }
    public struct MaxOfSqlByte: IAggregate{
      byte value;
      bool hasValue;
      public void Add(SqlByte value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (byte)value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = (byte)value;
        }
      }
      public SqlByte GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlByte.Null;
      }
    }
    public struct MaxOfSqlInt16: IAggregate{
      short value;
      bool hasValue;
      public void Add(SqlInt16 value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (short)value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = (short)value;
        }
      }
      public SqlInt16 GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlInt16.Null;
      }
    }
    public struct MaxOfSqlInt32: IAggregate{
      int value;
      bool hasValue;
      public void Add(SqlInt32 value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (int)value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = (int)value;
        }
      }
      public SqlInt32 GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlInt32.Null;
      }
    }
    public struct MaxOfSqlInt64: IAggregate{
      long value;
      bool hasValue;
      public void Add(SqlInt64 value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (long)value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = (long)value;
        }
      }
      public SqlInt64 GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlInt64.Null;
      }
    }
    public struct MaxOfSqlSingle: IAggregate{
      float value;
      bool hasValue;
      public void Add(SqlSingle value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = value.Value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = value.Value;
        }
      }
      public SqlSingle GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlSingle.Null;
      }
    }
    public struct MaxOfSqlDouble: IAggregate{
      double value;
      bool hasValue;
      public void Add(SqlDouble value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (double)value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = (double)value;
        }
      }
      public SqlDouble GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlDouble.Null;
      }
    }
    public struct MaxOfSqlDecimal: IAggregate{
      SqlDecimal value;
      bool hasValue;
      public void Add(SqlDecimal value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = value;
        }
      }
      public SqlDecimal GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlDecimal.Null;
      }
    }
    public struct MaxOfSqlMoney: IAggregate{
      SqlMoney value;
      bool hasValue;
      public void Add(SqlMoney value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = value;
        }
      }
      public SqlMoney GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlMoney.Null;
      }
    }
    public struct MaxOfSqlString: IAggregate{
      SqlString value;
      bool hasValue;
      public void Add(SqlString value){
        if (!value.IsNull){
          if (!this.hasValue || (bool)SqlString.GreaterThan(value, this.value)){
            this.value = value;
            this.hasValue = true;
          }
        }
      }
      public SqlString GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlString.Null;
      }
    }
    public struct MaxOfSqlDateTime: IAggregate{
      SqlDateTime value;
      bool hasValue;
      public void Add(SqlDateTime value){
        if (!value.IsNull){
          if (!this.hasValue || (bool)SqlDateTime.GreaterThan(value, this.value)){
            this.value = value;
            this.hasValue = true;
          }
        }
      }
      public SqlDateTime GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlDateTime.Null;
      }
    }
  }
  public class Sum: IAggregateGroup{
    public struct SumOfInt32: IAggregate{
      int total;
      public void Add(int value){
        this.total = this.total + value;
      }
      public int GetValue(){
        int ret = this.total;
        this.total = 0;
        return ret;
      }
    }
    public struct SumOfInt64: IAggregate{
      long total;
      public void Add(long value){
        this.total = this.total + value;
      }
      public long GetValue(){
        long ret = this.total;
        this.total = 0;
        return ret;
      }
    }
    public struct SumOfDouble: IAggregate{
      double total;
      public void Add(double value){
        this.total = this.total + value;
      }
      public double GetValue(){
        double ret = this.total;
        this.total = 0.0;
        return ret;
      }
    }
    public struct SumOfDecimal: IAggregate{
      decimal total;
      public void Add(decimal value){
        this.total = this.total + value;
      }
      public decimal GetValue(){
        decimal ret = this.total;
        this.total = 0;
        return ret;
      }
    }
    public struct SumOfSqlInt32: IAggregate{
      int total;
      bool hasValue;
      public void Add(SqlInt32 value){
        if (!value.IsNull){
          if (this.hasValue)
            this.total = this.total + (int) value;
          else{
            this.total = (int) value;
            this.hasValue = true;
          }
        }
      }
      public SqlInt32 GetValue(){
        if (!this.hasValue){
          return SqlInt32.Null;
        }
        this.hasValue = false;
        return (SqlInt32) this.total;
      }
    }
    public struct SumOfSqlInt64: IAggregate{
      long total;
      bool hasValue;
      public void Add(SqlInt64 value){
        if (!value.IsNull){
          if (this.hasValue)
            this.total = this.total + (long) value;
          else{
            this.total = (long) value;
            this.hasValue = true;
          }
        }
      }
      public SqlInt64 GetValue(){
        if (!this.hasValue) return SqlInt64.Null;
        this.hasValue = false;
        return (SqlInt64) this.total;
      }
    }
    public struct SumOfSqlDouble: IAggregate{
      SqlDouble total;
      bool hasValue;
      public void Add(SqlDouble value){
        if (!value.IsNull){
          if (this.hasValue){
            this.total = this.total + value;
          }else{
            this.total = value;
            this.hasValue = true;
          }
        }
      }
      public SqlDouble GetValue(){
        if (!this.hasValue) return SqlDouble.Null;
        this.hasValue = false;
        return this.total;
      }
    }
    public struct SumOfSqlDecimal: IAggregate{
      SqlDecimal total;
      bool hasValue;
      public void Add(SqlDecimal value){
        if (!value.IsNull){
          if (this.hasValue)
            this.total = this.total + value;
          else{
            this.total = value;
            this.hasValue = true;
          }
        }
      }
      public SqlDecimal GetValue(){
        if (!this.hasValue) return SqlDecimal.Null;
        this.hasValue = false;
        return this.total;
      }
    }
    public struct SumOfSqlMoney: IAggregate{
      SqlMoney total;
      bool hasValue;
      public void Add(SqlMoney value){
        if (!value.IsNull){
          if (this.hasValue)
            this.total = this.total + value;
          else{
            this.total = value;
            this.hasValue = true;
          }
        }
      }
      public SqlMoney GetValue(){
        if (!this.hasValue) return SqlMoney.Null;
        this.hasValue = false;
        return this.total;
      }
    }
  }
  public class Avg: IAggregateGroup{
    public struct AvgOfInt32: IAggregate{
      long total;
      long count;
      public void Add(int value){
        this.total += value;
        this.count++;
      }
      public int GetValue(){
        int result = (int)(this.total / this.count);
        this.total = 0;
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfInt64: IAggregate{
      decimal total;
      long count;
      public void Add(long value){
        this.total += value;
        this.count++;
      }
      public long GetValue(){
        long result = (long)(this.total / this.count);
        this.total = 0;
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfDouble: IAggregate{
      double total;
      long count;
      public void Add(double value){
        this.total += value;
        this.count++;
      }
      public double GetValue(){
        double result = this.total / this.count;
        this.total = 0;
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfDecimal: IAggregate{
      decimal total;
      long count;
      public void Add(decimal value){
        this.total += value;
        this.count++;
      }
      public decimal GetValue(){
        decimal result = this.total / this.count;
        this.total = 0;
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfSqlInt32: IAggregate{
      long total;
      long count;
      public void Add(SqlInt32 value){
        if (!value.IsNull){
          if (this.count == 0)
            this.total = (int)value;
          else
            this.total += (int)value;
          this.count++;
        }
      }
      public SqlInt32 GetValue(){
        if (this.count == 0) return SqlInt32.Null;
        int result = (int)(this.total / this.count);
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfSqlInt64: IAggregate{
      decimal total;
      long count;
      public void Add(SqlInt64 value){
        if (!value.IsNull){
          if (this.count == 0)
            this.total = (long)value;
          else
            this.total += (long)value;
          this.count++;
        }
      }
      public SqlInt64 GetValue(){
        if (this.count == 0) return SqlInt64.Null;
        long result = (long)(this.total / this.count);
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfSqlDouble: IAggregate{
      SqlDouble total;
      long count;
      public void Add(SqlDouble value){
        if (!value.IsNull){
          if (this.count == 0)
            this.total = value;
          else
            this.total += value;
          this.count++;
        }
      }
      public SqlDouble GetValue(){
        if (this.count == 0) return SqlDouble.Null;
        SqlDouble result = this.total / count;
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfSqlDecimal: IAggregate{
      SqlDecimal total;
      long count;
      public void Add(SqlDecimal value){
        if (!value.IsNull){
          if (this.count == 0)
            this.total = value;
          else
            this.total += value;
          this.count++;
        }
      }
      public SqlDecimal GetValue(){
        if (this.count == 0) return SqlDecimal.Null;
        SqlDecimal result = this.total / count;
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfSqlMoney: IAggregate{
      SqlMoney total;
      long count;
      public void Add(SqlMoney value){
        if (!value.IsNull){
          if (this.count == 0)
            this.total = value;
          else
            this.total += value;
          this.count++;
        }
      }
      public SqlMoney GetValue(){
        if (this.count == 0) return SqlMoney.Null;
        SqlMoney result = this.total / count;
        this.count = 0;
        return result;
      }
    }
  }
  public class Stdev: IAggregateGroup{
    public struct StdevOfDouble: IAggregate{
      double sumX;
      double sumX2;
      int count;
      public void Add(double value){
        this.sumX += value;
        this.sumX2 += (value * value);
        this.count++;
      }
      public double GetValue(){
        int c = count - 1;
        double result = Math.Sqrt((sumX2/c) - ((sumX * sumX)/count/c));
        this.sumX = 0;
        this.sumX2 = 0;
        this.count = 0;
        return result;
      }
    }
    public struct StdevOfDecimal: IAggregate{
      decimal sumX;
      decimal sumX2;
      int count;
      public void Add(decimal value){
        this.sumX += value;
        this.sumX2 += (value * value);
        this.count++;
      }
      public double GetValue(){
        int c = count - 1;
        // note: using Math.Sqrt(double) would lose precision, so use SqlDecimal.Power
        SqlDecimal result = SqlDecimal.Power((sumX2/c) - ((sumX * sumX)/count/c), 0.5);
        this.sumX = 0;
        this.sumX2 = 0;
        this.count = 0;
        return (double)(SqlDouble)result;
      }
    }
    public struct StdevOfSqlDouble: IAggregate{
      double sumX;
      double sumX2;
      int count;
      public void Add(SqlDouble value){
        if (!value.IsNull){
          double dv = (double) value;
          this.sumX += dv;
          this.sumX2 += dv * dv;
          this.count++;
        }
      }
      public SqlDouble GetValue(){
        if (this.count < 2) return SqlDouble.Null;
        int c = count - 1;
        double result = Math.Sqrt((sumX2/c) - ((sumX * sumX)/count/c));
        this.sumX = 0;
        this.sumX2 = 0;
        this.count = 0;
        return (SqlDouble) result;
      }
    }
    public struct StdevOfSqlDecimal: IAggregate{
      SqlDecimal sumX;
      SqlDecimal sumX2;
      int count;
      public void Add(SqlDecimal value){
        if (!value.IsNull){
          if (this.count == 0){
            this.sumX = value;
            this.sumX2 = value * value;
          }else{
            this.sumX += value;
            this.sumX2 += value * value;
          }
          this.count++;
        }
      }
      public SqlDouble GetValue(){
        if (this.count < 2) return SqlDecimal.Null;
        int c = count - 1;
        SqlDecimal result = SqlDecimal.Power((sumX2/c) - ((sumX * sumX)/count/c), 0.5);
        this.sumX = 0;
        this.sumX2 = 0;
        this.count = 0;
        return (SqlDouble)result;
      }
    }
    public struct StdevOfSqlMoney: IAggregate{
      SqlMoney sumX;
      SqlMoney sumX2;
      int count;
      public void Add(SqlMoney value){
        if (!value.IsNull){
          if (this.count == 0){
            this.sumX = value;
            this.sumX2 = value * value;
          }else{
            this.sumX += value;
            this.sumX2 += value * value;
          }
          this.count++;
        }
      }
      public SqlDouble GetValue(){
        if (this.count < 2) return SqlMoney.Null;
        int c = count - 1;
        SqlDecimal result = SqlDecimal.Power((sumX2/c) - ((sumX * sumX)/count/c), 0.5);
        this.sumX = 0;
        this.sumX2 = 0;
        this.count = 0;
        return (SqlDouble)result;
      }
    }
  }
  public class Count: IAggregateGroup{
    public struct CountOfObject: IAggregate{
      int count;
      public void Add(object value){
        count++;
      }
      public int GetValue(){
        int result = count;
        this.count = 0;
        return result;
      }
    }
  }

  [Anonymous]
  public sealed class SqlFunctions{
    public static SqlByte Abs(SqlByte value){
      return value;
    }
    public static SqlInt16 Abs(SqlInt16 value){
      if (value.IsNull) return SqlInt16.Null;
      return Math.Abs((short)value);
    }
    public static SqlInt32 Abs(SqlInt32 value){
      if (value.IsNull) return SqlInt32.Null;
      return Math.Abs((int)value);
    }
    public static SqlInt64 Abs(SqlInt64 value){
      if (value.IsNull) return SqlInt64.Null;
      return Math.Abs((long)value);
    }
    public static SqlDouble Abs(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Abs((double)value);
    }
    public static SqlDecimal Abs(SqlDecimal value){
      if (value.IsNull) return SqlDecimal.Null;
      return (value < 0) ? -value : value;
    }
    public static SqlMoney Abs(SqlMoney value){
      if (value.IsNull) return SqlMoney.Null;
      return (value < 0) ? -value : value;
    }
    public static SqlDouble Acos(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Acos((double)value);
    }
    public static SqlDouble Asin(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Asin((double)value);
    }
    public static SqlDouble Atan(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Atan((double)value);
    }
    public static SqlDouble Atn2(SqlDouble value1, SqlDouble value2){
      if (value1.IsNull || value2.IsNull) return SqlDouble.Null;
      return Math.Atan2((double)value1, (double)value2);
    }
    public static SqlByte Ceiling(SqlByte value){
      return value;
    }
    public static SqlInt16 Ceiling(SqlInt16 value){
      return value;
    }
    public static SqlInt32 Ceiling(SqlInt32 value){
      return value;
    }
    public static SqlInt64 Ceiling(SqlInt64 value){
      return value;
    }
    public static SqlDouble Ceiling(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Ceiling((double)value);
    }
    public static SqlDecimal Ceiling(SqlDecimal value){
      return SqlDecimal.Ceiling(value);
    }
    public static SqlMoney Ceiling(SqlMoney value){
      return (SqlMoney)SqlDecimal.Ceiling(value);
    }
    public static SqlInt32 CharIndex(SqlString pattern, SqlString source){
      if (pattern.IsNull || source.IsNull) return SqlInt32.Null;
      return ((string/*!*/)source.Value).IndexOf((string/*!*/)pattern.Value) + 1;
    }
    public static SqlDouble Cos(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Cos((double)value);
    }
    public static SqlDateTime DateAdd(SqlDatePart part, SqlInt32 value, SqlDateTime date){
      if (value.IsNull || date.IsNull) return SqlDateTime.Null;
      int incr = (int)value;
      DateTime dt = (DateTime)date;
      switch (part){
        case SqlDatePart.Year:
          return dt.AddYears(incr);
        case SqlDatePart.Month:
          return dt.AddMonths(incr);
        case SqlDatePart.Day:
          return dt.AddDays(incr);
        case SqlDatePart.Hour:
          return dt.AddHours(incr);
        case SqlDatePart.Minute:
          return dt.AddMinutes(incr);
        case SqlDatePart.Second:
          return dt.AddSeconds(incr);
        case SqlDatePart.Millisecond:
          return dt.AddMilliseconds(incr);
      }
      return dt;
    }
    public static SqlInt32 DatePart(SqlDatePart part, SqlDateTime date){
      if (date.IsNull) return SqlInt32.Null;
      DateTime dt = (DateTime)date;
      switch (part){
        case SqlDatePart.Year: 
          return dt.Year;
        case SqlDatePart.Month:
          return dt.Month;
        case SqlDatePart.Week:
          return (dt.DayOfYear + 6)/ 7;
        case SqlDatePart.WeekDay:
          return (int)dt.DayOfWeek;
        case SqlDatePart.Day:
          return dt.Day;
        case SqlDatePart.DayOfYear:
          return dt.DayOfYear;
        case SqlDatePart.Hour:
          return dt.Hour;
        case SqlDatePart.Minute:
          return dt.Minute;
        case SqlDatePart.Second:
          return dt.Second;
        case SqlDatePart.Millisecond:
          return dt.Millisecond;
      }
      return 0;
    }
    public static SqlDouble Degrees(SqlDouble radians){
      if (radians.IsNull) return SqlDouble.Null;
      return ((double)radians) * Math.PI / 2;
    }
    public static SqlDouble Exp(SqlDouble exponent){
      return Math.Exp((double)exponent);
    }
    public static SqlByte Floor(SqlByte value){
      return value;
    }
    public static SqlInt16 Floor(SqlInt16 value){
      return value;
    }
    public static SqlInt32 Floor(SqlInt32 value){
      return value;
    }
    public static SqlInt64 Floor(SqlInt64 value){
      return value;
    }
    public static SqlDouble Floor(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Floor((double)value);
    }
    public static SqlDecimal Floor(SqlDecimal value){
      return SqlDecimal.Floor(value);
    }
    public static SqlMoney Floor(SqlMoney value){
      return (SqlMoney)SqlDecimal.Floor(value);
    }
    public static SqlDateTime GetDate(){
      return DateTime.Now;
    }
    public static SqlDateTime GetUtcDate(){
      return DateTime.UtcNow;
    }
    public static SqlBoolean IsDate(SqlString value){
      if (value.IsNull) return SqlBoolean.Null;
      try{ DateTime.Parse((string)value); }
      catch{ return false; }
      return true;
    }
    public static SqlString Left(SqlString value, SqlInt32 length){
      if (value.IsNull || length.IsNull) return SqlString.Null;
      int len = (int)length;
      string str = (string/*!*/)value.Value;
      return str.Substring(0, len);
    }
    public static SqlInt32 Len(SqlString value){
      if (value.IsNull) return SqlInt32.Null;
      return ((string/*!*/)value.Value).Length;
    }
    public static SqlDouble Log(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Log((double)value);
    }
    public static SqlDouble Log10(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Log10((double)value);
    }
    public static SqlDouble Power(SqlDouble value, SqlDouble exponent){
      if (value.IsNull || exponent.IsNull) return SqlDouble.Null;
      return Math.Pow((double)value, (double)exponent);
    }
    public static SqlString Replace(SqlString source, SqlString oldValue, SqlString newValue){
      if (source.IsNull || oldValue.IsNull || newValue.IsNull) return SqlString.Null;
      return ((string/*!*/)source.Value).Replace((string/*!*/)oldValue.Value, (string/*!*/)newValue.Value);
    }
    public static SqlString Reverse(SqlString value){
      if (value.IsNull) return SqlString.Null;
      string str = (string/*!*/)value.Value;
      StringBuilder sb = new StringBuilder(str.Length);
      for(int i = str.Length - 1; i >= 0; i--)
        sb.Append(str[i]);       
      return sb.ToString();
    }
    public static SqlString Right(SqlString value, SqlInt32 length){
      if (value.IsNull || length.IsNull) return SqlString.Null;
      string str = (string/*!*/)value.Value;
      int len = Math.Min((int)length, str.Length);
      return str.Substring(str.Length - len - 1, len);
    }
    public static SqlDouble Round(SqlDouble value, SqlInt32 precision){
      if (value.IsNull || precision.IsNull) return SqlDouble.Null;
      return Math.Round((double)value, (int)precision);
    }
    public static SqlDecimal Round(SqlDecimal value, SqlInt32 precision){
      if (value.IsNull || precision.IsNull) return SqlDecimal.Null;
      return SqlDecimal.Round(value, (int)precision);
    }
    public static SqlMoney Round(SqlMoney value, SqlInt32 precision){
      if (value.IsNull || precision.IsNull) return SqlMoney.Null;
      return (SqlMoney) SqlDecimal.Round(value, (int)precision);
    }
    public static SqlDouble Sin(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Sin((double)value);
    }
    public static SqlString Stuff(SqlString source, SqlInt32 position, SqlInt32 length, SqlString value){
      if (source.IsNull || position.IsNull || length.IsNull) return SqlString.Null;
      int offset = ((int)position) - 1;
      string result = ((string/*!*/)source.Value).Remove(offset, (int)length);
      //^ assume result != null;
      if (!value.IsNull) result = result.Insert(offset, (string/*!*/)value.Value);
      //^ assume result != null;
      return result;
    }
    public static SqlString Substring(SqlString source, SqlInt32 position, SqlInt32 length){
      if (source.IsNull || position.IsNull || length.IsNull) return SqlString.Null;
      int offset = ((int)position) - 1;
      return ((string/*!*/)source.Value).Substring(offset, (int)length);
    }
  }

  [Anonymous]
  public enum SqlDatePart{
    Year,
    Quarter,
    Month,
    Day,
    DayOfYear,
    Week,
    WeekDay,
    Hour,
    Minute,
    Second,
    Millisecond
  }

  [Anonymous]
  public enum SqlHint{
    HoldLock,
    Serializable,
    RepeatableRead,
    ReadCommitted,
    ReadUncommitted,
    NoLock, 
    RowLock,
    PageLock,
    TableLock,
    TableLockExclusive,
    ReadPast,
    UpdateLock,
    ExclusiveLock,
  }
}
#endif
#else
#if CCINamespace
namespace Microsoft.Cci{
#else
namespace System.Compiler{
#endif
  /// <summary>
  /// Tells a sympathetic compiler that the name of the entity bearing this attribute should be suppressed. When applied to a class or enum,
  /// this means that the members of the class or enum should be injected into the same scope as would have contained the class/enum name.
  /// When applied to a field or property, it means that the members of structure of the type of the field/property should be visible
  /// without qualification by the field/property name.
  /// </summary>
  [AttributeUsage(AttributeTargets.Field|AttributeTargets.Property|AttributeTargets.Class|AttributeTargets.Enum)]
  public sealed class AnonymousAttribute: Attribute{
    private Anonymity type;
    public AnonymousAttribute(){
      this.type = Anonymity.Structural;
    }
    public Anonymity Anonymity{
      get {return this.type;}
    }
  }  
  public enum Anonymity{
    Unknown,
    None,
    Structural,
    Full
  }
  public enum CciMemberKind{
    Unknown,
    Regular,
    Auxiliary,
    FrameGuardGetter,
  }
  [AttributeUsage(AttributeTargets.All)]
  public class CciMemberKindAttribute: Attribute{
    public CciMemberKind Kind;
    public CciMemberKindAttribute(CciMemberKind kind){
      this.Kind = kind;
    }
  }
  [AttributeUsage(AttributeTargets.Class)]
  public sealed class ComposerAttribute: Attribute{
    public string AssemblyName = null;
    public string TypeName = null;
    public ComposerAttribute(){
    }
  }
  [AttributeUsage(AttributeTargets.Assembly|AttributeTargets.Module, AllowMultiple=true)]
  public sealed class CustomVisitorAttribute : Attribute{
    public string Assembly;
    public string Class;
    public string Phase;
    public bool Replace;
    public CustomVisitorAttribute(){
    }
  }
  [AttributeUsage(AttributeTargets.Class|AttributeTargets.Field|AttributeTargets.Property|AttributeTargets.Method)]
  public sealed class ElementTypeAttribute: Attribute{
    public Type ElementType = null;
    public ElementTypeAttribute(){
    }
  }
  public interface ITemplateParameter{
  }
  [AttributeUsage(AttributeTargets.Class|AttributeTargets.Delegate|AttributeTargets.Interface|AttributeTargets.Struct)]
  public sealed class TemplateAttribute : System.Attribute{
    public Type[] TemplateParameters;
    public TemplateAttribute(params Type[] parameters){
      this.TemplateParameters = parameters;
    }
  }
  [AttributeUsage(AttributeTargets.Class|AttributeTargets.Delegate|AttributeTargets.Interface|AttributeTargets.Struct)]
  public sealed class TemplateInstanceAttribute : System.Attribute{
    public Type Template;
    public Type[] TemplateArguments;
    public TemplateInstanceAttribute(Type template, params Type[] arguments){
      this.Template = template;
    }
  }

  [AttributeUsage(AttributeTargets.Class|AttributeTargets.Interface|AttributeTargets.Struct)]
  public sealed class TemplateParameterFlagsAttribute : System.Attribute{
    public int Flags;
    public TemplateParameterFlagsAttribute(int flags) {
      this.Flags = flags;
    }
  }
  namespace Diagnostics{
    public sealed class Debug{
      public static void Assert(bool condition){
        System.Diagnostics.Debug.Assert(condition);
      }
    }
  }
}
#if !NoData && !ROTOR
namespace System.Data{
  public interface IDbTransactable{
    IDbTransaction BeginTransaction();
    IDbTransaction BeginTransaction(IsolationLevel level);
  }
}
#endif
namespace StructuralTypes{
#if CCINamespace
  using Microsoft.Cci;
#else
  using System.Compiler;
#endif
  using System.Collections.Generic;
 
  public interface IConstrainedType{}
  public interface ITupleType{}
  public interface ITypeUnion{}
  public interface ITypeIntersection{}
  public interface ITypeAlias{}
  public interface ITypeDefinition{}

  [Template(typeof(ElementType))]
  public struct Boxed_1 : IEnumerable_1{
    private ElementType[] box;
    public Boxed_1(ElementType value){
      this.box = new ElementType[]{value};
    }
    public ElementType GetValue(){
      return this.box[0];
    }
    public void SetValue(ElementType value){
      this.box[0] = value;
    }
    public object ToObject(){
      if (this.box == null) return null;
      return this.box[0];
    }
    public bool IsNull(){
      return this.box == null;
    }
    IEnumerator_1 IEnumerable_1.GetEnumerator(){
      return new BoxedEnumerator_1(this.box);
    }
    public BoxedEnumerator_1 GetEnumerator(){
      return new BoxedEnumerator_1(this.box);
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){
      return new BoxedEnumerator_1(this.box);
    }
    public void Clear(){
      this.box = null;
    }
    public static implicit operator Boxed_1(ElementType value){
      return new Boxed_1(value);
    }
    public static explicit operator ElementType(Boxed_1 boxed){
      return boxed.GetValue();
    }
    public static bool operator ==(Boxed_1 a, Boxed_1 b){
      if (a.box == null || b.box == null) return false;
      return a.box[0].Equals(b.box[0]);
    }
    public static bool operator ==(Boxed_1 a, object o){
      return a.Equals(o);
    }
    public static bool operator !=(Boxed_1 a, object o){
      return !a.Equals(o);
    }
    public static bool operator ==(object o, Boxed_1 b){
      return b.Equals(o);
    }
    public static bool operator !=(object o, Boxed_1 b){
      return !b.Equals(o);
    }
    public static bool operator !=(Boxed_1 a, Boxed_1 b){
      if (a.box == null || b.box == null) return false;
      return !a.box[0].Equals(b.box[0]);
    }
    public override bool Equals(object o){
      if (this.box == null) return o == null;
      if (!(o is Boxed_1)) return false;
      Boxed_1 b = (Boxed_1)o;
      if (this.box == null || b.box == null) return this.box == b.box;
      return this.box[0].Equals(b.box[0]);
    }
    public override int GetHashCode(){
      return this.box[0].GetHashCode();
    }
  }
  [Template(typeof(ElementType))]
  public struct BoxedEnumerator_1: IEnumerator_1{
    private ElementType[] box;
    private int index;
    internal BoxedEnumerator_1(ElementType[] box){
      this.box = box;
      this.index = -1;
    }
    public ElementType Current{
      get { 
        return this.box[0];
      }
    }
    object System.Collections.IEnumerator.Current{
      get{
        return this.box[0];
      }
    }
    void System.Collections.IEnumerator.Reset(){
      this.index = -1;
    }
    void IDisposable.Dispose(){
    }
    public bool MoveNext(){
      if (this.box == null) return false;
      return ++this.index == 0;
    }
  }
  [Template(typeof(ElementType))]
  public struct Invariant_1{
    private ElementType value;
    public Invariant_1(ElementType value){
      if (value == null) throw new ArgumentNullException();
      if (value.GetType() != typeof(ElementType)) throw new ArgumentException();
      this.value = value;
    }
    public ElementType GetValue(){
      return this.value;
    }
    public object ToObject(){
      return this.value;
    }
    public static implicit operator ElementType(Invariant_1 invariantValue){
      return invariantValue.value;
    }
    public static implicit operator NonNull_1(Invariant_1 invariantValue){
      return new NonNull_1(invariantValue.value);
    }
    public static explicit operator Invariant_1(ElementType value){
      return new Invariant_1(value);
    }
  }
  [Template(typeof(ElementType))]
  public struct NonNull_1 : IEnumerable_1{
    private ElementType value;
    public NonNull_1(ElementType value){
      if (value == null) throw new ArgumentNullException();
      this.value = value;
    }
    public ElementType GetValue(){
      return this.value;
    }
    public object ToObject(){
      return this.value;
    }
    IEnumerator_1 IEnumerable_1.GetEnumerator(){
      return new ValueEnumerator_1(this.value);
    }
    public ValueEnumerator_1 GetEnumerator(){
      return new ValueEnumerator_1(this.value);
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){
      return new ValueEnumerator_1(this.value);
    }
    public static implicit operator ElementType(NonNull_1 nonNullValue){
      return nonNullValue.value;
    }
    public static explicit operator NonNull_1(ElementType value){
      return new NonNull_1(value);
    }
  }
  [Template(typeof(ElementType))]
  public struct NonEmptyIEnumerable_1 : IEnumerable_1{
    IEnumerable_1 enumerable;
    public NonEmptyIEnumerable_1(IEnumerable_1 enumerable){
      this.enumerable = enumerable;
      if (enumerable == null) 
        throw new ArgumentNullException();
      IEnumerator_1 enumerator = enumerable.GetEnumerator();
      if (enumerator == null || !enumerator.MoveNext())
        throw new ArgumentException();
    }
    public NonEmptyIEnumerable_1(ElementType element){
      this.enumerable = new NonNull_1(element);
    }
    public ElementType GetValue(){
      IEnumerator_1 e = this.enumerable.GetEnumerator();
      if (e.MoveNext()){
        ElementType result = e.Current;
        if (!e.MoveNext()) return result;
      }
      throw new ArgumentOutOfRangeException();
    }
    public object ToObject(){
      if (this.enumerable is NonNull_1){
        NonNull_1 nnull = (NonNull_1)this.enumerable;
        return nnull.ToObject();
      }
      if (this.enumerable is Boxed_1){
        Boxed_1 boxed = (Boxed_1)this.enumerable;
        return boxed.ToObject();
      }
      return this.enumerable;
    }
    public IEnumerator_1 GetEnumerator(){
      return this.enumerable.GetEnumerator();
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){
      return this.enumerable.GetEnumerator();
    }
    public static implicit operator NonEmptyIEnumerable_1(NonNull_1 element){
      return new NonEmptyIEnumerable_1((IEnumerable_1)element);
    }
    public static explicit operator NonEmptyIEnumerable_1(ElementType element){
      return new NonEmptyIEnumerable_1(element);
    }
    public static explicit operator NonEmptyIEnumerable_1(Boxed_1 element){
      return new NonEmptyIEnumerable_1((IEnumerable_1)element);
    }
    public static explicit operator NonEmptyIEnumerable_1(ElementType[] array){
      return new NonEmptyIEnumerable_1(new ArrayToIEnumerableAdapter_1(array));
    }
    public static explicit operator NonEmptyIEnumerable_1(List_1 list){
      return new NonEmptyIEnumerable_1(list);
    }
    public static explicit operator ElementType(NonEmptyIEnumerable_1 nonEmptyIEnumerable){
      return nonEmptyIEnumerable.GetValue();
    }
  }
  [Template(typeof(ElementType))]
  public sealed class Unboxer_1{
    public static object ToObject(IEnumerable_1 collection){
      if (collection is NonNull_1)
        return ((NonNull_1)collection).ToObject();
      if (collection is Boxed_1)
        return ((Boxed_1)collection).ToObject();
      return collection;
    }
  }

  [Template(typeof(ElementType))]
  public sealed class ArrayToIEnumerableAdapter_1 : IEnumerable_1{
    private ElementType[] array;
    public ArrayToIEnumerableAdapter_1(ElementType[] array){
      this.array = array;
    }
    public IEnumerator_1 GetEnumerator(){
      return new ArrayEnumerator_1(this.array); 
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){
      return new ArrayEnumerator_1(this.array); 
    }
  }
  [Template(typeof(ElementType))]
  public sealed class GenericIEnumerableToGenericIListAdapter_1 : IList_1{
    private List_1 list;
    private IEnumerable_1 collection;
    public GenericIEnumerableToGenericIListAdapter_1(IEnumerable_1 collection){
      this.collection = collection;
    }

    private List_1 List{  
      get{
        List_1 result = this.list;
        if (result == null){
          result = new List_1();
          this.list = result;
          if (this.collection != null){
            IEnumerator_1 enumerator = this.collection.GetEnumerator();
            if (enumerator != null){
              while (enumerator.MoveNext()){
                ElementType curr = enumerator.Current;
                result.Add(curr);
              }
            }
          }
        }
        return result;
      }
    }
    public IEnumerator_1 GetEnumerator(){
      if (this.list != null)
        return this.list.GetEnumerator();
      else
        return this.collection.GetEnumerator();
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){
      return this.GetEnumerator(); 
    }
    public int Count{
      get{
        return this.List.Count;
      }
    }
    public bool IsSynchronized{
      get{
        return false;
      }
    }
    public object SyncRoot{
      get{
        return this;
      }
    }
    public void CopyTo(Array array, int index){
      this.List.CopyTo(array, index);
    }
    public void CopyTo(ElementType[] array, int index){
      this.List.CopyTo(array, index);
    }

    public bool IsFixedSize{
      get{
        return false;
      }
    }
    public bool IsReadOnly{
      get{
        return false;
      }
    }
    public ElementType this[int index]{
      get{
        return this.List[index];
      }
      set{
        this.List[index] = value;
      }
    }
    public void Add(ElementType value){
      this.List.Add(value);
    }
    public void Clear(){
      this.List.Clear();
    }
    public bool Contains(ElementType value){
      return this.List.Contains(value);
    }
    public int IndexOf(ElementType value){
      return this.List.IndexOf(value);
    }
    public void Insert(int index, ElementType value){
      this.List.Insert(index, value);
    }
    public bool Remove(ElementType value){
      return this.List.Remove(value);
    }
    public void RemoveAt(int index){
      this.List.RemoveAt(index);
    }
  }
  [Template(typeof(ElementType))]
  public struct ValueEnumerator_1: IEnumerator_1{
    private ElementType value;
    private int index;

    public ValueEnumerator_1(ElementType value){
      this.value = value;
      this.index = -1;
    }

    public ElementType Current{
      get{
        return this.value;
      }
    }
    object System.Collections.IEnumerator.Current{
      get{
        return this.value;
      }
    }
    void System.Collections.IEnumerator.Reset(){
      this.index = -1;
    }
    void IDisposable.Dispose(){
    }
    public bool MoveNext(){
      return ++this.index == 0;
    }
  }

  [Template(typeof(ElementType))]
  public sealed class StreamUtility_1{
    private StreamUtility_1(){}
    public static bool IsNull(IEnumerable_1 stream){
      if (stream == null) return true;
      IEnumerator_1 enumerator = stream.GetEnumerator();
      while (enumerator.MoveNext())
        if (enumerator.Current != null) return false;
      return true;
    }
  }
}
namespace System{
#if CCINamespace
  using Microsoft.Cci;
#else
  using System.Compiler;
#endif
  using System.Collections.Generic;

  [Template(typeof(ElementType))]
  public struct Nullable_1{
    internal ElementType value;
    internal bool hasValue;
    
    public Nullable_1(ElementType value){
      this.value = value;
      this.hasValue = true;
    }

    public override bool Equals(object other){
      if (other is Nullable_1)
        return Nullable_1.Equals(this, (Nullable_1)other);
      return false;
    }

    public override int GetHashCode(){
      return hasValue ? value.GetHashCode() : 0;
    }

    public override string ToString(){
      return hasValue ? value.ToString() : "";
    }        

    public bool HasValue{
      get{
        return hasValue;
      }
    }

    public ElementType Value{
      get{
        if (!hasValue)
          throw new InvalidOperationException();
        return value;
      }
    }

    public bool Equals(Nullable_1 other){        
      return Nullable_1.Equals(this, other);
    }

    public ElementType GetValueOrDefault(){
      return value;
    }

    public ElementType GetValueOrDefault(ElementType defaultValue){
      return hasValue ? value : defaultValue;
    }

    public static implicit operator Nullable_1(ElementType value){
      return new Nullable_1(value);
    }

    public static explicit operator ElementType(Nullable_1 value){
      return value.Value;
    }
  }
}
namespace System.Collections.Generic{
#if CCINamespace
  using Microsoft.Cci;
#else
  using System.Compiler;
#endif
  using StructuralTypes;
  using SCIEnumerable = System.Collections.IEnumerable;
  using SCIEnumerator = System.Collections.IEnumerator;
  using SCIList = System.Collections.IList;

  public class ElementType : ITemplateParameter{
  }

  [Template(typeof(ElementType))]
  public interface IEnumerable_1 : SCIEnumerable{
    [return:Microsoft.Contracts.NotNull]
    new IEnumerator_1 GetEnumerator();
  }

  [Template(typeof(ElementType))]
  public interface ICollection_1 : IEnumerable_1, SCIEnumerable{
    int Count {get;}
    void Add(ElementType e);
    void Clear();
    bool Contains(ElementType e);
    void CopyTo(ElementType[] array, int index);
    bool Remove(ElementType e);
    bool IsReadOnly { get; }
  }

  [Template(typeof(ElementType))]
  public interface IList_1 : ICollection_1, IEnumerable_1, IEnumerable{
    ElementType this[int index] {get; set;}
    int IndexOf(ElementType value);
    void Insert(int index, ElementType value);
    void RemoveAt(int index);
  }
  [Template(typeof(ElementType))]
  public sealed class Stack_1 : IEnumerable_1, ICollection, IEnumerable{
    private ElementType[] elements;
    private int capacity;
    private int count;
    public Stack_1(){
      this.capacity = 0;
      this.count = 0;
    }
    public Stack_1(int capacity){
      this.capacity = capacity;
      this.count = 0;
      this.elements = new ElementType[capacity];
    }
    public int Count{
      get{
        return this.count;
      }
    }
    public void CopyTo(Array array, int index){
      ElementType[] elements = this.elements;
      int n = this.count;
      for (int i = 0; i < n; i++){
        object elem = elements[i];
        array.SetValue(elem, index++);
      }
    }
    public bool IsSynchronized{
      get{
        return false;
      }
    }
    public bool IsReadOnly{
      get{
        return false;
      }
    }
    public object SyncRoot{
      get{
        return this;
      }
    }
    IEnumerator_1 IEnumerable_1.GetEnumerator(){
      return new StackEnumerator_1(this);
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){
      return new StackEnumerator_1(this);
    }
    public object Clone(){
      Stack_1 s = new Stack_1(this.capacity);
      for (int i = 0, n = this.count; i < n; i++)
        s.elements[i] = this.elements[i];
      return s; //REVIEW: should this clone the elements too?
    }
    private void DoubleCapacity(){
      int oldCapacity = this.capacity;
      if (oldCapacity == 0){
        this.capacity = 16;
        this.elements = new ElementType[16];
        return;
      }
      this.capacity = oldCapacity*2;
      ElementType[] oldElements = this.elements;
      ElementType[] newElements = this.elements = new ElementType[this.capacity];
      for (int i = 0, n = this.count; i < n; i++)
        newElements[i] = oldElements[i];
    }
    public void Push(ElementType e){
      int i = this.count;
      int ip1 = i+1;
      if (ip1 > this.capacity) this.DoubleCapacity();
      this.elements[i] = e;
      this.count = ip1;
      return;
    }
    public ElementType Pop(){
      if (this.count == 0)
        throw new InvalidOperationException("Stack.Pop: empty stack");
      return this.elements[--this.count];
    }
    public bool Empty(){
      return this.count == 0;
    }
    public ElementType Peek(){
      if (this.count == 0)
        throw new InvalidOperationException("Stack.Peek: empty stack");
      return this.elements[this.count-1];
    }
    public void Clear() {
      this.count = 0;
    }
  }
  [Template(typeof(ElementType))]
  public struct StackEnumerator_1: IEnumerator_1, SCIEnumerator{
    private ElementType[] contents;
    private int index;
    private int count;

    public StackEnumerator_1(Stack_1 stack){
      this.count = stack.Count;
      this.contents = new ElementType[this.count];
      stack.CopyTo(contents,0);
      this.index = -1;
    }

    public ElementType Current{
      get{
        return this.contents[this.index];
      }
    }
    object SCIEnumerator.Current{
      get{
        return this.contents[this.index];
      }
    }
    void IDisposable.Dispose(){
    }
    public bool MoveNext(){
      return ++this.index < this.count;
    }
    public void Reset(){
      this.index = -1;
    }
  }
  [Template(typeof(ElementType))]
  public sealed class List_1 : IList_1, ICollection_1, IEnumerable_1, SCIList, ICollection, IEnumerable{
    private ElementType[] elements;
    private int capacity;
    private int count;

    public List_1(){
      this.capacity = 0;
      this.count = 0;
    }
    public List_1(int capacity){
      this.capacity = capacity;
      this.count = 0;
      this.elements = new ElementType[capacity];
    }
    public List_1(IEnumerable_1 collection)
      : this(16){
      IEnumerator_1 enumerator = collection.GetEnumerator();
      while (enumerator.MoveNext())
        this.Add(enumerator.Current);
    }

    public ListEnumerator_1 GetEnumerator(){
      return new ListEnumerator_1(this);
    }
    IEnumerator_1 IEnumerable_1.GetEnumerator(){
      return new ListEnumerator_1(this);
    }
    SCIEnumerator SCIEnumerable.GetEnumerator(){
      return new ListEnumerator_1(this);
    }
    public int Capacity{
      get{
        return this.capacity;
      }
      set{
        if (value < this.count) throw new ArgumentOutOfRangeException("value");
        ElementType[] oldElements = this.elements;
        ElementType[] newElements = this.elements = new ElementType[this.capacity = value];
        for (int i = 0, n = this.count; i < n; i++)
          newElements[i] = oldElements[i];
      }
    }
    public int Count{
      get{
        return this.count;
      }
    }
    public bool IsSynchronized{
      get{
        return false;
      }
    }
    public object SyncRoot{
      get{
        return this;
      }
    }
    public void CopyTo(Array array, int index){
      ElementType[] elements = this.elements;
      int n = this.count;
      for (int i = 0; i < n; i++){
        object elem = elements[i];
        array.SetValue(elem, index++);
      }
    }
    public void CopyTo(ElementType[] array, int index){
      ElementType[] elements = this.elements;
      int n = this.count;
      for (int i = 0; i < n; i++){
        object elem = elements[i];
        array.SetValue(elem, index++);
      }
    }
    private void DoubleCapacity(){
      int oldCapacity = this.capacity;
      if (oldCapacity == 0){
        this.capacity = 16;
        this.elements = new ElementType[16];
        return;
      }
      this.Capacity = oldCapacity*2;
    }
    public bool IsFixedSize{
      get{
        return false;
      }
    }
    public bool IsReadOnly{
      get{
        return false;
      }
    }
    public ElementType this[int index]{
      get{
        if (index < 0 || index >= this.count) throw new ArgumentOutOfRangeException("index");
        return this.elements[index];
      }
      set{
        if (index < 0 || index >= this.count) throw new ArgumentOutOfRangeException("index");
        this.elements[index] = value;
      }
    }
    object SCIList.this[int index]{
      get{
        return this[index];
      }
      set{
        this[index] = (ElementType)value;
      }
    }
    public void Add(ElementType value){
      int i = this.count;
      int ip1 = i+1;
      if (ip1 > this.capacity) this.DoubleCapacity();
      this.elements[i] = value;
      this.count = ip1;
    }
    int SCIList.Add(object value){
      int i = this.count;
      this.Add((ElementType)value);
      return i;
    }
    public void Clear(){
      this.count = 0;
    }
    public bool Contains(ElementType value){
      return this.IndexOf(value) >= 0;
    }
    bool SCIList.Contains(object value){
      return ((SCIList)this).IndexOf(value) >= 0;
    }
    public int IndexOf(ElementType value){
      return Array.IndexOf(this.elements, value, 0, this.count);
    }
    int SCIList.IndexOf(object value){
      return Array.IndexOf(this.elements, value, 0, this.count);
    }
    public void Insert(int index, ElementType value){
      if (index < 0 || index > this.count) throw new ArgumentOutOfRangeException("index");
      if (index == this.count)
        this.Add(value);
      else{
        int i = this.count;
        int ip1 = i+1;
        if (ip1 > this.capacity) this.DoubleCapacity();
        Array.Copy(this.elements, index, this.elements, index + 1, this.count - index);
        this.elements[index] = value;
      }
    }
    void SCIList.Insert(int index, object value){
      this.Insert(index, (ElementType)value);
    }
    public bool Remove(ElementType value){
      object oval = value;
      for(int i = 0; i < this.count; i++){
        object oval2 = this.elements[i];
        if (oval2 == oval || (oval2 != null && oval2.Equals(oval))){
          this.RemoveAt(i);
          return true;
        }
      }
      return false;
    }
    void SCIList.Remove(object value){
      this.Remove((ElementType)value);
    }
    public void RemoveAt(int index){
      if (index < 0 || index > count) throw new ArgumentOutOfRangeException("index");
      if (index < count - 1){
        Array.Copy(this.elements, index + 1, this.elements, index, count - index);
      }
      this.count -= 1;
    }
    public object Clone(){
      return new List_1(this); //REVIEW: should this clone the elements too?
    }
    public void AddRange(IEnumerable_1 elts){
      foreach (ElementType o in elts)
        this.Add(o);
    }
    public ICollection_1 AsReadOnly(){
      return this;
    }
  }

  [Template(typeof(ElementType))]
  public sealed class Queue_1 : IEnumerable_1, System.Collections.ICollection, IEnumerable{
    private ElementType[] elements;
    private int capacity;
    private int count;

    public Queue_1(){
      this.capacity = 0;
      this.count = 0;
    }
    public Queue_1(int capacity){
      this.capacity = capacity;
      this.count = 0;
      this.elements = new ElementType[capacity];
    }
    public Queue_1(IEnumerable_1 collection)
      : this(16){
      IEnumerator_1 enumerator = collection.GetEnumerator();
      while (enumerator.MoveNext())
        this.Enqueue(enumerator.Current);
    }

    public ArrayEnumerator_1 GetEnumerator(){
      return new ArrayEnumerator_1(this.elements);
    }
    IEnumerator_1 IEnumerable_1.GetEnumerator(){
      return new ArrayEnumerator_1(this.elements);
    }
    SCIEnumerator SCIEnumerable.GetEnumerator(){
      return new ArrayEnumerator_1(this.elements);
    }
    public int Capacity{
      get{
        return this.capacity;
      }
      set{
        if (value < this.count) throw new ArgumentOutOfRangeException("value");
        ElementType[] oldElements = this.elements;
        ElementType[] newElements = this.elements = new ElementType[this.capacity = value];
        for (int i = 0, n = this.count; i < n; i++)
          newElements[i] = oldElements[i];
      }
    }
    public int Count{
      get{
        return this.count;
      }
    }
    public bool IsSynchronized{
      get{
        return false;
      }
    }
    public object SyncRoot{
      get{
        return this;
      }
    }
    public void CopyTo(Array array, int index){
      ElementType[] elements = this.elements;
      int n = this.count;
      for (int i = 0; i < n; i++){
        object elem = elements[i];
        array.SetValue(elem, index++);
      }
    }
    private void DoubleCapacity(){
      int oldCapacity = this.capacity;
      if (oldCapacity == 0){
        this.capacity = 16;
        this.elements = new ElementType[16];
        return;
      }
      this.Capacity = oldCapacity*2;
    }
    public bool IsFixedSize{
      get{
        return false;
      }
    }
    public bool IsReadOnly{
      get{
        return false;
      }
    }
    public void Enqueue(ElementType value){
      int i = this.count;
      int ip1 = i+1;
      if (ip1 > this.capacity) this.DoubleCapacity();
      this.elements[i] = value;
      this.count = ip1;
    }
    public void Clear(){
      this.count = 0;
    }
    public bool Contains(ElementType value){
      return Array.IndexOf(this.elements, value, 0, this.count) >= 0;
    }
    public ElementType Dequeue(){
      if (this.count == 0){
        throw new InvalidOperationException();
      }
      ElementType oval = this.elements[0];
      for(int i = 0; i < this.count-1; i++){
        this.elements[i] = this.elements[i+1];
      }
      this.count--;
      return oval;
    }
    public ElementType Peek(){
      if (this.count == 0){
        throw new InvalidOperationException();
      }
      return this.elements[0];
    }
    public object Clone(){
      return new Queue_1(this); //REVIEW: should this clone the elements too?
    }
  }

  [Template(typeof(ElementType))]
  public interface IEnumerator_1 : IDisposable, SCIEnumerator{
    new ElementType Current{get;}
  }

  [Template(typeof(ElementType))]
  public struct ArrayEnumerator_1: IEnumerator_1, SCIEnumerator{
    private ElementType[] array;
    private int index;

    public ArrayEnumerator_1(ElementType[] array){
      this.array = array;
      this.index = -1;
    }

    public ElementType Current{
      get{
        return this.array[this.index];
      }
    }
    object SCIEnumerator.Current{
      get{
        return this.array[this.index];
      }
    }
    void IDisposable.Dispose(){
    }
    public bool MoveNext(){
      return ++this.index < this.array.Length;
    }
    void SCIEnumerator.Reset(){
      this.index = -1;
    }
  }

  [Template(typeof(ElementType))]
  public struct ListEnumerator_1: IEnumerator_1, SCIEnumerator{
    private List_1 list;
    private int index;

    public ListEnumerator_1(List_1 list){
      this.list = list;
      this.index = -1;
    }

    public ElementType Current{
      get{
        return this.list[this.index];
      }
    }
    object SCIEnumerator.Current{
      get{
        return this.list[this.index];
      }
    }
    void IDisposable.Dispose(){
    }
    public bool MoveNext(){
      return ++this.index < this.list.Count;
    }
    public void Reset(){
      this.index = -1;
    }
  }
}

#if !NoData && !ROTOR
namespace System.Query{
#if CCINamespace
  using Microsoft.Cci;
#else
  using System.Compiler;
#endif
  using System.Collections.Generic;
  using System.Data.SqlTypes;
  using System.Text;

  //TODO: this class should derive from SystemException and it should not contain a string
  //The message, if any, should be obtained from a resource file
  public class StreamNotSingletonException: Exception{
    public StreamNotSingletonException(): base("Stream not singleton"){
    }
  }
  
  public interface IAggregate{
  }
  public interface IAggregateGroup{
  }

  public class Min: IAggregateGroup{
    public struct MinOfByte: IAggregate{
      byte value;
      bool hasValue;
      public void Add(byte value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value){
          this.value = value;
        }
      }
      public byte GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfInt16: IAggregate{
      short value;
      bool hasValue;
      public void Add(short value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value){
          this.value = value;
        }
      }
      public short GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfInt32: IAggregate{
      int value;
      bool hasValue;
      public void Add(int value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value){
          this.value = value;
        }
      }
      public int GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfInt64: IAggregate{
      long value;
      bool hasValue;
      public void Add(long value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value)
          this.value = value;
      }
      public long GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfSingle: IAggregate{
      float value;
      bool hasValue;
      public void Add(float value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value){
          this.value = value;
        }
      }
      public float GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfDouble: IAggregate{
      double value;
      bool hasValue;
      public void Add(double value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value)
          this.value = value;
      }
      public double GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfDecimal: IAggregate{
      decimal value;
      bool hasValue;
      public void Add(decimal value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value < this.value)
          this.value = value;
      }
      public decimal GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MinOfString: IAggregate{
      string value;
      public void Add(string value){
        if (value != null){
          if (this.value == null || value.CompareTo(this.value) < 0)
            this.value = value;
        }
      }
      public string GetValue(){
        string result = this.value;
        this.value = null;
        return result;
      }
    }
    public struct MinOfDateTime: IAggregate{
      DateTime value;
      bool hasValue;
      public void Add(DateTime value){
        if (!this.hasValue || value < this.value){
          this.value = value;
          this.hasValue = true;
        }
      }
      public DateTime GetValue(){
        DateTime result = this.value;
        this.value = new DateTime();
        this.hasValue = false;
        return result;
      }
    }
    public struct MinOfSqlByte: IAggregate{
      byte value;
      bool hasValue;
      public void Add(SqlByte value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (byte)value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = (byte)value;
          }
        }
      }
      public SqlByte GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlByte.Null;
      }
    }
    public struct MinOfSqlInt16: IAggregate{
      short value;
      bool hasValue;
      public void Add(SqlInt16 value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (short)value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = (short)value;
          }
        }
      }
      public SqlInt16 GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlInt16.Null;
      }
    }
    public struct MinOfSqlInt32: IAggregate{
      int value;
      bool hasValue;
      public void Add(SqlInt32 value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (int)value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = (int)value;
          }
        }
      }
      public SqlInt32 GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlInt32.Null;
      }
    }
    public struct MinOfSqlInt64: IAggregate{
      long value;
      bool hasValue;
      public void Add(SqlInt64 value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (long)value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = (long)value;
          }
        }
      }
      public SqlInt64 GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlInt64.Null;
      }
    }
    public struct MinOfSqlSingle: IAggregate{
      float value;
      bool hasValue;
      public void Add(SqlSingle value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = value.Value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = value.Value;
          }
        }
      }
      public SqlSingle GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlSingle.Null;
      }
    }
    public struct MinOfSqlDouble: IAggregate{
      double value;
      bool hasValue;
      public void Add(SqlDouble value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (double)value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = (double)value;
          }
        }
      }
      public SqlDouble GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlDouble.Null;
      }
    }
    public struct MinOfSqlDecimal: IAggregate{
      SqlDecimal value;
      bool hasValue;
      public void Add(SqlDecimal value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = value;
          }
        }
      }
      public SqlDecimal GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlDecimal.Null;
      }
    }
    public struct MinOfSqlMoney: IAggregate{
      SqlMoney value;
      bool hasValue;
      public void Add(SqlMoney value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = value;
            this.hasValue = true;
          }
          if (value < this.value){
            this.value = value;
          }
        }
      }
      public SqlMoney GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlMoney.Null;
      }
    }
    public struct MinOfSqlString: IAggregate{
      SqlString value;
      bool hasValue;
      public void Add(SqlString value){
        if (!value.IsNull){
          if (!this.hasValue || (bool)SqlString.LessThan(value, this.value)){
            this.value = value;
            this.hasValue = true;
          }
        }
      }
      public SqlString GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlString.Null;
      }
    }
    public struct MinOfSqlDateTime: IAggregate{
      SqlDateTime value;
      bool hasValue;
      public void Add(SqlDateTime value){
        if (!value.IsNull){
          if (!this.hasValue || (bool)SqlDateTime.LessThan(value, this.value)){
            this.value = value;
            this.hasValue = true;
          }
        }
      }
      public SqlDateTime GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlDateTime.Null;
      }
    }
  }
  public class Max: IAggregateGroup{
    public struct MaxOfByte: IAggregate{
      byte value;
      bool hasValue;
      public void Add(byte value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public byte GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfInt16: IAggregate{
      short value;
      bool hasValue;
      public void Add(short value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public short GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfInt32: IAggregate{
      int value;
      bool hasValue;
      public void Add(int value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public int GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfInt64: IAggregate{
      long value;
      bool hasValue;
      public void Add(long value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public long GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfSingle: IAggregate{
      float value;
      bool hasValue;
      public void Add(float value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public float GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfDouble: IAggregate{
      double value;
      bool hasValue;
      public void Add(double value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public double GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfDecimal: IAggregate{
      decimal value;
      bool hasValue;
      public void Add(decimal value){
        if (!this.hasValue){
          this.value = value;
          this.hasValue = true;
        }
        if (value > this.value)
          this.value = value;
      }
      public decimal GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return 0;
      }
    }
    public struct MaxOfString: IAggregate{
      string value;
      public void Add(string value){
        if (value != null){
          if (this.value == null || value.CompareTo(this.value) > 0)
            this.value = value;
        }
      }
      public string GetValue(){
        string result = this.value;
        this.value = null;
        return result;
      }
    }
    public struct MaxOfDateTime: IAggregate{
      DateTime value;
      bool hasValue;
      public void Add(DateTime value){
        if (!this.hasValue || value > this.value){
          this.value = value;
          this.hasValue = true;
        }
      }
      public DateTime GetValue(){
        DateTime result = this.value;
        this.value = new DateTime();
        this.hasValue = false;
        return result;
      }
    }
    public struct MaxOfSqlByte: IAggregate{
      byte value;
      bool hasValue;
      public void Add(SqlByte value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (byte)value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = (byte)value;
        }
      }
      public SqlByte GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlByte.Null;
      }
    }
    public struct MaxOfSqlInt16: IAggregate{
      short value;
      bool hasValue;
      public void Add(SqlInt16 value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (short)value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = (short)value;
        }
      }
      public SqlInt16 GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlInt16.Null;
      }
    }
    public struct MaxOfSqlInt32: IAggregate{
      int value;
      bool hasValue;
      public void Add(SqlInt32 value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (int)value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = (int)value;
        }
      }
      public SqlInt32 GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlInt32.Null;
      }
    }
    public struct MaxOfSqlInt64: IAggregate{
      long value;
      bool hasValue;
      public void Add(SqlInt64 value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (long)value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = (long)value;
        }
      }
      public SqlInt64 GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlInt64.Null;
      }
    }
    public struct MaxOfSqlSingle: IAggregate{
      float value;
      bool hasValue;
      public void Add(SqlSingle value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = value.Value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = value.Value;
        }
      }
      public SqlSingle GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlSingle.Null;
      }
    }
    public struct MaxOfSqlDouble: IAggregate{
      double value;
      bool hasValue;
      public void Add(SqlDouble value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = (double)value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = (double)value;
        }
      }
      public SqlDouble GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlDouble.Null;
      }
    }
    public struct MaxOfSqlDecimal: IAggregate{
      SqlDecimal value;
      bool hasValue;
      public void Add(SqlDecimal value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = value;
        }
      }
      public SqlDecimal GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlDecimal.Null;
      }
    }
    public struct MaxOfSqlMoney: IAggregate{
      SqlMoney value;
      bool hasValue;
      public void Add(SqlMoney value){
        if (!value.IsNull){
          if (!this.hasValue){
            this.value = value;
            this.hasValue = true;
          }
          if (value > this.value)
            this.value = value;
        }
      }
      public SqlMoney GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlMoney.Null;
      }
    }
    public struct MaxOfSqlString: IAggregate{
      SqlString value;
      bool hasValue;
      public void Add(SqlString value){
        if (!value.IsNull){
          if (!this.hasValue || (bool)SqlString.GreaterThan(value, this.value)){
            this.value = value;
            this.hasValue = true;
          }
        }
      }
      public SqlString GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlString.Null;
      }
    }
    public struct MaxOfSqlDateTime: IAggregate{
      SqlDateTime value;
      bool hasValue;
      public void Add(SqlDateTime value){
        if (!value.IsNull){
          if (!this.hasValue || (bool)SqlDateTime.GreaterThan(value, this.value)){
            this.value = value;
            this.hasValue = true;
          }
        }
      }
      public SqlDateTime GetValue(){
        if (this.hasValue){
          this.hasValue = false;
          return this.value;
        }
        return SqlDateTime.Null;
      }
    }
  }
  public class Sum: IAggregateGroup{
    public struct SumOfInt32: IAggregate{
      int total;
      public void Add(int value){
        this.total = this.total + value;
      }
      public int GetValue(){
        int ret = this.total;
        this.total = 0;
        return ret;
      }
    }
    public struct SumOfInt64: IAggregate{
      long total;
      public void Add(long value){
        this.total = this.total + value;
      }
      public long GetValue(){
        long ret = this.total;
        this.total = 0;
        return ret;
      }
    }
    public struct SumOfDouble: IAggregate{
      double total;
      public void Add(double value){
        this.total = this.total + value;
      }
      public double GetValue(){
        double ret = this.total;
        this.total = 0.0;
        return ret;
      }
    }
    public struct SumOfDecimal: IAggregate{
      decimal total;
      public void Add(decimal value){
        this.total = this.total + value;
      }
      public decimal GetValue(){
        decimal ret = this.total;
        this.total = 0;
        return ret;
      }
    }
    public struct SumOfSqlInt32: IAggregate{
      int total;
      bool hasValue;
      public void Add(SqlInt32 value){
        if (!value.IsNull){
          if (this.hasValue)
            this.total = this.total + (int) value;
          else{
            this.total = (int) value;
            this.hasValue = true;
          }
        }
      }
      public SqlInt32 GetValue(){
        if (!this.hasValue){
          return SqlInt32.Null;
        }
        this.hasValue = false;
        return (SqlInt32) this.total;
      }
    }
    public struct SumOfSqlInt64: IAggregate{
      long total;
      bool hasValue;
      public void Add(SqlInt64 value){
        if (!value.IsNull){
          if (this.hasValue)
            this.total = this.total + (long) value;
          else{
            this.total = (long) value;
            this.hasValue = true;
          }
        }
      }
      public SqlInt64 GetValue(){
        if (!this.hasValue) return SqlInt64.Null;
        this.hasValue = false;
        return (SqlInt64) this.total;
      }
    }
    public struct SumOfSqlDouble: IAggregate{
      SqlDouble total;
      bool hasValue;
      public void Add(SqlDouble value){
        if (!value.IsNull){
          if (this.hasValue){
            this.total = this.total + value;
          }else{
            this.total = value;
            this.hasValue = true;
          }
        }
      }
      public SqlDouble GetValue(){
        if (!this.hasValue) return SqlDouble.Null;
        this.hasValue = false;
        return this.total;
      }
    }
    public struct SumOfSqlDecimal: IAggregate{
      SqlDecimal total;
      bool hasValue;
      public void Add(SqlDecimal value){
        if (!value.IsNull){
          if (this.hasValue)
            this.total = this.total + value;
          else{
            this.total = value;
            this.hasValue = true;
          }
        }
      }
      public SqlDecimal GetValue(){
        if (!this.hasValue) return SqlDecimal.Null;
        this.hasValue = false;
        return this.total;
      }
    }
    public struct SumOfSqlMoney: IAggregate{
      SqlMoney total;
      bool hasValue;
      public void Add(SqlMoney value){
        if (!value.IsNull){
          if (this.hasValue)
            this.total = this.total + value;
          else{
            this.total = value;
            this.hasValue = true;
          }
        }
      }
      public SqlMoney GetValue(){
        if (!this.hasValue) return SqlMoney.Null;
        this.hasValue = false;
        return this.total;
      }
    }
  }
  public class Avg: IAggregateGroup{
    public struct AvgOfInt32: IAggregate{
      long total;
      long count;
      public void Add(int value){
        this.total += value;
        this.count++;
      }
      public int GetValue(){
        int result = (int)(this.total / this.count);
        this.total = 0;
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfInt64: IAggregate{
      decimal total;
      long count;
      public void Add(long value){
        this.total += value;
        this.count++;
      }
      public long GetValue(){
        long result = (long)(this.total / this.count);
        this.total = 0;
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfDouble: IAggregate{
      double total;
      long count;
      public void Add(double value){
        this.total += value;
        this.count++;
      }
      public double GetValue(){
        double result = this.total / this.count;
        this.total = 0;
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfDecimal: IAggregate{
      decimal total;
      long count;
      public void Add(decimal value){
        this.total += value;
        this.count++;
      }
      public decimal GetValue(){
        decimal result = this.total / this.count;
        this.total = 0;
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfSqlInt32: IAggregate{
      long total;
      long count;
      public void Add(SqlInt32 value){
        if (!value.IsNull){
          if (this.count == 0)
            this.total = (int)value;
          else
            this.total += (int)value;
          this.count++;
        }
      }
      public SqlInt32 GetValue(){
        if (this.count == 0) return SqlInt32.Null;
        int result = (int)(this.total / this.count);
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfSqlInt64: IAggregate{
      decimal total;
      long count;
      public void Add(SqlInt64 value){
        if (!value.IsNull){
          if (this.count == 0)
            this.total = (long)value;
          else
            this.total += (long)value;
          this.count++;
        }
      }
      public SqlInt64 GetValue(){
        if (this.count == 0) return SqlInt64.Null;
        long result = (long)(this.total / this.count);
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfSqlDouble: IAggregate{
      SqlDouble total;
      long count;
      public void Add(SqlDouble value){
        if (!value.IsNull){
          if (this.count == 0)
            this.total = value;
          else
            this.total += value;
          this.count++;
        }
      }
      public SqlDouble GetValue(){
        if (this.count == 0) return SqlDouble.Null;
        SqlDouble result = this.total / count;
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfSqlDecimal: IAggregate{
      SqlDecimal total;
      long count;
      public void Add(SqlDecimal value){
        if (!value.IsNull){
          if (this.count == 0)
            this.total = value;
          else
            this.total += value;
          this.count++;
        }
      }
      public SqlDecimal GetValue(){
        if (this.count == 0) return SqlDecimal.Null;
        SqlDecimal result = this.total / count;
        this.count = 0;
        return result;
      }
    }
    public struct AvgOfSqlMoney: IAggregate{
      SqlMoney total;
      long count;
      public void Add(SqlMoney value){
        if (!value.IsNull){
          if (this.count == 0)
            this.total = value;
          else
            this.total += value;
          this.count++;
        }
      }
      public SqlMoney GetValue(){
        if (this.count == 0) return SqlMoney.Null;
        SqlMoney result = this.total / count;
        this.count = 0;
        return result;
      }
    }
  }
  public class Stdev: IAggregateGroup{
    public struct StdevOfDouble: IAggregate{
      double sumX;
      double sumX2;
      int count;
      public void Add(double value){
        this.sumX += value;
        this.sumX2 += (value * value);
        this.count++;
      }
      public double GetValue(){
        int c = count - 1;
        double result = Math.Sqrt((sumX2/c) - ((sumX * sumX)/count/c));
        this.sumX = 0;
        this.sumX2 = 0;
        this.count = 0;
        return result;
      }
    }
    public struct StdevOfDecimal: IAggregate{
      decimal sumX;
      decimal sumX2;
      int count;
      public void Add(decimal value){
        this.sumX += value;
        this.sumX2 += (value * value);
        this.count++;
      }
      public double GetValue(){
        int c = count - 1;
        // note: using Math.Sqrt(double) would lose precision, so use SqlDecimal.Power
        SqlDecimal result = SqlDecimal.Power((sumX2/c) - ((sumX * sumX)/count/c), 0.5);
        this.sumX = 0;
        this.sumX2 = 0;
        this.count = 0;
        return (double)(SqlDouble)result;
      }
    }
    public struct StdevOfSqlDouble: IAggregate{
      double sumX;
      double sumX2;
      int count;
      public void Add(SqlDouble value){
        if (!value.IsNull){
          double dv = (double) value;
          this.sumX += dv;
          this.sumX2 += dv * dv;
          this.count++;
        }
      }
      public SqlDouble GetValue(){
        if (this.count < 2) return SqlDouble.Null;
        int c = count - 1;
        double result = Math.Sqrt((sumX2/c) - ((sumX * sumX)/count/c));
        this.sumX = 0;
        this.sumX2 = 0;
        this.count = 0;
        return (SqlDouble) result;
      }
    }
    public struct StdevOfSqlDecimal: IAggregate{
      SqlDecimal sumX;
      SqlDecimal sumX2;
      int count;
      public void Add(SqlDecimal value){
        if (!value.IsNull){
          if (this.count == 0){
            this.sumX = value;
            this.sumX2 = value * value;
          }else{
            this.sumX += value;
            this.sumX2 += value * value;
          }
          this.count++;
        }
      }
      public SqlDouble GetValue(){
        if (this.count < 2) return SqlDecimal.Null;
        int c = count - 1;
        SqlDecimal result = SqlDecimal.Power((sumX2/c) - ((sumX * sumX)/count/c), 0.5);
        this.sumX = 0;
        this.sumX2 = 0;
        this.count = 0;
        return (SqlDouble)result;
      }
    }
    public struct StdevOfSqlMoney: IAggregate{
      SqlMoney sumX;
      SqlMoney sumX2;
      int count;
      public void Add(SqlMoney value){
        if (!value.IsNull){
          if (this.count == 0){
            this.sumX = value;
            this.sumX2 = value * value;
          }else{
            this.sumX += value;
            this.sumX2 += value * value;
          }
          this.count++;
        }
      }
      public SqlDouble GetValue(){
        if (this.count < 2) return SqlMoney.Null;
        int c = count - 1;
        SqlDecimal result = SqlDecimal.Power((sumX2/c) - ((sumX * sumX)/count/c), 0.5);
        this.sumX = 0;
        this.sumX2 = 0;
        this.count = 0;
        return (SqlDouble)result;
      }
    }
  }
  public class Count: IAggregateGroup{
    public struct CountOfObject: IAggregate{
      int count;
      public void Add(object value){
        count++;
      }
      public int GetValue(){
        int result = count;
        this.count = 0;
        return result;
      }
    }
  }

  [Anonymous]
  public sealed class SqlFunctions{
    public static SqlByte Abs(SqlByte value){
      return value;
    }
    public static SqlInt16 Abs(SqlInt16 value){
      if (value.IsNull) return SqlInt16.Null;
      return Math.Abs((short)value);
    }
    public static SqlInt32 Abs(SqlInt32 value){
      if (value.IsNull) return SqlInt32.Null;
      return Math.Abs((int)value);
    }
    public static SqlInt64 Abs(SqlInt64 value){
      if (value.IsNull) return SqlInt64.Null;
      return Math.Abs((long)value);
    }
    public static SqlDouble Abs(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Abs((double)value);
    }
    public static SqlDecimal Abs(SqlDecimal value){
      if (value.IsNull) return SqlDecimal.Null;
      return (value < 0) ? -value : value;
    }
    public static SqlMoney Abs(SqlMoney value){
      if (value.IsNull) return SqlMoney.Null;
      return (value < 0) ? -value : value;
    }
    public static SqlDouble Acos(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Acos((double)value);
    }
    public static SqlDouble Asin(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Asin((double)value);
    }
    public static SqlDouble Atan(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Atan((double)value);
    }
    public static SqlDouble Atn2(SqlDouble value1, SqlDouble value2){
      if (value1.IsNull || value2.IsNull) return SqlDouble.Null;
      return Math.Atan2((double)value1, (double)value2);
    }
    public static SqlByte Ceiling(SqlByte value){
      return value;
    }
    public static SqlInt16 Ceiling(SqlInt16 value){
      return value;
    }
    public static SqlInt32 Ceiling(SqlInt32 value){
      return value;
    }
    public static SqlInt64 Ceiling(SqlInt64 value){
      return value;
    }
    public static SqlDouble Ceiling(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Ceiling((double)value);
    }
    public static SqlDecimal Ceiling(SqlDecimal value){
      return SqlDecimal.Ceiling(value);
    }
    public static SqlMoney Ceiling(SqlMoney value){
      return (SqlMoney)SqlDecimal.Ceiling(value);
    }
    public static SqlInt32 CharIndex(SqlString pattern, SqlString source){
      if (pattern.IsNull || source.IsNull) return SqlInt32.Null;
      return ((string)source).IndexOf((string)pattern) + 1;
    }
    public static SqlDouble Cos(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Cos((double)value);
    }
    public static SqlDateTime DateAdd(SqlDatePart part, SqlInt32 value, SqlDateTime date){
      if (value.IsNull || date.IsNull) return SqlDateTime.Null;
      int incr = (int)value;
      DateTime dt = (DateTime)date;
      switch (part){
        case SqlDatePart.Year:
          return dt.AddYears(incr);
        case SqlDatePart.Month:
          return dt.AddMonths(incr);
        case SqlDatePart.Day:
          return dt.AddDays(incr);
        case SqlDatePart.Hour:
          return dt.AddHours(incr);
        case SqlDatePart.Minute:
          return dt.AddMinutes(incr);
        case SqlDatePart.Second:
          return dt.AddSeconds(incr);
        case SqlDatePart.Millisecond:
          return dt.AddMilliseconds(incr);
      }
      return dt;
    }
    public static SqlInt32 DatePart(SqlDatePart part, SqlDateTime date){
      if (date.IsNull) return SqlInt32.Null;
      DateTime dt = (DateTime)date;
      switch (part){
        case SqlDatePart.Year: 
          return dt.Year;
        case SqlDatePart.Month:
          return dt.Month;
        case SqlDatePart.Week:
          return (dt.DayOfYear + 6)/ 7;
        case SqlDatePart.WeekDay:
          return (int)dt.DayOfWeek;
        case SqlDatePart.Day:
          return dt.Day;
        case SqlDatePart.DayOfYear:
          return dt.DayOfYear;
        case SqlDatePart.Hour:
          return dt.Hour;
        case SqlDatePart.Minute:
          return dt.Minute;
        case SqlDatePart.Second:
          return dt.Second;
        case SqlDatePart.Millisecond:
          return dt.Millisecond;
      }
      return 0;
    }
    public static SqlDouble Degrees(SqlDouble radians){
      if (radians.IsNull) return SqlDouble.Null;
      return ((double)radians) * Math.PI / 2;
    }
    public static SqlDouble Exp(SqlDouble exponent){
      return Math.Exp((double)exponent);
    }
    public static SqlByte Floor(SqlByte value){
      return value;
    }
    public static SqlInt16 Floor(SqlInt16 value){
      return value;
    }
    public static SqlInt32 Floor(SqlInt32 value){
      return value;
    }
    public static SqlInt64 Floor(SqlInt64 value){
      return value;
    }
    public static SqlDouble Floor(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Floor((double)value);
    }
    public static SqlDecimal Floor(SqlDecimal value){
      return SqlDecimal.Floor(value);
    }
    public static SqlMoney Floor(SqlMoney value){
      return (SqlMoney)SqlDecimal.Floor(value);
    }
    public static SqlDateTime GetDate(){
      return DateTime.Now;
    }
    public static SqlDateTime GetUtcDate(){
      return DateTime.UtcNow;
    }
    public static SqlBoolean IsDate(SqlString value){
      if (value.IsNull) return SqlBoolean.Null;
      try{ DateTime.Parse((string)value); }
      catch{ return false; }
      return true;
    }
    public static SqlString Left(SqlString value, SqlInt32 length){
      if (value.IsNull || length.IsNull) return SqlString.Null;
      int len = (int)length;
      string str = (string)value;
      return str.Substring(0, len);
    }
    public static SqlInt32 Len(SqlString value){
      if (value.IsNull) return SqlInt32.Null;
      return ((string)value).Length;
    }
    public static SqlDouble Log(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Log((double)value);
    }
    public static SqlDouble Log10(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Log10((double)value);
    }
    public static SqlDouble Power(SqlDouble value, SqlDouble exponent){
      if (value.IsNull || exponent.IsNull) return SqlDouble.Null;
      return Math.Pow((double)value, (double)exponent);
    }
    public static SqlString Replace(SqlString source, SqlString oldValue, SqlString newValue){
      if (source.IsNull || oldValue.IsNull || newValue.IsNull) return SqlString.Null;
      return ((string)source).Replace((string)oldValue, (string)newValue);
    }
    public static SqlString Reverse(SqlString value){
      if (value.IsNull) return SqlString.Null;
      string str = (string)value;
      StringBuilder sb = new StringBuilder(str.Length);
      for(int i = str.Length - 1; i >= 0; i--)
        sb.Append(str[i]);       
      return sb.ToString();
    }
    public static SqlString Right(SqlString value, SqlInt32 length){
      if (value.IsNull || length.IsNull) return SqlString.Null;
      string str = (string)value;
      int len = Math.Min((int)length, str.Length);
      return str.Substring(str.Length - len - 1, len);
    }
    public static SqlDouble Round(SqlDouble value, SqlInt32 precision){
      if (value.IsNull || precision.IsNull) return SqlDouble.Null;
      return Math.Round((double)value, (int)precision);
    }
    public static SqlDecimal Round(SqlDecimal value, SqlInt32 precision){
      if (value.IsNull || precision.IsNull) return SqlDecimal.Null;
      return SqlDecimal.Round(value, (int)precision);
    }
    public static SqlMoney Round(SqlMoney value, SqlInt32 precision){
      if (value.IsNull || precision.IsNull) return SqlMoney.Null;
      return (SqlMoney) SqlDecimal.Round(value, (int)precision);
    }
    public static SqlDouble Sin(SqlDouble value){
      if (value.IsNull) return SqlDouble.Null;
      return Math.Sin((double)value);
    }
    public static SqlString Stuff(SqlString source, SqlInt32 position, SqlInt32 length, SqlString value){
      if (source.IsNull || position.IsNull || length.IsNull) return SqlString.Null;
      int offset = ((int)position) - 1;
      string result = ((string)source).Remove(offset, (int)length);
      if (!value.IsNull) result = result.Insert(offset, (string)value);
      return result;
    }
    public static SqlString Substring(SqlString source, SqlInt32 position, SqlInt32 length){
      if (source.IsNull || position.IsNull || length.IsNull) return SqlString.Null;
      int offset = ((int)position) - 1;
      return ((string)source).Substring(offset, (int)length);
    }
  }

  [Anonymous]
  public enum SqlDatePart{
    Year,
    Quarter,
    Month,
    Day,
    DayOfYear,
    Week,
    WeekDay,
    Hour,
    Minute,
    Second,
    Millisecond
  }

  [Anonymous]
  public enum SqlHint{
    HoldLock,
    Serializable,
    RepeatableRead,
    ReadCommitted,
    ReadUncommitted,
    NoLock, 
    RowLock,
    PageLock,
    TableLock,
    TableLockExclusive,
    ReadPast,
    UpdateLock,
    ExclusiveLock,
  }
}
#endif
#endif
namespace Microsoft.Contracts{

#if CCINamespace
  using Microsoft.Cci;
#else
  using System.Compiler;
#endif

  [Template(typeof(ElementTypeAttribute))]
  public class Range: System.Collections.IEnumerable{
    public int From, To, Step;
    public int FromO, ToO;
    //private bool ok;
    //public Range(int f, int t, int s) {
    //From=f-1; To=t; Step=s; ok = false;
    //}
    public Range(int f, int t) {
      From=f; To=t; Step=1; //ok = false;
    }
    public RangeEnumerator GetEnumerator(){
      return new RangeEnumerator(From, To, Step);
    }
    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator(){
      return new RangeEnumerator(From, To, Step);
    }
    
    public struct RangeEnumerator:System.Collections.IEnumerator{
      private int from, to, step;
      private bool ok ;
      public RangeEnumerator(int f, int t, int s) {
        from=f; to=t; step=s; ok = false;
      }
      public object Current{get {if(ok) return from; else throw new Exception("RangeEnumerator.Current: wrong protocol");}}
      public bool MoveNext() {if (!ok) ok = true; else from+=step; return from<=to;}
      public void Reset() {throw new Exception("RangeEnumerator.Reset: not implemented");}
    }
  }

  /// <summary>
  /// Used as an optional modifier on type parameter occurrences to override any non-null
  /// instantiations.
  /// </summary>
  public sealed class NullableType {
  }
  public sealed class NonNullType {
    [Throws("System.NullException")]
    [StateIndependent]
    [System.Diagnostics.DebuggerStepThrough]
    [System.Diagnostics.Conditional("DEBUG")]
    public static void AssertNotNull([Delayed] UIntPtr ptr) {
      if (ptr == (UIntPtr)0) {
#if KERNEL
        Microsoft.Singularity.DebugStub.Break();
#else
        Microsoft.Singularity.V1.Services.DebugService.Break();
#endif
        throw new NullException();
      }
    }
    [Throws("System.NullException")]
    [StateIndependent]
    [System.Diagnostics.DebuggerStepThrough]
    [System.Diagnostics.Conditional("DEBUG")]
    public static void AssertNotNullImplicit([Delayed] UIntPtr ptr) {
      if (ptr == (UIntPtr)0) {
#if KERNEL
        Microsoft.Singularity.DebugStub.Break();
#else
        Microsoft.Singularity.V1.Services.DebugService.Break();
#endif
        throw new NullException();
      }
    }
    [Throws("System.NullException")]
    [StateIndependent]
    [System.Diagnostics.DebuggerStepThrough]
    [System.Diagnostics.Conditional("DEBUG")]
    public static void AssertNotNull([Delayed] object obj) {
      if (obj == null) {
#if KERNEL
        Microsoft.Singularity.DebugStub.Break();
#else
        Microsoft.Singularity.V1.Services.DebugService.Break();
#endif
        throw new NullException();
      }
    }
    [Throws("System.NullException")]
    [StateIndependent]
    [System.Diagnostics.DebuggerStepThrough]
    [System.Diagnostics.Conditional("DEBUG")]
    public static void AssertNotNullImplicit([Delayed] object obj) {
      if (obj == null) {
#if KERNEL
        Microsoft.Singularity.DebugStub.Break();
#else
        Microsoft.Singularity.V1.Services.DebugService.Break();
#endif
        throw new NullException();
      }
    }
  }
  public class AssertHelpers {
    #region Assert methods
    [System.Diagnostics.DebuggerStepThrough]
    public static void Assert(bool b) {
      if (!b)
        throw new Contracts.AssertException();
    }
    [System.Diagnostics.DebuggerStepThrough]
    public static void AssertLoopInvariant(bool b) {
      if (!b)
        throw new Contracts.LoopInvariantException();
    }
    [System.Diagnostics.DebuggerStepThrough]
    public static void Assert(bool b, string s) {
      if (!b)
        throw new Contracts.AssertException(s);
    }
    [System.Diagnostics.DebuggerStepThrough]
    public static void Assert(bool b, string s, Exception inner) {
      if (!b)
        throw new Contracts.AssertException(s,inner);
    }
    /// <summary>
    /// Is deserialized by Boogie.
    /// </summary>
    /// <param name="condition">Serialized condition</param>
    [System.Diagnostics.DebuggerStepThrough]
    [Obsolete("Use the two-argument version instead. Delete this one when the LKG > 7301.")]
    public static void AssertStatement(string condition) {
    }
    /// <summary>
    /// Is deserialized by Boogie.
    /// </summary>
    /// <param name="condition">Serialized condition</param>
    /// <param name="messageForUser">Text to use in error messages</param>
    [System.Diagnostics.DebuggerStepThrough]
    public static void AssertStatement(string condition, string messageForUser) {
    }
    /// <summary>
    /// Is deserialized by Boogie.
    /// </summary>
    /// <param name="condition">Serialized condition</param>
    [System.Diagnostics.DebuggerStepThrough]
    [Obsolete("Use the two-argument version instead. Delete this one when the LKG > 7301.")]
    public static void LoopInvariant(string condition) {
    }
    /// <summary>
    /// Is deserialized by Boogie.
    /// </summary>
    /// <param name="condition">Serialized condition</param>
    /// <param name="messageForUser">Text to use in error messages</param>
    [System.Diagnostics.DebuggerStepThrough]
    public static void LoopInvariant(string condition, string messageForUser) {
    }
    #endregion Assert methods
    #region Assume methods
    [System.Diagnostics.DebuggerStepThrough]
    public static void Assume(bool b) {
      if (!b)
        throw new Contracts.AssumeException();
    }
    [System.Diagnostics.DebuggerStepThrough]
    public static void Assume(bool b, string s) {
      if (!b)
        throw new Contracts.AssumeException(s);
    }
    [System.Diagnostics.DebuggerStepThrough]
    public static void Assume(bool b, string s, Exception inner) {
      if (!b)
        throw new Contracts.AssumeException(s,inner);
    }
    /// <summary>
    /// Is deserialized by Boogie.
    /// </summary>
    /// <param name="condition">Serialized condition</param>
    [System.Diagnostics.DebuggerStepThrough]
    public static void AssumeStatement(string condition) {
    }
    #endregion Assume methods
    [return: Microsoft.Contracts.NotNull]
    public static object OwnerIs(object owner, [Microsoft.Contracts.NotNull] object owned_object) { return owned_object; }
  }
  #region Exceptions
  //---------------------------------------------------------------------------
  //Exceptions
  //---------------------------------------------------------------------------

  public class NoChoiceException : Exception {}
  public class IllegalUpcastException : Exception {}

  public interface ICheckedException {}
  public class CheckedException: Exception, ICheckedException {}

  /// <summary>
  /// The Spec# compiler emits "throw new UnreachableException();" statements in places that it knows are unreachable, but that are considered reachable by the CLR verifier.
  /// </summary>
  public class UnreachableException : Exception {
    public UnreachableException() { }
    public UnreachableException(string s) : base(s) { }
    public UnreachableException(string s, Exception inner) : base(s, inner) { }
  }
  public class ContractException : Exception {
    public ContractException() {}
    public ContractException(string s) : base(s) {}
    public ContractException(string s, Exception inner) : base(s,inner) {}
  }
  public class AssertException : ContractException {
    public AssertException() {}
    public AssertException(string s) : base(s) {}
    public AssertException(string s, Exception inner) : base(s,inner) {}
  }
  public class LoopInvariantException : AssertException {
    public LoopInvariantException() {}
    public LoopInvariantException(string s) : base(s) {}
    public LoopInvariantException(string s, Exception inner) : base(s,inner) {}
  }
  public class AssumeException : ContractException {
    public AssumeException() {}
    public AssumeException(string s) : base(s) {}
    public AssumeException(string s, Exception inner) : base(s,inner) {}
  }
  /// <summary>
  /// Thrown when evaluation of a contract clause throws an exception.
  /// </summary>
  public class InvalidContractException : ContractException {
    public InvalidContractException() {}
    public InvalidContractException(string s) : base(s) {}
    public InvalidContractException(string s, Exception inner) : base(s,inner) {}
  }
  public class RequiresException : ContractException {
    public RequiresException() {}
    public RequiresException(string s) : base(s) {}
    public RequiresException(string s, Exception inner) : base(s,inner) {}
  }
  public class EnsuresException : ContractException {
    public EnsuresException() {}
    public EnsuresException(string s) : base(s) {}
    public EnsuresException(string s, Exception inner) : base(s,inner) {}
  }
  public class ModifiesException : ContractException {
    public ModifiesException() {}
    public ModifiesException(string s) : base(s) {}
    public ModifiesException(string s, Exception inner) : base(s,inner) {}
  }
  public class ThrowsException : ContractException {
    public ThrowsException() {}
    public ThrowsException(string s) : base(s) {}
    public ThrowsException(string s, Exception inner) : base(s,inner) {}
  }
  public class DoesException : ContractException {
    public DoesException() {}
    public DoesException(string s) : base(s) {}
    public DoesException(string s, Exception inner) : base(s,inner) {}
  }
  public class InvariantException : ContractException {
    public InvariantException() {}
    public InvariantException(string s) : base(s) {}
    public InvariantException(string s, Exception inner) : base(s,inner) {}
  }
  public class NullException : ContractException {
    public NullException() {}
    public NullException(string s) : base(s) {}
    public NullException(string s, Exception inner) : base(s,inner) {}
  }
  public class ContractMarkerException : ContractException {
  }
  #endregion Exceptions
  #region Attributes
  //---------------------------------------------------------------------------
  //Attributes
  //---------------------------------------------------------------------------
  internal sealed class SpecTargets{
    internal const AttributeTargets Code = 
      AttributeTargets.Constructor|AttributeTargets.Method|AttributeTargets.Property|AttributeTargets.Event|AttributeTargets.Delegate;
    internal const AttributeTargets Containers = 
      AttributeTargets.Struct|AttributeTargets.Class|AttributeTargets.Interface;
    internal const AttributeTargets CodeAndTheirContainers =
      Code|Containers;
    internal const AttributeTargets 
      CodeFieldsAndTheirContainers = CodeAndTheirContainers|AttributeTargets.Field;
  }
  /// <summary>
  /// We serialize constructs like Requires as custom attributes. But then there
  /// is the problem of how to serialize custom attributes that have been put onto
  /// such constructs. Since nested attributes are not allowed, we encode them
  /// by serializing the nested attributes and then emitting an attribute of type
  /// NestedAttributeCount with the number of nested attributes. That way, upon
  /// deserialization, as long as the order of the serialized attributes can be
  /// depended upon, we can reconstitute the nested attributes.
  /// So the Spec# source:
  /// "[A][B] requires P"
  /// would be serialized as
  /// "A(...), B(...), NestedAttributeCount(2), Requires(P,...)".
  /// </summary>
 /*
  [AttributeUsage(AttributeTargets.All,AllowMultiple=true, Inherited = true)]
  public class NestedAttributeCount : Attribute{
    public int numberOfNestedAttributes;
    public NestedAttributeCount(int _numberOfNestedAttributes){
      numberOfNestedAttributes = _numberOfNestedAttributes;
    }
  }
  */
  public class AttributeWithContext : Attribute{
    public string Filename = "<unknown>";
    public int StartLine = 0;
    public int StartColumn = 0;
    public int EndLine = 0;
    public int EndColumn = 0;
    public string SourceText = "";
    public AttributeWithContext(){}
    public AttributeWithContext(string filename, int startline, int startcol, int endline, int endcol)
    : this(filename, startline, startcol, endline, endcol, "")
    {}
    public AttributeWithContext(string filename, int startline, int startcol, int endline, int endcol, string sourceText){
      this.Filename = filename;
      this.StartLine = startline;
      this.StartColumn = startcol;
      this.EndLine = endline;
      this.EndColumn = endcol;
      this.SourceText = sourceText;
    }
  }
  [AttributeUsage(Microsoft.Contracts.SpecTargets.Code, AllowMultiple=false, Inherited = true)]
  public sealed class PureAttribute: Microsoft.Contracts.AttributeWithContext{
  }
  /*Diego's Attributes */
  [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
  public sealed class OnceAttribute : AttributeWithContext
  {
  }
  [AttributeUsage(SpecTargets.Code,AllowMultiple=false, Inherited = true)]
  public sealed class WriteConfinedAttribute: AttributeWithContext{
  }
    [AttributeUsage(SpecTargets.Code,AllowMultiple=false, Inherited = true)]
  public sealed class GlobalWriteAttribute: AttributeWithContext{
      public bool Value;
      GlobalWriteAttribute()
      {
          Value = true;
      }
      GlobalWriteAttribute(bool value)
      {
          this.Value = value;
      }

  }
    [AttributeUsage(SpecTargets.Code,AllowMultiple=false, Inherited = true)]
  public sealed class GlobalReadAttribute: AttributeWithContext{
      public bool Value;
      GlobalReadAttribute()
      {
          Value = true;
      }
      GlobalReadAttribute(bool value)
      {
          this.Value = value;
      }

  }
    [AttributeUsage(SpecTargets.Code, AllowMultiple = false, Inherited = true)]
    public sealed class GlobalAccessAttribute : AttributeWithContext
    {
        public bool Value;
        GlobalAccessAttribute()
        {
            Value = true;
        }
        GlobalAccessAttribute(bool value)
        {
            this.Value = value;
        }

    }
    [AttributeUsage(SpecTargets.Code | AttributeTargets.ReturnValue | AttributeTargets.Field | AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)]
  public sealed class FreshAttribute: AttributeWithContext{
  }
    [AttributeUsage(SpecTargets.Code | AttributeTargets.Parameter, AllowMultiple = true, Inherited = true)]
  public sealed class EscapesAttribute: AttributeWithContext{
      public bool Value;
      public bool Owned;
      public EscapesAttribute()
      {
          Value = false;
          Owned = false;
      }
      public EscapesAttribute(bool value)
      {
          this.Value = value;
          this.Owned = true;
      }
    public EscapesAttribute(bool value, bool own) {
      this.Value = value;
      this.Owned = own;
    }
  }
    /**/

  [AttributeUsage(SpecTargets.Code,AllowMultiple=false, Inherited = true)]
  public sealed class StateIndependentAttribute: AttributeWithContext{
  }
  [AttributeUsage(AttributeTargets.ReturnValue|AttributeTargets.Field|AttributeTargets.Parameter,AllowMultiple=true, Inherited = false)]
  public sealed class NotNullAttribute: AttributeWithContext{
  }
  [AttributeUsage(AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Parameter, AllowMultiple = false, Inherited = true)]
  public sealed class DelayedAttribute : AttributeWithContext {
  }
  [AttributeUsage(AttributeTargets.Constructor, AllowMultiple = false)]
  public sealed class NotDelayedAttribute : AttributeWithContext {
  }
  
  [AttributeUsage(SpecTargets.Containers, AllowMultiple = false, Inherited = false)]
  public sealed class NotNullGenericArgumentsAttribute : AttributeWithContext {
    public string PositionOfNotNulls;
    public NotNullGenericArgumentsAttribute(string positionOfNotNulls) {
      PositionOfNotNulls = positionOfNotNulls;
    }
  }
  [AttributeUsage(SpecTargets.CodeFieldsAndTheirContainers, AllowMultiple = false, Inherited = false)]
  public sealed class EncodedTypeSpecAttribute : AttributeWithContext {
    public int token;
    public EncodedTypeSpecAttribute(int token) {
      this.token = token;
    }
  }
  [AttributeUsage(AttributeTargets.Field)]
  public sealed class StrictReadonlyAttribute: Attribute{
  }
  [AttributeUsage(SpecTargets.CodeFieldsAndTheirContainers,AllowMultiple=false, Inherited = true)]
  public sealed class ModelAttribute: AttributeWithContext{
  }
  [AttributeUsage(SpecTargets.CodeFieldsAndTheirContainers,AllowMultiple=false, Inherited = true)]
  public sealed class SpecPublicAttribute: AttributeWithContext{
  }
  [AttributeUsage(SpecTargets.CodeFieldsAndTheirContainers,AllowMultiple=false, Inherited = true)]
  public sealed class SpecProtectedAttribute: AttributeWithContext{
  }
  [AttributeUsage(SpecTargets.CodeFieldsAndTheirContainers,AllowMultiple=false, Inherited = true)]
  public sealed class SpecInternalAttribute: AttributeWithContext{
  }

  /// <summary>
  /// Used to mark the beginning of contracts so that static verification can recognize them
  /// (either to ignore them or to treat them specially)
  /// </summary>
  public sealed class ContractMarkers {
    public static void BeginRequires() { }
    public static void EndRequires() { }
  }
  [AttributeUsage(SpecTargets.Code,AllowMultiple=true, Inherited = true)]
  public sealed class RequiresAttribute: AttributeWithContext{
    public string Requires;
    public RequiresAttribute(string _requires){
      Requires = _requires;
    }
    public RequiresAttribute(string _requires, string filename, int startline, int startcol, int endline, int endcol)
      : base(filename,startline,startcol,endline,endcol){
      Requires = _requires;
    }
    public RequiresAttribute(string _requires, string filename, int startline, int startcol, int endline, int endcol, string sourceText)
      : base(filename,startline,startcol,endline,endcol,sourceText){
      Requires = _requires;
    }
  }
  [AttributeUsage(SpecTargets.Code,AllowMultiple=true, Inherited = true)]
  public sealed class EnsuresAttribute: AttributeWithContext{
    public string Ensures;
    public EnsuresAttribute(string _ensures) {
      Ensures = _ensures;
    }
    public EnsuresAttribute(string _ensures, string filename, int startline, int startcol, int endline, int endcol)
      : base(filename,startline,startcol,endline,endcol){
      Ensures = _ensures;
    }
    public EnsuresAttribute(string _ensures, string filename, int startline, int startcol, int endline, int endcol, string sourceText)
      : base(filename,startline,startcol,endline,endcol,sourceText){
      Ensures = _ensures;
    }
}
  [AttributeUsage(SpecTargets.Code,AllowMultiple=true, Inherited = true)]
  public sealed class ModifiesAttribute: AttributeWithContext{
    public string Modifies;
    public ModifiesAttribute(string _modifies) {
      Modifies = _modifies;
    }
    public ModifiesAttribute(string _modifies, string filename, int startline, int startcol, int endline, int endcol)
      : base(filename,startline,startcol,endline,endcol){
      Modifies = _modifies;
    }
    public ModifiesAttribute(string _modifies, string filename, int startline, int startcol, int endline, int endcol, string sourceText)
      : base(filename,startline,startcol,endline,endcol,sourceText){
      Modifies = _modifies;
    }
  }
  [AttributeUsage(SpecTargets.Code, AllowMultiple = false, Inherited = false)]
  public sealed class HasWitnessAttribute : AttributeWithContext {
  }
  [AttributeUsage(SpecTargets.Code, AllowMultiple = false, Inherited = false)]
  public sealed class InferredReturnValueAttribute : AttributeWithContext {
    public string Value;
    public InferredReturnValueAttribute(string value) {
      this.Value = value;
    }
  }
  [AttributeUsage(SpecTargets.Code,AllowMultiple=true, Inherited = true)]
  public sealed class ThrowsAttribute: AttributeWithContext{
    public string Throws;
    public ThrowsAttribute(string _throws) {
      Throws = _throws;
    }
    public ThrowsAttribute(string _throws, string filename, int startline, int startcol, int endline, int endcol)
      : base(filename,startline,startcol,endline,endcol){
      Throws = _throws;
    }
    public ThrowsAttribute(string _throws, string filename, int startline, int startcol, int endline, int endcol, string sourceText)
      : base(filename,startline,startcol,endline,endcol,sourceText){
      Throws = _throws;
    }
  }
  [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property,AllowMultiple=true, Inherited = false)]
  public sealed class DoesAttribute: AttributeWithContext{
    public string Does;
    public DoesAttribute(string _does) {
      Does = _does;
    }
    public DoesAttribute(string _does, string filename, int startline, int startcol, int endline, int endcol)
      : base(filename,startline,startcol,endline,endcol){
      Does = _does;
    }
    public DoesAttribute(string _does, string filename, int startline, int startcol, int endline, int endcol, string sourceText)
      : base(filename,startline,startcol,endline,endcol,sourceText){
      Does = _does;
    }
  }




  [AttributeUsage(SpecTargets.Containers,AllowMultiple=true, Inherited = true)]
  public sealed class InvariantAttribute: AttributeWithContext{
    public string Invariant;
    public InvariantAttribute(string _invariant) {
      Invariant = _invariant;
    }
    public InvariantAttribute(string _invariant, string filename, int startline, int startcol, int endline, int endcol) {
      Invariant = _invariant;
      Filename = filename;
      StartLine = startline;
      StartColumn = startcol;
      EndLine = endline;
      EndColumn = endcol;
    }
  }
  
  [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false, Inherited = false)]
  public sealed class ShadowsAssemblyAttribute : System.Attribute{
    //TODO: we really want a single argument that provides a complete name and then construct an AssemblyReference from it.
    //TODO: make the Spec# compiler aware of this attribute so that it can check that the argument really is a strong name.
    public string PublicKey;
    public string Version;
    public string Name; 
    public ShadowsAssemblyAttribute(string publicKey, string version, string name) {PublicKey=publicKey; Version=version; Name=name;}
  }
  #endregion Attributes
}

#if CCINamespace
namespace Microsoft.Cci.TypeExtensions {
#else
namespace System.Compiler.TypeExtensions {
#endif
}

#if CCINamespace
namespace Microsoft.Cci {
#else
namespace System.Compiler {
#endif
  /// <summary>
  /// This attribute marks a template parameter T as being instantiable only with unmanaged structs
  /// thereby allowing types such as T* in the generic code.
  /// It needs to be present under Everett and Whidbey, since MSIL 2.0 does not have a way to encode
  /// this AFAIK.
  /// </summary>
  [AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Struct)]
  public sealed class UnmanagedStructTemplateParameterAttribute : System.Attribute
  {
  }

}

namespace Microsoft.Contracts{
#if CCINamespace
  using Microsoft.Cci;
#endif
  using System.Collections;
  using System.Threading;

  /// <summary>
  /// Called by a <see cref="Guard"/> object to initialize its <i>guard sets</i>.
  /// </summary>
  /// <remarks>
  /// This delegate should not call any methods other than
  /// <see cref="Guard.AddRep"/>,
  /// <see cref="Guard.AddRepObject"/>,
  /// <see cref="Guard.AddImmutableCertificate"/>,
  /// <see cref="Guard.AddObjectImmutableCertificate"/>,
  /// <see cref="Guard.AddLockProtectedCertificate"/>, and
  /// <see cref="Guard.AddObjectLockProtectedCertificate"/>.
  /// </remarks>
  public delegate void InitGuardSetsDelegate();
  // TODO: Remove once the LKG compiler uses CheckInvariantDelegate.
  public delegate bool InvariantHoldsDelegate();
  /// <summary>
  /// Called by a <see cref="Guard"/> object to check that its invariant holds, when it ends writing.
  /// </summary>
  /// <param name="throwException">If true and the invariant does not hold, throws an exception. If false and the invariant does not hold, returns false.</param>
  public delegate bool CheckInvariantDelegate(bool throwException);
  /// <summary>
  /// Called by the <see cref="Guard.AcquireForReading"/> and <see cref="Guard.AcquireForWriting"/> methods
  /// to decide whether to return or to wait.
  /// </summary>
  public delegate bool ThreadConditionDelegate();
  /// <summary>
  /// Called by the <see cref="System.Threading.ThreadStart"/> delegate returned by the
  /// <see cref="Guard.CreateThreadStart"/> method.
  /// </summary>
  public delegate void GuardThreadStart();
  /// <summary>
  /// Delegate that grants access to the frame guards of the objects of a particular type.
  /// </summary>
  /// <param name="o">Object whose frame guard to return</param>
  /// <returns>The frame guard of <paramref name="o"/></returns>
  [return:NotNull]
  public delegate Guard FrameGuardGetter(object o);
  /// <summary>
  /// Thrown by a <see cref="Guard"/> object whenever a race condition, an ownership violation, or an invariant violation is
  /// detected.
  /// </summary>
  public class GuardException : Exception {
    public GuardException() {}
    public GuardException(string message) : base(message) {}
  }

  /// <summary>
  /// Indicates the capability of a thread with respect to a guard (and the resource it protects).
  /// </summary>
  public enum ThreadCapability{
    /// <summary>
    /// The thread cannot access the resource.
    /// </summary>
    None,
    /// <summary>
    /// The thread can read the resource.
    /// </summary>
    Readable,
    /// <summary>
    /// The thread can read and write the resource.
    /// </summary>
    Writable
  }
  /// <summary>
  /// Indicates the activity being performed by a thread on a guard (and the resource it protects).
  /// </summary>
  public enum ThreadActivity{
    /// <summary>
    /// The thread is not acting on the resource.
    /// </summary>
    None,
    /// <summary>
    /// The thread is reading the resource.
    /// </summary>
    Reading,
    /// <summary>
    /// The thread is writing the resource.
    /// </summary>
    Writing
  }
  /// <summary>
  /// Indicates how a thread shares a guard (and the resource it protects).
  /// </summary>
  public enum SharingMode{
    /// <summary>
    /// The thread does not share the resource.
    /// </summary>
    /// <remarks>
    /// Either the object itself is unshared, or the object is shared but not with the thread.
    /// </remarks>
    Unshared,
    /// <summary>
    /// The thread shares the lock-protected resource.
    /// </summary>
    LockProtected,
    /// <summary>
    /// The thread shares the immutable resource.
    /// </summary>
    Immutable
  }
  /// <summary>
  /// Helps guard an object or other resource against race conditions, enforce ownership, and enforce invariants.
  /// </summary>
  public sealed class Guard {
    sealed class Commitment {
      private Guard outer;
      public Guard owner;

      internal Commitment(Guard outer, Guard owner){
        this.outer = outer;
        this.owner = owner;
      }

      public void Release(){
        LocalData locals = outer.Locals;
        outer.owner = null;
        locals.Capability = ThreadCapability.Writable;
        outer = null;
      }
    }
    sealed class RepFrame{
      public Guard/*!*/ frame;
      public Commitment commitment;

      public RepFrame(Guard/*!*/ frame) {
        this.frame = frame;
        //^ base();
      }

      public void Commit(Guard/*!*/ owner) {
        commitment = frame.Commit(owner);
      }

      public void Release(){
        commitment.Release();
        commitment = null;
      }
    }

    sealed class LocalData {
      public SharingMode SharingMode;
      public ThreadCapability Capability;
      public ThreadActivity Activity;
      public override string ToString() {
        return "<" + this.SharingMode.ToString() + "," + this.Capability.ToString() + "," + this.Activity.ToString() + ">";
      }

    }

    sealed class Scheduler {
      bool writerActive;
      int activeReaderCount;
      QueueEntry nextWriter;
      /// <summary>
      /// The queue of entries that will be re-evaluated after the next ReleaseForWriting.
      /// </summary>
      Queue queue = new Queue();

      // invariant writerActive ==> (activeReaderCount == 0 && nextWriter == null);
      // invariant (!writerActive && nextWriter != null) ==> activeReaderCount != 0;
      // The following invariants assume that IsEnabled changes only when writerActive.
      // invariant nextWriter != null ==> nextWriter.IsEnabled; 
      // invariant (!writerActive && nextWriter == null) ==> forall(QueueEntry e in queue; !e.IsReader ==> !e.IsEnabled);

      sealed class QueueEntry {
        public readonly bool IsReader;
        readonly ThreadConditionDelegate condition;
        bool runnable;

        public QueueEntry(bool reader, ThreadConditionDelegate condition){
          this.IsReader = reader;
          this.condition = condition;
        }

        public bool IsEnabled {
          get {
            return condition == null || condition();
          }
        }

        public void Run(){
          lock (this){
            runnable = true;
            Monitor.Pulse(this);
          }
        }

        public void Wait(){
          lock (this){
            while (!runnable)
              Monitor.Wait(this);
          }
        }
      }

      public void AcquireForReading(ThreadConditionDelegate condition){
        QueueEntry entry = new QueueEntry(true, condition);
        lock (this){
          if (writerActive || nextWriter != null || !entry.IsEnabled){
            // This reader will get a chance after the next ReleaseForWriting
            queue.Enqueue(entry);
          } else {
            activeReaderCount++;
            entry.Run();
          }
        }
        entry.Wait();
      }

      public void AcquireForWriting(ThreadConditionDelegate condition){
        QueueEntry entry = new QueueEntry(false, condition);
        lock (this){
          if (writerActive || nextWriter != null || !entry.IsEnabled){
            // This writer will get a chance after the next ReleaseForWriting
            queue.Enqueue(entry);
          } else if (activeReaderCount == 0){
            writerActive = true;
            entry.Run();
          } else {
            nextWriter = entry;
          }
        }
        entry.Wait();
      }

      public void ReleaseForReading(){
        lock (this){
          activeReaderCount--;
          if (activeReaderCount == 0 && nextWriter != null){
            nextWriter.Run();
            writerActive = true;
            nextWriter = null;
          }
        }
      }

      public void ReleaseForWriting(){
        lock (this){
          writerActive = false;
          Queue newQueue = new Queue();
          while (queue.Count > 0){
            QueueEntry entry = (QueueEntry/*!*/)queue.Dequeue();
            if (entry.IsReader && entry.IsEnabled){
              activeReaderCount++;
              entry.Run();
            } else if (!entry.IsReader && nextWriter == null && entry.IsEnabled){
              nextWriter = entry;
            } else {
              newQueue.Enqueue(entry);
            }
          }
          queue = newQueue;
          if (activeReaderCount == 0 && nextWriter != null){
            nextWriter.Run();
            writerActive = true;
            nextWriter = null;
          }
        }
      }
    }

    readonly InitGuardSetsDelegate initFrameSets;
    readonly CheckInvariantDelegate checkInvariant;
    Scheduler scheduler;
    readonly Hashtable/*!*/ repFrames = new Hashtable();
    readonly Hashtable/*!*/ sharedFrames = new Hashtable();
    /// <summary>
    /// Thread-local data indicating the sharing mode, the capability and the activity of the current thread with respect
    /// to this object.
    /// </summary>
    readonly LocalDataStoreSlot localData = Thread.AllocateDataSlot();
    object owner;

    class InvariantHoldsAdaptor{
      InvariantHoldsDelegate invariantHolds;

      public InvariantHoldsAdaptor(InvariantHoldsDelegate invariantHolds){
        this.invariantHolds = invariantHolds;
      }

      public bool CheckInvariant(bool throwException){
        if (!invariantHolds())
          if (throwException)
            throw new Microsoft.Contracts.ObjectInvariantException();
          else
            return false;
        return true;
      }
    }

    // TODO: Remove once the LKG uses the other constructor.
    public Guard([Delayed] InitGuardSetsDelegate initGuardSets, [Delayed] InvariantHoldsDelegate invariantHolds)
      : this(initGuardSets, new CheckInvariantDelegate(new InvariantHoldsAdaptor(invariantHolds).CheckInvariant))
    {
    }

    /// <summary>
    /// Creates a new guard object.
    /// </summary>
    /// <remarks>
    /// Initially, the object is unshared;
    /// the current thread can write and is writing the guard;
    /// and no other thread can access the guard.
    /// </remarks>
    /// <param name="initGuardSets">A delegate that is called to initialize the guard's <i>guard sets</i>.</param>
    /// <param name="checkInvariant">A delegate that is called to check the guard's invariant.</param>
    public Guard([Delayed] InitGuardSetsDelegate initGuardSets, [Delayed] CheckInvariantDelegate checkInvariant){
      this.initFrameSets = initGuardSets;
      this.checkInvariant = checkInvariant;
      LocalData locals = Locals;
      locals.Capability = ThreadCapability.Writable;
      locals.Activity = ThreadActivity.Writing;
    }

    LocalData/*!*/ Locals {
      get {
        LocalData locals;
        object o = Thread.GetData(localData);
        if (o == null) {
          locals = new LocalData();
          Thread.SetData(localData, locals);
        } else
          locals = (LocalData) o;
        return locals;
      }
    }

    /// <summary>
    /// Returns true if the current thread can read the resource; otherwise, returns false.
    /// </summary>
    /// <remarks>
    /// Equivalent to <c>Capability != ThreadCapability.None</c>.
    /// </remarks>
    public bool CanRead {
      get {
        return Locals.Capability != ThreadCapability.None;
      }
    }

    /// <summary>
    /// Returns true if the current thread can write the resource; otherwise, returns false.
    /// </summary>
    /// <remarks>
    /// Equivalent to <c>Capability == ThreadCapability.Writable</c>.
    /// </remarks>
    public bool CanWrite {
      get {
        return Locals.Capability == ThreadCapability.Writable;
      }
    }

    /// <summary>
    /// Returns true if the current thread is reading or writing the resource; otherwise, returns false.
    /// </summary>
    /// <remarks>
    /// Equivalent to <c>Activity != ThreadActivity.None</c>.
    /// </remarks>
    public bool IsActive {
      get {
        return Locals.Activity != ThreadActivity.None;
      }
    }

    public void CheckIsReading(){
      if (Locals.Activity == ThreadActivity.None)
        throw new GuardException("Thread is not reading object.");
    }

    public void CheckIsWriting(){
      if (Locals.Activity != ThreadActivity.Writing)
        throw new GuardException("Thread is not writing object.");
    }

    /// <summary>
    /// Returns the current thread's sharing mode for the resource.
    /// </summary>
    public SharingMode SharingMode {
      get {
        return Locals.SharingMode;
      }
    }

    /// <summary>
    /// Returns the current thread's capability with respect to the resource.
    /// </summary>
    public ThreadCapability Capability {
      get {
        return Locals.Capability;
      }
    }

    /// <summary>
    /// Returns the current thread's activity with respect to the resource.
    /// </summary>
    public ThreadActivity Activity {
      get {
        return Locals.Activity;
      }
    }

    /// <summary>
    /// Starts reading the resource.
    /// </summary>
    public void StartReading(){
      LocalData locals = Locals;
      if (locals.Capability == ThreadCapability.None)
        throw new GuardException("Object is not readable by current thread.");
      if (locals.Activity != ThreadActivity.None)
        throw new GuardException("Thread is already reading or writing object.");
      RegisterSharedFrames();
      locals.Activity = ThreadActivity.Reading;
      foreach (RepFrame repFrame in repFrames.Values)
        repFrame.frame.Locals.Capability = ThreadCapability.Readable;
    }

    /// <summary>
    /// Starts reading the resource; starts reading any transitive owners as necessary.
    /// </summary>
    /// <returns>The furthest transitive owner that was not yet reading.</returns>
    [return:Microsoft.Contracts.NotNull]
    public Guard StartReadingTransitively(){
      Guard rootFrame;
      Commitment commitment = owner as Commitment;
      if (commitment != null)
        rootFrame = commitment.owner.StartReadingTransitively();
      else
        rootFrame = this;
      StartReading();
      return rootFrame;
    }

    /// <summary>
    /// Ends reading the resource.
    /// </summary>
    public void EndReading(){
      EndReading(false);
    }

    /// <summary>
    /// Ends reading the resource; ends reading any transitive owned resources as necessary.
    /// </summary>
    public void EndReadingTransitively(){
      EndReading(true);
    }

    void EndReading(bool transitively){
      LocalData locals = Locals;
      if (locals.Activity != ThreadActivity.Reading)
        throw new GuardException("Thread is not reading object.");
      foreach (RepFrame repFrame in repFrames.Values)
        if (repFrame.frame.Locals.Activity == ThreadActivity.Reading)
          if (transitively)
            repFrame.frame.EndReading(true);
          else
            throw new GuardException("Thread is still reading an owned object.");
      foreach (RepFrame repFrame in repFrames.Values)
        repFrame.frame.Locals.Capability = ThreadCapability.None;
      locals.Activity = ThreadActivity.None;
    }

    /// <summary>
    /// Ends writing the resource.
    /// </summary>
    [Delayed] // This [Delayed] tag isn't actually verifiable, but we believe it does hold here.
    public void EndWriting(){
      EndWriting(false, false);
    }

    [Pure]
    public bool CanStartWriting{
      get {
        LocalData locals = Locals;
        if (locals.Capability != ThreadCapability.Writable)
          return false;
        if (locals.Activity != ThreadActivity.None)
          return false;
        return true;
      }
    }
    [Pure]
    public bool CheckCanStartWriting(){
      LocalData locals = Locals;
      if (locals.Capability != ThreadCapability.Writable)
        throw new GuardException("Object is not writable by current thread.");
      if (locals.Activity != ThreadActivity.None)
        throw new GuardException("Thread is already reading or writing the object.");
      return true;
    }
    [Pure]
    public bool CanStartWritingTransitively{
      get {
        if (this.CanStartWriting)
          return true;
        Commitment commitment = owner as Commitment;
        if (commitment != null)
          return commitment.owner.CanStartWritingTransitively;
        else
          return false;
      }
    }

    #region Unpack/Pack methods
    /// <summary>
    /// Starts writing the resource; starts writing any transitive owners as necessary.
    /// </summary>
    /// <returns>The furthest transitive owner that was not yet writing.</returns>
    /// 
    [return:Microsoft.Contracts.NotNull]
    public Guard/*!*/ StartWritingTransitively(){
      Guard rootFrame;
      Commitment commitment = owner as Commitment;
      if (commitment != null)
        rootFrame = commitment.owner.StartWritingTransitively();
      else
        rootFrame = this;
      StartWriting();
      return rootFrame;
    }
    /// <summary>
    /// Ends writing the resource; ends writing any transitive reps as necessary.
    /// </summary>
    public void EndWritingTransitively() {
      EndWriting(true, false);
    }

    /// <summary>
    /// Starts writing the resource.
    /// </summary>
    public void StartWriting() {
      //      Console.WriteLine("StartWriting: " + locals.ToString());
      CheckCanStartWriting();
      RegisterSharedFrames();
      Locals.Activity = ThreadActivity.Writing;
      foreach (RepFrame repFrame in repFrames.Values)
        repFrame.Release();
      repFrames.Clear();
      sharedFrames.Clear();
    }
    void EndWriting(bool transitively, bool reflexively) {
      LocalData locals = Locals;
      if (locals.Activity != ThreadActivity.Writing)
        if (reflexively)
          return;
        else
          throw new GuardException("Thread is not writing object.");
      repFrames.Clear();
      sharedFrames.Clear();
      initFrameSets();
      if (transitively)
        foreach (RepFrame repFrame in repFrames.Values)
          repFrame.frame.EndWriting(true, true);
      checkInvariant(true);
      foreach (RepFrame repFrame in repFrames.Values)
        repFrame.Commit(this);
      locals.Activity = ThreadActivity.None;
    }

    public static void StartWritingFrame([NotNull] object o, [NotNull] Type t) { }
    public static void EndWritingFrame([NotNull] object o, [NotNull] Type t) { }

    // The next two pairs of methods are for use when an object is being exposed at
    // one particular type, *without* being unpacked at all subtypes (which is how
    // the "normal" unpacking is done).

    // The first pair, WritingAtNop, is for those occurrences where nothing
    // should be done at runtime, but downstream tools may still need to know
    // that the object is being unpacked.
    public static void StartWritingAtNop([NotNull] object o, [NotNull] Type t) { }
    public static void EndWritingAtNop([NotNull] object o, [NotNull] Type t) { }

    // The second pair, WritingAtTransitively, behaves at runtime just as WritingTransitively,
    // but it knows to not check the invariant for any subtype below t.
    [return: Microsoft.Contracts.NotNull]
    public Guard/*!*/ StartWritingAtTransitively([NotNull] Type t) { return this.StartWritingTransitively(); }
    public void EndWritingAtTransitively([NotNull] Type t) { this.EndWriting(true, false); }
    #endregion Unpack/Pack methods

    /// <summary>
    /// Commits the resource.
    /// </summary>
    /// <param name="owner">The new owner.</param>
    /// <returns>A new commitment.</returns>
    /// <remarks>
    /// A thread that calls this method afterwards no longer has access to the object.
    /// Any thread can gain access to the object by calling the <see cref="Commitment.Release"/> method on the new commitment.
    /// </remarks>
    Commitment Commit(Guard/*!*/ owner) {
      LocalData locals = Locals;
      if (locals.Capability != ThreadCapability.Writable)
        throw new GuardException("Object is not writable by current thread.");
      if (locals.SharingMode != SharingMode.Unshared)
        throw new GuardException("Object is shared.");
      if (locals.Activity != ThreadActivity.None)
        throw new GuardException("Thread is still reading or writing object.");
      Commitment commitment = new Commitment(this, owner);
      this.owner = commitment;
      locals.Capability = ThreadCapability.None;
      return commitment;
    }

    /// <summary>
    /// Adds a resource to this guard's set of <i>reps</i>.
    /// </summary>
    /// <param name="rep">The resource being added.</param>
    /// <remarks>
    /// When a guard ends writing, it gains ownership of its reps.
    /// </remarks>
    public void AddRep(Guard/*!*/ rep) {
      LocalData locals = Locals;
      if (locals.Activity != ThreadActivity.Writing)
        throw new GuardException("Thread is not writing the object.");
      repFrames[rep] = new RepFrame(rep);
    }

    /// <summary>
    /// Adds an object to this guard's set of <i>reps</i>.
    /// </summary>
    /// <param name="repObject">The object being added.</param>
    /// <remarks>
    /// If <paramref name="repObject"/> is not a guarded object, the method does nothing.
    /// </remarks>
    public void AddRepObject(object repObject){
      if (repObject == null) return;
      Guard g = Guard.GetObjectGuard(repObject);
      if (g != null)
        AddRep(g);
    }

    /// <summary>
    /// Adds a frame to this guard's set of <i>reps</i>.
    /// </summary>
    /// <remarks>
    /// If <paramref name="repObject"/> is not a guarded object, the method does nothing.
    /// </remarks>
    public void AddRepFrame(object o, Type t){
      Guard g = Guard.GetFrameGuard(o, t);
      if (g != null)
        AddRep(g);
    }

    /// <summary>
    /// Turns this unshared resource into a lock-protected resource.
    /// </summary>
    /// <remarks>
    /// When this method returns, only the current thread shares the resource.
    /// Share the resource with other threads using
    /// the <see cref="AddLockProtectedCertificate"/> method
    /// or
    /// the <see cref="CreateThreadStartForLockProtected"/> method.
    /// </remarks>
    public void ShareLockProtected(){
      Share(SharingMode.LockProtected);
    }

    /// <summary>
    /// Turns the unshared resource into an immutable resource.
    /// </summary>
    /// <remarks>
    /// When this method returns, only the current thread shares the resource.
    /// Share the resource with other threads using
    /// the <see cref="AddImmutableCertificate"/> method
    /// or the <see cref="CreateThreadStartForImmutable"/> method.
    /// </remarks>
    public void ShareImmutable(){
      Share(SharingMode.Immutable);
    }

    void Share(SharingMode mode){
      LocalData locals = Locals;
//      Console.WriteLine("Share: " + locals.ToString() + ", asked to share as: " + mode.ToString());
      if (mode != SharingMode.Unshared && locals.SharingMode == mode)
        return;
      if (locals.Capability != ThreadCapability.Writable)
        throw new GuardException("Object is not writable by the current thread.");
      if (locals.Activity != ThreadActivity.None)
        throw new GuardException("Thread is still reading or writing the object.");
      if (locals.SharingMode != SharingMode.Unshared)
        throw new GuardException("Object is already shared.");
      locals.SharingMode = mode;
      switch (mode){
        case SharingMode.LockProtected:
          locals.Capability = ThreadCapability.None;
          scheduler = new Scheduler();
          break;
        case SharingMode.Unshared:
          locals.Capability = ThreadCapability.None;
          break;
        default:
          // assert mode == SharingMode.Immutable;
          locals.Capability = ThreadCapability.Readable;
          break;
      }
//      Console.WriteLine("Share: local state now: " + locals.ToString());
    }

    /// <summary>
    /// Acquires exclusive access to this resource.
    /// </summary>
    /// <param name="condition">If not null, indicates when the thread can acquire the resource.</param>
    public void AcquireForWriting(ThreadConditionDelegate condition){
      LocalData locals = Locals;
      if (locals.SharingMode != SharingMode.LockProtected)
        throw new GuardException("Object is not lock-protected.");
      if (locals.Capability != ThreadCapability.None)
        throw new GuardException("Thread has already acquired the object.");
      locals.Capability = ThreadCapability.Readable; // Allow condition code to read the object.
      scheduler.AcquireForWriting(condition);
      locals.Capability = ThreadCapability.Writable;
    }

    /// <summary>
    /// Relinquishes exclusive access to this resource.
    /// </summary>
    public void ReleaseForWriting(){
      LocalData locals = Locals;
      if (locals.SharingMode != SharingMode.LockProtected)
        throw new GuardException("Object is not lock-protected.");
      if (locals.Capability != ThreadCapability.Writable)
        throw new GuardException("Thread has not acquired the object for writing.");
      if (locals.Activity != ThreadActivity.None)
        throw new GuardException("Thread is still reading or writing the object.");
      locals.Capability = ThreadCapability.Readable; // Allow condition code to read the object.
      scheduler.ReleaseForWriting();
      locals.Capability = ThreadCapability.None;
    }

    /// <summary>
    /// Acquires read access to this resource.
    /// </summary>
    /// <param name="condition">If not null, indicates when the thread can acquire the resource.</param>
    public void AcquireForReading(ThreadConditionDelegate condition){
      LocalData locals = Locals;
      if (locals.SharingMode != SharingMode.LockProtected)
        throw new GuardException("Object is not lock-protected.");
      if (locals.Capability != ThreadCapability.None)
        throw new GuardException("Thread has already acquired the object.");
      locals.Capability = ThreadCapability.Readable; // Allow condition code to read the object.
      scheduler.AcquireForReading(condition);
    }

    /// <summary>
    /// Relinquishes read access to this resource.
    /// </summary>
    public void ReleaseForReading(){
      LocalData locals = Locals;
      if (locals.SharingMode != SharingMode.LockProtected)
        throw new GuardException("Object is not lock-protected.");
      if (locals.Capability != ThreadCapability.Readable)
        throw new GuardException("Thread has not acquired the object for reading.");
      if (locals.Activity != ThreadActivity.None)
        throw new GuardException("Thread is still reading the object.");
      scheduler.ReleaseForReading();
      locals.Capability = ThreadCapability.None;
    }

    /// <summary>
    /// Adds a resource to this guard's set of <i>lock-protected certificates</i>.
    /// </summary>
    /// <param name="guard">The resource being added.</param>
    /// <remarks>
    /// When a thread subsequently starts reading or writing this guard,
    /// the resource is shared with the thread.
    /// </remarks>
    public void AddLockProtectedCertificate(Guard/*!*/ guard) {
      AddSharedFrame(guard, SharingMode.LockProtected);
    }

    /// <summary>
    /// Adds a resource to this guard's set of <i>immutable certificates</i>.
    /// </summary>
    /// <param name="guard">The resource being added.</param>
    /// <remarks>
    /// When a thread subsequently starts reading or writing this guard,
    /// the resource is shared with the thread.
    /// </remarks>
    public void AddImmutableCertificate(Guard/*!*/ guard) {
      AddSharedFrame(guard, SharingMode.Immutable);
    }

    void AddSharedFrame(Guard/*!*/ frame, SharingMode mode) {
      frame.Share(mode);
      LocalData locals = Locals;
      if (locals.Activity != ThreadActivity.Writing)
        throw new GuardException("Thread is not writing the object.");
      sharedFrames[frame] = mode;
    }

    /// <summary>
    /// Stores a certificate for a lock-protected object.
    /// Does nothing if the object is not guarded.
    /// </summary>
    /// <param name="sharedObject">The object for which a certificate is stored.</param>
    /// <seealso cref="AddLockProtectedCertificate"/>
    public void AddObjectLockProtectedCertificate(object sharedObject){
      if (sharedObject == null) return;
      Guard g = Guard.GetObjectGuard(sharedObject);
      if (g != null)
        AddLockProtectedCertificate(g);
    }

    /// <summary>
    /// Stores a certificate for an immutable object.
    /// Does nothing if the object is not guarded.
    /// </summary>
    /// <param name="sharedObject">The object for which a certificate is stored.</param>
    /// <seealso cref="AddLockProtectedCertificate"/>
    public void AddObjectImmutableCertificate(object sharedObject){
      if (sharedObject == null) return;
      Guard g = Guard.GetObjectGuard(sharedObject);
      if (g != null)
        AddImmutableCertificate(g);
    }

    void RegisterSharingMode(SharingMode mode){
      LocalData sharedFrameLocals = Locals;
      sharedFrameLocals.SharingMode = mode;
      if (mode == SharingMode.Immutable)
        sharedFrameLocals.Capability = ThreadCapability.Readable;
      else if (mode == SharingMode.Unshared)
        sharedFrameLocals.Capability = ThreadCapability.Writable;
    }

    void RegisterSharedFrames(){
      foreach (DictionaryEntry entry in sharedFrames){
        Guard sharedFrame = (Guard)entry.Key;
        //^ assume sharedFrame != null;
        object value = entry.Value;
        if (value == null) continue;
        SharingMode mode = (SharingMode)value;
        sharedFrame.RegisterSharingMode(mode);
      }
    }

    class ThreadStartTarget{
      Guard frame;
      GuardThreadStart threadStart;
      SharingMode sharingMode;

      public ThreadStartTarget(Guard frame, GuardThreadStart threadStart, SharingMode sharingMode){
        this.frame = frame;
        this.threadStart = threadStart;
        this.sharingMode = sharingMode;
      }

      public void Start(){
        if (this.frame == null){
          // this makes Start() non-re-entrant
          throw new GuardException("Start() method can be called at most once.");
        }
        frame.RegisterSharingMode(sharingMode);
        this.frame = null;
        threadStart();
      }
    }

    ThreadStart CreateThreadStart(GuardThreadStart threadStart, SharingMode sharingMode){
      Share(sharingMode);
      return new ThreadStart(new ThreadStartTarget(this, threadStart, sharingMode).Start);
    }
  
    /// <summary>
    /// Use this method to share the resource with a new thread.
    /// </summary>
    /// <param name="threadStart">A method to be executed by the new sharing thread.</param>
    /// <returns>A delegate that shares the resource with the thread calling it (which is typically a newly started thread)
    /// and then calls <paramref name="threadStart"/>.</returns>
    public ThreadStart CreateThreadStartForImmutable(GuardThreadStart threadStart){
      return CreateThreadStart(threadStart, SharingMode.Immutable);
    }

    /// <summary>
    /// Use this method to share the resource with a new thread.
    /// </summary>
    /// <param name="threadStart">A method to be executed by the new sharing thread.</param>
    /// <returns>A delegate that shares the resource with the thread calling it (which is typically a newly started thread)
    /// and then calls <paramref name="threadStart"/>.</returns>
    public ThreadStart CreateThreadStartForLockProtected(GuardThreadStart threadStart){
      return CreateThreadStart(threadStart, SharingMode.LockProtected);
    }
    /// <summary>
    /// Use this method to transfer the resource to a new thread.
    /// </summary>
    /// <param name="threadStart">A method to be executed by the new standalone thread.</param>
    /// <returns>A delegate that transfers the resource to the thread calling it (which is typically a newly started thread)
    /// and then calls <paramref name="threadStart"/>.</returns>
    public ThreadStart CreateThreadStartForOwn(GuardThreadStart threadStart){
//      Console.WriteLine("CreateThreadStartForOwn: " + threadStart.ToString());
      return CreateThreadStart(threadStart, SharingMode.Unshared);
    }

    /// <summary>
    /// Holds the frame guard getter delegates of the guarded classes loaded into the AppDomain.
    /// </summary>
    /// <remarks>
    /// Lock this object to access it.
    /// </remarks>
    static readonly Hashtable/*<Type,FrameGuardGetter!>!*/ frameGuardGetters = new Hashtable();

    public static void RegisterGuardedClass(Type t, FrameGuardGetter getter) {
      if (getter == null)
        throw new ArgumentNullException("getter");
#if !SINGULARITY
      if (System.Reflection.Assembly.GetCallingAssembly() != t.Assembly)
        throw new ArgumentException("An assembly can register only its own types.");
#endif
      lock (frameGuardGetters) {
        frameGuardGetters.Add(t, getter);
      }
    }

    /// <summary>
    /// Returns the frame guard of object <paramref name="o"/> at type <paramref name="t"/>,
    /// or <code>null</code> if <paramref name="t"/> is not a guarded class.
    /// </summary>
    public static Guard GetFrameGuard([NotNull] object o, [NotNull] Type t){
      FrameGuardGetter getter;
      // The Hashtable documentation allows one writer and multiple readers to access a non-synchronized Hashtable concurrently.
      // See the documentation for the System.Collections.Hashtable.Synchronized method.
      getter = (FrameGuardGetter)frameGuardGetters[t];
      return getter == null ? null : getter(o);
    }

    /// <summary>
    /// Returns the guard of object <paramref name="o"/>, or
    /// <code>null</code> if <paramref name="o"/> is not guarded.
    /// </summary>
    public static Guard GetObjectGuard([NotNull] object o){
      Type t = o.GetType();
      while (t != null){
        Guard guard = GetFrameGuard(o, t);
        if (guard != null)
          return guard;
        t = t.BaseType;
      }
      return null;
    }

    [Pure]
    public static bool IsConsistent([NotNull] object o){
      Guard objectGuard = GetObjectGuard(o);
      if (objectGuard != null){
        return objectGuard.CanStartWriting;
      }else{
        return true; // Objects that do not have an invariant are always consistent.
      }
    }

    [Pure]
    public static bool IsPeerConsistent([NotNull] object o){
      return IsConsistent(o);
    }

    [Pure]
    public bool IsExposable{
      get{
        return this.CanStartWritingTransitively;
      }
    }

    [Pure]
    public static bool FrameIsExposable([NotNull] object o, [NotNull] Type t){
      Guard guard = GetFrameGuard(o, t);
      return guard == null ? true : guard.IsExposable;
    }

    [Pure]
    public static bool BaseIsConsistent([NotNull] object o, [NotNull] Type t){
      // System.Reflection does not seem to allow one to express a base call; this is a workaround.
      return FrameIsExposable(o, t.BaseType);
    }

    [Pure]
    public bool IsExposed{
      get{
        return this.Activity == ThreadActivity.Writing;
      }
    }

    [Pure]
    public static bool FrameIsExposed([NotNull] object o, [NotNull] Type t){
      Guard guard = GetFrameGuard(o, t);
      return guard == null ? true : guard.IsExposed;
    }

    [Pure]
    public bool IsPrevalid{
      get{
        LocalData locals = Locals;
        if (locals.Activity != ThreadActivity.Writing)
          return false;
        repFrames.Clear();
        sharedFrames.Clear();
        initFrameSets();
        foreach (RepFrame repFrame in repFrames.Values)
          if (!repFrame.frame.IsExposable)
            return false;
        return true;
      }
    }

    [Pure]
    public static bool FrameIsPrevalid([NotNull] object o, [NotNull] Type t){
      Guard guard = GetFrameGuard(o, t);
      return guard == null ? true : guard.IsPrevalid;
    }

    [Pure]
    public bool IsValid{
      get{
        return this.IsPrevalid && this.checkInvariant(false);
      }
    }

    [Pure]
    public static bool FrameIsValid([NotNull] object o, [NotNull] Type t){
      Guard guard = GetFrameGuard(o, t);
      return guard == null ? true : guard.IsValid;
    }

    public static void ShareLockProtected([NotNull] object o){
      Guard guard = GetObjectGuard(o);
      if (guard != null)
        guard.ShareLockProtected();
    }

    [Pure]
    public static bool IsLockProtected(object o){
      Guard g = GetObjectGuard(o);
      return g != null ? g.SharingMode == SharingMode.LockProtected : true;
    }

    [Confined]
    public static void ModifiesObject(object o){}
    [Confined]
    public static void ModifiesArray(object o) { }
    [Pure]
    public static void ModifiesPeers(object o) { }
    [Pure]
    public static void ModifiesNothing(object o) { }

    /// <summary>
    /// In a method's ensures clause, indicates that <paramref name="o"/> was not allocated in the pre-state.
    /// Note: this is a temporary measure that will be replaced with a more modular construct in the future.
    /// </summary>
    [Confined]
    public static bool IsNew(object o) { return true; }

    /// <summary>
    /// Used in the Boogie bytecode translator.
    /// </summary>
    public static void NoOp(){}
  }
}

namespace Microsoft.Contracts{
#if CCINamespace
  using Microsoft.Cci;
#endif
  /// <summary>
  /// Indicates that the field refers to a lock-protected object.
  /// </summary>
  /// <remarks>
  /// This attribute causes the Spec# compiler to emit a call to the <see cref="Microsoft.Contracts.Guard.AddObjectLockProtectedCertificate"/>
  /// method in its <see cref="Microsoft.Contracts.InitGuardSetsDelegate"/> implementation.
  /// </remarks>
  [AttributeUsage(AttributeTargets.Field|AttributeTargets.Parameter)]
  public class LockProtectedAttribute : Attribute {}
  /// <summary>
  /// Indicates that the method requires that the target is lock-protected.
  /// </summary>
  /// <remarks>
  /// This attribute causes the Spec# compiler's ThreadStart conversion feature
  /// to share the lock-protected target object
  /// with the newly started thread.
  /// </remarks>
  [AttributeUsage(AttributeTargets.Method)]
  public class RequiresLockProtectedAttribute : Attribute {}
  /// <summary>
  /// Indicates that the field refers to an immutable object.
  /// </summary>
  /// <remarks>
  /// This attribute causes the Spec# compiler to emit a call to the <see cref="Microsoft.Contracts.Guard.AddObjectImmutableCertificate"/>
  /// method in its <see cref="Microsoft.Contracts.InitGuardSetsDelegate"/> implementation.
  /// </remarks>
  [AttributeUsage(AttributeTargets.Interface | AttributeTargets.Class | AttributeTargets.Field, AllowMultiple = false, Inherited = true)]
  public sealed class ImmutableAttribute : Attribute { }
  /// <summary>
  /// Indicates that the method requires that the target is writeable.
  /// </summary>
  /// <remarks>
  /// This attribute causes the Spec# compiler's ThreadStart conversion feature to transfer the target object
  /// to the newly started thread.
  /// </remarks>
  [AttributeUsage(AttributeTargets.Method)]
  public class RequiresCanWriteAttribute : Attribute {}
  /// <summary>
  /// Indicates that the method requires that the target is immutable.
  /// </summary>
  /// <remarks>
  /// This attribute causes the Spec# compiler's ThreadStart conversion feature to share the immutable target object
  /// with the newly started thread.
  /// </remarks>
  [AttributeUsage(AttributeTargets.Method)]
  public class RequiresImmutableAttribute : Attribute {}
  /// <summary>
  /// Indicates that the method reads the target.
  /// </summary>
  /// <remarks>
  /// This attribute causes the Spec# compiler to enclose the method's body in a <c>read (this)</c> statement.
  /// </remarks>
  [AttributeUsage(AttributeTargets.Method)]
  public class ReaderAttribute : Attribute {}
  /// <summary>
  /// Indicates that the method writes the target.
  /// </summary>
  /// <remarks>
  /// This attribute causes the Spec# compiler to enclose the method's body in a <c>write (this)</c> statement.
  /// </remarks>
  [AttributeUsage(AttributeTargets.Method)]
  public class WriterAttribute : Attribute {}
  [AttributeUsage(SpecTargets.Code,AllowMultiple=false, Inherited = true)]
  public sealed class ConfinedAttribute: AttributeWithContext{
  }
  [Obsolete("Use Microsoft.Contracts.NoDefaultContract instead")]
  [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Constructor, AllowMultiple = true, Inherited = false)]
  public sealed class NoDefaultActivityAttribute: AttributeWithContext{
  }
  [AttributeUsage(AttributeTargets.Method | AttributeTargets.Property | AttributeTargets.Class | AttributeTargets.Constructor | AttributeTargets.Parameter,AllowMultiple=true, Inherited = false)]
  public sealed class NoDefaultContractAttribute: AttributeWithContext{
  }
  [Obsolete("Use Microsoft.Contracts.Rep or Microsoft.Contracts.Peer instead")]
  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
  public sealed class OwnedAttribute: Attribute{
    /// <summary>
    /// True if the field is owned; false otherwise.
    /// </summary>
    public bool Value;
    /// <summary>
    /// True if the field is a peer field; false otherwise.
    /// </summary>
    public bool Peer;
    public OwnedAttribute() { this.Value = true; this.Peer = false; }
    public OwnedAttribute(bool value) { this.Value = value; this.Peer = false; }
    public OwnedAttribute(string value) {
      switch (value) {
        case "peer":
          this.Value = false;
          this.Peer = true;
          break;
        case "this":
          this.Value = true;
          this.Peer = false;
          break;
        default:
          System.Diagnostics.Debug.Assert(false);
          break;
      }
    }
  }
  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
  public sealed class RepAttribute : Attribute {
  }
  [AttributeUsage(AttributeTargets.Field | AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
  public sealed class PeerAttribute : Attribute {
  }
  /// <summary>
  /// Fields of array-type or subtype of IEnumerable can be marked ElementsRep meaning that the elements of the 
  /// array or collection are rep of the array or collection. 
  /// </summary>
  [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
  public sealed class ElementsRepAttribute : AttributeWithContext {
  }
  /// <summary>
  /// Fields of array-type or subtype of IEnumerable can be marked ElementsPeer meaning that the elements of the 
  /// array or collection are peer of the array or collection. 
  /// </summary>
  [AttributeUsage(AttributeTargets.Field, AllowMultiple = false, Inherited = false)]
  public sealed class ElementsPeerAttribute : AttributeWithContext {
  }
  /// <summary>
  /// Methods of subtypes of IEnumerable can be marked Element meaning that the method returns an 
  /// element of the collection. 
  /// </summary>
  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
  public sealed class ElementAttribute : AttributeWithContext {
  }
  /// <summary>
  /// Methods of subtypes of IEnumerable can be marked ElementCollection meaning that the method returns 
  /// a set of elements of the collection. 
  /// </summary>
  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
  public sealed class ElementCollectionAttribute : AttributeWithContext {
  }
  /// <summary>
  /// Used to ensure acyclicity of method call chains in specifications of methods.
  /// Indicates the maximum number of method calls before the call chain terminates.
  /// E.g. zero if method's specification does not contain method calls.
  /// </summary>
  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
  public sealed class RecursionTerminationAttribute : AttributeWithContext {
    public int level;
    public RecursionTerminationAttribute() { this.level = 0; }
    public RecursionTerminationAttribute(int level) { this.level = level; }
  }
  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
  public sealed class NoReferenceComparisonAttribute : AttributeWithContext {
  }
  [AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
  public sealed class ResultNotNewlyAllocatedAttribute : AttributeWithContext {
  }
  /// <summary>
  /// Indicates that a parameter, or the receiver parameter if applied to a method or constructor, starts in an unowned state and may cause the owner to change.
  /// </summary>
  [AttributeUsage(AttributeTargets.Parameter | AttributeTargets.Method | AttributeTargets.Constructor, AllowMultiple=false)]
  public sealed class CapturedAttribute : Attribute{
  }
  [AttributeUsage(AttributeTargets.Field, AllowMultiple = true, Inherited = false)]
  public sealed class DependentAttribute : Attribute {
    /// <summary>
    /// The type that is allowed to have an invariant referring to the field
    /// this attribute is attached to.
    /// </summary>
    public Type otherType;
    public DependentAttribute(Type otherType) { this.otherType = otherType; }
  }
  public sealed class Owner{
    /// <summary>
    /// As seen by the static program verifier:  returns true iff c and d are owned by the same owner or
    /// if they have no owner and belong to the same peer group.
    /// Dynamically, this method always returns true.  If you want the negation, you Different.
    /// </summary>
    /// <param name="c"></param>
    /// <param name="d"></param>
    /// <returns></returns>
    [Pure]
    public static bool Same([NotNull] [Delayed] object c, [NotNull] object d) { return true; }
    /// <summary>
    /// As seen by the static program verifier:  returns false iff c and d are owned by the same owner or
    /// if they have no owner and belong to the same peer group.
    /// Dynamically, this method always returns true.  If you want the negation, you Same.
    /// </summary>
    /// <param name="c"></param>
    /// <param name="d"></param>
    /// <returns></returns>
    [Pure]
    public static bool Different([NotNull] [Delayed] object c, [NotNull] object d) { return true; }
    /// <summary>
    /// As seen by the static program verifier:  returns true iff subject has no owner.
    /// Dynamically, this method always returns true.
    /// </summary>
    /// <param name="c"></param>
    /// <returns></returns>
    [Pure]
    public static bool None([NotNull] [Delayed] object c) { return true; }
    /// <summary>
    /// As seen by the static program verifier:  returns true iff subject is owned by (owner,frame).
    /// Dynamically, this method always returns true.
    /// </summary>
    /// <param name="subject"></param>
    /// <param name="owner"></param>
    /// <param name="frame"></param>
    /// <returns></returns>
    [Pure]
    public static bool Is([NotNull] [Delayed] object subject, [NotNull] object owner, [NotNull] Type frame) { return true; }
    /// <summary>
    /// As seen by the static program verifier:  returns true iff subject has no owner and is in
    /// in peer group represented by itself.  That is, returns true iff the subject's owner is
    /// the same as it is in the post-state of a non-capturing constructor.
    /// Dynamically, this method always returns true.
    /// </summary>
    /// <param name="c"></param>
    /// <returns></returns>
    [Pure]
    public static bool New([NotNull] [Delayed] object c) { return true; }
    /// <summary>
    /// As seen by the static program verifier:  Requires that subject initially has no owner, and sets the owner of
    /// subject and any other objects in its peer group to (owner,frame).
    /// That is:
    ///   requires Owner.None(subject);
    ///   ensures Owner.Is(subject, owner, frame);
    /// Dynamically, this method is a no-op.
    /// </summary>
    /// <param name="subject"></param>
    /// <param name="owner"></param>
    /// <param name="frame"></param>
    public static void Assign([NotNull] [Delayed] object subject, [NotNull] object owner, [NotNull] Type frame) { }
    /// <summary>
    /// As seen by the static program verifier:  Requires that "subject" initially has no owner, and sets the owner of
    /// "subject" and any other objects in its peer group to the same owner or peer group as "peer"..
    /// That is:
    ///   requires Owner.None(subject);
    ///   ensures Owner.Same(subject, peer);
    /// Dynamically, this method is a no-op.
    /// </summary>
    /// <param name="subject"></param>
    /// <param name="peer"></param>
    public static void AssignSame([NotNull] [Delayed] object subject, [NotNull] object peer) { }
  }
  public class ObjectInvariantException : Microsoft.Contracts.GuardException{
    public ObjectInvariantException() : base("Object invariant does not hold.") {}
  }
  ///<summary>
  ///Instructs downstream tools to assume the correctness of this assembly, type or member without performing any verification.
  /// Can use [SkipVerification(false)] to explicitly mark assembly, type or member as one to have verification performed on it.
  /// Most specific element found (member, type, then assembly) takes precedence.
  /// (That is useful if downstream tools allow a user to decide which polarity is the default, unmarked case.)
  ///</summary>
  ///<remarks>
  ///Apply this attribute to a type to apply to all members of the type, including nested types.
  ///Apply this attribute to an assembly to skip verification of all types and members of the assembly.
  /// Default is true, so [SkipVerification] is the same as [SkipVerification(true)].
  ///</remarks>
  [Obsolete("Use Microsoft.Contracts.Verify instead")]
  [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor)]
  public sealed class SkipVerificationAttribute : Attribute { 
    public bool Value;
    public SkipVerificationAttribute() { this.Value = true; }
    public SkipVerificationAttribute(bool value) { this.Value = value; }
  }
  ///<summary>
  ///Instructs downstream tools whether to assume the correctness of this assembly, type or member without performing any verification or not.
  /// Can use [Verify(false)] to explicitly mark assembly, type or member as one to *not* have verification performed on it.
  /// Most specific element found (member, type, then assembly) takes precedence.
  /// (That is useful if downstream tools allow a user to decide which polarity is the default, unmarked case.)
  ///</summary>
  ///<remarks>
  ///Apply this attribute to a type to apply to all members of the type, including nested types.
  ///Apply this attribute to an assembly to apply to all types and members of the assembly.
  /// Apply this attribute to a property to apply to both the getter and setter.
  ///Default is true, so [Verify] is the same as [Verify(true)].
  ///</remarks>
  [AttributeUsage(AttributeTargets.Assembly | AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Constructor | AttributeTargets.Property)]
  public sealed class VerifyAttribute : Attribute {
    public bool Value;
    public VerifyAttribute() { this.Value = true; }
    public VerifyAttribute(bool value) { this.Value = value; }
  }

  [AttributeUsage(AttributeTargets.Method | AttributeTargets.Field | AttributeTargets.Parameter | AttributeTargets.ReturnValue)]
  public sealed class AdditiveAttribute : Attribute 
  {
    public bool Value;
    public AdditiveAttribute() { this.Value = true; }
    public AdditiveAttribute(bool value) { this.Value = value; }
  }
  [AttributeUsage(AttributeTargets.Method | AttributeTargets.Parameter | AttributeTargets.ReturnValue)]
  public sealed class InsideAttribute : Attribute {
    public bool Value;
    public InsideAttribute() { this.Value = true; }
    public InsideAttribute(bool value) { this.Value = value; }
  }
}
