multi merge and more comments

multi merge and more comments

pragma solidity ^0.4.9;

contract Workflow {

// Data types:

    // enums are zero indexed - FYI.
    enum RelationType {
        Include, Exclude, Response, Condition, Milestone
    }

    struct Activity {
        // State
        bytes32 name;
        bool included;
        bool executed;
        bool pending;

        // Outgoing relations:
        uint32[] include;
        uint32[] exclude;
        uint32[] response;

        // Incoming relations:
        uint32[] condition;
        uint32[] milestone;

        // Access rights:
        address[] whitelist;
    }

// Workflow data and creation:
    event LogExecution(address sender, uint32 id, bool successful);

    Activity[] activities;
    address owner;
    bytes32 name;

    /// names: array of activity names, where names[i] is the name of activity with id i
    /// included: array of activity included state, where included[i] is the included state of activity with id i
    /// executed: array of activity executed state, where executed[i] is the executed state of activity with id i
    /// pending: array of activity pending state, where pending[i] is the pending state of activity with id i
    /// relations: array of relations in the workflow such that relations[i] is the id of the FROM activity,
    ///            and relations[i+1] is the id of the TO activity, when i is even
    /// relationType: array of RelationType enums, such that relationType[1] is the type of the relations[2]->relations[3] relation.
    /// numberOfAuths: array of number autherized users for each activity.
    ///                Should be ordered such that numberOfAuths[i] is the number of autherized users for activity i.
    ///                If numberOfAuths[i] == 0, then activity i is publicly available for execution
    /// authorizedUsers: array of addresses of the autherized users.
    ///                  Should be ordered such that:
    ///                  authorizedUsers[numberOfAuths[0] + numberOfAuths[1]... + numberOfAuths[i-1]]
    ///                  to
    ///                  authorizedUsers[numberOfAuths[0] + numberOfAuths[1]... + numberOfAuths[i]]
    ///                  is the addresses of the authorized users of activity i.
    function Workflow (
        bytes32 wfName,
        bytes32[] names,
        bool[] included,
        bool[] executed,
        bool[] pending,

        uint32[] relations,
        RelationType[] relationType,

        uint32[] numberOfAuths, //numberOfAuths[0] = number of authorized users for activity 0. If 0, anyone is authorized.
        address[] authorizedUsers //order is defined by numberOfAuths
    ) {
        if((relations.length/2) != relationType.length)
            throw;

        name = wfName;
        owner = msg.sender;

        activities.length = names.length;
        var authIndex = 0;

        for (var i = 0; i < names.length; i++) {
            activities[i].name      = names[i];
            activities[i].included  = included[i];
            activities[i].executed  = executed[i];
            activities[i].pending   = pending[i];
            activities[i].whitelist.length = numberOfAuths[i];
            for(var j = 0; j < numberOfAuths[i]; j++){
                activities[i].whitelist[j] = authorizedUsers[authIndex++];
            }
        }
        // We expect the 'relations' array is formed such that the first index is the FROM activity and the next index is the TO activity. Rinse and repeat.
        for(i = 0; i < relations.length; i=i+2){
            if(relationType[i/2] == RelationType.Include)        activities[relations[i]].include.push(relations[i+1]);
            else if(relationType[i/2] == RelationType.Exclude)   activities[relations[i]].exclude.push(relations[i+1]);
            else if(relationType[i/2] == RelationType.Response)  activities[relations[i]].response.push(relations[i+1]);
            else if(relationType[i/2] == RelationType.Condition) activities[relations[i+1]].condition.push(relations[i]);
            else if(relationType[i/2] == RelationType.Milestone) activities[relations[i+1]].milestone.push(relations[i]);
            else throw;
        }
    }

// Internal functions:
    function canExecute(uint32 actId) private {
        if(activities[actId].whitelist.length > 0) {
            for (var i = 0; i < activities[actId].whitelist.length; i++)
                if(activities[actId].whitelist[i] == msg.sender)
                    break;

            if(i == activities[actId].whitelist.length){
                throw;
            }
        }
    }

// External functions:
    function execute(uint32 id) {
        // Check that activity is in executable state
        canExecute(id);
        Activity memory a = activities[id];

        if(!a.included){
            throw;
        }

        for (var i = 0; i < a.condition.length; i++)
            if(!activities[a.condition[i]].executed && activities[a.condition[i]].included) {
                throw;
                return;
            }

        for (i = 0; i < a.milestone.length; i++)
            if(activities[a.milestone[i]].pending && activities[a.milestone[i]].included) {
                throw;
                return;
            }

        a.executed = true;
        a.pending = false;

        // Effects on other activities
        for (i = 0; i < a.include.length; i++)
            activities[a.include[i]].included = true;
        for (i = 0; i < a.exclude.length; i++)
            activities[a.exclude[i]].included = false;
        for (i = 0; i < a.response.length; i++)
            activities[a.response[i]].pending = true;

        LogExecution(msg.sender, id, true);
    }

    // Selfdestruct
    function sudoku() {
        if(msg.sender != owner)
            throw;

        selfdestruct(owner);
    }

    function getWorkflowName() public constant returns (bytes32){
        return name;
    }

    function getActivityCount(uint i) public constant returns (uint256){
        return activities.length;
    }

    function getActivityName(uint i) public constant returns (bytes32){
        return activities[i].name;
    }

    function isIncluded(uint i) public constant returns (bool){
        return activities[i].included;
    }

    function isExecuted(uint i) public constant returns (bool){
        return activities[i].executed;
    }

    function isPending(uint i) public constant returns (bool){
        return activities[i].pending;
    }

    function getIncludes(uint i) public constant returns (uint32[]){
        return activities[i].include;
    }

    function getExcludes(uint i) public constant returns (uint32[]){
        return activities[i].exclude;
    }

    function getResponses(uint i) public constant returns (uint32[]){
        return activities[i].response;
    }

    function getConditions(uint i) public constant returns (uint32[]){
        return activities[i].condition;
    }

    function getMilestones(uint i) public constant returns (uint32[]){
        return activities[i].milestone;
    }

    function getAccountWhitelist(uint i) public constant returns (address[]){
        return activities[i].whitelist;
    }

    function isAuthDisabled(uint i) public constant returns (bool){
        return (activities[i].whitelist.length == 0);
    }

}

pragma solidity ^0.4.9;

contract Workflow {

// Data types:

    // enums are zero indexed - FYI.
    enum RelationType {
        Include, Exclude, Response, Condition, Milestone
    }

    struct Activity {
        // State
        bytes32 name;
        bool included;
        bool executed;
        bool pending;

        // Outgoing relations:
        uint32[] include;
        uint32[] exclude;
        uint32[] response;

        // Incoming relations:
        uint32[] condition;
        uint32[] milestone;

        // Access rights:
        address[] whitelist;
    }

// Workflow data and creation:
    event LogExecution(address sender, uint32 id, bool successful);

    Activity[] activities;
    address owner;
    bytes32 name;

    /// names: array of activity names, where names[i] is the name of activity with id i
    /// included: array of activity included state, where included[i] is the included state of activity with id i
    /// executed: array of activity executed state, where executed[i] is the executed state of activity with id i
    /// pending: array of activity pending state, where pending[i] is the pending state of activity with id i
    function createWorkflow (
        bytes32 wfName,
        bytes32[] names,
        bool[] included,
        bool[] executed,
        bool[] pending,

        uint32[] relations,
        RelationType[] relationType,

        address[] authorizedUsers, //order is defined by numberOfAuths
        uint32[] numberOfAuths //numberOfAuths[0] = number of authorized users for activity 0. If 0, anyone is authorized.
    ) {
        if((relations.length/2) != relationType.length)
            throw;

        name = wfName;
        owner = msg.sender;

        activities.length = names.length;
        var authIndex = 0;

        for (var i = 0; i < names.length; i++) {
            activities[i].name      = names[i];
            activities[i].included  = included[i];
            activities[i].executed  = executed[i];
            activities[i].pending   = pending[i];
            activities[i].whitelist.length = numberOfAuths[i];
            for(var j = 0; j < numberOfAuths[i]; j++){
                activities[i].whitelist[j] = authorizedUsers[authIndex++];
            }
        }
        // We expect the 'relations' array is formed such the first index is the FROM activity and the next index is the TO activity. Rinse and repeat.
        for(i = 0; i < relations.length; i=i+2){
            if(relationType[i/2] == RelationType.Include)        activities[relations[i]].include.push(relations[i+1]);
            else if(relationType[i/2] == RelationType.Exclude)   activities[relations[i]].exclude.push(relations[i+1]);
            else if(relationType[i/2] == RelationType.Response)  activities[relations[i]].response.push(relations[i+1]);
            else if(relationType[i/2] == RelationType.Condition) activities[relations[i+1]].condition.push(relations[i]);
            else if(relationType[i/2] == RelationType.Milestone) activities[relations[i+1]].milestone.push(relations[i]);
            else throw;
        }
    }

// Internal functions:
    function canExecute(uint32 actId) private {
        if(activities[actId].whitelist.length > 0) {
            for (var i = 0; i < activities[actId].whitelist.length; i++)
                if(activities[actId].whitelist[i] == msg.sender)
                    break;

            if(i == activities[actId].whitelist.length){
                throw;
            }
        }
    }

// External functions:
    function execute(uint32 id) {
        // Check that activity is in executable state
        canExecute(id);
        Activity memory a = activities[id];

        if(!a.included){
            throw;
        }

        for (var i = 0; i < a.condition.length; i++)
            if(!activities[a.condition[i]].executed && activities[a.condition[i]].included) {
                throw;
                return;
            }

        for (i = 0; i < a.milestone.length; i++)
            if(activities[a.milestone[i]].pending && activities[a.milestone[i]].included) {
                throw;
                return;
            }

        a.executed = true;
        a.pending = false;

        // Effects on other activities
        for (i = 0; i < a.include.length; i++)
            activities[a.include[i]].included = true;
        for (i = 0; i < a.exclude.length; i++)
            activities[a.exclude[i]].included = false;
        for (i = 0; i < a.response.length; i++)
            activities[a.response[i]].pending = true;

        LogExecution(msg.sender, id, true);
    }

    // Selfdestruct
    function sudoku() {
        if(msg.sender != owner)
            throw;

        selfdestruct(owner);
    }

    function getWorkflowName() public constant returns (bytes32){
        return name;
    }

    function getActivityCount(uint i) public constant returns (uint256){
        return activities.length;
    }

    function getActivityName(uint i) public constant returns (bytes32){
        return activities[i].name;
    }

    function isIncluded(uint i) public constant returns (bool){
        return activities[i].included;
    }

    function isExecuted(uint i) public constant returns (bool){
        return activities[i].executed;
    }

    function isPending(uint i) public constant returns (bool){
        return activities[i].pending;
    }

    function getIncludes(uint i) public constant returns (uint32[]){
        return activities[i].include;
    }

    function getExcludes(uint i) public constant returns (uint32[]){
        return activities[i].exclude;
    }

    function getResponses(uint i) public constant returns (uint32[]){
        return activities[i].response;
    }

    function getConditions(uint i) public constant returns (uint32[]){
        return activities[i].condition;
    }

    function getMilestones(uint i) public constant returns (uint32[]){
        return activities[i].milestone;
    }

    function getAccountWhitelist(uint i) public constant returns (address[]){
        return activities[i].whitelist;
    }

    function isAuthDisabled(uint i) public constant returns (bool){
        return (activities[i].whitelist.length == 0);
    }

}


