#include utility.js

if(!('WebSocket' in window) && 'MozWebSocket' in window)
    window.WebSocket = window.MozWebSocket;

if(!('Map' in window))
    window.Map = function(iterable) {
        var keys = [], values = [];
        var obj = { size: 0 };

        if(typeof iterable === 'object')
            if(Array.isArray(iterable)) {
                for(var i in iterable) {
                    keys.push(iterable[i][0]);
                    values.push(iterable[i][1]);
                    ++obj.size;
                }
            } else if('next' in iterable) {
                for(;;) {
                    var state = iterable.next();
                    if(state.done) break;
                    keys.push(state.value[0]);
                    values.push(state.value[1]);
                    ++obj.size;
                }
            }

        obj.clear = function() {
            keys = [];
            values = [];
            obj.size = 0;
        };

        obj.delete = function(key) {
            var index = keys.indexOf(key);
            if(key < 0) return false;

            $ar(keys, index);
            $ar(values, index);
            --obj.size;
        };

        obj.entries = function() {
            var index = -1;
            return {
                next: function() {
                    if(++index >= obj.size)
                        return { done: true };
                    return { value: [keys[index], values[index]] };
                },
            };
        };

        obj.forEach = function(callbackFn, thisArg) {
            if(typeof callbackFn !== 'function') return;
            if(thisArg === undefined) thisArg = obj;
            for(var i = 0; i < obj.size; ++i)
                callbackFn.call(thisArg, values[i], keys[i], obj);
        };

        obj.get = function(key) {
            var index = keys.indexOf(key);
            if(index < 0) return undefined;
            return values[index];
        };

        obj.has = function(key) {
            return keys.indexOf(key) >= 0;
        };

        obj.keys = function() {
            var index = -1;
            return {
                next: function() {
                    if(++index >= obj.size)
                        return { done: true };
                    return { value: values[index] };
                },
            };
        };

        obj.set = function(key, value) {
            var index = keys.indexOf(key);

            if(index < 0) {
                keys.push(key);
                values.push(value);
                ++obj.size;
            } else values[index] = value;

            return obj;
        };

        obj.values = function() {
            var index = -1;
            return {
                next: function() {
                    if(++index >= obj.size)
                        return { done: true };
                    return { value: keys[index] };
                },
            };
        };

        return obj;
    };