    package flare.analytics.graph
    {
        import flare.animate.Transitioner;
        import flare.util.Property;
        import flare.vis.data.Data;
        import flare.vis.data.EdgeSprite;
        import flare.vis.data.NodeSprite;
        import flare.vis.operator.Operator;

        import flash.utils.Dictionary;

        /**
         * Calculates the maximum flow along edges of a graph using the
         * Edmonds-Karp method. Each edge in the graph will be annotated with its
         * final flow value, as well as a boolean value indicating if the edge
         * is part of the minimum cut of the flow graph. Nodes are annotated with
         * their partition according to the minimum cut: a partition value of 0
         * indicates the source-side of the cut, a value of 1 indicates the
         * sink-side of the cut.
         */
        public class MaxFlowMinCut extends Operator
        {
            private var _c:Property = Property.$("props.capacity");
            private var _f:Property = Property.$("props.flow");
            private var _p:Property = Property.$("props.predecessor");
            private var _k:Property = Property.$("props.mincut");
            private var _cap:Function = null;

            /** The property in which to store computed flow values. This property
             *  is used to annotate edges with the computed flow. The default
             *  value is "props.flow". */
            public function get flowField():String { return _f.name; }
            public function set flowField(f:String):void { _f = Property.$(f); }

            /** The property in which to store minimum-cut data. The default value
             *  is "props.mincut". This property is used to annotate nodes with
             *  their partition (0 for source-side, 1 for sink-side) and to
             *  annotate edges with min-cut membership (true if part of the
             *  minimum cut, false otherwise). */
            public function get mincutField():String { return _k.name; }
            public function set mincutField(f:String):void { _k = Property.$(f); }

            /** The source node for which to compute the max flow. */
            public var source:NodeSprite;
            /** The sink node for which to compute the max flow. */
            public var sink:NodeSprite;
            /** A function defining the edge capacities for flow. When setting
             *  this value, one can pass in either a Function, which should take an
             *  EdgeSprite as input and return a Number as output, or a String, in
             *  which case the string will be used as a property name from which to
             *  retrieve the edge capacity value from an EdgeSprite instance.
             *  If the value is null (the default) all edges will be assumed to have
             *  capacity 1.
             *
             *  <p><b>NOTE:</b> Capacities must be greater than or equal to zero!
             *  </p> */
            public function get edgeCapacity():Function { return _cap; }
            public function set edgeCapacity(c:*):void {
                if (c==null) {
                    _cap = null;
                } else if (c is String) {
                    _cap = Property.$(String(c)).getValue;
                } else if (c is Function) {
                    _cap = c;
                } else {
                    throw new Error("Unrecognized edgeCapacity value. " +
                        "The value should be a Function or String.");
                }
            }

            /** The computed maximum flow value. This value is zero by default
             *  and is populated once the max flow calculation is run. */
            public function get maxFlow():Number { return _maxFlow; }

            private var _data:Data, _s:NodeSprite, _t:NodeSprite;
            private var _maxFlow:Number = 0;

            // --------------------------------------------------------------------

            /**
             * Creates a new MaxFlowMinCut operator.
             * @param source the source node in the flow graph
             * @param sink the sink node in the flow graph
             * @param edgeCapacity the edge capacity values. This can either be a
             *  <code>Function</code> that returns capacity values or a
             *  <code>String</code> providing the name of a property to look up on
             *  <code>EdgeSprite</code> instances.
             */
            public function MaxFlowMinCut(source:NodeSprite=null,
                sink:NodeSprite=null, edgeCapacity:*=n