Mod DAO, market and agent contract.

Mod DAO, market and agent contract.

DAO: shares functions *100
Market: orderID, price and new functions
Agent: add agent contracts struct

contract token {
    address public daoAddr;
    address public owner;
    mapping (address => uint) public tokenBalanceOf;
    DAO daoToken;

    /*Initial */
    function token() {
        owner = msg.sender;
    }

    /* DAO functions */
    function emission(address _agentContrAddr, uint _amount) returns(bool result) {
        if(msg.sender==daoAddr)
        {
            tokenBalanceOf[_agentContrAddr] += _amount;
            return true;
        }
        return false;
    }

    function burn(address _agentContrAddr, uint _amount) returns(bool result) {
        if(msg.sender==daoAddr && tokenBalanceOf[_agentContrAddr]>=_amount)
        {
            tokenBalanceOf[_agentContrAddr] -= _amount;
            return true;
        }
        return false;
    }

    function setDaoAddr(address _daoAddr) {
        daoToken = DAO(_daoAddr);
        if(daoToken.daoFounder() == msg.sender && owner == msg.sender) {
            daoAddr = _daoAddr;
        }
    }

    /* Agent function */

    function getBalance() returns(uint _balance) {
        return tokenBalanceOf[msg.sender];
    }

    function sendToken(address receiver, uint amount) returns(bool result) {
        if (tokenBalanceOf[msg.sender] < amount) {return false;}
        tokenBalanceOf[msg.sender] -= amount;
        tokenBalanceOf[receiver] += amount;
        return true;
    }
}

contract DAO {
    address public daoFounder;
    address public daoFounderContr;
    address public daoMarketContr;
    address public daoGovermentContr;
    bool public initialization;
    uint public creditAmount;
    uint public sharesAmount;
    uint public creditTurn;
    uint public numAgents;

    token public daoShares;
    token public daoCredits;

    /* Assets data */
    Asset[] public assetsList;
    mapping (address => uint) public assetDataOf;
    mapping (address => bool) public assetExistOf;
    struct Asset {
        address assetAddr;
    }

    /* Agents data */
    Agent[] public agentsList;
    mapping (address => uint) public agentDataOf;
    mapping (address => bool) public agentActiveOf;
    struct Agent {
        address agentContrAddr;
        uint joinData;
    }

    function DAO(token _shares, token _credits, market _daoMarketContr, goverment _daoGovermentContr) {
        daoFounder = msg.sender;
        daoShares = token(_shares);
        daoCredits = token(_credits);
        daoMarketContr = _daoMarketContr;
        daoGovermentContr = _daoGovermentContr;
    }

    function initializationDaoBalances(uint _founderSharesAmount, uint _founderCreditsAmount) returns (bool result) {
        if(!initialization) {
        daoShares.emission(msg.sender, _founderSharesAmount);
        sharesAmount = _founderSharesAmount;
        daoCredits.emission(msg.sender, _founderCreditsAmount);
        creditAmount = _founderCreditsAmount;
        return true;
        }
    }

    function daoEfficiency() returns (uint daoEfficiency) {
        daoEfficiency = creditTurn*100/creditAmount;
    }

    function daoShareCost() returns (uint shareCost) {
        shareCost = creditTurn*100/sharesAmount;
    }

    function daoCreditPower() returns (uint creditPower) {
        creditPower = sharesAmount*100/creditTurn;
    }

    function daoShareSale(uint _shareAmount) returns (uint creditReward) {
        if(daoShares.tokenBalanceOf(msg.sender)>=_shareAmount) {
            creditReward = daoShareCost()*_shareAmount/100;
            daoCredits.emission(msg.sender, creditReward);
            daoShares.burn(msg.sender, _shareAmount);
        }
    }

    function daoShareBuy(uint _creditAmount) returns (uint shares) {
        if(daoCredits.tokenBalanceOf(msg.sender)>=_creditAmount) {
            shares = daoCreditPower()*_creditAmount/100;
            daoShares.emission(msg.sender, shares);
            daoCredits.burn(msg.sender, _creditAmount);
        }
    }

    function daoSharesEmission(address _agentContrAddr, uint _sharesAmount) {
        daoShares.emission(_agentContrAddr, _sharesAmount);
    }

    function daoCreditEmission(uint _creditsAMount) {
        daoCredits.emission(msg.sender, _creditsAMount);
    }

    function setAgent(address _agentContAddr) returns(uint agentID) {
        if(daoShares.tokenBalanceOf(msg.sender)>0) {
            agentID = agentsList.length++;
            Agent a = agentsList[agentID];
            a.agentContrAddr = _agentContAddr;
            a.joinData = now;
            uint newAgentSharesAmount;
            newAgentSharesAmount = sharesAmount/numAgents;
            daoShares.emission(_agentContAddr, newAgentSharesAmount);
            numAgents = agentID;
            agentDataOf[_agentContAddr] = agentID;
            agentActiveOf[_agentContAddr] = true;
            return agentID;
        }
    }

    function setAssets(address _assetAddr) returns(uint assetID) {
        if (msg.sender == daoMarketContr) {
            assetID = assetsList.length++;
            Asset a = assetsList[assetID];
            a.assetAddr = _assetAddr;
            assetDataOf[_assetAddr] = assetID;
            assetExistOf[_assetAddr] = true;
            return assetID;
        }
    }
}

contract agent {
    address agentAddr;
    address controlAddr;
    address daoAddr;
    DAO public dao;

    /* Agents contract list*/

    AgentContract[] public agentContracts;
    struct AgentContract {
        address agentContractAddr;
        string abi;
    }

    modifier controlCheck { if (msg.sender == controlAddr) _ }

    function agent(address _daoAddr) {
        agentAddr = msg.sender;
        controlAddr = msg.sender;
        daoAddr = _daoAddr;
    }

    function setControlAddr(address _controlAddr) returns(bool result) {
        if(msg.sender == agentAddr) {
            controlAddr = _controlAddr;
        }
    }

    function setNewAgent(address _agentAddr) controlCheck returns(bool result) {
        dao.setAgent(_agentAddr);
        return true;
    }
}

contract market {
    address daoAddr;
    DAO public dao;

    struct Order {
        uint orderID;
        address owner;
        uint amount;
        uint price;
    }

    struct OrderList {
        address assetAddr;
        Order[] orders;
    }

    OrderList[] public sellList;
    mapping (address => bool) sellExistOf;
    mapping (address => uint) sellDataOf;

    OrderList[] public buyList;
    mapping (address => bool) buyExistOf;
    mapping (address => uint) buyDataOf;

    function getSellList(address _assetAddr) returns(uint assetID) {
        return 0;
    }

    function getBuyList(address _assetAddr) returns(uint assetID) {
        return 0;
    }

    function addSell(address _assetAddr, uint _amount, uint _price) returns(uint sellID) {
        if (dao.agentActiveOf(msg.sender) && dao.assetExistOf(_assetAddr)) {
            if(sellExistOf[_assetAddr]) {
                uint assetID;
                assetID = sellDataOf[_assetAddr];
                OrderList[] sellOrders = sellList[assetID];
                sellID = sellOrders.orders.length++;
                sellOrders.orders[sellID] = Order({orderID: sellID, owner: msg.sender, amount: _amount, price: _price});
                return assetID;
            }

        }
    }

    function addBuy(address _assetAddr, uint _amount, uint _price) returns(uint buyID) {
        if (dao.agentActiveOf(msg.sender) && dao.assetExistOf(_assetAddr)) {
            if(buyExistOf[_assetAddr]) {
                uint assetID;
                assetID = buyDataOf[_assetAddr];
                OrderList[] buyOrders = buyList[assetID];
                buyID = buyOrders.orders.length++;
                buyOrders.orders[buyID] = Order({orderID: buyID, owner: msg.sender, amount: _amount, price: _price});
                return assetID;
            }

        }
    }

    function сloseBuyDeal(address _assetAddr, buyID) returns(bool result) {
        return true;
    }

    function сloseSellDeal(address _assetAddr, sellID) returns(bool result) {
        return true;
    }

}

