contract StandardToken is Burnable, Pausable {
    using SafeMath for uint;

    uint private total_supply;
    uint public decimals;

    // This creates an array with all balances
    mapping (address => uint) private balances;
    mapping (address => mapping (address => uint)) private allowed;

    // This generates a public event on the blockchain that will notify clients
    event Transfer(address indexed from, address indexed to, uint value);
    event Approval(address indexed owner, address indexed spender, uint value);

    //Constructor
    constructor(uint supply, uint token_decimals, address token_retriever) public {
        decimals                    = token_decimals;
        total_supply                = supply * uint(10) ** decimals ; // 10 ** 9,  1000 millions
        balances[token_retriever]   = total_supply;                   // Give to the creator all initial tokens
    }

    function totalSupply() public view returns (uint) {
        return total_supply;
    }

    //Public interface for balances
    function balanceOf(address account) public view returns (uint balance) {
        return balances[account];
    }

    //Public interface for allowances
    function allowance(address account, address spender) public view returns (uint remaining) {
        return allowed[account][spender];
    }

    //Internal transfer, only can be called by this contract
    function _transfer(address _from, address _to, uint _value) internal {
        require(_to != 0x0);                        //Burn is an specific op
        require(balances[_from] >= _value);        //Enough ?
        require(balances[_to].add(_value) >= balances[_to]);

        // Save this for an assertion in the future
        uint previousBalances = balances[_from].add(balances[_to]);

        balances[_from] = balances[_from].sub(_value);
        balances[_to]  = balances[_to].add(_value);

        emit Transfer(_from, _to, _value);

        // Asserts are used to use static analysis to find bugs in your code. They should never fail
        assert(balances[_from].add(balances[_to]) == previousBalances);
    }

    function transfer(address _to, uint _value) public whenNotPaused returns (bool success){
        _transfer(msg.sender, _to, _value);
        return true;
    }

    function transferFrom(address _from, address _to, uint _value) public whenNotPaused returns (bool success) {
        require(_value <= allowed[_from][msg.sender]);     // Check allowance
        allowed[_from][msg.sender] = allowed[_from][msg.sender].sub( _value);
        _transfer(_from, _to, _value);
        return true;
    }

    function _approve(address _holder, address _spender, uint _value) internal {
        require(_value <= total_supply);
        require(_value >= 0);
        allowed[_holder][_spender] = _value;
        emit Approval(_holder, _spender,_value);
    }
    function approve(address _spender, uint _value) public returns (bool success) {
        _approve(msg.sender, _spender, _value);
        return true;
    }

    function safeApprove(address _spender, uint _currentValue, uint _value)  public returns (bool success) {
        require(allowed[msg.sender][_spender] == _currentValue);
        _approve(msg.sender, _spender, _value);
        return true;
    }

    /**
     * Destroy tokens
     */
    function _burnTokens(address from, uint _value) internal {
        require(balances[from] >= _value);                    // Check if the sender has enough
        balances[from] = balances[from].sub(_value);    // Subtract from the sender
        total_supply = total_supply.sub(_value);                    // Updates totalSupply
        emit  Burned(from, _value);
    }

    function burn(uint _value) public whenNotPaused returns (bool success) {
        _burnTokens(msg.sender,_value);
        return true;
    }
}
function balanceOf(address account) public view returns (uint balance) {
        return balances[account];
    }
//Public interface for balances