﻿// Decompiled with JetBrains decompiler
// Type: MongoDB.Bson.BsonDocument
// Assembly: MongoDB.Bson, Version=1.6.1.21837, Culture=neutral, PublicKeyToken=f686731cfb9cc103
// MVID: 93880221-3735-46FB-8891-84D897158E28
// Assembly location: C:\Users\CGA Computer\Desktop\LEGO Universe Stuff\LOCO Server\Unity Web Player Extractor\Saved Files\LOCO Server.unity3d_unpacked\MongoDB.Bson.dll

using MongoDB.Bson.IO;
using MongoDB.Bson.Serialization;
using MongoDB.Bson.Serialization.IdGenerators;
using MongoDB.Bson.Serialization.Options;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;

namespace MongoDB.Bson
{
  [Serializable]
  public class BsonDocument : BsonValue, IBsonSerializable, IComparable<BsonDocument>, IConvertibleToBsonDocument, IEnumerable<BsonElement>, IEnumerable, IEquatable<BsonDocument>
  {
    private List<BsonElement> _elements = new List<BsonElement>();
    private Dictionary<string, int> _indexes = new Dictionary<string, int>();
    private bool _allowDuplicateNames;

    public bool AllowDuplicateNames
    {
      get
      {
        return this._allowDuplicateNames;
      }
      set
      {
        this._allowDuplicateNames = value;
      }
    }

    public int ElementCount
    {
      get
      {
        return this._elements.Count;
      }
    }

    public IEnumerable<BsonElement> Elements
    {
      get
      {
        return (IEnumerable<BsonElement>) this._elements;
      }
    }

    public IEnumerable<string> Names
    {
      get
      {
        return Enumerable.Select<BsonElement, string>((IEnumerable<BsonElement>) this._elements, (Func<BsonElement, string>) (e => e.Name));
      }
    }

    public IEnumerable<object> RawValues
    {
      get
      {
        return Enumerable.Select<BsonElement, object>((IEnumerable<BsonElement>) this._elements, (Func<BsonElement, object>) (e => e.Value.RawValue));
      }
    }

    public IEnumerable<BsonValue> Values
    {
      get
      {
        return Enumerable.Select<BsonElement, BsonValue>((IEnumerable<BsonElement>) this._elements, (Func<BsonElement, BsonValue>) (e => e.Value));
      }
    }

    public BsonValue this[int index]
    {
      get
      {
        return this._elements[index].Value;
      }
      set
      {
        if (value == (BsonValue) null)
          throw new ArgumentNullException("value");
        this._elements[index].Value = value;
      }
    }

    public BsonValue this[string name, BsonValue defaultValue]
    {
      get
      {
        if (name == null)
          throw new ArgumentNullException("name");
        int index;
        if (this._indexes.TryGetValue(name, out index))
          return this._elements[index].Value;
        return defaultValue;
      }
    }

    public BsonValue this[string name]
    {
      get
      {
        if (name == null)
          throw new ArgumentNullException("name");
        int index;
        if (this._indexes.TryGetValue(name, out index))
          return this._elements[index].Value;
        throw new KeyNotFoundException(string.Format("Element '{0}' not found.", (object) name));
      }
      set
      {
        if (name == null)
          throw new ArgumentNullException("name");
        if (value == (BsonValue) null)
          throw new ArgumentNullException("value");
        int index;
        if (this._indexes.TryGetValue(name, out index))
          this._elements[index].Value = value;
        else
          this.Add(new BsonElement(name, value));
      }
    }

    public BsonDocument()
      : base(BsonType.Document)
    {
    }

    public BsonDocument(bool allowDuplicateNames)
      : base(BsonType.Document)
    {
      this._allowDuplicateNames = allowDuplicateNames;
    }

    public BsonDocument(BsonElement element)
      : base(BsonType.Document)
    {
      this.Add(element);
    }

    public BsonDocument(Dictionary<string, object> dictionary)
      : base(BsonType.Document)
    {
      this.Add(dictionary);
    }