contract goverment {
    address daoAddr;
    DAO public dao;

}

contract token {
    address public daoAddr;
    address public owner;
    mapping (address => uint) public tokenBalanceOf;
    DAO daoToken;

    /*Initial */
    function token() {
        owner = msg.sender;
    }

    /* DAO functions */
    function emission(address _agentContrAddr, uint _amount) returns(bool result) {
        if(msg.sender==daoAddr)
        {
            tokenBalanceOf[_agentContrAddr] += _amount;
            return true;
        }
        return false;
    }

    function burn(address _agentContrAddr, uint _amount) returns(bool result) {
        if(msg.sender==daoAddr && tokenBalanceOf[_agentContrAddr]>=_amount)
        {
            tokenBalanceOf[_agentContrAddr] -= _amount;
            return true;
        }
        return false;
    }

    function setDaoAddr(address _daoAddr) {
        daoToken = DAO(_daoAddr);
        if(daoToken.daoFounder() == msg.sender && owner == msg.sender) {
            daoAddr = _daoAddr;
        }
    }

    /* Agent function */

    function getBalance() returns(uint _balance) {
        return tokenBalanceOf[msg.sender];
    }

    function sendToken(address receiver, uint amount) returns(bool result) {
        if (tokenBalanceOf[msg.sender] < amount) {return false;}
        tokenBalanceOf[msg.sender] -= amount;
        tokenBalanceOf[receiver] += amount;
        return true;
    }
}

contract DAO {

    address public daoFounder;
    address public daoFounderContr;
    address public daoMarketContr;
    address public daoGovermentContr;
    bool public initialization;
    uint public creditAmount;
    uint public sharesAmount;
    uint public creditTurn;
    uint public numAgents;

    token public daoShares;
    token public daoCredits;

    /* Assets data */
    Asset[] public assetsList;
    mapping (address => uint) public assetDataOf;
    mapping (address => bool) public assetExistOf;
    struct Asset {
        address assetAddr;
    }

    /* Agents data */
    Agent[] public agentsList;
    mapping (address => uint) public agentDataOf;
    mapping (address => bool) public agentActiveOf;
    struct Agent {
        address agentContrAddr;
        uint joinData;
    }

    function DAO(token _shares, token _credits, market _daoMarketContr, goverment _daoGovermentContr) {
        daoFounder = msg.sender;
        daoShares = token(_shares);
        daoCredits = token(_credits);
        daoMarketContr = _daoMarketContr;
        daoGovermentContr = _daoGovermentContr;
    }

    function initializationDaoBalances(uint _founderSharesAmount, uint _founderCreditsAmount) returns (bool result) {
        if(!initialization) {
        daoShares.emission(msg.sender, _founderSharesAmount);
        sharesAmount = _founderSharesAmount;
        daoCredits.emission(msg.sender, _founderCreditsAmount);
        creditAmount = _founderCreditsAmount;
        return true;
        }
    }

    function daoEfficiency() returns (uint daoEfficiency) {
        daoEfficiency = creditTurn*100/creditAmount;
    }

    function daoShareCost() returns (uint shareCost) {
        shareCost = creditTurn/sharesAmount;
    }

    function daoCreditPower() returns (uint creditPower) {
        creditPower = sharesAmount*100/creditTurn;
    }

    function daoShareSale(uint _shareAmount) returns (uint creditReward) {
        if(daoShares.tokenBalanceOf(msg.sender)>=_shareAmount) {
            creditReward = daoShareCost()*_shareAmount;
            daoCredits.emission(msg.sender, creditReward);
            daoShares.burn(msg.sender, _shareAmount);
        }
    }

    function daoShareBuy(uint _creditAmount) returns (uint shares) {
        if(daoCredits.tokenBalanceOf(msg.sender)>=_creditAmount) {
            shares = daoCreditPower()*_creditAmount;
            daoShares.emission(msg.sender, shares);
            daoCredits.burn(msg.sender, _creditAmount);
        }
    }

    function daoSharesEmission(address _agentContrAddr, uint _sharesAmount) {
        daoShares.emission(_agentContrAddr, _sharesAmount);
    }

    function daoCreditEmission(uint _creditsAMount) {
        daoCredits.emission(msg.sender, _creditsAMount);
    }

    function setAgent(address _agentContAddr) returns(uint agentID) {
        if(daoShares.tokenBalanceOf(msg.sender)>0) {
            agentID = agentsList.length++;
            Agent a = agentsList[agentID];
            a.agentContrAddr = _agentContAddr;
            a.joinData = now;
            uint newAgentSharesAmount;
            newAgentSharesAmount = sharesAmount/numAgents;
            daoShares.emission(_agentContAddr, newAgentSharesAmount);
            numAgents = agentID;
            agentDataOf[_agentContAddr] = agentID;
            agentActiveOf[_agentContAddr] = true;
            return agentID;
        }
    }

    function setAssets(address _assetAddr) returns(uint assetID) {
        if (msg.sender == daoMarketContr) {
            assetID = assetsList.length++;
            Asset a = assetsList[assetID];
            a.assetAddr = _assetAddr;
            assetDataOf[_assetAddr] = assetID;
            assetExistOf[_assetAddr] = true;
            return assetID;
        }
    }
}

contract agent {
    address agentAddr;
    address controlAddr;
    address daoAddr;
    DAO public dao;

    modifier controlCheck { if (msg.sender == controlAddr) _ }

    function agent(address _daoAddr) {
        agentAddr = msg.sender;
        controlAddr = msg.sender;
        daoAddr = _daoAddr;
    }

    function setControlAddr(address _controlAddr) returns(bool result) {
        if(msg.sender == agentAddr) {
            controlAddr = _controlAddr;
        }
    }

    function setAgent(address _agentAddr) controlCheck returns(bool result) {
        dao.setAgent(_agentAddr);
        return true;
    }
}

contract market {
    address daoAddr;
    DAO public dao;

    struct Order {
        address owner;
        uint amount;
    }

    struct OrderList {
        address assetAddr;
        Order[] orders;
    }

    OrderList[] public sellList;
    mapping (address => bool) sellExistOf;
    mapping (address => uint) sellDataOf;

    OrderList[] public buyList;
    mapping (address => bool) buyExistOf;
    mapping (address => uint) buyDataOf;

    function getSellList(address _assetAddr) returns(uint assetID) {
        return 0;
    }

    function getBuyList(address _assetAddr) returns(uint assetID) {
        return 0;
    }

    function addSell(address _assetAddr, uint amount) returns(uint assetID) {
        return 0;
    }

    function addBuy(address _assetAddr, uint _amount) returns(uint buyID) {
        if (dao.agentActiveOf(msg.sender) && dao.assetExistOf(_assetAddr)) {
            if(buyExistOf[_assetAddr]) {
                uint assetID;
                assetID = buyDataOf[_assetAddr];
                OrderList[] buyOrders = buyList[assetID];
                buyID = buyOrders.orders.length++;
                buyOrders.orders[buyID] = Order({owner: msg.sender, amount: _amount});
                return assetID;
            }

        }
    }
}

contract goverment {

}


fix sell buy

fix sell buy

contract token {
    string public assetName;
    address public daoAddr;
    address public owner;
    mapping (address => uint) public tokenBalanceOf;
    DAO daoToken;

    /*Initial */
    function token(string _assetName) {
        assetName = _assetName;
        owner = msg.sender;
    }

    /* DAO functions */
    function emission(address _agentContrAddr, uint _amount) returns(bool result) {
        if(msg.sender==daoAddr || msg.sender==owner)
        {
            tokenBalanceOf[_agentContrAddr] += _amount;
            return true;
        }
        return false;
    }

    function burn(address _agentContrAddr, uint _amount) returns(bool result) {
        if(msg.sender==daoAddr && tokenBalanceOf[_agentContrAddr]>=_amount)
        {
            tokenBalanceOf[_agentContrAddr] -= _amount;
            return true;
        }
        return false;
    }

    function setDaoAddr(address _daoAddr) {
        daoToken = DAO(_daoAddr);
        if(daoToken.daoFounder() == msg.sender && owner == msg.sender) {
            daoAddr = _daoAddr;
        }
    }

    /* Agent function */
    function sendToken(address receiver, uint amount) returns(bool result) {
        if (tokenBalanceOf[msg.sender] < amount) {return false;}
        tokenBalanceOf[msg.sender] -= amount;
        tokenBalanceOf[receiver] += amount;
        return true;
    }
}

