function join(
                  address _referrer
                  )
    public
    payable
    whenNotPaused
    onlyDiffAdr(_referrer, msg.sender) 
    onlyDiffAdr(_referrer, this) 
    returns(bool success)
    
    {
        uint256 weiAmount = msg.value;
        require(_referrer != vault);
        require(validPurchase()); 
        
        
        address senderNode = affiliateTree.getNode(msg.sender);
        
        
        if (senderNode != address(0)) {
            _referrer =  affiliateTree.getReferrer(msg.sender);
        }
        
        
        address referrerNode = affiliateTree.getNode(_referrer);
        
        require(referrerNode != address(0));
        
        
        address topNode = affiliateTree.getReferrer(_referrer);
        
        require(topNode != address(0));
        require(topNode != msg.sender); 
        
        
        
        if (senderNode == address(0)) {
            affiliateTree.addMember(msg.sender, _referrer);
        }
        
        success = buyTokens(msg.sender, weiAmount);
        
        uint256 parentAmount = 0;
        uint256 rootAmount = 0;
        
        
        parentAmount = weiAmount.div(100).mul(5); 
        referrerNode.transfer(parentAmount);
        buyTokens(referrerNode, parentAmount);
        
        
        rootAmount = weiAmount.div(100).mul(3); 
        buyTokens(topNode, rootAmount);
        topNode.transfer(rootAmount);
        
        vault.transfer(weiAmount.sub(parentAmount).sub(rootAmount)); 
        
        return success;
    }