I=(S=Uno.Dictionary__string__object = function(){
}).prototype;

I.rehash = function()
{
    var oldBuckets = this.buckets;
    this.buckets = _newFilledArray(this.buckets.length * 2, function() { return new Uno.Dictionary__string__object.Bucket__string__object; });
    this.count = 0;
    this.dummies = 0;

    for (var i = 0; i < oldBuckets.length; i++)
    {
        if (oldBuckets[i].State == 1)
        {
            this.Add(oldBuckets[i].Key, oldBuckets[i].Value);
        }
    }
};

I.GetKey = function(iterator)
{
    return this.buckets[iterator].Key;
};

I.GetValue = function(iterator)
{
    return this.buckets[iterator].Value;
};

I.Next = function(iterator)
{
    for (var i = iterator + 1; i < this.buckets.length; i++)
    {
        if (this.buckets[i].State == 1)
        {
            return i;
        }
    }

    return -1;
};

I.End = function()
{
    return -1;
};

I.Begin = function()
{
    return this.Next(-1);
};

I.Clear = function()
{
    for (var i = 0; i < this.buckets.length; i++)
    {
        this.buckets[i].State = 0;
    }

    this.count = 0;
    this.dummies = 0;
};

I.Add = function(key, value)
{
    if ((this.count + this.dummies) > (this.buckets.length / 2))
    {
        this.rehash();
    }

    var x = Math.abs(key.GetHashCode()) & (this.buckets.length - 1);

    while (true)
    {
        if (this.buckets[x].State == 0)
        {
            this.buckets[x].State = 1;
            this.buckets[x].Value = value;
            this.buckets[x].Key = key;
            this.count++;
            return;
        }
        else if (this.buckets[x].State == 2)
        {
            this.buckets[x].State = 1;
            this.buckets[x].Value = value;
            this.buckets[x].Key = key;
            this.count++;
            this.dummies--;
            return;
        }
        else if (this.buckets[x].State == 1)
        {
            if (this.buckets[x].Key == key)
            {
                throw Uno.Exception.$0("Dictionary already contains the given key");
            }
        }

        x++;

        if (x >= this.buckets.length)
        {
            x = 0;
        }
    }
};

I.TryGetValue = function(key, value)
{
    var x = Math.abs(key.GetHashCode()) & (this.buckets.length - 1);

    while (true)
    {
        if (this.buckets[x].State == 1)
        {
            if (this.buckets[x].Key == key)
            {
                value(this.buckets[x].Value);
                return true;
            }
        }
        else if (this.buckets[x].State == 0)
        {
            value(null);
            return false;
        }

        x++;

        if (x >= this.buckets.length)
        {
            x = 0;
        }
    }
};

I.Remove = function(key)
{
    var x = Math.abs(key.GetHashCode()) & (this.buckets.length - 1);

    while (true)
    {
        if (this.buckets[x].State == 1)
        {
            if (this.buckets[x].Key == key)
            {
                this.buckets[x].State = 2;
                this.count--;
                this.dummies++;
                return;
            }
        }
        else if (this.buckets[x].State == 0)
        {
            throw Uno.Exception.$0("Dictionary did not contain the given key");
        }

        x++;

        if (x >= this.buckets.length)
        {
            x = 0;
        }
    }
};

I.ContainsKey = function(key)
{
    var x = Math.abs(key.GetHashCode()) & (this.buckets.length - 1);

    while (true)
    {
        if (this.buckets[x].State == 1)
        {
            if (this.buckets[x].Key == key)
            {
                return true;
            }
        }
        else if (this.buckets[x].State == 0)
        {
            return false;
        }

        x++;

        if (x >= this.buckets.length)
        {
            x = 0;
        }
    }
};

I.Count = function()
{
    return this.count;
};

I.indexer = function(key, value)
{
    if (value !== undefined)
    {
        var x = Math.abs(key.GetHashCode()) & (this.buckets.length - 1);

        while (true)
        {
            if (this.buckets[x].State == 1)
            {
                if (this.buckets[x].Key == key)
                {
                    this.buckets[x].Value = value;
                    return;
                }
            }
            else if (this.buckets[x].State == 0)
            {
                throw Uno.Exception.$0("Dictionary did not contain the given key");
            }

            x++;

            if (x >= this.buckets.length)
            {
                x = 0;
            }
        }
    }

    else
    {
        var x = Math.abs(key.GetHashCode()) & (this.buckets.length - 1);

        while (true)
        {
            if (this.buckets[x].State == 1)
            {
                if (this.buckets[x].Key == key)
                {
                    return this.buckets[x].Value;
                }
            }
            else if (this.buckets[x].State == 0)
            {
                throw Uno.Exception.$0("Dictionary did not contain the given key");
            }

            x++;

            if (x >= this.buckets.length)
            {
                x = 0;
            }
        }
    }
};

S.$0 = function($this) {
    if (!$this) $this = new Uno.Dictionary__string__object;
    $this.buckets = _newFilledArray(8, function() { return new Uno.Dictionary__string__object.Bucket__string__object; });
    $this.count = 0;
    $this.dummies = 0;
    return $this;
};