contract DAO {
    address public daoFounder;
    address public daoFounderContr;
    address public daoMarketContr;
    address public daoGovermentContr;
    bool public initialization;
    uint public creditAmount;
    uint public sharesAmount;
    uint public creditTurn;
    uint public numAgents;

    token public daoShares;
    token public daoCredits;

    /* Assets data */
    Asset[] public assetsList;
    mapping (address => uint) public assetDataOf;
    mapping (address => bool) public assetExistOf;
    struct Asset {
        address assetAddr;
    }

    /* Agents data */
    Agent[] public agentsList;
    mapping (address => uint) public agentDataOf;
    mapping (address => bool) public agentActiveOf;
    mapping (address => address) public agentContractOf;
    struct Agent {
        address agentContrAddr;
        uint joinData;
    }

    function DAO(token _shares, token _credits, agent _daoFounderContr, market _daoMarketContr, goverment _daoGovermentContr) {
        daoFounder = msg.sender;
        daoShares = token(_shares);
        daoCredits = token(_credits);
        daoFounderContr = _daoFounderContr;
        daoMarketContr = _daoMarketContr;
        daoGovermentContr = _daoGovermentContr;
    }

    function initializationDaoBalances(uint _founderSharesAmount, uint _founderCreditsAmount) returns (bool result) {
        if(!initialization) {
			daoShares.emission(daoFounderContr, _founderSharesAmount);
			sharesAmount = _founderSharesAmount;
			daoCredits.emission(daoFounderContr, _founderCreditsAmount);
			creditAmount = _founderCreditsAmount;
			initialization = true;
			return true;
        }
    }

    function daoEfficiency() returns (uint daoEfficiency) {
        daoEfficiency = creditTurn*100/creditAmount;
    }

    function daoShareCost() returns (uint shareCost) {
        shareCost = creditTurn/sharesAmount;
    }

    function daoCreditPower() returns (uint creditPower) {
        creditPower = sharesAmount*100/creditTurn;
    }

    function daoShareSale(uint _shareAmount) returns (uint creditReward) {
        if(daoShares.tokenBalanceOf(msg.sender)>=_shareAmount) {
            creditReward = daoShareCost()*_shareAmount;
            daoCredits.emission(msg.sender, creditReward);
            daoShares.burn(msg.sender, _shareAmount);
        }
    }

    function daoShareBuy(uint _creditAmount) returns (uint shares) {
        if(daoCredits.tokenBalanceOf(msg.sender)>=_creditAmount) {
            shares = daoCreditPower()*_creditAmount;
            daoShares.emission(msg.sender, shares);
            daoCredits.burn(msg.sender, _creditAmount);
        }
    }

    function daoSharesEmission(address _agentContrAddr, uint _sharesAmount) {
        daoShares.emission(_agentContrAddr, _sharesAmount);
    }

    function daoCreditEmission(address _agentContrAddr, uint _creditsAmount) {
        daoCredits.emission(_agentContrAddr, _creditsAmount);
    }

    function setAgent(address _agentContAddr) returns(uint agentID) {
        if(daoShares.tokenBalanceOf(msg.sender)>0) {
            agentID = agentsList.length++;
            Agent a = agentsList[agentID];
            a.agentContrAddr = _agentContAddr;
            a.joinData = now;
            uint newAgentSharesAmount;
            numAgents = agentID + 1;
            newAgentSharesAmount = sharesAmount/numAgents*daoEfficiency();
            daoShares.emission(_agentContAddr, newAgentSharesAmount);
            agentDataOf[_agentContAddr] = agentID;
            agentActiveOf[_agentContAddr] = true;
            agent Agn = agent(_agentContAddr);
            agentContractOf[Agn.agentAddr()] = _agentContAddr;
            return agentID;
        }
    }

    function setAssets(address _assetAddr) returns(uint assetID) {
        if (agentActiveOf[msg.sender] == true) {
            assetID = assetsList.length++;
            Asset a = assetsList[assetID];
            a.assetAddr = _assetAddr;
            assetDataOf[_assetAddr] = assetID;
            assetExistOf[_assetAddr] = true;
            return assetID;
        }
    }
}

contract agent {
    address public agentAddr;
    address controlAddr;
    address daoAddr;
    DAO public dao;

    /* Agents contract list*/

    AgentContract[] public agentContractList;
    struct AgentContract {
        address agentContractAddr;
        string abi;
        string desc;
        bool active;
    }

    modifier controlCheck { if (msg.sender == controlAddr) _ }

    function agent() {
        agentAddr = msg.sender;
        controlAddr = msg.sender;
    }

    function addAsset(address _tokenAddr) {
        if (msg.sender == agentAddr) {
			dao.setAssets(_tokenAddr);
		}
    }

    function sendToken(address assetAddr, address receiver, uint amount) {
        if (msg.sender == agentAddr || msg.sender == dao.daoMarketContr()) {
			token asset = token(assetAddr);
			asset.sendToken(receiver, amount);
		}
    }

    function setDao(address _daoAddr) {
        if(msg.sender == agentAddr) {
        	daoAddr = _daoAddr;
			dao = DAO(daoAddr);
        }
    }

    function setControlAddr(address _controlAddr) returns(bool result) {
        if(msg.sender == agentAddr) {
            controlAddr = _controlAddr;
        }
    }

    function setNewAgent(address _agentAddr) controlCheck returns(bool result) {
        dao.setAgent(_agentAddr);
        return true;
    }

    function setAgentContract(address _agentContractAddr, string _abi, string _desc) controlCheck returns(uint contractID) {
        contractID = agentContractList.length++;
        AgentContract a = agentContractList[contractID];
        a.agentContractAddr = _agentContractAddr;
        a.abi = _abi;
        a.desc = _desc;
        a.active = true;
        return contractID;
    }

    function inactiveAgentContract(address _agentContractAddr) controlCheck returns(bool result) {

    }
}

contract market {
    address daoAddr;
    DAO public dao;

    struct Order {
        uint orderID;
        address owner;
        uint amount;
        uint price;
        bool active;
    }

    struct SaleAssetList {
        address assetAddr;
        Order[] sellOrderList;
    }

    struct BuyAssetList {
        address assetAddr;
        Order[] buyOrderList;
    }

    SaleAssetList[] public sellAssetList;
    Order[] public sellOrderList;
    mapping (address => bool) sellExistOf;
    mapping (address => uint) sellDataOf;

    BuyAssetList[] public buyAssetList;
    Order[] public buyOrderList;
    mapping (address => bool) buyExistOf;
    mapping (address => uint) buyDataOf;

    function setDao(address _daoAddr) {
		daoAddr = _daoAddr;
		dao = DAO(daoAddr);
    }

    function getSellList(address _assetAddr) returns(uint assetID) {
        return 0;
    }

    function getBuyList(address _assetAddr) returns(uint assetID) {
        return 0;
    }

    function addSell(address _assetAddr, uint _amount, uint _price) returns(uint sellID) {
    	address agentContrAddr = dao.agentContractOf(msg.sender);
        if (dao.agentActiveOf(agentContrAddr) && dao.assetExistOf(_assetAddr)) {
        	uint assetID;
            if (sellExistOf[_assetAddr]) {
                assetID = sellDataOf[_assetAddr];
                SaleAssetList sellAssetOrders = sellAssetList[assetID];
                sellID = sellAssetOrders.sellOrderList.length++;
                sellAssetOrders.sellOrderList[sellID] = Order({orderID: sellID, owner: agentContrAddr, amount: _amount, price: _price, active: true});
                return sellID;
            } else {
            	assetID = sellAssetList.length++;
				sellExistOf[_assetAddr] = true;
                sellAssetOrders = sellAssetList[assetID];
                sellAssetOrders.assetAddr = _assetAddr;
				sellID = sellAssetOrders.sellOrderList.length++;
                sellAssetOrders.sellOrderList[sellID] = Order({orderID: sellID, owner: agentContrAddr, amount: _amount, price: _price, active: true});
				return sellID;
            }
        }
    }

    function getSellId(address _assetAddr, uint _amount) returns(uint sellID) {
		if (sellExistOf[_assetAddr]) {
			uint assetID = sellDataOf[_assetAddr];
			uint i;
			uint min = 0;
			for (i = 0; i <= sellAssetList[assetID].sellOrderList.length - 1; i++) {
				if (sellAssetList[assetID].sellOrderList[i].active == true && sellAssetList[assetID].sellOrderList[i].amount == _amount && (sellAssetList[assetID].sellOrderList[i].price < min || min == 0)) {
					min = sellAssetList[assetID].sellOrderList[i].price;
					sellID = i;
				}
			}
		}
		return sellID;
    }

    function addBuy(address _assetAddr, uint _amount, uint _price) returns(uint buyID) {
    	address agentContrAddr = dao.agentContractOf(msg.sender);
		if (dao.agentActiveOf(agentContrAddr) && dao.assetExistOf(_assetAddr)) {
			uint assetID;
			if (buyExistOf[_assetAddr]) {
				assetID = buyDataOf[_assetAddr];
				BuyAssetList buyAssetOrders = buyAssetList[assetID];
				buyID = buyAssetOrders.buyOrderList.length++;
				buyAssetOrders.buyOrderList[buyID] = Order({orderID: buyID, owner: agentContrAddr, amount: _amount, price: _price, active: true});
				return buyID;
			} else {
				assetID = buyAssetList.length++;
				buyExistOf[_assetAddr] = true;
				buyAssetOrders = buyAssetList[assetID];
				buyAssetOrders.assetAddr = _assetAddr;
				buyID = buyAssetOrders.buyOrderList.length++;
				buyAssetOrders.buyOrderList[buyID] = Order({orderID: buyID, owner: agentContrAddr, amount: _amount, price: _price, active: true});
				return buyID;
			}
		}
    }

    function getBuyId(address _assetAddr, uint _amount) returns(uint buyID) {
		if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
			uint i;
			uint max = 0;
			for (i = 0; i <= buyAssetList[assetID].buyOrderList.length - 1; i++) {
            	if (buyAssetList[assetID].buyOrderList[i].active == true && buyAssetList[assetID].buyOrderList[i].amount == _amount && (buyAssetList[assetID].buyOrderList[i].price > max || max == 0)) {
            		max = buyAssetList[assetID].buyOrderList[i].price;
            		buyID = i;
            	}
            }
		}
        return buyID;
    }

    function BuyDeal(address _assetAddr, uint _buyID) returns(bool result) {
		if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
			Order order = sellAssetList[assetID].sellOrderList[_buyID];

			address agent_buy_addr = dao.agentContractOf(msg.sender);
			agent agent_buy = agent(agent_buy_addr);
			agent_buy.sendToken(dao.daoCredits(), order.owner, order.price);

			agent agent_sell = agent(order.owner);
			agent_sell.sendToken(sellAssetList[assetID].assetAddr, agent_buy_addr, order.amount);

			/*order.buyer = agent_buy_addr;*/
			order.active = false;
			return true;
        }
        return false;
    }

    function SellDeal(address _assetAddr, uint sellID) returns(bool result) {
        if (buyExistOf[_assetAddr]) {
			uint assetID = buyDataOf[_assetAddr];
			BuyAssetList buyAsset = buyAssetList[assetID];
			Order order = buyAsset.buyOrderList[sellID];

			address agent_sell_addr = dao.agentContractOf(msg.sender);
			agent agent_sell = agent(agent_sell_addr);
			agent_sell.sendToken(buyAsset.assetAddr, order.owner, order.amount);

			agent agent_buy = agent(order.owner);
			agent_buy.sendToken(dao.daoCredits(), agent_sell_addr, order.price);

			/*order.buyer = agent_sell_addr;*/
			order.active = false;
			return true;
		}
		return false;
    }
}