    public BsonDocument(Dictionary<string, object> dictionary, IEnumerable<string> keys)
      : base(BsonType.Document)
    {
      this.Add(dictionary, keys);
    }

    public BsonDocument(IDictionary<string, object> dictionary)
      : base(BsonType.Document)
    {
      this.Add(dictionary);
    }

    public BsonDocument(IDictionary<string, object> dictionary, IEnumerable<string> keys)
      : base(BsonType.Document)
    {
      this.Add(dictionary, keys);
    }

    public BsonDocument(IDictionary dictionary)
      : base(BsonType.Document)
    {
      this.Add(dictionary);
    }

    public BsonDocument(IDictionary dictionary, IEnumerable keys)
      : base(BsonType.Document)
    {
      this.Add(dictionary, keys);
    }

    public BsonDocument(IEnumerable<BsonElement> elements)
      : base(BsonType.Document)
    {
      this.Add(elements);
    }

    public BsonDocument(params BsonElement[] elements)
      : base(BsonType.Document)
    {
      this.Add(elements);
    }

    public BsonDocument(string name, BsonValue value)
      : base(BsonType.Document)
    {
      this.Add(name, value);
    }

    public static bool operator !=(BsonDocument lhs, BsonDocument rhs)
    {
      return !(lhs == rhs);
    }

    public static bool operator ==(BsonDocument lhs, BsonDocument rhs)
    {
      if (object.ReferenceEquals((object) lhs, (object) null))
        return object.ReferenceEquals((object) rhs, (object) null);
      return lhs.Equals(rhs);
    }

    public static BsonDocument Create(object value)
    {
      if (value != null)
        return (BsonDocument) BsonTypeMapper.MapToBsonValue(value, BsonType.Document);
      return (BsonDocument) null;
    }

    public static BsonDocument Parse(string json)
    {
      using (BsonReader bsonReader = BsonReader.Create(json))
        return (BsonDocument) new BsonDocument().Deserialize(bsonReader, typeof (BsonDocument), (IBsonSerializationOptions) null);
    }

    public static BsonDocument ReadFrom(BsonBuffer buffer)
    {
      using (BsonReader bsonReader = BsonReader.Create(buffer))
        return BsonDocument.ReadFrom(bsonReader);
    }

    public static BsonDocument ReadFrom(BsonReader bsonReader)
    {
      return (BsonDocument) new BsonDocument().Deserialize(bsonReader, typeof (BsonDocument), (IBsonSerializationOptions) null);
    }

    public static BsonDocument ReadFrom(byte[] bytes)
    {
      using (BsonReader bsonReader = BsonReader.Create((Stream) new MemoryStream(bytes)))
        return BsonDocument.ReadFrom(bsonReader);
    }

    public static BsonDocument ReadFrom(Stream stream)
    {
      using (BsonReader bsonReader = BsonReader.Create(stream))
        return BsonDocument.ReadFrom(bsonReader);
    }

    public static BsonDocument ReadFrom(string filename)
    {
      using (BsonReader bsonReader = BsonReader.Create((Stream) new FileStream(filename, FileMode.Open, FileAccess.Read, FileShare.None)))
        return BsonDocument.ReadFrom(bsonReader);
    }

    public BsonDocument Add(BsonElement element)
    {
      if (element != (BsonElement) null)
      {
        int num;
        bool flag;
        if ((flag = this._indexes.TryGetValue(element.Name, out num)) && !this._allowDuplicateNames)
          throw new InvalidOperationException(string.Format("Duplicate element name '{0}'.", (object) element.Name));
        this._elements.Add(element);
        if (!flag)
          this._indexes.Add(element.Name, this._elements.Count - 1);
      }
      return this;
    }

    public BsonDocument Add(Dictionary<string, object> dictionary)
    {
      return this.Add((IDictionary<string, object>) dictionary);
    }

    public BsonDocument Add(Dictionary<string, object> dictionary, IEnumerable<string> keys)
    {
      return this.Add((IDictionary<string, object>) dictionary, keys);
    }

