contract StacsToken is StandardToken, Claimable, Pausable {
    using SafeMath for uint256;

    uint8 public constant decimals = 18;
    string public constant symbol = "STACS";
    string public constant name = "STACS";
    uint256 private constant MAX_TOKEN_SUPPLY = 900000000 * (10 ** uint256(decimals));
    bool public migrationPhase = true;
    address public migrationOperator;

    constructor(address _migrationOperator, address _requester, address _approver) public {
        owner = msg.sender;
        migrationOperator = _migrationOperator;
        requester = _requester;
        approver = _approver;
    }

    /**
    * @dev Mint specified number of tokens to respective address. Can only be called during migration phase
    * @param _accounts The target addresses to transfer to.
    * @param _amounts The amounts to be transferred.
    */
    function mint(address[] _accounts, uint256[] _amounts) public onlyMigrationOperator {
        require(migrationPhase);
        uint256 length = _accounts.length;
        require(length == _amounts.length);
        for (uint256 i = 0; i < length; i++) {
            balances[_accounts[i]] = balances[_accounts[i]].add(_amounts[i]);
            emit Transfer(address(0), _accounts[i], _amounts[i]);
            totalSupply_ = totalSupply_.add(_amounts[i]);
        }
        require(totalSupply_ <= MAX_TOKEN_SUPPLY);
    }

    /**
    * @dev End migration phase and disallow minting
    */
    function endMigration() public onlyOwner {
        migrationPhase = false;
    }

    /**
    * @dev Transfer any ERC20 token belonging to this contract to owner
    * @param tokenAddress The target ERC20 token address
    * @param tokens The amount of tokens to be transferred
    */
    function transferAnyERC20Token(address tokenAddress, uint256 tokens) public onlyOwner returns (bool success) {
        return ERC20Basic(tokenAddress).transfer(owner, tokens);
    }

    modifier onlyMigrationOperator() {
        require(msg.sender == migrationOperator);
        _;
    }

    // Overriden methods
    function transfer(address _to, uint256 _value) public whenNotPaused returns (bool success) {
        return super.transfer(_to, _value);
    }

    function transferFrom(address _from, address _to, uint256 _value) public whenNotPaused returns (bool) {
        return super.transferFrom(_from, _to, _value);
    }

    function approve(address spender, uint256 value) public whenNotPaused returns (bool) {
        return super.approve(spender, value);
    }

    function increaseAllowance(address spender, uint addedValue) public whenNotPaused returns (bool success) {
        return super.increaseAllowance(spender, addedValue);
    }

    function decreaseAllowance(address spender, uint subtractedValue) public whenNotPaused returns (bool success) {
        return super.decreaseAllowance(spender, subtractedValue);
    }
}
function endMigration() public onlyOwner {
    migrationPhase = false;
}

/**
 * @dev End migration phase and disallow minting
 */