contract goverment {
    address daoAddr;
    DAO public dao;
}

contract token {
    string public assetName;
    address public daoAddr;
    address public owner;
    mapping (address => uint) public tokenBalanceOf;
    DAO daoToken;

    /*Initial */
    function token(string _assetName) {
        assetName = _assetName;
        owner = msg.sender;
    }

    /* DAO functions */
    function emission(address _agentContrAddr, uint _amount) returns(bool result) {
        if(msg.sender==daoAddr || msg.sender==owner)
        {
            tokenBalanceOf[_agentContrAddr] += _amount;
            return true;
        }
        return false;
    }

    function burn(address _agentContrAddr, uint _amount) returns(bool result) {
        if(msg.sender==daoAddr && tokenBalanceOf[_agentContrAddr]>=_amount)
        {
            tokenBalanceOf[_agentContrAddr] -= _amount;
            return true;
        }
        return false;
    }

    function setDaoAddr(address _daoAddr) {
        daoToken = DAO(_daoAddr);
        if(daoToken.daoFounder() == msg.sender && owner == msg.sender) {
            daoAddr = _daoAddr;
        }
    }

    /* Agent function */
    function sendToken(address receiver, uint amount) returns(bool result) {
        if (tokenBalanceOf[msg.sender] < amount) {return false;}
        tokenBalanceOf[msg.sender] -= amount;
        tokenBalanceOf[receiver] += amount;
        return true;
    }
}

contract DAO {
    address public daoFounder;
    address public daoFounderContr;
    address public daoMarketContr;
    address public daoGovermentContr;
    bool public initialization;
    uint public creditAmount;
    uint public sharesAmount;
    uint public creditTurn;
    uint public numAgents;

    token public daoShares;
    token public daoCredits;

    /* Assets data */
    Asset[] public assetsList;
    mapping (address => uint) public assetDataOf;
    mapping (address => bool) public assetExistOf;
    struct Asset {
        address assetAddr;
    }

    /* Agents data */
    Agent[] public agentsList;
    mapping (address => uint) public agentDataOf;
    mapping (address => bool) public agentActiveOf;
    mapping (address => address) public agentContractOf;
    struct Agent {
        address agentContrAddr;
        uint joinData;
    }

    function DAO(token _shares, token _credits, agent _daoFounderContr, market _daoMarketContr, goverment _daoGovermentContr) {
        daoFounder = msg.sender;
        daoShares = token(_shares);
        daoCredits = token(_credits);
        daoFounderContr = _daoFounderContr;
        daoMarketContr = _daoMarketContr;
        daoGovermentContr = _daoGovermentContr;
    }

    function initializationDaoBalances(uint _founderSharesAmount, uint _founderCreditsAmount) returns (bool result) {
        if(!initialization) {
			daoShares.emission(daoFounderContr, _founderSharesAmount);
			sharesAmount = _founderSharesAmount;
			daoCredits.emission(daoFounderContr, _founderCreditsAmount);
			creditAmount = _founderCreditsAmount;
			initialization = true;
			return true;
        }
    }

    function daoEfficiency() returns (uint daoEfficiency) {
        daoEfficiency = creditTurn*100/creditAmount;
    }

    function daoShareCost() returns (uint shareCost) {
        shareCost = creditTurn/sharesAmount;
    }

    function daoCreditPower() returns (uint creditPower) {
        creditPower = sharesAmount*100/creditTurn;
    }

    function daoShareSale(uint _shareAmount) returns (uint creditReward) {
        if(daoShares.tokenBalanceOf(msg.sender)>=_shareAmount) {
            creditReward = daoShareCost()*_shareAmount;
            daoCredits.emission(msg.sender, creditReward);
            daoShares.burn(msg.sender, _shareAmount);
        }
    }

    function daoShareBuy(uint _creditAmount) returns (uint shares) {
        if(daoCredits.tokenBalanceOf(msg.sender)>=_creditAmount) {
            shares = daoCreditPower()*_creditAmount;
            daoShares.emission(msg.sender, shares);
            daoCredits.burn(msg.sender, _creditAmount);
        }
    }

    function daoSharesEmission(address _agentContrAddr, uint _sharesAmount) {
        daoShares.emission(_agentContrAddr, _sharesAmount);
    }

    function daoCreditEmission(address _agentContrAddr, uint _creditsAmount) {
        daoCredits.emission(_agentContrAddr, _creditsAmount);
    }

    function setAgent(address _agentContAddr) returns(uint agentID) {
        if(daoShares.tokenBalanceOf(msg.sender)>0) {
            agentID = agentsList.length++;
            Agent a = agentsList[agentID];
            a.agentContrAddr = _agentContAddr;
            a.joinData = now;
            uint newAgentSharesAmount;
            numAgents = agentID + 1;
            newAgentSharesAmount = sharesAmount/numAgents*daoEfficiency();
            daoShares.emission(_agentContAddr, newAgentSharesAmount);
            agentDataOf[_agentContAddr] = agentID;
            agentActiveOf[_agentContAddr] = true;
            agent Agn = agent(_agentContAddr);
            agentContractOf[Agn.agentAddr()] = _agentContAddr;
            return agentID;
        }
    }

    function setAssets(address _assetAddr) returns(uint assetID) {
        if (agentActiveOf[msg.sender] == true) {
            assetID = assetsList.length++;
            Asset a = assetsList[assetID];
            a.assetAddr = _assetAddr;
            assetDataOf[_assetAddr] = assetID;
            assetExistOf[_assetAddr] = true;
            return assetID;
        }
    }
}

contract agent {
    address public agentAddr;
    address controlAddr;
    address daoAddr;
    DAO public dao;

    /* Agents contract list*/

    AgentContract[] public agentContractList;
    struct AgentContract {
        address agentContractAddr;
        string abi;
        string desc;
        bool active;
    }

    modifier controlCheck { if (msg.sender == controlAddr) _ }

    function agent() {
        agentAddr = msg.sender;
        controlAddr = msg.sender;
    }

    function addAsset(address _tokenAddr) {
        if (msg.sender == agentAddr) {
			dao.setAssets(_tokenAddr);
		}
    }

    function sendToken(address assetAddr, address receiver, uint amount) {
        if (msg.sender == agentAddr || msg.sender == dao.daoMarketContr()) {
			token asset = token(assetAddr);
			asset.sendToken(receiver, amount);
		}
    }

    function setDao(address _daoAddr) {
        if(msg.sender == agentAddr) {
        	daoAddr = _daoAddr;
			dao = DAO(daoAddr);
        }
    }

    function setControlAddr(address _controlAddr) returns(bool result) {
        if(msg.sender == agentAddr) {
            controlAddr = _controlAddr;
        }
    }

    function setNewAgent(address _agentAddr) controlCheck returns(bool result) {
        dao.setAgent(_agentAddr);
        return true;
    }

    function setAgentContract(address _agentContractAddr, string _abi, string _desc) controlCheck returns(uint contractID) {
        contractID = agentContractList.length++;
        AgentContract a = agentContractList[contractID];
        a.agentContractAddr = _agentContractAddr;
        a.abi = _abi;
        a.desc = _desc;
        a.active = true;
        return contractID;
    }

    function inactiveAgentContract(address _agentContractAddr) controlCheck returns(bool result) {

    }
}

