TweenPro = function()
	{        
	    this._beginReady = this._endReady = this._thenReady = false;
	    
	    
	    
	    /**
	     * Called on first tween start
	     * 
	     * @returns {TweenPro}
	     */
	    this._run = function()
	    {
	        if(this._duration)
	        {
	            this._startProgress();
	        }
	        // get current display and/or visibility values before starting, if needed
	        if(this._hasStaticProps)
	        {
	            this._fetchStaticProps();
	            this._setStaticProps('tween');                                        
	        }

	        this._running = true;
	        this._delayDummy = null;
	        
	        if(this._emulatedBegin && this._hasHandlers('_begin'))
	        {
	            this._runHandlers('_begin');
	        }
	        
	        // if from() or fromTo() tween, need to jump to begin position before starting the animation
	        if(this._emulatedFrom && this._from)
	        {
	            this._setTween('begin');
	        }
	        
	        this._startTime = Tw.ticker.now();             
	        this._playTween();

	        return this;            
	    };                                 


	    /**
	     * Used to restore begin or end style values accordingly to current direction
	     * 
	     * @param {string} field
	     */
	    this._backTween = function(field)
	    {
	        this._resetTween(field);
	    };


	    /**
	     * Set style values accordinglty to the param, and perform postTween actions
	     * 
	     * @param {string} field
	     */
	    this._resetTween = function(field)
	    {
	        this._setTween(field);
	        this._postTween(field);            
	    };


	    /**
	     * Perform actions before starting the tween. Apply to both directions
	     * 
	     * @param {boolean} direction - true = forward, false = backward
	     */
	    this._preTween = function(direction)
	    {
	        var field = direction? 'begin' : 'end';
	        if(this._hasStaticProps && this._duration)
	        {
	            this._setStaticProps(field, 'tween');                            
	        }
	        this._setTween(field);
	    };
	    

	    /**
	     * Perform actions after ending the tween. Apply to both directions
	     * 
	     * @param {string} field
	     */
	    this._postTween = function(field)
	    {
	        if(field == 'end')                
	        {
	            if(this._hasThen)
	            {
	                this._setTween('then');
	            }
	            if(this._hasStaticProps)
	            {
	                this._setStaticProps(field, 'then');
	            }
	        }
	        else
	        {
	            // if the tween is reversed, restore previous style values
	            // this is needed in timelines, when a reversed tween is preceded by others that refer common targets, with a time gap between them
	            // otherwise, during the time gap in reverse direction the targets will have wrong style values
	            if(this._hasPre)// && this._offset !== 0)
	            {
	                this._setTween('pre');
	            }
	            this._setStaticProps(field);
	        }

	    };


	    /**
	     * Get a simple name: value map of style property, ready to be passed to the chosen animation library.
	     * If supported, set also the per-property easing specified by the user
	     * 
	     * @param {object} tween - tween data structure
	     * @param {string} field - 'begin' | 'end' | 'pre' | 'then'
	     * @param {boolean} isSet - true when the values are needed for changing the style instantly. Easing info are omitted in this case
	     * @returns {object}
	     */
	    this._getTweenValues = function(tween, field, isSet)
	    {
	        var values = {}, entry, value, name, easing, i = 0;
	        for(name in tween)
	        {
	            entry = tween[name];
	            value = null;
	            easing = entry.easing;

	            if(entry[field] !== null)
	            {
	                i++;
	                // cast pure numeric string to number. This avoid bugs in Transit and other libraries that potentially does not support numeric 
	                // values passed as string
	                value = isNumeric(entry[field])? Number(entry[field]) : entry[field];
	                value = isSet || !this._allowMultipleEasing || !easing? value : [value, this._getRealEasing(easing)];
	                values[name] = value;
	            }            
	        }

	        // instead of handling different errors from any library involved, if there are no values to set, we force a fake tween
	        if(!i)
	        {
	            values.opacity = '+=0';
	        }

	        return values;
	    };


	    /**
	     * Fetch a style value for a dom element
	     * 
	     * @param {object} item - dom element
	     * @param {string} name - property name
	     * @param {boolean} useStyle - if true, use element.style instead of computedStyle value
	     * @returns {string|number}
	     */
	    this._getCurrentValue = function(item, name, useStyle)
	    {
	        var style = useStyle? item.style : window.getComputedStyle(item);
	        return style[name];        
	    };


	    /**
	     * Fetch current values for display and / or visibility properties
	     * 
	     */
	    this._fetchStaticProps = function()
	    {             
	        this._staticProps = [];
	        
	        var item, i, end, names, name, value, fieldName, field, hidden, tweenValue, values;
	        for(i = 0, end = this._getTargetLength(); i < end; i++)
	        {
	            item = this._target.get(i);
	            names = {display: false, visibility: false};
	            
	            this._staticProps[i] = {
	                begin: {},
	                end: {},
	                then: {},
	                tween: {}
	            };
	            
	            for(name in names)
	            {
	                fieldName = '_' + name;
	                field = cloneObject(this[fieldName]);
	                if(field.mask > 0)
	                {
	                    if(field.mask < 7)
	                    {
	                        value = this._getCurrentValue(item, name, false);
	                        if(field.begin === null)
	                        {
	                            field.begin = value;
	                        }

	                        if(field.end === null)
	                        {
	                            field.end = value;
	                            if(field.then === null)
	                            {
	                                field.then = value;
	                            }
	                        }                                                                                
	                    }

	                    values = this._staticProps[i];
	                    
	                    values.begin[name] = field.begin;
	                    values.end[name] = field.end;
	                    values.then[name] = field.then;
	                    // values that show the element need to be set before the tween
	                    hidden = (name == 'display')? 'none' : 'hidden';
	                    tweenValue = field.begin != hidden? field.begin : (field.end != hidden? field.end : false);
	                    if(tweenValue !== false)
	                    {
	                        values.tween[name] = tweenValue;
	                    }                    
	                }
	            }
	        }
	    };
	    
	    
	    /**
	     * Set display and visibility properties, that are handled separately
	     * @link http://tweene.com/docs/#displayVisibility
	     * 
	     * @param {string} first
	     * @param {string} [second] two set of values could be applied toghether in some cases, for example end + then or begin + tween
	     */
	    this._setStaticProps = function(first, second)
	    {
	        if(this._staticProps.length)
	        {
	            var i, end, values;
	            for(i = 0, end = this._getTargetLength(); i < end; i++)
	            {                
	                values = this._staticProps[i][first];
	                if(second)
	                {
	                    values = extendObject(values, this._staticProps[i][second]);
	                }
	                if(!isEmpty(values))
	                {
	                    this._target.eq(i).css(values);
	                }
	            }
	        }
	    };         
	    

	    /**
	     * Override TweenCommon._getRealEasing()
	     * It generates also custom bezier curves needed for resuming a paused tween honoring the original easing effect
	     * 
	     * @param {string|array} value
	     * @returns {string|array|function}
	     */
	    this._getRealEasing = function(value)
	    {
	        if(isString(value) && value in easings)
	        {
	            value = easings[value];
	        }

	        if(isArray(value))
	        {
	            var position = this._position;
	            // in backward direction, reverse the bezier curve too
	            if(!this._localFwd)
	            {
	                value = reverseBezier(value);
	                position = this._duration - position;
	            }

	            var timeRatio = position / this._duration;
	            value = this._getBezierEasing(getNewBezier(value, timeRatio));
	        }

	        return value;
	    };


	}
Vars and methods used in tween object, for animation library that does not have native support 
for playhead control (play / pause / reverse and so on) 
@mixin