    public BsonDocument Add(IDictionary<string, object> dictionary)
    {
      if (dictionary != null)
      {
        foreach (KeyValuePair<string, object> keyValuePair in (IEnumerable<KeyValuePair<string, object>>) dictionary)
          this.Add(keyValuePair.Key, BsonTypeMapper.MapToBsonValue(keyValuePair.Value));
      }
      return this;
    }

    public BsonDocument Add(IDictionary<string, object> dictionary, IEnumerable<string> keys)
    {
      if (keys == null)
        throw new ArgumentNullException("keys");
      if (dictionary != null)
      {
        foreach (string name in keys)
          this.Add(name, BsonTypeMapper.MapToBsonValue(dictionary[name]));
      }
      return this;
    }

    public BsonDocument Add(IDictionary dictionary)
    {
      if (dictionary != null)
      {
        foreach (DictionaryEntry dictionaryEntry in dictionary)
        {
          if (dictionaryEntry.Key.GetType() != typeof (string))
            throw new ArgumentOutOfRangeException("One or more keys in the dictionary passed to BsonDocument.Add is not a string.");
          this.Add((string) dictionaryEntry.Key, BsonTypeMapper.MapToBsonValue(dictionaryEntry.Value));
        }
      }
      return this;
    }

    public BsonDocument Add(IDictionary dictionary, IEnumerable keys)
    {
      if (keys == null)
        throw new ArgumentNullException("keys");
      if (dictionary != null)
      {
        foreach (object index in keys)
        {
          if (index.GetType() != typeof (string))
            throw new ArgumentOutOfRangeException("A key passed to BsonDocument.Add is not a string.");
          this.Add((string) index, BsonTypeMapper.MapToBsonValue(dictionary[index]));
        }
      }
      return this;
    }

    public BsonDocument Add(IEnumerable<BsonElement> elements)
    {
      if (elements != null)
      {
        foreach (BsonElement element in elements)
          this.Add(element);
      }
      return this;
    }

    public BsonDocument Add(params BsonElement[] elements)
    {
      return this.Add((IEnumerable<BsonElement>) elements);
    }

    public BsonDocument Add(string name, BsonValue value)
    {
      if (name == null)
        throw new ArgumentNullException("name");
      if (value != (BsonValue) null)
        this.Add(new BsonElement(name, value));
      return this;
    }

    public BsonDocument Add(string name, BsonValue value, bool condition)
    {
      if (name == null)
        throw new ArgumentNullException("name");
      if (value != (BsonValue) null && condition)
        this.Add(new BsonElement(name, value));
      return this;
    }

    public void Clear()
    {
      this._elements.Clear();
      this._indexes.Clear();
    }

    public override BsonValue Clone()
    {
      BsonDocument bsonDocument = new BsonDocument();
      foreach (BsonElement bsonElement in this._elements)
        bsonDocument.Add(bsonElement.Clone());
      return (BsonValue) bsonDocument;
    }

    public int CompareTo(BsonDocument other)
    {
      if (other == (BsonDocument) null)
        return 1;
      for (int index = 0; index < this._elements.Count && index < other._elements.Count; ++index)
      {
        int num1 = this._elements[index].Name.CompareTo(other._elements[index].Name);
        if (num1 != 0)
          return num1;
        int num2 = this._elements[index].Value.CompareTo(other._elements[index].Value);
        if (num2 != 0)
          return num2;
      }
      return this._elements.Count.CompareTo(other._elements.Count);
    }

    public override int CompareTo(BsonValue other)
    {
      if (other == (BsonValue) null)
        return 1;
      BsonDocument other1 = other as BsonDocument;
      if (other1 != (BsonDocument) null)
        return this.CompareTo(other1);
      return this.CompareTypeTo(other);
    }

    public bool Contains(string name)
    {
      return this._indexes.ContainsKey(name);
    }