contract market {
    address daoAddr;
    DAO public dao;

    struct Order {
        uint orderID;
        address owner;
        uint amount;
        uint price;
        bool active;
    }

    struct SaleAssetList {
        address assetAddr;
        Order[] sellOrderList;
    }

    struct BuyAssetList {
        address assetAddr;
        Order[] buyOrderList;
    }

    SaleAssetList[] public sellAssetList;
    Order[] public sellOrderList;
    mapping (address => bool) sellExistOf;
    mapping (address => uint) sellDataOf;

    BuyAssetList[] public buyAssetList;
    Order[] public buyOrderList;
    mapping (address => bool) buyExistOf;
    mapping (address => uint) buyDataOf;

    function setDao(address _daoAddr) {
		daoAddr = _daoAddr;
		dao = DAO(daoAddr);
    }

    function getSellList(address _assetAddr) returns(uint assetID) {
        return 0;
    }

    function getBuyList(address _assetAddr) returns(uint assetID) {
        return 0;
    }

    function addSell(address _assetAddr, uint _amount, uint _price) returns(uint sellID) {
    	address agentContrAddr = dao.agentContractOf(msg.sender);
        if (dao.agentActiveOf(agentContrAddr) && dao.assetExistOf(_assetAddr)) {
        	uint assetID;
            SaleAssetList sellAssetOrders = sellAssetList[0];
            if (sellExistOf[_assetAddr]) {
                assetID = sellDataOf[_assetAddr];
                sellAssetOrders = sellAssetList[assetID];
                sellID = sellAssetOrders.sellOrderList.length++;
                sellAssetOrders.sellOrderList[sellID] = Order({orderID: sellID, owner: agentContrAddr, amount: _amount, price: _price, active: true});
                return sellID;
            } else {
            	assetID = sellAssetList.length++;
				sellID = 0;
				sellExistOf[_assetAddr] = true;
                sellAssetOrders = sellAssetList[assetID];
                sellAssetOrders.assetAddr = _assetAddr;
                sellAssetOrders.sellOrderList[sellID] = Order({orderID: sellID, owner: agentContrAddr, amount: _amount, price: _price, active: true});
				return sellID;
            }
        }
    }

    function getSellId(address _assetAddr, uint _amount) returns(uint sellID) {
		sellID = 0;
		if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
			uint i;
			uint min = 0;
			for (i = 0; i <= sellAssetList[assetID].sellOrderList.length - 1; i++) {
            	if (sellAssetList[assetID].sellOrderList[i].active == true && sellAssetList[assetID].sellOrderList[i].amount == _amount && (sellAssetList[assetID].sellOrderList[i].amount < min || min == 0)) {
            		min = sellAssetList[assetID].sellOrderList[i].amount;
            		sellID = i;
            	}
            }
		}
        return sellID;
    }

    function addBuy(address _assetAddr, uint _amount, uint _price) returns(uint buyID) {
    	address agentContrAddr = dao.agentContractOf(msg.sender);
        if (dao.agentActiveOf(agentContrAddr) && dao.assetExistOf(_assetAddr)) {
        	uint assetID;
            BuyAssetList buyAssetOrders = buyAssetList[0];
            if (buyExistOf[_assetAddr]) {
                assetID = buyDataOf[_assetAddr];
                buyAssetOrders = buyAssetList[assetID];
                buyID = buyAssetOrders.buyOrderList.length++;
                buyAssetOrders.buyOrderList[buyID] = Order({orderID: buyID, owner: agentContrAddr, amount: _amount, price: _price, active: true});
                return buyID;
            } else {
            	assetID = buyAssetList.length++;
				buyID = 0;
				buyExistOf[_assetAddr] = true;
                buyAssetOrders = buyAssetList[assetID];
                buyAssetOrders.assetAddr = _assetAddr;
                buyAssetOrders.buyOrderList[buyID] = Order({orderID: buyID, owner: agentContrAddr, amount: _amount, price: _price, active: true});
				return buyID;
            }
        }
    }

    function getById(address _assetAddr, uint _amount) returns(uint buyID) {
		buyID = 0;
		if (buyExistOf[_assetAddr]) {
            uint assetID = buyDataOf[_assetAddr];
			uint i;
			uint min = 0;
			for (i = 0; i <= buyAssetList[assetID].buyOrderList.length - 1; i++) {
            	if (buyAssetList[assetID].buyOrderList[i].active == true && buyAssetList[assetID].buyOrderList[i].amount == _amount && (buyAssetList[assetID].buyOrderList[i].amount < min || min == 0)) {
            		min = buyAssetList[assetID].buyOrderList[i].amount;
            		buyID = i;
            	}
            }
		}
        return buyID;
    }

    function BuyDeal(address _assetAddr, uint _buyID) returns(bool result) {
		if (sellExistOf[_assetAddr]) {
            uint assetID = sellDataOf[_assetAddr];
			Order order = sellAssetList[assetID].sellOrderList[_buyID];

			address agent_buy_addr = dao.agentContractOf(msg.sender);
			agent agent_buy = agent(agent_buy_addr);
			agent_buy.sendToken(dao.daoCredits(), order.owner, order.price);

			agent agent_sell = agent(order.owner);
			agent_sell.sendToken(sellAssetList[assetID].assetAddr, agent_buy_addr, order.amount);

			/*order.buyer = agent_buy_addr;*/
			order.active = false;
			return true;
        }
        return false;
    }

    function SellDeal(address _assetAddr, uint sellID) returns(bool result) {
        if (buyExistOf[_assetAddr]) {
			uint assetID = buyDataOf[_assetAddr];
			BuyAssetList buyAsset = buyAssetList[assetID];
			Order order = buyAsset.buyOrderList[sellID];

			address agent_sell_addr = dao.agentContractOf(msg.sender);
			agent agent_sell = agent(agent_sell_addr);
			agent_sell.sendToken(buyAsset.assetAddr, order.owner, order.amount);

			agent agent_buy = agent(order.owner);
			agent_buy.sendToken(dao.daoCredits(), agent_sell_addr, order.price);

			/*order.buyer = agent_sell_addr;*/
			order.active = false;
			return true;
		}
		return false;
    }
}

contract goverment {
    address daoAddr;
    DAO public dao;
}


:art: Use mixedCase for state variable names of contracts.

pragma solidity ^0.4.24;

import "../lib/AddressArray.sol";
import "../common/ReservedAddrPublic.sol";
import "../../interaction/interface/ISysConfig.sol";
import "../../interaction/interface/IAuthorization.sol";

/// @title Authorization about the permission and account
/// @author ["Cryptape Technologies <contact@cryptape.com>"]
/// @notice The address: 0xffffffffffffffffffffffffffffffffff020006
///         The interface can be called: Only query type
contract Authorization is IAuthorization, ReservedAddrPublic {

    mapping(address => address[]) permissions;
    mapping(address => address[]) accounts;

    address[] allAccounts;
    ISysConfig sysConfig = ISysConfig(sysConfigAddr);

    event AuthSetted(address indexed _account, address indexed _permission);
    event AuthCanceled(address indexed _account, address indexed _permission);
    event AuthCleared(address indexed _account);

    modifier onlyPermissionManagement {
        require(
            permissionManagementAddr == msg.sender || roleAuthAddr == msg.sender,
            "permission denied"
        );
        _;
    }

    modifier notSuperAdmin(address _account) {
        require(_account != allAccounts[0], "not superAdmin");
        _;
    }

    /// @notice Initialize the superAdmin's auth
    constructor(address _superAdmin) public {
        for (uint8 i;i < builtInPermissions.length; i++)
            _setAuth(_superAdmin, builtInPermissions[i]);

        // rootGroup: basic permissions
        _setAuth(rootGroupAddr, sendTxAddr);
        _setAuth(rootGroupAddr, createContractAddr);
    }

    /// @notice Set permission to the account
    /// @param _account The account to be setted
    /// @param _permission The permission to be setted
    /// @return true if successed, otherwise false
    function setAuth(address _account, address _permission)
        public
        onlyPermissionManagement
        returns (bool)
    {
        return _setAuth(_account, _permission);
    }

    /// @notice Cancel the account's permission
    /// @param _account The account to be canceled
    /// @param _permission The permission to be canceled
    /// @return true if successed, otherwise false
    function cancelAuth(address _account, address _permission)
        public
        onlyPermissionManagement
        notSuperAdmin(_account)
        returns (bool)
    {
        AddressArray.remove(_account, accounts[_permission]);
        AddressArray.remove(_permission, permissions[_account]);
        emit AuthCanceled(_account, _permission);
        return true;
    }

    /// @notice Clear the account's permissions
    /// @param _account The account to be cleared
    /// @return true if successed, otherwise false
    function clearAuth(address _account)
        public
        onlyPermissionManagement
        notSuperAdmin(_account)
        returns (bool)
    {
        // Delete the account of all the account's permissions
        for (uint i = 0; i < permissions[_account].length; i++)
            AddressArray.remove(_account, accounts[permissions[_account][i]]);

        delete permissions[_account];
        AddressArray.remove(_account, allAccounts);

        emit AuthCleared(_account);
        return true;
    }

    /// @notice Clear the auth of the accounts who have the permission
    /// @param _permission The permission to be cleared
    /// @return true if successed, otherwise false
    function clearAuthOfPermission(address _permission)
        public
        onlyPermissionManagement
        returns (bool)
    {
        address[] memory _accounts = queryAccounts(_permission);

        for (uint i = 0; i < _accounts.length; i++)
            assert(cancelAuth(_accounts[i], _permission));

        return true;
    }

    /// @notice Query the account's permissions
    /// @param _account The account to be queried
    /// @return The permissions of account
    function queryPermissions(address _account)
        public
        view
        returns (address[] _permissions)
    {
        return permissions[_account];
    }

    /// @notice Query the permission's accounts
    /// @param _permission The permission to be queried
    /// @return The accounts of permission
    function queryAccounts(address _permission)
        public
        view
        returns (address[] _accounts)
    {
        return accounts[_permission];
    }

    /// @notice Query all accounts
    /// @return All the accounts
    function queryAllAccounts()
        public
        view
        returns (address[])
    {
        return allAccounts;
    }

    /// @notice Check account has a resource(deprecation)
    /// @return true if passed, otherwise false
    function checkResource(address, address, bytes4)
        public
        pure
        returns (bool)
    {
        // address[] memory perms = queryPermissions(_account);

        // for (uint i = 0; i < perms.length; i++) {
        //     Permission perm = Permission(perms[i]);
        //     if (perm.inPermission(_cont, _func))
        //         return true;
        // }

        // return false;
    }

    /// @notice Check account has a permission
    /// @param _account The account to be checked
    /// @param _permission The address of permission
    /// @return true if passed, otherwise false
    function checkPermission(address _account, address _permission)
        public
        view
        returns (bool)
    {
        if (sysConfig.getPermissionCheck()) {
            return AddressArray.exist(_permission, permissions[_account]);
        }
        return true;
    }

    /// @notice Private: Set the permission to the account
    function _setAuth(address _account, address _permission)
        private
        returns (bool)
    {
        if (!AddressArray.exist(_permission, permissions[_account]))
            permissions[_account].push(_permission);
        if (!AddressArray.exist(_account, accounts[_permission]))
            accounts[_permission].push(_account);
        if (!AddressArray.exist(_account, allAccounts))
            allAccounts.push(_account);

        emit AuthSetted(_account, _permission);
        return true;
    }
}

