function vestedAmount(address _beneficiary) public view whenPlanExist(_beneficiary) returns (uint256) {

        if (block.timestamp <= plans[_beneficiary].locktoTime) {
            return 0;
        } else if (plans[_beneficiary].isRevoked) {
            return plans[_beneficiary].releasedAmount;
        } else if (block.timestamp > plans[_beneficiary].endTime && plans[_beneficiary].totalToken == plans[_beneficiary].releasedAmount) {
            return plans[_beneficiary].totalToken;
        }
        
        uint256 totalTime = plans[_beneficiary].endTime.sub(plans[_beneficiary].locktoTime);
        uint256 totalToken = plans[_beneficiary].totalToken;
        uint256 releaseStages = plans[_beneficiary].releaseStages;
        uint256 endTime = block.timestamp > plans[_beneficiary].endTime ? plans[_beneficiary].endTime : block.timestamp;
        uint256 passedTime = endTime.sub(plans[_beneficiary].locktoTime);
        
        uint256 unitStageTime = totalTime.div(releaseStages);
        uint256 unitToken = totalToken.div(releaseStages);
        uint256 currStage = passedTime.div(unitStageTime);

        uint256 totalBalance = 0;        
        if(currStage > 0 && releaseStages == currStage && (totalTime % releaseStages) > 0 && block.timestamp < plans[_beneficiary].endTime) {
            totalBalance = unitToken.mul(releaseStages.sub(1));
        } else if(currStage > 0 && releaseStages == currStage) {
            totalBalance = totalToken;
        } else if(currStage > 0) {
            totalBalance = unitToken.mul(currStage);
        }
        return totalBalance;
        
    }