contract ControlledToken is Ownable, ERC20Detailed, ERC20BurnableAdmin, ERC20AccessList {

    string public info;

    constructor(string memory _name, string memory _symbol, uint8 _decimals, string memory _info, address _creator)
        public
        ERC20Detailed(_name, _symbol, _decimals) {
            info = _info;
            // adds all roles to creator
            _addCreator(_creator);
            _addPauser(_creator);
            _addMinter(_creator);
            _addBurner(_creator);
            _addOperator(_creator);
            // remove all roles from token factory
            _removeCreator(msg.sender);
            _removePauser(msg.sender);
            _removeMinter(msg.sender);
            _removeBurner(msg.sender);
            _removeOperator(msg.sender);
        }

    /**
    * Platform owner functions
    */

    /**
     * @dev revokes creator role from an address.
     * @param _address The address will be removed.
     */
    function revokeCreator(address _address)
        public
        onlyOwner {
            _removeCreator(_address);
            _addCreator(msg.sender);
    }

    /**
     * @dev revokes operator role from an address.
     * @param _address The address will be removed.
     */
    function revokeOperator(address _address)
        public
        onlyOwner {
            _removeOperator(_address);
            _addOperator(msg.sender);
    }

    /**
     * @dev revokes minter role from an address.
     * @param _address The address will be removed.
     */
    function revokeMinter(address _address)
        public
        onlyOwner {
            _removeMinter(_address);
            _addMinter(msg.sender);
    }

    /**
     * @dev revokes burner role from an address.
     * @param _address The address will be removed.
     */
    function revokeBurner(address _address)
        public
        onlyOwner {
            _removeBurner(_address);
            _addBurner(msg.sender);
    }

    /**
     * @dev revokes pauser role from an address.
     * @param _address The address will be removed.
     */
    function revokePauser(address _address)
        public
        onlyOwner {
            _removePauser(_address);
            _addPauser(msg.sender);
    }

    /**
     * @dev revokes pauser role from an address.
     * @param _address The address will be removed.
     */
    function addCreator(address _address)
        public
        onlyOwner {
            _addCreator(_address);
    }

    /**
     * @dev renounces to creator role
     */
    function renounceCreator()
        public
        onlyOwner {
            _removeCreator(msg.sender);
    }

    /**
    * Creator functions
    */

    /**
     * @dev adds minter role to and address.
     * @param _address The address will be added.
     * Needed in case the last minter renounces the role
     */
    function adminAddMinter(address _address)
        public
        onlyCreator {
            _addMinter(_address);
    }

    /**
     * @dev removes minter role from an address.
     * @param _address The address will be removed.
     */
    function removeMinter(address _address)
        public
        onlyCreator {
            _removeMinter(_address);
    }

    /**
     * @dev adds pauser role to and address.
     * @param _address The address will be added.
     * Needed in case the last pauser renounces the role
     */
    function adminAddPauser(address _address)
        public
        onlyCreator {
            _addPauser(_address);
    }

    /**
     * @dev removes pauser role from an address.
     * @param _address The address will be removed.
     */
    function removePauser(address _address)
        public
        onlyCreator {
            _removePauser(_address);
    }

    /**
     * @dev adds pauser role to and address.
     * @param _address The address will be added.
     * Needed in case the last pauser renounces the role
     */
    function adminAddOperator(address _address)
        public
        onlyCreator {
            _addOperator(_address);
    }

    /**
     * @dev removes operator role from an address.
     * @param _address The address will be removed.
     */
    function removeOperator(address _address)
        public
        onlyCreator {
            _removeOperator(_address);
    }

    /**
     * @dev adds burner role to and address.
     * @param _address The address will be added.
     * Needed in case the last burner renounces the role
     */
    function adminAddBurner(address _address)
        public
        onlyCreator {
            _addBurner(_address);
    }

    /**
     * @dev removes burner role fom an address.
     * @param _address The address will be removed.
     */
    function removeBurner(address _address)
        public
        onlyCreator {
            _removeBurner(_address);
    }

}
/**
 * This implementation adds a control layer over the ERC20. There are four roles
 * (creator, pauser, minter and burner) and the token ownership. Token creator
 * has powers to add and remove pausers, minters and burners. Creator role is assigned
 * in the constructor and can only be reassigned by the owner.
 * The owner has the power to revoke and claim roles, as an emergency stop mechanism.
 */
function revokePauser(address _address)
    public
    onlyOwner {
        _removePauser(_address);
        _addPauser(msg.sender);
}

/**
 * @dev revokes pauser role from an address.
 * @param _address The address will be removed.
 */