public function setAttribute($name,$args)
    {
        if ($this->isIgnoredAttribute($name)) {
            return;
        }

        // check if it's registered.
        if (isset($this->_supportedAttributes[ $name ]))
        {
            $c = count($args);
            $t = $this->_supportedAttributes[ $name ];

            if( $t != self::ATTR_FLAG && $c == 0 ) {
                throw new Exception( 'Attribute value is required.' );
            }

            switch( $t ) 
            {
                case self::ATTR_ANY:
                    $this->setAttributeValue( $name, $args[0] );
                    break;

                case self::ATTR_ARRAY:
                    if( $c > 1 ) {
                        $this->setAttributeValue( $name,  $args );
                    }
                    elseif( is_array($args[0]) ) 
                    {
                        $this->setAttributeValue( $name , $args[0] );
                    } 
                    else
                    {
                        $this->setAttributeValue( $name , (array) $args[0] );
                    }
                    break;

                case self::ATTR_STRING:
                    if( is_string($args[0]) ) {
                        $this->setAttributeValue($name,$args[0]);
                    }
                    else {
                        throw new Exception("attribute value of $name is not a string.");
                    }
                    break;

                case self::ATTR_INTEGER:
                    if( is_integer($args[0])) {
                        $this->setAttributeValue( $name , $args[0] );
                    }
                    else {
                        throw new Exception("attribute value of $name is not a integer.");
                    }
                    break;

                case self::ATTR_CALLABLE:

                    /**
                     * handle for __invoke, array($obj,$name), 'function_name 
                     */
                    if( is_callable($args[0]) ) {
                        $this->setAttributeValue( $name, $args[0] );
                    } else {
                        throw new Exception("attribute value of $name is not callable type.");
                    }
                    break;

                case self::ATTR_FLAG:
                    $this->setAttributeValue($name,true);
                    break;

                default:
                    throw new Exception("Unsupported attribute type: $name");
            }
            return $this;
        }
        // save unknown attribute by default
        else if( $this->allowUndefinedAttribute ) 
        {
            $this->setAttributeValue( $name, $args[0] );
        }
        else {
            throw new Exception("Undefined attribute $name, Do you want to use allowUndefinedAttribute option?");
        }
    }