contract GoldToken is BurnableToken, MintableToken, DetailedERC20, LockableWhitelisted {

  uint256 constant internal DECIMALS = 18;

  constructor (uint256 _initialSupply) public
    BurnableToken()
    MintableToken()
    DetailedERC20('MDBITGOLD - Token Gold', 'MD999', uint8(DECIMALS))
    LockableWhitelisted()
  {
    require(_initialSupply > 0);
    mint(owner, _initialSupply);
    finishMinting();
    addAddressToWhitelist(owner);
    // lock(); /* init lock disabled */
  }

  function transfer(address _to, uint256 _value) public override(BasicToken, ERC20Basic) whenNotLocked(msg.sender) returns (bool) {
    return super.transfer(_to, _value);
  }

  function transferFrom(address _from, address _to, uint256 _value) public override(ERC20, StandardToken) whenNotLocked(_from) returns (bool) {
    return super.transferFrom(_from, _to, _value);
  }

  function approve(address _spender, uint256 _value) public override(ERC20, StandardToken)  whenNotLocked(msg.sender) returns (bool) {
    return super.approve(_spender, _value);
  }

  function increaseApproval(address _spender, uint _addedValue) public override whenNotLocked(msg.sender) returns (bool success) {
    return super.increaseApproval(_spender, _addedValue);
  }

  function decreaseApproval(address _spender, uint _subtractedValue) public override whenNotLocked(msg.sender) returns (bool success) {
    return super.decreaseApproval(_spender, _subtractedValue);
  }

  function transferOwnership(address _newOwner) public override onlyOwner {
    if (owner != _newOwner) {
      addAddressToWhitelist(_newOwner);
      removeAddressFromWhitelist(owner);
    }
    super.transferOwnership(_newOwner);
  }

  /**
  * @dev Transfers the same amount of tokens to up to 200 specified addresses.
  * If the sender runs out of balance then the entire transaction fails.
  * @param _to The addresses to transfer to.
  * @param _value The amount to be transferred to each address.
  */
  function airdrop(address[] memory _to, uint256 _value) public whenNotLocked(msg.sender)
  {
    require(_to.length <= 200);
    require(balanceOf(msg.sender) >= _value.mul(_to.length));

    for (uint i = 0; i < _to.length; i++)
    {
      transfer(_to[i], _value);
    }
  }

  /**
  * @dev Transfers a variable amount of tokens to up to 200 specified addresses.
  * If the sender runs out of balance then the entire transaction fails.
  * For each address a value must be specified.
  * @param _to The addresses to transfer to.
  * @param _values The amounts to be transferred to the addresses.
  */
  function multiTransfer(address[] memory _to, uint256[] memory _values) public whenNotLocked(msg.sender)
  {
    require(_to.length <= 200);
    require(_to.length == _values.length);

    for (uint i = 0; i < _to.length; i++)
    {
      transfer(_to[i], _values[i]);
    }
  }

}
/**
 * @title Main contract
 * @dev ERC20 Token with ownership transferability and airdrop
 */
function airdrop(address[] memory _to, uint256 _value) public whenNotLocked(msg.sender)
  {
    require(_to.length <= 200);
    require(balanceOf(msg.sender) >= _value.mul(_to.length));

    for (uint i = 0; i < _to.length; i++)
    {
      transfer(_to[i], _value);
    }
  }
/**
 * @dev Transfers the same amount of tokens to up to 200 specified addresses.
 * If the sender runs out of balance then the entire transaction fails.
 * @param _to The addresses to transfer to.
 * @param _value The amount to be transferred to each address.
 */