          */
         public function map(callback:Function):Stream
         {
+            return new Stream(source.map(transform(callback)));
+        }
+
+        /**
+         * 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(transform(callback));
+        }
+
+        /**
+         * 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;
+        }
+
+        private function transform(callback:Function):Function
+        {
             var count:uint = callback.length;
             var f:Function;
             switch(count)

        {
            var result:Stream = new Stream();
            var dict:Dictionary = new Dictionary();
            for each (var item:* in source)
            {
                var name:* = key(item);
                var s:Stream = dict[name];
                if(s == null)
                {

         */
        public function find(callback:Function, reverse:Boolean = false):*
        {
            callback = transform(callback);

            if(reverse)
            {
                for(var k:int = source.length - 1; k > 0; k--)
                {
                    if(callback(source[k], k, source))
                    {
                        return source[k];
                    }
