context: using System;
  using System.Collections;
  using Org.BouncyCastle.Utilities;
  
  namespace Org.BouncyCastle.Asn1.Cms
  {
      public class AttributeTable
      {
          private readonly IDictionary attributes;
  
  #if !SILVERLIGHT
          [Obsolete]
          public AttributeTable(
              Hashtable attrs)
          {
              this.attributes = Platform.CreateHashtable(attrs);
          }
  #endif
  
          public AttributeTable(
              IDictionary attrs)
          {
              this.attributes = Platform.CreateHashtable(attrs);
          }
  
          public AttributeTable(
              Asn1EncodableVector v)
          {
              this.attributes = Platform.CreateHashtable(v.Count);
  
  			foreach (Asn1Encodable o in v)
              {
                  Attribute a = Attribute.GetInstance(o);
  
  				AddAttribute(a);
              }
          }
  
          public AttributeTable(
              Asn1Set s)
          {
              this.attributes = Platform.CreateHashtable(s.Count);
  
  			for (int i = 0; i != s.Count; i++)
              {
                  Attribute a = Attribute.GetInstance(s[i]);
  
                  AddAttribute(a);
              }
          }
  
  		public AttributeTable(
  			Attributes attrs)
  			: this(Asn1Set.GetInstance(attrs.ToAsn1Object()))
  		{
  		}
  
  		private void AddAttribute(
              Attribute a)
          {
  			DerObjectIdentifier oid = a.AttrType;
              object obj = attributes[oid];
  
              if (obj == null)
              {
                  attributes[oid] = a;
              }
              else
              {
                  IList v;
  
                  if (obj is Attribute)
                  {
                      v = Platform.CreateArrayList();
  
                      v.Add(obj);
                      v.Add(a);
                  }
                  else
                  {
                      v = (IList) obj;
  
                      v.Add(a);
                  }
  
                  attributes[oid] = v;
              }
          }
  
  		/// <summary>Return the first attribute matching the given OBJECT IDENTIFIER</summary>
  		public Attribute this[DerObjectIdentifier oid]
  		{
  			get
  			{
  				object obj = attributes[oid];
  
  				if (obj is IList)
  				{
  					return (Attribute)((IList)obj)[0];
  				}
  
  				return (Attribute) obj;
  			}
  		}
  
  		[Obsolete("Use 'object[oid]' syntax instead")]
          public Attribute Get(
              DerObjectIdentifier oid)
          {
  			return this[oid];
          }
  
  		/**
          * Return all the attributes matching the OBJECT IDENTIFIER oid. The vector will be
          * empty if there are no attributes of the required type present.
          *
          * @param oid type of attribute required.
          * @return a vector of all the attributes found of type oid.
          */
          public Asn1EncodableVector GetAll(
              DerObjectIdentifier oid)
          {
              Asn1EncodableVector v = new Asn1EncodableVector();
  
              object obj = attributes[oid];
  
  			if (obj is IList)
              {
                  foreach (Attribute a in (IList)obj)
                  {
                      v.Add(a);
                  }
              }
              else if (obj != null)
              {
                  v.Add((Attribute) obj);
              }
  
  			return v;
          }
  
  		public int Count
  		{
  			get
  			{
  				int total = 0;
  
  				foreach (object o in attributes.Values)
  				{
  					if (o is IList)
  					{
  						total += ((IList)o).Count;
  					}
  					else
  					{
  						++total;
  					}
  				}
  
  				return total;
  			}
  		}
  
          public IDictionary ToDictionary()
          {
              return Platform.CreateHashtable(attributes);
          }
  
  #if !SILVERLIGHT
          [Obsolete("Use 'ToDictionary' instead")]
  		public Hashtable ToHashtable()
          {
              return new Hashtable(attributes);
          }
  #endif
  
  		public Asn1EncodableVector ToAsn1EncodableVector()
          {
              Asn1EncodableVector v = new Asn1EncodableVector();
  
  			foreach (object obj in attributes.Values)
              {
                  if (obj is IList)
                  {
                      foreach (object el in (IList)obj)
                      {
                          v.Add(Attribute.GetInstance(el));
                      }
                  }
                  else
                  {
                      v.Add(Attribute.GetInstance(obj));
                  }
              }
  
  			return v;
          }
  
  		public Attributes ToAttributes()
  		{
  			return new Attributes(this.ToAsn1EncodableVector());
  		}
  
  		/**
  		 * Return a new table with the passed in attribute added.
  		 *
  		 * @param attrType
  		 * @param attrValue
  		 * @return
  		 */
  		public AttributeTable Add(DerObjectIdentifier attrType, Asn1Encodable attrValue)
  		{
  
gt: 			AttributeTable newTable = new AttributeTable(attributes);