    public bool ContainsValue(BsonValue value)
    {
      if (value == (BsonValue) null)
        throw new ArgumentNullException("value");
      return Enumerable.Any<BsonElement>((IEnumerable<BsonElement>) this._elements, (Func<BsonElement, bool>) (e => e.Value == value));
    }

    public override BsonValue DeepClone()
    {
      BsonDocument bsonDocument = new BsonDocument();
      foreach (BsonElement bsonElement in this._elements)
        bsonDocument.Add(bsonElement.DeepClone());
      return (BsonValue) bsonDocument;
    }

    [Obsolete("Deserialize was intended to be private and will become private in a future release.")]
    public object Deserialize(BsonReader bsonReader, Type nominalType, IBsonSerializationOptions options)
    {
      if (bsonReader.GetCurrentBsonType() == BsonType.Null)
      {
        bsonReader.ReadNull();
        return (object) null;
      }
      DocumentSerializationOptions serializationOptions = (options ?? (IBsonSerializationOptions) DocumentSerializationOptions.Defaults) as DocumentSerializationOptions;
      if (serializationOptions == null)
        throw new BsonSerializationException(string.Format("Serialize method of BsonDocument expected serialization options of type {0}, not {1}.", (object) BsonUtils.GetFriendlyTypeName(typeof (DocumentSerializationOptions)), (object) BsonUtils.GetFriendlyTypeName(options.GetType())));
      this._allowDuplicateNames = serializationOptions.AllowDuplicateNames;
      bsonReader.ReadStartDocument();
      this.Clear();
      BsonElement element;
      while (BsonElement.ReadFrom(bsonReader, out element))
        this.Add(element);
      bsonReader.ReadEndDocument();
      return (object) this;
    }

    [Obsolete("GetDocumentId was intended to be private and will become private in a future release. Use document[\"_id\"] or document.GetValue(\"_id\") instead.")]
    public bool GetDocumentId(out object id, out Type idNominalType, out IIdGenerator idGenerator)
    {
      BsonElement bsonElement;
      if (this.TryGetElement("_id", out bsonElement))
      {
        id = bsonElement.Value.RawValue;
        if (id == null)
          id = (object) bsonElement.Value;
        idGenerator = BsonSerializer.LookupIdGenerator(id.GetType());
        if (idGenerator == null)
        {
          BsonBinaryData bsonBinaryData = id as BsonBinaryData;
          if (bsonBinaryData != (BsonBinaryData) null && (bsonBinaryData.SubType == BsonBinarySubType.UuidLegacy || bsonBinaryData.SubType == BsonBinarySubType.UuidStandard))
            idGenerator = (IIdGenerator) BsonBinaryDataGuidGenerator.GetInstance(bsonBinaryData.GuidRepresentation);
        }
      }
      else
      {
        id = (object) null;
        idGenerator = (IIdGenerator) ObjectIdGenerator.Instance;
      }
      idNominalType = typeof (BsonValue);
      return true;
    }

    public bool Equals(BsonDocument rhs)
    {
      if (object.ReferenceEquals((object) rhs, (object) null) || this.GetType() != rhs.GetType())
        return false;
      if (!object.ReferenceEquals((object) this, (object) rhs))
        return Enumerable.SequenceEqual<BsonElement>((IEnumerable<BsonElement>) this._elements, (IEnumerable<BsonElement>) rhs._elements);
      return true;
    }

    public override bool Equals(object obj)
    {
      return this.Equals(obj as BsonDocument);
    }

    public BsonElement GetElement(int index)
    {
      return this._elements[index];
    }

    public BsonElement GetElement(string name)
    {
      if (name == null)
        throw new ArgumentNullException("name");
      int index;
      if (this._indexes.TryGetValue(name, out index))
        return this._elements[index];
      throw new KeyNotFoundException(string.Format("Element '{0}' not found.", (object) name));
    }

    public IEnumerator<BsonElement> GetEnumerator()
    {
      return (IEnumerator<BsonElement>) this._elements.GetEnumerator();
    }

