contract HoldableToken is StandardToken {

	//Specific block to support holdwallet
    mapping (address => bool) private holdFlag;

    //Another contract can do a finer track of the hold
    address public holdAssistantAddr = address(0);

	function holded(address _account) public view returns(bool) {
		return holdFlag[_account];
	}

    function adminHold(bool _status) public onlyOwner returns (bool) {
        holdFlag[msg.sender] = _status;

        //Just in case that fine tracker exists
        if (address(0) != holdAssistantAddr) {
            HoldAssistant(holdAssistantAddr).adminHold(msg.sender, balanceOf(msg.sender), _status);
        }
        emit Log_AdminHold(msg.sender, block.number, balanceOf(msg.sender), _status);
		return true;
    }
    function hold(bool _status) public returns (bool) {
        holdFlag[msg.sender] = _status;

        //Just in case that fine tracker exists
        if (address(0) != holdAssistantAddr) {
            require(HoldAssistant(holdAssistantAddr).hold(msg.sender, balanceOf(msg.sender), _status));
        }
        emit Log_Hold(msg.sender, block.number, balanceOf(msg.sender), _status);
		return true;
    }
    event Log_Hold(address indexed _account, uint _holdBlock, uint _balance, bool _holded);
    event Log_AdminHold(address indexed _account, uint _holdBlock, uint _balance, bool _holded);

    function setHoldAssistant(address _newHoldAssistant) public onlyOwner returns(bool) {
        holdAssistantAddr = _newHoldAssistant;
        emit Log_SetHoldAssistant(holdAssistantAddr);
		return true;
    }
    event Log_SetHoldAssistant(address);

    modifier notHolded(address _account) {
        require(! holdFlag[_account]);
        _;
    }


  	//We restrict transfers by overriding it
  	function transfer(address to, uint value) public notHolded(msg.sender) returns (bool success) {
  		return super.transfer(to, value);
  	}

  	//We restrict transferFrom by overriding it
  	//"from" must be an agent before released
  	function transferFrom(address from, address to, uint value) public notHolded(from) returns (bool success) {
   	 	return super.transferFrom(from, to, value);
  	}

  	//We restrict burn by overriding it
  	function burn(uint value) public notHolded(msg.sender) returns (bool success) {
    	return super.burn(value);
  	}

}
//Define interface for releasing the token transfer after a successful crowdsale.
function transferFrom(address from, address to, uint value) public notHolded(from) returns (bool success) {
   	 	return super.transferFrom(from, to, value);
  	}
//We restrict transferFrom by overriding it
//"from" must be an agent before released