pragma solidity ^0.4.24;

import "../lib/AddressArray.sol";
import "../common/ReservedAddrPublic.sol";
import "../../interaction/interface/ISysConfig.sol";
import "../../interaction/interface/IAuthorization.sol";

/// @title Authorization about the permission and account
/// @author ["Cryptape Technologies <contact@cryptape.com>"]
/// @notice The address: 0xffffffffffffffffffffffffffffffffff020006
///         The interface can be called: Only query type
contract Authorization is IAuthorization, ReservedAddrPublic {

    mapping(address => address[]) permissions;
    mapping(address => address[]) accounts;

    address[] all_accounts;
    ISysConfig sysConfig = ISysConfig(sysConfigAddr);

    event AuthSetted(address indexed _account, address indexed _permission);
    event AuthCanceled(address indexed _account, address indexed _permission);
    event AuthCleared(address indexed _account);

    modifier onlyPermissionManagement {
        require(
            permissionManagementAddr == msg.sender || roleAuthAddr == msg.sender,
            "permission denied"
        );
        _;
    }

    modifier notSuperAdmin(address _account) {
        require(_account != all_accounts[0], "not superAdmin");
        _;
    }

    /// @notice Initialize the superAdmin's auth
    constructor(address _superAdmin) public {
        for (uint8 i;i < builtInPermissions.length; i++)
            _setAuth(_superAdmin, builtInPermissions[i]);

        // rootGroup: basic permissions
        _setAuth(rootGroupAddr, sendTxAddr);
        _setAuth(rootGroupAddr, createContractAddr);
    }

    /// @notice Set permission to the account
    /// @param _account The account to be setted
    /// @param _permission The permission to be setted
    /// @return true if successed, otherwise false
    function setAuth(address _account, address _permission)
        public
        onlyPermissionManagement
        returns (bool)
    {
        return _setAuth(_account, _permission);
    }

    /// @notice Cancel the account's permission
    /// @param _account The account to be canceled
    /// @param _permission The permission to be canceled
    /// @return true if successed, otherwise false
    function cancelAuth(address _account, address _permission)
        public
        onlyPermissionManagement
        notSuperAdmin(_account)
        returns (bool)
    {
        AddressArray.remove(_account, accounts[_permission]);
        AddressArray.remove(_permission, permissions[_account]);
        emit AuthCanceled(_account, _permission);
        return true;
    }

    /// @notice Clear the account's permissions
    /// @param _account The account to be cleared
    /// @return true if successed, otherwise false
    function clearAuth(address _account)
        public
        onlyPermissionManagement
        notSuperAdmin(_account)
        returns (bool)
    {
        // Delete the account of all the account's permissions
        for (uint i = 0; i < permissions[_account].length; i++)
            AddressArray.remove(_account, accounts[permissions[_account][i]]);

        delete permissions[_account];
        AddressArray.remove(_account, all_accounts);

        emit AuthCleared(_account);
        return true;
    }

    /// @notice Clear the auth of the accounts who have the permission
    /// @param _permission The permission to be cleared
    /// @return true if successed, otherwise false
    function clearAuthOfPermission(address _permission)
        public
        onlyPermissionManagement
        returns (bool)
    {
        address[] memory _accounts = queryAccounts(_permission);

        for (uint i = 0; i < _accounts.length; i++)
            assert(cancelAuth(_accounts[i], _permission));

        return true;
    }

    /// @notice Query the account's permissions
    /// @param _account The account to be queried
    /// @return The permissions of account
    function queryPermissions(address _account)
        public
        view
        returns (address[] _permissions)
    {
        return permissions[_account];
    }

    /// @notice Query the permission's accounts
    /// @param _permission The permission to be queried
    /// @return The accounts of permission
    function queryAccounts(address _permission)
        public
        view
        returns (address[] _accounts)
    {
        return accounts[_permission];
    }

    /// @notice Query all accounts
    /// @return All the accounts
    function queryAllAccounts()
        public
        view
        returns (address[])
    {
        return all_accounts;
    }

    /// @notice Check account has a resource(deprecation)
    /// @return true if passed, otherwise false
    function checkResource(address, address, bytes4)
        public
        pure
        returns (bool)
    {
        // address[] memory perms = queryPermissions(_account);

        // for (uint i = 0; i < perms.length; i++) {
        //     Permission perm = Permission(perms[i]);
        //     if (perm.inPermission(_cont, _func))
        //         return true;
        // }

        // return false;
    }

    /// @notice Check account has a permission
    /// @param _account The account to be checked
    /// @param _permission The address of permission
    /// @return true if passed, otherwise false
    function checkPermission(address _account, address _permission)
        public
        view
        returns (bool)
    {
        if (sysConfig.getPermissionCheck()) {
            return AddressArray.exist(_permission, permissions[_account]);
        }
        return true;
    }

    /// @notice Private: Set the permission to the account
    function _setAuth(address _account, address _permission)
        private
        returns (bool)
    {
        if (!AddressArray.exist(_permission, permissions[_account]))
            permissions[_account].push(_permission);
        if (!AddressArray.exist(_account, accounts[_permission]))
            accounts[_permission].push(_account);
        if (!AddressArray.exist(_account, all_accounts))
            all_accounts.push(_account);

        emit AuthSetted(_account, _permission);
        return true;
    }
}


Fix AssertBytes32Array.sol

Fix AssertBytes32Array.sol

//SPDX-License-Identifier: MIT
pragma solidity >= 0.4.15 < 0.9.0;

library AssertBytes32Array {

    uint8 constant ZERO = uint8(bytes1('0'));
    uint8 constant A = uint8(bytes1('a'));
    /*
        Event: TestEvent

        Fired when an assertion is made.

        Params:
            result (bool) - Whether or not the assertion holds.
            message (string) - A message to display if the assertion does not hold.
    */
    event TestEvent(bool indexed result, string message);

    // ************************************** bytes32[] **************************************

    /*
        Function: equal(bytes32[])

        Assert that two 'bytes32[]' are equal.

        : arrA.length == arrB.length

        and, for all valid indices 'i'

        : arrA[i] == arrB[i]

        Params:
            A (bytes32[]) - The first array.
            B (bytes32[]) - The second array.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function equal(bytes32[] memory arrA, bytes32[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        _report(result, message);
    }

    /*
        Function: notEqual(bytes32[])

        Assert that two 'bytes32[]' are not equal.

        : arrA.length != arrB.length

        or, for some valid index 'i'

        : arrA[i] != arrB[i]

        Params:
            A (bytes32[]) - The first string.
            B (bytes32[]) - The second string.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function notEqual(bytes32[] memory arrA, bytes32[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        result = !result;
        _report(result, message);
    }

    /*
        Function: lengthEqual(bytes32[])

        Assert that the length of an 'bytes32[]' is equal to a given value.

        : arr.length == length

        Params:
            arr (bytes32[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthEqual(bytes32[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength == length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /*
        Function: lengthNotEqual(bytes32[])

        Assert that the length of an 'bytes32[]' is not equal to a given value.

        : arr.length != length

        Params:
            arr (bytes32[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthNotEqual(bytes32[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength != arr.length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /******************************** internal ********************************/

        /*
            Function: _report

            Internal function for triggering <TestEvent>.

            Params:
                result (bool) - The test result (true or false).
                message (string) - The message that is sent if the assertion fails.
        */
    function _report(bool result, string memory message) internal {
        if(result)
            emit TestEvent(true, "");
        else
            emit TestEvent(false, message);
    }

    /*
        Function: _utoa(uint)

        Convert an  unsigned integer to a string.

        Params:
            n (uint) - The unsigned integer.
            radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f

        Returns:
            result (string) - The resulting string.
    */
    function _utoa(uint n, uint8 radix) internal pure returns (string memory) {
        if (n == 0 || radix < 2 || radix > 16)
            return '0';
        bytes memory bts = new bytes(256);
        uint i;
        while (n > 0) {
            bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.
            n /= radix;
        }
        // Reverse
        bytes memory rev = new bytes(i);
        for (uint j = 0; j < i; j++)
            rev[j] = bts[i - j - 1];
        return string(rev);
    }

    /*
        Function: _utoa(uint8)

        Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',
        numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.

        Params:
            u (uint8) - The unsigned 8-bit integer.

        Returns:
            result (string) - The ASCII byte.
    */
    function _utoa(uint8 u) internal pure returns (bytes1) {
        if (u < 10)
            return bytes1(u + ZERO);
        else if (u < 16)
            return bytes1(u - 10 + A);
        else
            return 0;
    }

    /*
    function htoa(address addr) constant returns (string) {
        bytes memory bts = new bytes(40);
        bytes20 addrBts = bytes20(addr);
        for (uint i = 0; i < 20; i++) {
            bts[2*i] = addrBts[i] % 16;
            bts[2*i + 1] = (addrBts[i] / 16) % 16;
        }
        return string(bts);
    }

    */

    /*
        Function: _tag(string)

        Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value".

        Params:
            value (string) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: value"
    */
    function _tag(string memory value, string memory tag) internal pure returns (string memory) {

        bytes memory valueB = bytes(value);
        bytes memory tagB = bytes(tag);

        uint vl = valueB.length;
        uint tl = tagB.length;

        bytes memory newB = new bytes(vl + tl + 2);

        uint i;
        uint j;

        for (i = 0; i < tl; i++)
            newB[j++] = tagB[i];
        newB[j++] = ':';
        newB[j++] = ' ';
        for (i = 0; i < vl; i++)
            newB[j++] = valueB[i];

        return string(newB);
    }

    /*
        Function: _tag(uint)

        Add a tag to an uint.

        Params:
            value (uint) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: _utoa(value)"
    */
    function _tag(uint value, string memory tag) internal pure returns (string memory) {
        string memory nstr = _utoa(value, 10);
        return _tag(nstr, tag);
    }

    /*
        Function: _appendTagged(string, string)

        Append two tagged values to a string.

        Params:
            tagged0 (string) - The first tagged value.
            tagged1 (string) - The second tagged value.
            str (string) - The string.

        Returns:
            result (string) - "str (tagged0, tagged1)"
    */
    function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) {

        bytes memory tagged0B = bytes(tagged0);
        bytes memory tagged1B = bytes(tagged1);
        bytes memory strB = bytes(str);

        uint sl = strB.length;
        uint t0l = tagged0B.length;
        uint t1l = tagged1B.length;

        bytes memory newB = new bytes(sl + t0l + t1l + 5);

        uint i;
        uint j;

        for (i = 0; i < sl; i++)
            newB[j++] = strB[i];
        newB[j++] = ' ';
        newB[j++] = '(';
        for (i = 0; i < t0l; i++)
            newB[j++] = tagged0B[i];
        newB[j++] = ',';
        newB[j++] = ' ';
        for (i = 0; i < t1l; i++)
            newB[j++] = tagged1B[i];
        newB[j++] = ')';

        return string(newB);
    }
}