    public override int GetHashCode()
    {
      int num = 37 * this.BsonType.GetHashCode();
      foreach (BsonElement bsonElement in this._elements)
        num = 37 * num + bsonElement.GetHashCode();
      return num;
    }

    public BsonValue GetValue(int index)
    {
      return this[index];
    }

    public BsonValue GetValue(string name)
    {
      if (name == null)
        throw new ArgumentNullException("name");
      return this[name];
    }

    public BsonValue GetValue(string name, BsonValue defaultValue)
    {
      if (name == null)
        throw new ArgumentNullException("name");
      return this[name, defaultValue];
    }

    public void InsertAt(int index, BsonElement element)
    {
      if (element == (BsonElement) null)
        throw new ArgumentNullException("element");
      if (this._indexes.ContainsKey(element.Name) && !this._allowDuplicateNames)
        throw new InvalidOperationException(string.Format("Duplicate element name '{0}' not allowed.", (object) element.Name));
      this._elements.Insert(index, element);
      this.RebuildDictionary();
    }

    public BsonDocument Merge(BsonDocument document)
    {
      this.Merge(document, false);
      return this;
    }

    public BsonDocument Merge(BsonDocument document, bool overwriteExistingElements)
    {
      if (document != (BsonDocument) null)
      {
        foreach (BsonElement bsonElement in document)
        {
          if (overwriteExistingElements || !this.Contains(bsonElement.Name))
            this[bsonElement.Name] = bsonElement.Value;
        }
      }
      return this;
    }

    public void Remove(string name)
    {
      if (name == null)
        throw new ArgumentNullException("name");
      if (!this._indexes.ContainsKey(name))
        return;
      this._elements.RemoveAll((Predicate<BsonElement>) (e => e.Name == name));
      this.RebuildDictionary();
    }

    public void RemoveAt(int index)
    {
      this._elements.RemoveAt(index);
      this.RebuildDictionary();
    }

    public void RemoveElement(BsonElement element)
    {
      if (element == (BsonElement) null)
        throw new ArgumentNullException("element");
      this._elements.Remove(element);
      this.RebuildDictionary();
    }

    [Obsolete("Serialize was intended to be private and will become private in a future release.")]
    public void Serialize(BsonWriter bsonWriter, Type nominalType, IBsonSerializationOptions options)
    {
      if (bsonWriter == null)
        throw new ArgumentNullException("bsonWriter");
      if (nominalType == null)
        throw new ArgumentNullException("nominalType");
      DocumentSerializationOptions serializationOptions = (options ?? (IBsonSerializationOptions) DocumentSerializationOptions.Defaults) as DocumentSerializationOptions;
      if (serializationOptions == null)
        throw new BsonSerializationException(string.Format("Serialize method of BsonDocument expected serialization options of type {0}, not {1}.", (object) BsonUtils.GetFriendlyTypeName(typeof (DocumentSerializationOptions)), (object) BsonUtils.GetFriendlyTypeName(options.GetType())));
      bsonWriter.WriteStartDocument();
      int index1;
      if (serializationOptions.SerializeIdFirst && this._indexes.TryGetValue("_id", out index1))
        this._elements[index1].WriteTo(bsonWriter);
      else
        index1 = -1;
      for (int index2 = 0; index2 < this._elements.Count; ++index2)
      {
        if (index2 != index1)
          this._elements[index2].WriteTo(bsonWriter);
      }
      bsonWriter.WriteEndDocument();
    }

    public BsonDocument Set(int index, BsonValue value)
    {
      if (value == (BsonValue) null)
        throw new ArgumentNullException("value");
      this[index] = value;
      return this;
    }

    public BsonDocument Set(string name, BsonValue value)
    {
      if (name == null)
        throw new ArgumentNullException("name");
      if (value == (BsonValue) null)
        throw new ArgumentNullException("value");
      this[name] = value;
      return this;
    }

