                 }
                 s.push(item);
             }
+
             return dict;
         }
 

                default:
                    throw new StreamError("Unexpected arguments count: " + count);
            }
            return new Stream(source.map(f));
        }

        /**
         * Executes a test function on each item in the list until an item is reached
         * that returns true. Use this method to determine whether any items in a
         * list meet a criterion, such as having a value less than a particular number.
         * @param callback The function to run on each item in the list.
         *                 <p>function(item:*):Boolean</p>
         * @return  A Boolean value of true if any items in the list return true for
         * the specified function; otherwise false.
         * @example
         * <pre>
         *     var s:Stream = $(1, 2, 3);
         *     var c:Boolean = s.some(function(item:Number):Boolean
         *     {
         *        return item > 2;
         *     });
         *     trace(c);
         *     //true
         * </pre>
         * @internal immutable
         */
        public function some(callback:Function):Boolean
        {
            return source.some(function (item:*, index:int, array:Array):Boolean
            {
                return callback(item);
            });
        }

        /**
         * Adds one or more items to the end of a list and returns the new length of the list.
         * @param rest One or more values to append to the list.
         * @return An integer representing the new length of the list.
         * @example
         * <pre>
         *     var s:Stream = $(1, 2, 3);
         *     s.push(4);
         *     trace(s);
         *     //Stream{1, 2, 3, 4}
         * </pre>
         * @internal mutable
         */
        public function push(...rest):uint
        {
            return source.push.apply(null, rest);
        }

        /**
         * Removes the last item from a list and returns the value of that item.
         * @return The value of the last item (of any data type) in the specified list.
         * @example
         * <pre>
         *     var s:Stream = $(1, 2, 3);
         *     trace(s.pop());
         *     //3
         * </pre>
         * @internal mutable
         */
        public function pop():*
        {
            return source.pop();
        }

        /**
         * A non-negative integer specifying the number of items in the list.
         * This property is automatically updated when new items are added to the list.
         * When you assign a value to a list item (for example, my_list[index] = value),
         * if index is a number, and index+1 is greater than the length property,
         * the length property is updated to index+1.<p/>
         *
         * <b>Note</b>: If you assign a value to the length property that is shorter
         * than the existing length, the list will be truncated.
         * @example
         * <pre>
         *     var s:Stream = $(1, 2, 3);
         *     trace(s.length);
         *     //3
         * </pre>
         * @internal immutable
         */
        public function get length():int
        {
            return source.length;
        }

        /**
         * @private
         * @internal mutable
         */
        public function set length(value:int):void
        {
            source.length = value;
        }

        /**
         * @private
         * @internal immutable
         */
        override flash_proxy function getDescendants(name:*):*
        {
            var result:Array = [];

            for each (var item:* in source)
            {
                if(item != null && item.hasOwnProperty(name))
                {
                    result.push(item[name]);
                }
            }
            return new Stream(result);
        }

        /**
         * @private
         * @internal immutable
         */
        override flash_proxy function getProperty(name:*):*
        {
            var index:Number = NaN;
            try
            {
                // If caller passed in a number such as 5.5, it will be floored.
                index = parseInt(String(name));
            }
            catch(e:Error) // localName was not a number
            {
            }

            if(index != index)
            {
                throw new StreamError("Incorrect index: " + String(name));
            }
            else
            {
                return index < 0 ? source[source.length + index] : source[index];
            }
        }

        /**
         * @private
         * @internal mutable
         */
        override flash_proxy function setProperty(name:*, value:*):void
        {
            var index:Number = NaN;
            try
            {
                // If caller passed in a number such as 5.5, it will be floored.
                index = parseInt(String(name));
            }
            catch(e:Error) // localName was not a number
            {
            }

            if(index != index)
            {
                throw new StreamError("Incorrect index: " + String(name));
            }
            else
            {
                setItem(value, index);
            }
        }

        /**
         * @private
         * @internal immutable
         */
        override flash_proxy function hasProperty(name:*):Boolean
        {
            var index:Number = NaN;
            try
            {
                // If caller passed in a number such as 5.5, it will be floored.
                index = parseInt(String(name));
            }
            catch(e:Error) // localName was not a number
            {
            }

            if(index != index)
            {
                return false;
            }

            return (index >= 0 && index < source.length) || (index < 0 && index >= -source.length);
        }

        /**
         * @private
         * @internal immutable
         */
        override flash_proxy function nextNameIndex(index:int):int
        {
            return index < length ? index + 1 : 0;
        }

        /**
         * @private
         * @internal immutable
         */
        override flash_proxy function nextName(index:int):String
        {
            return (index - 1).toString();
        }

        /**
         * @private
         * @internal immutable
         */
        override flash_proxy function nextValue(index:int):*
        {
            return source[index - 1];
        }

        /**
         * @private
         * @internal immutable
         */
        override flash_proxy function callProperty(name:*, ...rest):*
        {
            if(rest.length != 1 || !(rest[0] is Function))
            {
                throw new StreamError("Shortcut filter must have exactly one parameter (Function)");
            }

            var criteria:Function = rest[0] as Function;

            return this.filter(function (item:*):Boolean
            {
                return item != null && item.hasOwnProperty(name) && criteria(item[name]);
            });
        }

        /**
         * @private
         * @internal mutable
         */
        override flash_proxy function deleteProperty(name:*):Boolean
        {
            var index:Number = NaN;
            try
            {
                // If caller passed in a number such as 5.5, it will be floored.
                index = parseInt(String(name));
            }
            catch(e:Error) // localName was not a number
            {
            }

            if(index != index)
            {
                return false;
            }

            return removeItem(index);
        }

        /**
         * @private
         * A class implements this method to decode itself from a data list by calling
         * the methods of the IDataInput interface. This method must read the values in
         * the same sequence and with the same types as were written by the writeExternal() method.
         * @param input The name of the class that implements the IDataInput interface.
         * @see flash.utils.IExternalizable#readExternal
         * @internal immutable
         */
        public function readExternal(input:IDataInput):void
        {
            source = input.readObject() as Array;
        }

        /**
         * @private
         * A class implements this method to encode itself for a data list by calling
         * the methods of the IDataOutput interface.
         * @param output The name of the class that implements the IDataOutput interface.
         * @see flash.utils.IExternalizable#readExternal
         * @internal immutable
         */
        public function writeExternal(output:IDataOutput):void
        {
            output.writeObject(source);
        }

        /**
         * Returns the string representation of list object.
         * @return a String
         * @example
         * <pre>
         *     var s:Stream = $(1, 2, 3);
         *     trace(s.toString());
         *     //Stream{1, 2, 3}
         * </pre>
         * @internal immutable
         */
        public function toString():String
        {
            return "Stream{" + source.join(",") + "}";
        }

        /**
         * Creates Stream object from items
         * @param rest objects used as source for Stream
         * @return created Stream object
         * @example
         * <pre>
         *     var s:Stream = Stream.of(1, 2, 3);
         *
         *     //All expressions are equivalent to:
         *     var s:Stream = new Stream([1, 2, 3])
         * </pre>
         * @internal immutable
         */
        public static function of(...rest):Stream
        {
            if (rest.length == 0)
            {
                //empty $
                return new Stream();
            }

            //$ from argument list
            return new Stream(rest.concat());
        }

        /**
         * Creates Stream object from iterable object
         * @param object object used as source for a stream
         * @param callback callback used to map result Stream
         * @return created Stream object
         * @example
         * <pre>
         *     var s:Stream = Stream.from([1, 2, 3]);
         *
         *     //Expression is equivalent to:
         *     var s:Stream = new Stream([1, 2, 3])
         *
         *     var obj:Object = {name1: "first", name2: "second"};
         *     var s:Stream = Stream.from(obj, function(entry:Stream):Stream
         *     {
         *         return entry.first;
         *     });
         *     trace(s);
         *     //prints ["name1", "name2"]
         * </pre>
         * @internal immutable
         */
        public static function from(object:*, callback:Function = null):Stream
        {
            var result:Stream;
            if (object == null || object === undefined)
            {
                //empty $
                result = new Stream();
            }
            else if (object is Array)
            {
                //$ from array
                result = new Stream((object as Array).concat());
            }
            else if (object is Vector.<*> || object is Vector.<Number> || object is Vector.<int> || object is Vector.<uint>)
            {
                var a:Array = [];
                for (var i:int = 0; i < object.length; i++)
                {
                    a[i] = object[i];
                }
                result = new Stream(a);
            }
            else if (object is IList)
            {
                //$ from list
                result = new Stream(object.toArray());
            }
            else if (object is Stream)
            {
                //$ from list
                result = Stream(object).concat();
            }
            else if(object is XML)
            {
                var xm:Array = [];
                for each(var xml:XML in (object as XML).children())
                {
                    xm.push(xml);
                }
                result = new Stream(xm);
            }
            else if(object is XMLList)
            {
                var x:Array = [];
                for each(var xmlItem:XML in object)
                {
                    x.push(xmlItem);
                }
                result = new Stream(x);
            }
            else
            {
                result = new Stream();
                for (var prop:String in object)
                {
                    if(object.hasOwnProperty(prop))
                    {
                        result.push(new Stream([prop, object[prop]]));
                    }
                }
            }

            return callback == null ? result : result.map(callback);
        }

        /**
         * Create stream from object(dictionary) property names.
         * @param object object used as source for a stream
         * @return created Stream object
         * @example
         * <pre>
         *     var obj:Object = {name1: "first", name2: "second"};
         *     var s:Stream = Stream.fromKeys(obj);
         *     trace(s);
         *     //prints ["name1", "name2"]
         * </pre>
         * @internal immutable
         */
        public static function fromKeys(object:Object):Stream
        {
            var result:Stream = new Stream();
            for (var prop:String in object)
            {
                if(object.hasOwnProperty(prop))
                {
                    result.push(prop);
                }
            }
            return result;
        }

        /**
         * Create stream from object(dictionary) property values.
         * @param object object used as source for a stream
         * @return created Stream object
         * @example
         * <pre>
         *     var obj:Object = {name1: "first", name2: "second"};
         *     var s:Stream = Stream.fromValues(obj);
         *     trace(s);
         *     //prints ["first", "second"]
         * </pre>
         * @internal immutable
         */
        public static function fromValues(object:Object):Stream
        {
            var result:Stream = new Stream();
            for (var prop:String in object)
            {
                if(object.hasOwnProperty(prop))
                {
                    result.push(object[prop]);
                }
            }
            return result;
        }
    }
}

                callback = _;
            }

            callback = transform(callback);

            var max:* = first;
            var maxValue:Number = callback(first, 0, source);

            for(var i:int = 0; i < source.length; i++)
            {
                var current:* = source[i];
                var result:Number = callback(current, i, source);
                if(maxValue < result)
                {
                    maxValue = result;