//SPDX-License-Identifier: MIT
pragma solidity >= 0.4.15 < 0.9.0;

library AssertBytes32Array {

    uint8 constant ZERO = uint8(byte('0'));
    uint8 constant A = uint8(byte('a'));
    /*
        Event: TestEvent

        Fired when an assertion is made.

        Params:
            result (bool) - Whether or not the assertion holds.
            message (string) - A message to display if the assertion does not hold.
    */
    event TestEvent(bool indexed result, string message);

    // ************************************** bytes32[] **************************************

    /*
        Function: equal(bytes32[])

        Assert that two 'bytes32[]' are equal.

        : arrA.length == arrB.length

        and, for all valid indices 'i'

        : arrA[i] == arrB[i]

        Params:
            A (bytes32[]) - The first array.
            B (bytes32[]) - The second array.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function equal(bytes32[] memory arrA, bytes32[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        _report(result, message);
    }

    /*
        Function: notEqual(bytes32[])

        Assert that two 'bytes32[]' are not equal.

        : arrA.length != arrB.length

        or, for some valid index 'i'

        : arrA[i] != arrB[i]

        Params:
            A (bytes32[]) - The first string.
            B (bytes32[]) - The second string.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function notEqual(bytes32[] memory arrA, bytes32[] memory arrB, string memory message) public returns (bool result) {
        result = arrA.length == arrB.length;
        if (result) {
            for (uint i = 0; i < arrA.length; i++) {
                if (arrA[i] != arrB[i]) {
                    result = false;
                    break;
                }
            }
        }
        result = !result;
        _report(result, message);
    }

    /*
        Function: lengthEqual(bytes32[])

        Assert that the length of an 'bytes32[]' is equal to a given value.

        : arr.length == length

        Params:
            arr (bytes32[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthEqual(bytes32[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength == length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /*
        Function: lengthNotEqual(bytes32[])

        Assert that the length of an 'bytes32[]' is not equal to a given value.

        : arr.length != length

        Params:
            arr (bytes32[]) - The array.
            length (uint) - The length.
            message (string) - A message that is sent if the assertion fails.

        Returns:
            result (bool) - The result.
    */
    function lengthNotEqual(bytes32[] memory arr, uint length, string memory message) public returns (bool result) {
        uint arrLength = arr.length;
        if (arrLength != arr.length)
            _report(result, "");
        else
            _report(result, _appendTagged(_tag(arrLength, "Tested"), _tag(length, "Against"), message));
    }

    /******************************** internal ********************************/

        /*
            Function: _report

            Internal function for triggering <TestEvent>.

            Params:
                result (bool) - The test result (true or false).
                message (string) - The message that is sent if the assertion fails.
        */
    function _report(bool result, string memory message) internal {
        if(result)
            emit TestEvent(true, "");
        else
            emit TestEvent(false, message);
    }

    /*
        Function: _utoa(uint)

        Convert an  unsigned integer to a string.

        Params:
            n (uint) - The unsigned integer.
            radix (uint8) - A number between 2 and 16 (inclusive). Characters used are 0-9,a-f

        Returns:
            result (string) - The resulting string.
    */
    function _utoa(uint n, uint8 radix) internal pure returns (string memory) {
        if (n == 0 || radix < 2 || radix > 16)
            return '0';
        bytes memory bts = new bytes(256);
        uint i;
        while (n > 0) {
            bts[i++] = _utoa(uint8(n % radix)); // Turn it to ascii.
            n /= radix;
        }
        // Reverse
        bytes memory rev = new bytes(i);
        for (uint j = 0; j < i; j++)
            rev[j] = bts[i - j - 1];
        return string(rev);
    }

    /*
        Function: _utoa(uint8)

        Convert an unsigned 8-bit integer to its ASCII byte representation. Numbers 0-9 are converted to '0'-'9',
        numbers 10-16 to 'a'-'f'. Numbers larger then 16 return the null byte.

        Params:
            u (uint8) - The unsigned 8-bit integer.

        Returns:
            result (string) - The ASCII byte.
    */
    function _utoa(uint8 u) internal pure returns (byte) {
        if (u < 10)
            return byte(u + ZERO);
        else if (u < 16)
            return byte(u - 10 + A);
        else
            return 0;
    }

    /*
    function htoa(address addr) constant returns (string) {
        bytes memory bts = new bytes(40);
        bytes20 addrBts = bytes20(addr);
        for (uint i = 0; i < 20; i++) {
            bts[2*i] = addrBts[i] % 16;
            bts[2*i + 1] = (addrBts[i] / 16) % 16;
        }
        return string(bts);
    }

    */

    /*
        Function: _tag(string)

        Add a tag to a string. The 'value' and 'tag' strings are returned on the form "tag: value".

        Params:
            value (string) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: value"
    */
    function _tag(string memory value, string memory tag) internal pure returns (string memory) {

        bytes memory valueB = bytes(value);
        bytes memory tagB = bytes(tag);

        uint vl = valueB.length;
        uint tl = tagB.length;

        bytes memory newB = new bytes(vl + tl + 2);

        uint i;
        uint j;

        for (i = 0; i < tl; i++)
            newB[j++] = tagB[i];
        newB[j++] = ':';
        newB[j++] = ' ';
        for (i = 0; i < vl; i++)
            newB[j++] = valueB[i];

        return string(newB);
    }

    /*
        Function: _tag(uint)

        Add a tag to an uint.

        Params:
            value (uint) - The value.
            tag (string) - The tag.

        Returns:
            result (string) - "tag: _utoa(value)"
    */
    function _tag(uint value, string memory tag) internal pure returns (string memory) {
        string memory nstr = _utoa(value, 10);
        return _tag(nstr, tag);
    }

    /*
        Function: _appendTagged(string, string)

        Append two tagged values to a string.

        Params:
            tagged0 (string) - The first tagged value.
            tagged1 (string) - The second tagged value.
            str (string) - The string.

        Returns:
            result (string) - "str (tagged0, tagged1)"
    */
    function _appendTagged(string memory tagged0, string memory tagged1, string memory str) internal pure returns (string memory) {

        bytes memory tagged0B = bytes(tagged0);
        bytes memory tagged1B = bytes(tagged1);
        bytes memory strB = bytes(str);

        uint sl = strB.length;
        uint t0l = tagged0B.length;
        uint t1l = tagged1B.length;

        bytes memory newB = new bytes(sl + t0l + t1l + 5);

        uint i;
        uint j;

        for (i = 0; i < sl; i++)
            newB[j++] = strB[i];
        newB[j++] = ' ';
        newB[j++] = '(';
        for (i = 0; i < t0l; i++)
            newB[j++] = tagged0B[i];
        newB[j++] = ',';
        newB[j++] = ' ';
        for (i = 0; i < t1l; i++)
            newB[j++] = tagged1B[i];
        newB[j++] = ')';

        return string(newB);
    }
}