    [Obsolete("SetDocumentId was intended to be private and will become private in a future release. Use document[\"_id\"] = value or document.Set(\"_id\", value) instead.")]
    public void SetDocumentId(object id)
    {
      if (id == null)
        throw new ArgumentNullException("id");
      BsonValue bsonValue = id as BsonValue;
      if (bsonValue == (BsonValue) null)
        bsonValue = BsonValue.Create(id);
      BsonElement bsonElement;
      if (this.TryGetElement("_id", out bsonElement))
        bsonElement.Value = bsonValue;
      else
        this.InsertAt(0, new BsonElement("_id", bsonValue));
    }

    public BsonDocument SetElement(int index, BsonElement element)
    {
      if (element == (BsonElement) null)
        throw new ArgumentNullException("element");
      this._elements[index] = element;
      this.RebuildDictionary();
      return this;
    }

    public BsonDocument SetElement(BsonElement element)
    {
      if (element == (BsonElement) null)
        throw new ArgumentNullException("element");
      int index;
      if (this._indexes.TryGetValue(element.Name, out index))
        this._elements[index] = element;
      else
        this.Add(element);
      return this;
    }

    public Dictionary<string, object> ToDictionary()
    {
      return (Dictionary<string, object>) BsonTypeMapper.MapToDotNetValue((BsonValue) this, new BsonTypeMapperOptions()
      {
        DuplicateNameHandling = DuplicateNameHandling.ThrowException,
        MapBsonArrayTo = typeof (object[]),
        MapBsonDocumentTo = typeof (Dictionary<string, object>),
        MapOldBinaryToByteArray = false
      });
    }

    public Hashtable ToHashtable()
    {
      return (Hashtable) BsonTypeMapper.MapToDotNetValue((BsonValue) this, new BsonTypeMapperOptions()
      {
        DuplicateNameHandling = DuplicateNameHandling.ThrowException,
        MapBsonArrayTo = typeof (object[]),
        MapBsonDocumentTo = typeof (Hashtable),
        MapOldBinaryToByteArray = false
      });
    }

    public override string ToString()
    {
      return BsonExtensionMethods.ToJson<BsonDocument>(this);
    }

    public bool TryGetElement(string name, out BsonElement value)
    {
      if (name == null)
        throw new ArgumentNullException("name");
      int index;
      if (this._indexes.TryGetValue(name, out index))
      {
        value = this._elements[index];
        return true;
      }
      value = (BsonElement) null;
      return false;
    }

    public bool TryGetValue(string name, out BsonValue value)
    {
      if (name == null)
        throw new ArgumentNullException("name");
      int index;
      if (this._indexes.TryGetValue(name, out index))
      {
        value = this._elements[index].Value;
        return true;
      }
      value = (BsonValue) null;
      return false;
    }

    public new void WriteTo(BsonWriter bsonWriter)
    {
      this.Serialize(bsonWriter, typeof (BsonDocument), (IBsonSerializationOptions) null);
    }

    public void WriteTo(BsonBuffer buffer)
    {
      using (BsonWriter bsonWriter = BsonWriter.Create(buffer))
        this.WriteTo(bsonWriter);
    }

    public void WriteTo(Stream stream)
    {
      using (BsonWriter bsonWriter = BsonWriter.Create(stream))
        this.WriteTo(bsonWriter);
    }

    public void WriteTo(string filename)
    {
      using (FileStream fileStream = new FileStream(filename, FileMode.Create, FileAccess.Write))
        this.WriteTo((Stream) fileStream);
    }

    private void RebuildDictionary()
    {
      this._indexes.Clear();
      for (int index = 0; index < this._elements.Count; ++index)
      {
        BsonElement bsonElement = this._elements[index];
        if (!this._indexes.ContainsKey(bsonElement.Name))
          this._indexes.Add(bsonElement.Name, index);
      }
    }

    BsonDocument IConvertibleToBsonDocument.ToBsonDocument()
    {
      return this;
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
      return (IEnumerator) this._elements.GetEnumerator();
    }
  }
}
