Allow ApiProviders governed by DirectDemocracy to be modified until they get their OwnersDb contracts set.

contract DirectDemocracy is PermissionsProvider, PersistentProtectedContract {
    // PoC-8
    // include "action.sol"

    uint public quorum;
    uint8 public quorumPercent;
    uint public marginForVictory;
    uint8 public marginForVictoryPercent;
    uint public minimumVotingWindow;
    uint public maximumVotingWindow;

    uint VOTING_WINDOW_MIN = 600; // 10 minutes
    bytes32 OWNERS_DB = "OwnersDb";

    mapping (address => Proposal) public proposals;
    mapping (address => bool) permittedAction;

    enum Vote {
        Null, Yes, No, Abstain
    }

    struct Proposal {
        uint timestamp;
        mapping (address => Vote) votes;
        uint numVotes;
        address proposedAction;
    }

    function DirectDemocracy() {
        quorum = 1;
        quorumPercent = 60;
        marginForVictory = 0;
        marginForVictoryPercent = 0;
    }

    function permitted(address action) returns (bool result) {
        return permittedAction[action]
        || api == 0x0
        || ApiProvider(api).contracts(OWNERS_DB) == 0x0;
    }

    function addOwner(address owner) returns (bool added) {
        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        if (dbAddress == 0x0 || !permittedSender()) return false;

        added = OwnersDb(dbAddress).addOwner(owner);

        if (added) {
            _updateMargins();
        }
    }

    function removeOwner(address owner) returns (bool removed) {
        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        var db = OwnersDb(dbAddress);
        var iter = db.owners(owner);

        if (dbAddress == 0x0 || iter == 0x0 || !permittedSender()) {
            return false;
        }

        if (!db.removeOwner(owner)) return false;

        Proposal proposal;
        var numOwners = db.numOwners();

        for (uint i=0; i < numOwners; i+=1) {
            proposal = proposals[iter];
            iter = db.owners(iter);

            if (proposal.proposedAction == 0x0) continue;

            if (proposal.votes[owner] != Vote.Null) {
                delete proposal.votes[owner];
                proposal.numVotes -= 1;
            }
        }

        delete proposals[owner];
        _updateMargins();

        return true;
    }

    function proposeAction(address proposedAction) {
        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        var db = OwnersDb(dbAddress);
        if (db.owners(msg.sender) == 0x0
            || Action(proposedAction).owner() != address(this)) {
            return;
        }

        var proposal = proposals[msg.sender];
        proposal.timestamp = block.timestamp;
        proposal.proposedAction = proposedAction;
        proposal.votes[msg.sender] = Vote.Yes;
        proposal.numVotes = 1;
    }

    function withdrawProposedAction() {
        _removeProposal(msg.sender);
    }

    function setQuorumPercent(uint8 percent) {
        if (!permittedSender()) return;
        quorumPercent = percent;
        _updateMargins();
    }

    function setMarginForVictoryPercent(uint8 percent) {
        if (!permittedSender()) return;
        marginForVictoryPercent = percent;
        _updateMargins();
    }

    function setMinimumVotingWindow(uint minimumWindow) {
        if (!permittedSender()) return;
        minimumVotingWindow = minimumWindow;
    }

    function setMaximumVotingWindow(uint maximumWindow) {
        if ((maximumWindow < VOTING_WINDOW_MIN && maximumWindow != 0)
            || !permittedSender()) {
            return;
        }
        maximumVotingWindow = maximumWindow;
    }

    function wipeProposedActions() {
        if (!permittedSender()) return;

        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        var db = OwnersDb(dbAddress);
        var iter = db.ownersTail();
        var numOwners = db.numOwners();

        for (uint i=0; i < numOwners; i += 1) {
            if (proposals[iter].proposedAction != 0x0) {
                Action(proposals[iter].proposedAction).remove();
                delete proposals[iter];
            }
            iter = db.owners(iter);
        }
    }

    function vote(address owner, address action, Vote vote) {
        // We require the action parameter to make sure the voter knows
        // exactly what they are voting on, to prevent "bait & switch."
        var proposal = proposals[owner];

        if (action == 0x0
            || proposal.proposedAction != action
            || vote == Vote.Null) {
            return;
        }

        if (maximumVotingWindow == 0
            || block.timestamp <= (proposal.timestamp + maximumVotingWindow)) {

            if (proposal.votes[msg.sender] == Vote.Null) {
                proposal.numVotes += 1;
            }

            proposal.votes[msg.sender] = vote;
        }

        if (block.timestamp > (proposal.timestamp + minimumVotingWindow)) {
            var outcome = _checkVotes(owner);

            if (outcome == Vote.Null) return;

            if (outcome == Vote.Yes) {
                permittedAction[proposal.proposedAction] = true;
                Action(proposal.proposedAction).execute();
                delete permittedAction[proposal.proposedAction];
            }
            _removeProposal(owner);
        }
    }

    function spend(address recipient, uint amount) {
        if (!permittedSender()) return;
        recipient.send(amount);
    }

    function remove() {
        if (!permittedSender()) return;
        super.remove();
    }

    function _removeProposal(address owner) private {
        if (proposals[owner].proposedAction == 0x0) return;
        delete proposals[owner];
    }

    function _updateMargins() private {
        var numOwners = OwnersDb(ApiProvider(api).contracts(OWNERS_DB)).numOwners();
        quorum = (numOwners * 100) / quorumPercent;
        marginForVictory = (numOwners * 100) / marginForVictoryPercent;
    }

    function _checkVotes(address owner) private returns (Vote result) {
        var proposal = proposals[owner];
        if (proposal.numVotes < quorum) {
            return Vote.Null;
        }

        uint yesTally = 0;
        uint noTally = 0;
        var db = OwnersDb(ApiProvider(api).contracts(OWNERS_DB));
        var numOwners = db.numOwners();
        var iter = db.ownersTail();

        for (uint i=0; i < numOwners; i+=1) {
            iter = db.owners(iter);

            if (proposal.votes[iter] == Vote.Abstain || proposal.votes[iter] == Vote.Null) {
                continue;
            }

            if (proposal.votes[iter] == Vote.Yes) {
                yesTally += 1;
            } else {
                noTally -= 1;
            }
        }

        if (noTally > yesTally && (noTally - yesTally) >= marginForVictory) {
            return Vote.No;

        } else if (yesTally > noTally && (yesTally - noTally) >= marginForVictory) {
            return Vote.Yes;
        }

        return Vote.Null;
    }
}

contract DirectDemocracy is PermissionsProvider, PersistentProtectedContract {
    // PoC-8
    // include "action.sol"

    uint public quorum;
    uint8 public quorumPercent;
    uint public marginForVictory;
    uint8 public marginForVictoryPercent;
    uint public minimumVotingWindow;
    uint public maximumVotingWindow;

    uint VOTING_WINDOW_MIN = 600; // 10 minutes
    bytes32 OWNERS_DB = "OwnersDb";

    mapping (address => Proposal) public proposals;
    mapping (address => bool) permittedAction;

    enum Vote {
        Null, Yes, No, Abstain
    }

    struct Proposal {
        uint timestamp;
        mapping (address => Vote) votes;
        uint numVotes;
        address proposedAction;
    }

    function DirectDemocracy() {
        quorum = 1;
        quorumPercent = 60;
        marginForVictory = 0;
        marginForVictoryPercent = 0;
    }

    function permitted(address action) returns (bool result) {
        return permittedAction[action];
    }

    function addOwner(address owner) returns (bool added) {
        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        if (dbAddress == 0x0 || !permittedSender()) return false;

        added = OwnersDb(dbAddress).addOwner(owner);

        if (added) {
            _updateMargins();
        }
    }

    function removeOwner(address owner) returns (bool removed) {
        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        var db = OwnersDb(dbAddress);
        var iter = db.owners(owner);

        if (dbAddress == 0x0 || iter == 0x0 || !permittedSender()) {
            return false;
        }

        if (!db.removeOwner(owner)) return false;

        Proposal proposal;
        var numOwners = db.numOwners();

        for (uint i=0; i < numOwners; i+=1) {
            proposal = proposals[iter];
            iter = db.owners(iter);

            if (proposal.proposedAction == 0x0) continue;

            if (proposal.votes[owner] != Vote.Null) {
                delete proposal.votes[owner];
                proposal.numVotes -= 1;
            }
        }

        delete proposals[owner];
        _updateMargins();

        return true;
    }

    function proposeAction(address proposedAction) {
        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        var db = OwnersDb(dbAddress);
        if (db.owners(msg.sender) == 0x0
            || Action(proposedAction).owner() != address(this)) {
            return;
        }

        var proposal = proposals[msg.sender];
        proposal.timestamp = block.timestamp;
        proposal.proposedAction = proposedAction;
        proposal.votes[msg.sender] = Vote.Yes;
        proposal.numVotes = 1;
    }

    function withdrawProposedAction() {
        _removeProposal(msg.sender);
    }

    function setQuorumPercent(uint8 percent) {
        if (!permittedSender()) return;
        quorumPercent = percent;
        _updateMargins();
    }

    function setMarginForVictoryPercent(uint8 percent) {
        if (!permittedSender()) return;
        marginForVictoryPercent = percent;
        _updateMargins();
    }

    function setMinimumVotingWindow(uint minimumWindow) {
        if (!permittedSender()) return;
        minimumVotingWindow = minimumWindow;
    }

    function setMaximumVotingWindow(uint maximumWindow) {
        if ((maximumWindow < VOTING_WINDOW_MIN && maximumWindow != 0)
            || !permittedSender()) {
            return;
        }
        maximumVotingWindow = maximumWindow;
    }

    function wipeProposedActions() {
        if (!permittedSender()) return;

        var dbAddress = ApiProvider(api).contracts(OWNERS_DB);
        var db = OwnersDb(dbAddress);
        var iter = db.ownersTail();
        var numOwners = db.numOwners();

        for (uint i=0; i < numOwners; i += 1) {
            if (proposals[iter].proposedAction != 0x0) {
                Action(proposals[iter].proposedAction).remove();
                delete proposals[iter];
            }
            iter = db.owners(iter);
        }
    }

    function vote(address owner, address action, Vote vote) {
        // We require the action parameter to make sure the voter knows
        // exactly what they are voting on, to prevent "bait & switch."
        var proposal = proposals[owner];

        if (action == 0x0
            || proposal.proposedAction != action
            || vote == Vote.Null) {
            return;
        }

        if (maximumVotingWindow == 0
            || block.timestamp <= (proposal.timestamp + maximumVotingWindow)) {

            if (proposal.votes[msg.sender] == Vote.Null) {
                proposal.numVotes += 1;
            }

            proposal.votes[msg.sender] = vote;
        }

        if (block.timestamp > (proposal.timestamp + minimumVotingWindow)) {
            var outcome = _checkVotes(owner);

            if (outcome == Vote.Null) return;

            if (outcome == Vote.Yes) {
                permittedAction[proposal.proposedAction] = true;
                Action(proposal.proposedAction).execute();
                delete permittedAction[proposal.proposedAction];
            }
            _removeProposal(owner);
        }
    }

    function spend(address recipient, uint amount) {
        if (!permittedSender()) return;
        recipient.send(amount);
    }

    function remove() {
        if (!permittedSender()) return;
        super.remove();
    }

    function _removeProposal(address owner) private {
        if (proposals[owner].proposedAction == 0x0) return;
        delete proposals[owner];
    }

    function _updateMargins() private {
        var numOwners = OwnersDb(ApiProvider(api).contracts(OWNERS_DB)).numOwners();
        quorum = (numOwners * 100) / quorumPercent;
        marginForVictory = (numOwners * 100) / marginForVictoryPercent;
    }

    function _checkVotes(address owner) private returns (Vote result) {
        var proposal = proposals[owner];
        if (proposal.numVotes < quorum) {
            return Vote.Null;
        }

        uint yesTally = 0;
        uint noTally = 0;
        var db = OwnersDb(ApiProvider(api).contracts(OWNERS_DB));
        var numOwners = db.numOwners();
        var iter = db.ownersTail();

        for (uint i=0; i < numOwners; i+=1) {
            iter = db.owners(iter);

            if (proposal.votes[iter] == Vote.Abstain || proposal.votes[iter] == Vote.Null) {
                continue;
            }

            if (proposal.votes[iter] == Vote.Yes) {
                yesTally += 1;
            } else {
                noTally -= 1;
            }
        }

        if (noTally > yesTally && (noTally - yesTally) >= marginForVictory) {
            return Vote.No;

        } else if (yesTally > noTally && (yesTally - noTally) >= marginForVictory) {
            return Vote.Yes;
        }

        return Vote.Null;
    }
}


Reindent assert sol to pick up syntax highlighting

// This file taken from here: https://raw.githubusercontent.com/smartcontractproduction/sol-unit/master/contracts/src/Assertions.sol
// It was renamed to Assert.sol by Tim Coulter.

pragma solidity ^0.4.17;

/*
  File: Assertions.slb

  Author: Andreas Olofsson (androlo1980@gmail.com)

  Library: Assertions

  Assertions for unit testing contracts. Tests are run with the
  <solUnit at https://github.com/smartcontractproduction/sol-unit>
  unit-testing framework.

  (start code)
  contract ModAdder {

  function addMod(uint a, uint b, uint modulus) constant returns (uint sum) {
  if (modulus == 0)
  throw;
  return addmod(a, b, modulus);
  }

  }

  contract SomeTest {
  using Assertions for uint;

  function testAdd() {
  var adder = new ModAdder();
  adder.addMod(50, 66, 30).equal(26, "addition returned the wrong sum");
  }
  }
  (end)

  It is also possible to extend <Test>, to have all bindings (using) properly set up.

  (start code)

  contract SomeTest is Test {

  function testAdd() {
  var adder = new ModAdder();
  adder.addMod(50, 66, 30).equal(26, "addition returned the wrong sum");
  }
  }
  (end)
*/
library Assert {

  // Constant: ADDRESS_NULL
  // The null address: 0
  address constant ADDRESS_NULL = 0x0000000000000000000000000000000000000000;
  // Constant: BYTES32_NULL
  // The null bytes32: 0
  bytes32 constant BYTES32_NULL = 0x0;
  // Constant: STRING_NULL
  // The null string: ""
  string constant STRING_NULL = "";

  uint8 constant ZERO = uint8(byte('0'));
  uint8 constant A = uint8(byte('a'));

  byte constant MINUS = byte('-');

  /*
    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);

  // ************************************** general **************************************

  /*
    Function: fail()

    Mark the test as failed.

    Params:
    message (string) - A message associated with the failure.

    Returns:
    result (bool) - false.
  */
  function fail(string message) public returns (bool result) {
    _report(false, message);
    return false;
  }

  // ************************************** strings **************************************

  /*
    Function: equal(string)

    Assert that two strings are equal.

    : _stringsEqual(A, B) == true

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

    Returns:
    result (bool) - The result.
  */
  function equal(string a, string b, string message) public returns (bool result) {
    result = _stringsEqual(a, b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: notEqual(string)

    Assert that two strings are not equal.

    : _stringsEqual(A, B) == false

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

    Returns:
    result (bool) - The result.
  */
  function notEqual(string a, string b, string message) public returns (bool result) {
    result = !_stringsEqual(a, b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: isEmpty(string)

    Assert that a string is empty.

    : _stringsEqual(str, STRING_NULL) == true

    Params:
    str (string) - The string.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function isEmpty(string str, string message) public returns (bool result) {
    result = _stringsEqual(str, STRING_NULL);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(str, "Tested"), message));
  }

  /*
    Function: isNotEmpty(string)

    Assert that a string is not empty.

    : _stringsEqual(str, STRING_NULL) == false

    Params:
    str (string) - The string.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function isNotEmpty(string str, string message) public returns (bool result) {
    result = !_stringsEqual(str, STRING_NULL);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(str, "Tested"), message));
  }

  // ************************************** bytes32 **************************************

  /*
    Function: equal(bytes32)

    Assert that two 'bytes32' are equal.

    : A == B

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

    Returns:
    result (bool) - The result.
  */
  function equal(bytes32 a, bytes32 b, string message) public returns (bool result) {
    result = (a == b);
    _report(result, message);
  }

  /*
    Function: notEqual(bytes32)

    Assert that two 'bytes32' are not equal.

    : A != B

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

    Returns:
    result (bool) - The result.
  */
  function notEqual(bytes32 a, bytes32 b, string message) public returns (bool result) {
    result = (a != b);
    _report(result, message);
  }

  /*
    Function: isZero(bytes32)

    Assert that a 'bytes32' is zero.

    : bts == BYTES32_NULL

    Params:
    bts (bytes32) - The 'bytes32'.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function isZero(bytes32 bts, string message) public returns (bool result) {
    result = (bts == BYTES32_NULL);
    _report(result, message);
  }

  /*
    Function: isNotZero(bytes32)

    Assert that a 'bytes32' is not zero.

    : bts != BYTES32_NULL

    Params:
    bts (bytes32) - The 'bytes32'.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function isNotZero(bytes32 bts, string message) public returns (bool result) {
    result = (bts != BYTES32_NULL);
    _report(result, message);
  }

  // ************************************** address **************************************

  /*
    Function: equal(address)

    Assert that two addresses are equal.

    : A == B

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

    Returns:
    result (bool) - The result.
  */
  function equal(address a, address b, string message) public returns (bool result) {
    result = (a == b);
    _report(result, message);
  }
  /*
    Function: notEqual(address)

    Assert that two addresses are not equal.

    : A != B

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

    Returns:
    result (bool) - The result.
  */
  function notEqual(address a, address b, string message) public returns (bool result) {
    result = (a != b);
    _report(result, message);
  }

  /*
    Function: isZero(address)

    Assert that an address is zero.

    : addr == ADDRESS_NULL

    Params:
    addr (address) - The address.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function isZero(address addr, string message) public returns (bool result) {
    result = (addr == ADDRESS_NULL);
    _report(result, message);
  }

  /*
    Function: isNotZero(address)

    Assert that an address is not zero.

    : addr != ADDRESS_NULL

    Params:
    addr (address) - The address.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function isNotZero(address addr, string message) public returns (bool result) {
    result = (addr != ADDRESS_NULL);
    _report(result, message);
  }

  // ************************************** bool **************************************

  /*
    Function: isTrue

    Assert that a boolean is 'true'.

    : b == true

    Params:
    b (bool) - The boolean.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function isTrue(bool b, string message) public returns (bool result) {
    result = b;
    _report(result, message);
  }

  /*
    Function: isFalse

    Assert that a boolean is 'false'.

    : b == false

    Params:
    b (bool) - The boolean.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function isFalse(bool b, string message) public returns (bool result) {
    result = !b;
    _report(result, message);
  }

  /*
    Function: equal(bool)

    Assert that two booleans are equal.

    : A == B

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

    Returns:
    result (bool) - The result.
  */
  function equal(bool a, bool b, string message) public returns (bool result) {
    result = (a == b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: notEqual(bool)

    Assert that two booleans are not equal.

    : A != B

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

    Returns:
    result (bool) - The result.
  */
  function notEqual(bool a, bool b, string message) public returns (bool result) {
    result = (a != b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  // ************************************** uint **************************************

  /*
    Function: equal(uint)

    Assert that two (256 bit) unsigned integers are equal.

    : A == B

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

    Returns:
    result (bool) - The result.
  */
  function equal(uint a, uint b, string message) public returns (bool result) {
    result = (a == b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: notEqual(uint)

    Assert that two (256 bit) unsigned integers are not equal.

    : A != B

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

    Returns:
    result (bool) - The result.
  */
  function notEqual(uint a, uint b, string message) public returns (bool result) {
    result = (a != b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: isAbove(uint)

    Assert that the uint 'A' is greater than the uint 'B'.

    : A > B

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

    Returns:
    result (bool) - The result.
  */
  function isAbove(uint a, uint b, string message) public returns (bool result) {
    result = (a > b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: isAtLeast(uint)

    Assert that the uint 'A' is greater than or equal to the uint 'B'.

    : A >= B

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

    Returns:
    result (bool) - The result.
  */
  function isAtLeast(uint a, uint b, string message) public returns (bool result) {
    result = (a >= b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: isBelow(uint)

    Assert that the uint 'A' is lesser than the uint 'B'.

    : A < B

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

    Returns:
    result (bool) - The result.
  */
  function isBelow(uint a, uint b, string message) public returns (bool result) {
    result = (a < b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: isAtMost(uint)

    Assert that the uint 'A' is lesser than or equal to the uint 'B'.

    : A <= B

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

    Returns:
    result (bool) - The result.
  */
  function isAtMost(uint a, uint b, string message) public returns (bool result) {
    result = (a <= b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: isZero(uint)

    Assert that a (256 bit) unsigned integer is 0.

    : number == 0

    Params:
    number (uint) - The uint.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function isZero(uint number, string message) public returns (bool result) {
    result = (number == 0);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(number, "Tested"), message));
  }

  /*
    Function: isNotZero(uint)

    Assert that a (256 bit) unsigned integer is not 0.

    : number != 0

    Params:
    number (uint) - The uint.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function isNotZero(uint number, string message) public returns (bool result) {
    result = (number != 0);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(number, "Tested"), message));
  }

  // ************************************** int **************************************

  /*
    Function: equal(int)

    Assert that two (256 bit) signed integers are equal.

    : A == B

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

    Returns:
    result (bool) - The result.
  */
  function equal(int a, int b, string message) public returns (bool result) {
    result = (a == b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: notEqual(int)

    Assert that two (256 bit) signed integers are not equal.

    : A != B

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

    Returns:
    result (bool) - The result.
  */
  function notEqual(int a, int b, string message) public returns (bool result) {
    result = (a != b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: isAbove(int)

    Assert that the int 'A' is greater than the int 'B'.

    : A > B

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

    Returns:
    result (bool) - The result.
  */
  function isAbove(int a, int b, string message) public returns (bool result) {
    result = (a > b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: isAtLeast(int)

    Assert that the int 'A' is greater than or equal to the int 'B'.

    : A >= B

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

    Returns:
    result (bool) - The result.
  */
  function isAtLeast(int a, int b, string message) public returns (bool result) {
    result = (a >= b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: isBelow(int)

    Assert that the int 'A' is lesser than the int 'B'.

    : A < B

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

    Returns:
    result (bool) - The result.
  */
  function isBelow(int a, int b, string message) public returns (bool result) {
    result = (a < b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: isAtMost(int)

    Assert that the int 'A' is lesser than or equal to the int 'B'.

    : A <= B

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

    Returns:
    result (bool) - The result.
  */
  function isAtMost(int a, int b, string message) public returns (bool result) {
    result = (a <= b);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(a, "Tested"), _tag(b, "Against"), message));
  }

  /*
    Function: isZero(int)

    Assert that a (256 bit) signed integer is 0.

    : number == 0

    Params:
    number (int) - The int.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function isZero(int number, string message) public returns (bool result) {
    result = (number == 0);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(number, "Tested"), message));
  }

  /*
    Function: isNotZero(int)

    Assert that a (256 bit) signed integer is not 0.

    : number != 0

    Params:
    number (int) - The int.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function isNotZero(int number, string message) public returns (bool result) {
    result = (number != 0);
    if (result)
      _report(result, message);
    else
      _report(result, _appendTagged(_tag(number, "Tested"), message));
  }

  // ************************************** uint[] **************************************

  /*
    Function: equal(uint[])

    Assert that two 'uint[ ]' are equal.

    : arrA.length == arrB.length

    and, for all valid indices 'i'

    : arrA[i] == arrB[i]

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

    Returns:
    result (bool) - The result.
  */
  function equal(uint[] arrA, uint[] arrB, string 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(uint[])

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

    : arrA.length != arrB.length

    or, for some valid index 'i'

    : arrA[i] != arrB[i]

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

    Returns:
    result (bool) - The result.
  */
  function notEqual(uint[] arrA, uint[] arrB, string 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(uint[])

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

    : arr.length == length

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

    Returns:
    result (bool) - The result.
  */
  function lengthEqual(uint[] arr, uint length, string 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(uint[])

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

    : arr.length != length

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

    Returns:
    result (bool) - The result.
  */
  function lengthNotEqual(uint[] arr, uint length, string 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));
  }

  // ************************************** int[] **************************************

  /*
    Function: equal(int[])

    Assert that two 'int[]' are equal.

    : arrA.length == arrB.length

    and, for all valid indices 'i'

    : arrA[i] == arrB[i]

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

    Returns:
    result (bool) - The result.
  */
  function equal(int[] arrA, int[] arrB, string 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(int[])

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

    : arrA.length != arrB.length

    or, for some valid index 'i'

    : arrA[i] != arrB[i]

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

    Returns:
    result (bool) - The result.
  */
  function notEqual(int[] arrA, int[] arrB, string 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(int[])

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

    : arr.length == length

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

    Returns:
    result (bool) - The result.
  */
  function lengthEqual(int[] arr, uint length, string 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(int[])

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

    : arr.length != length

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

    Returns:
    result (bool) - The result.
  */
  function lengthNotEqual(int[] arr, uint length, string 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));
  }

  // ************************************** address[] **************************************

  /*
    Function: equal(address[])

    Assert that two 'address[]' are equal.

    : arrA.length == arrB.length

    and, for all valid indices 'i'

    : arrA[i] == arrB[i]

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

    Returns:
    result (bool) - The result.
  */
  function equal(address[] arrA, address[] arrB, string 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(address[])

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

    : arrA.length != arrB.length

    or, for some valid index 'i'

    : arrA[i] != arrB[i]

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

    Returns:
    result (bool) - The result.
  */
  function notEqual(address[] arrA, address[] arrB, string 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(address[])

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

    : arr.length == length

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

    Returns:
    result (bool) - The result.
  */
  function lengthEqual(address[] arr, uint length, string 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(address[])

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

    : arr.length != length

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

    Returns:
    result (bool) - The result.
  */
  function lengthNotEqual(address[] arr, uint length, string 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));
  }

  // ************************************** 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[] arrA, bytes32[] arrB, string 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[] arrA, bytes32[] arrB, string 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[] arr, uint length, string 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[] arr, uint length, string 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));
  }

  // ************************************** balances **************************************

  /*
    Function: balanceEqual

    Assert that the balance of an account 'A' is equal to a given number 'b'.

    : A.balance = b

    Params:
    A (address) - The first address.
    b (uint) - The balance.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function balanceEqual(address a, uint b, string message) public returns (bool result) {
    result = (a.balance == b);
    _report(result, message);
  }

  /*
    Function: balanceNotEqual

    Assert that the balance of an account 'A' is not equal to a given number 'b'.

    : A.balance != b

    Params:
    A (address) - The first address.
    b (uint) - The balance.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function balanceNotEqual(address a, uint b, string message) public returns (bool result) {
    result = (a.balance != b);
    _report(result, message);
  }

  /*
    Function: balanceIsZero

    Assert that the balance of an account 'A' is zero.

    : A.balance == 0

    Params:
    A (address) - The first address.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function balanceIsZero(address a, string message) public returns (bool result) {
    result = (a.balance == 0);
    _report(result, message);
  }

  /*
    Function: balanceIsNotZero

    Assert that the balance of an account 'A' is not zero.

    : A.balance != 0

    Params:
    A (address) - The first address.
    message (string) - A message that is sent if the assertion fails.

    Returns:
    result (bool) - The result.
  */
  function balanceIsNotZero(address a, string message) public returns (bool result) {
    result = (a.balance != 0);
    _report(result, 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 message) internal {
    if(result)
      emit TestEvent(true, "");
    else
      emit TestEvent(false, message);
  }

  /*
    Function: _stringsEqual

    Compares two strings. Taken from the StringUtils contract in the Ethereum Dapp-bin
    (https://github.com/ethereum/dapp-bin/blob/master/library/stringUtils.sol).

    Params:
    a (string) - The first string.
    b (string) - The second string.

    Returns:
    result (bool) - 'true' if the strings are equal, otherwise 'false'.
  */
  function _stringsEqual(string a, string b) internal pure returns (bool result) {
    bytes memory ba = bytes(a);
    bytes memory bb = bytes(b);

    if (ba.length != bb.length)
      return false;
    for (uint i = 0; i < ba.length; i ++) {
      if (ba[i] != bb[i])
        return false;
    }
    return true;
  }

  /*
    Function: _itoa

    Convert a signed integer to a string. Negative numbers gets a '-' in front, e.g. "-54".

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

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

    for (; j < size; j++)
      rev[j] = bts[size - j - 1];
    return string(rev);
  }

  /*
    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) {
    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: _ltoa

    Convert an boolean to a string.

    Params:
    val (bool) - The boolean.

    Returns:
    result (string) - "true" if true, "false" if false.
  */
  function _ltoa(bool val) internal pure returns (string) {
    bytes memory b;
    if (val) {
      b = new bytes(4);
      b[0] = 't';
      b[1] = 'r';
      b[2] = 'u';
      b[3] = 'e';
      return string(b);
    }
    else {
      b = new bytes(5);
      b[0] = 'f';
      b[1] = 'a';
      b[2] = 'l';
      b[3] = 's';
      b[4] = 'e';
      return string(b);
    }
  }

  /*
    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 value, string tag) internal pure returns (string) {

    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(int)

    Add a tag to an int.

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

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

  /*
    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 tag) internal pure returns (string) {
    string memory nstr = _utoa(value, 10);
    return _tag(nstr, tag);
  }

  /*
    Function: _tag(bool)

    Add a tag to a boolean.

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

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

  /*
    Function: _appendTagged(string)

    Append a tagged value to a string.

    Params:
    tagged (string) - The tagged value.
    str (string) - The string.

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

    bytes memory taggedB = bytes(tagged);
    bytes memory strB = bytes(str);

    uint sl = strB.length;
    uint tl = taggedB.length;

    bytes memory newB = new bytes(sl + tl + 3);

    uint i;
    uint j;

    for (i = 0; i < sl; i++)
      newB[j++] = strB[i];
    newB[j++] = ' ';
    newB[j++] = '(';
    for (i = 0; i < tl; i++)
      newB[j++] = taggedB[i];
    newB[j++] = ')';

    return string(newB);
  }

  /*
    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 tagged0, string tagged1, string str) internal pure returns (string) {

    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);
  }

}


remove adding to members twice

remove adding to members twice

pragma solidity ^0.4.0;

import "./UserRegistry.sol";
import "./ConceptRegistry.sol";
import "./Assessment.sol";
import "./Math.sol";

//@purpose: To store concept data and create and manage assessments and members
contract Concept {
  address[] public parents; //The concepts that this concept is child to (ie: Calculus is child to Math)
  address[] public children; //The concepts that this concept is parent to (ie: Math is parent to Calculus)
  address userRegistry;
  address conceptRegistry;
  uint public maxWeight; //The current highest weight for this assessment
  address[] public members; //Those who have earned the concept
  mapping (address => int) public currentScores; //The most recent score of a user
  mapping (address => bool) public assessmentExists; //All existing assessments
  mapping (address => uint) public weights; //The weighting used by the assessor selection algorhitm for each owner
  mapping (address => mapping (address => uint)) public approval;

  modifier onlyUserRegistry() {
    if(msg.sender != userRegistry)
    {
      throw;
    }
    _;
  }

  modifier onlyConceptRegistry() {
    if(msg.sender != conceptRegistry) {
      throw;
    }
    _;
  }

  modifier onlyThis() {
    if(msg.sender != address(this)) {
      throw;
    }
    _;
  }

  modifier onlyConcept(){
      if(!ConceptRegistry(conceptRegistry).conceptExists(msg.sender)) {
          throw;
      }
      _;
  }

  /*
  @type: event
  @name: CompletedAssessment
  @purpose: To build a database of completed assessments
  */
  event CompletedAssessment (
    address _assessee, //The address of the user who took the assessment
    int _score, //The score of the assessee
    address _assessment
  );

  function Concept(address[] _parents, address _userRegistry) {
    parents = _parents;
    userRegistry = _userRegistry;
    conceptRegistry = UserRegistry(userRegistry).conceptRegistry();
  }

  function getMemberLength() constant returns(uint) {
    return members.length;
  }

  function getParentsLength() constant returns(uint) {
    return parents.length;
  }

  function getChildrenLength() constant returns(uint) {
    return children.length;
  }

  /*
  @purpose: To add the firstUser to Mew
  */
  function addFirstUser(address user) onlyUserRegistry() {
    if(ConceptRegistry(conceptRegistry).mewAddress() == address(this))
    {
      this.addMember(user, 100);
    }
  }

  function addParent(address _parent) onlyConceptRegistry() {
    parents.push(_parent);
  }

  function addChild(address _child) onlyConceptRegistry() {
    children.push(_child);
  }

  //@purpose: returns a random member of the Concept. Users with high weights are more likely to be called
  function getRandomMember(uint seed) returns(address) {
    address randomUser = members[Math.getRandom(seed, members.length-1)];
    if(UserRegistry(userRegistry).availability(randomUser) && weights[randomUser] > now % maxWeight) {
        return randomUser;
     }
    return address(0x0);
  }

  /*
  @purpose: To make a new assessment
  @param: uint cost = the cost per assessor
  @param: uint size = the number of assessors
  */
  function makeAssessment(uint cost, uint size) returns(bool) {
    if(size >= 5 && subtractBalance(msg.sender, cost*size)) { //Checks if the assessment has a size of at least 5 and tries to subtract the neccesary tokens from the user
      Assessment newAssessment = new Assessment(msg.sender, userRegistry, conceptRegistry, size, cost);
      assessmentExists[address(newAssessment)] = true; //Sets the assessment's existance to true
      UserRegistry(userRegistry).notification(address(this), 0); //You have been charged for your assessment
      newAssessment.setAssessorPool(block.number, address(this), size*20); //Calls the function to set the assessor pool
      return true;
    }
    else {
      return false;
    }
  }
  function approve(address _from, uint _amount) returns(bool) {
    approval[msg.sender][_from] = _amount;
    return true;
  }

  function makeAssessmentFrom(address _assessee, uint _cost, uint _size) returns(bool) {
    if(approval[_assessee][msg.sender] >= _cost * _size &&
       _size >= 5 &&
       subtractBalance(_assessee, _cost*_size)) {
        Assessment newAssessment = new Assessment(_assessee, userRegistry, conceptRegistry, _size, _cost);
        assessmentExists[address(newAssessment)] = true;
        newAssessment.setAssessorPool(block.number, address(this), _size*20);
        approval[_assessee][msg.sender] -= _cost*_size;
        return true;
    }
    else {
        return false;
    }
  }

  /*
  @purpose: To finish the assessment process
  @param: int score = the assessee's score
  @param: address assessee = the address of the assessee
  @param: address assessment = the address of the assessment
  @returns: nothing
  */
  function finishAssessment(int score, address assessee, address assessment) {
    if(msg.sender == assessment) {
      if(score > 0) {
        uint weight = Assessment(assessment).size()*uint(score);
        this.addMember(assessee, weight);
      }
      currentScores[assessee] = score; //Maps the assessee to their score
      CompletedAssessment(assessee, score, assessment); //Makes an event with this assessment's data
    }
  }

  /*
  @purpose: To add a member to a concept and recursively add a member to parent concept, halving the added weight with each generation and chinging the macWeight for a concept if neccisairy
  @param: bool pass = whether or not the assessee passed the assessment
  @param: address assessee = the address of the assessee
  @param: uint weight = the weight for the member
  @returns: nothing
  */
  function addMember(address assessee, uint weight) onlyConcept() {
    members.push(assessee); //adds the member to the array
    weights[assessee] += weight; //adds the weight to the current value in mapping
    if(weight > maxWeight) {//checks if the weight is greater than the currant maxWeight
      maxWeight = weight; //if so changes the maxWeight value
    }
    for(uint i = 0; i < parents.length; i++) {
      Concept(parents[i]).addMember(assessee, weight/2); //recursively adds member to all parent concepts but with half the weight
    }
  }

  function subtractBalance(address _from, uint _amount) returns(bool) {
    if(assessmentExists[msg.sender] || msg.sender == address(this)) { //Checks if msg.sender is an existing assessment or the concept
      return UserRegistry(userRegistry).subtractBalance(_from, _amount);
    }
  }

  function addBalance(address _to, uint _amount)  returns(bool) {
    if(assessmentExists[msg.sender]) { //Checks if msg.sender is an existing assessment
      return UserRegistry(userRegistry).addBalance(_to, _amount);
    }
  }

  function remove(address reciever) onlyThis() {
    suicide(reciever);
  }
}

pragma solidity ^0.4.0;

import "./UserRegistry.sol";
import "./ConceptRegistry.sol";
import "./Assessment.sol";
import "./Math.sol";

//@purpose: To store concept data and create and manage assessments and members
contract Concept {
  address[] public parents; //The concepts that this concept is child to (ie: Calculus is child to Math)
  address[] public children; //The concepts that this concept is parent to (ie: Math is parent to Calculus)
  address userRegistry;
  address conceptRegistry;
  uint public maxWeight; //The current highest weight for this assessment
  address[] public members; //Those who have earned the concept
  mapping (address => int) public currentScores; //The most recent score of a user
  mapping (address => bool) public assessmentExists; //All existing assessments
  mapping (address => uint) public weights; //The weighting used by the assessor selection algorhitm for each owner
  mapping (address => mapping (address => uint)) public approval;

  modifier onlyUserRegistry() {
    if(msg.sender != userRegistry)
    {
      throw;
    }
    _;
  }

  modifier onlyConceptRegistry() {
    if(msg.sender != conceptRegistry) {
      throw;
    }
    _;
  }

  modifier onlyThis() {
    if(msg.sender != address(this)) {
      throw;
    }
    _;
  }

  modifier onlyConcept(){
      if(!ConceptRegistry(conceptRegistry).conceptExists(msg.sender)) {
          throw;
      }
      _;
  }

  /*
  @type: event
  @name: CompletedAssessment
  @purpose: To build a database of completed assessments
  */
  event CompletedAssessment (
    address _assessee, //The address of the user who took the assessment
    int _score, //The score of the assessee
    address _assessment
  );

  function Concept(address[] _parents, address _userRegistry) {
    parents = _parents;
    userRegistry = _userRegistry;
    conceptRegistry = UserRegistry(userRegistry).conceptRegistry();
  }

  function getMemberLength() constant returns(uint) {
    return members.length;
  }

  function getParentsLength() constant returns(uint) {
    return parents.length;
  }

  function getChildrenLength() constant returns(uint) {
    return children.length;
  }

  /*
  @purpose: To add the firstUser to Mew
  */
  function addFirstUser(address user) onlyUserRegistry() {
    if(ConceptRegistry(conceptRegistry).mewAddress() == address(this))
    {
      this.addMember(user, 100);
    }
  }

  function addParent(address _parent) onlyConceptRegistry() {
    parents.push(_parent);
  }

  function addChild(address _child) onlyConceptRegistry() {
    children.push(_child);
  }

  //@purpose: returns a random member of the Concept. Users with high weights are more likely to be called
  function getRandomMember(uint seed) returns(address) {
    address randomUser = members[Math.getRandom(seed, members.length-1)];
    if(UserRegistry(userRegistry).availability(randomUser) && weights[randomUser] > now % maxWeight) {
        return randomUser;
     }
    return address(0x0);
  }

  /*
  @purpose: To make a new assessment
  @param: uint cost = the cost per assessor
  @param: uint size = the number of assessors
  */
  function makeAssessment(uint cost, uint size) returns(bool) {
    if(size >= 5 && subtractBalance(msg.sender, cost*size)) { //Checks if the assessment has a size of at least 5 and tries to subtract the neccesary tokens from the user
      Assessment newAssessment = new Assessment(msg.sender, userRegistry, conceptRegistry, size, cost);
      assessmentExists[address(newAssessment)] = true; //Sets the assessment's existance to true
      UserRegistry(userRegistry).notification(address(this), 0); //You have been charged for your assessment
      newAssessment.setAssessorPool(block.number, address(this), size*20); //Calls the function to set the assessor pool
      return true;
    }
    else {
      return false;
    }
  }
  function approve(address _from, uint _amount) returns(bool) {
    approval[msg.sender][_from] = _amount;
    return true;
  }

  function makeAssessmentFrom(address _assessee, uint _cost, uint _size) returns(bool) {
    if(approval[_assessee][msg.sender] >= _cost * _size &&
       _size >= 5 &&
       subtractBalance(_assessee, _cost*_size)) {
        Assessment newAssessment = new Assessment(_assessee, userRegistry, conceptRegistry, _size, _cost);
        assessmentExists[address(newAssessment)] = true;
        newAssessment.setAssessorPool(block.number, address(this), _size*20);
        approval[_assessee][msg.sender] -= _cost*_size;
        return true;
    }
    else {
        return false;
    }
  }

  /*
  @purpose: To finish the assessment process
  @param: int score = the assessee's score
  @param: address assessee = the address of the assessee
  @param: address assessment = the address of the assessment
  @returns: nothing
  */
  function finishAssessment(int score, address assessee, address assessment) {
    if(msg.sender == assessment) {
      if(score > 0) {
        members.push(assessee); //Makes the assessee an member of this concept
        uint weight = Assessment(assessment).size()*uint(score);
        this.addMember(assessee, weight);
      }
      currentScores[assessee] = score; //Maps the assessee to their score
      CompletedAssessment(assessee, score, assessment); //Makes an event with this assessment's data
    }
  }

  /*
  @purpose: To add a member to a concept and recursively add a member to parent concept, halving the added weight with each generation and chinging the macWeight for a concept if neccisairy
  @param: bool pass = whether or not the assessee passed the assessment
  @param: address assessee = the address of the assessee
  @param: uint weight = the weight for the member
  @returns: nothing
  */
  function addMember(address assessee, uint weight) onlyConcept() {
    members.push(assessee); //adds the member to the array
    weights[assessee] += weight; //adds the weight to the current value in mapping
    if(weight > maxWeight) {//checks if the weight is greater than the currant maxWeight
      maxWeight = weight; //if so changes the maxWeight value
    }
    for(uint i = 0; i < parents.length; i++) {
      Concept(parents[i]).addMember(assessee, weight/2); //recursively adds member to all parent concepts but with half the weight
    }
  }

  function subtractBalance(address _from, uint _amount) returns(bool) {
    if(assessmentExists[msg.sender] || msg.sender == address(this)) { //Checks if msg.sender is an existing assessment or the concept
      return UserRegistry(userRegistry).subtractBalance(_from, _amount);
    }
  }

  function addBalance(address _to, uint _amount)  returns(bool) {
    if(assessmentExists[msg.sender]) { //Checks if msg.sender is an existing assessment
      return UserRegistry(userRegistry).addBalance(_to, _amount);
    }
  }

  function remove(address reciever) onlyThis() {
    suicide(reciever);
  }
}


solc > 0.4.24

solc > 0.4.24

pragma solidity >0.4.24;

import "./../../contracts/SHA1.sol";

contract SHA1Test {
    function sha1(bytes memory message) public pure returns(bytes20 ret) {
      return SHA1.sha1(message);
    }
}

pragma solidity >=0.5.0;

import "./../../contracts/SHA1.sol";

contract SHA1Test {
    function sha1(bytes memory message) public pure returns(bytes20 ret) {
      return SHA1.sha1(message);
    }
}


Remove extraneous quantity check, fixes #1454 (#1455)

pragma solidity ^0.4.24;

import "./IERC20.sol";
import "../../math/SafeMath.sol";

/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
 * Originally based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
 */
contract ERC20 is IERC20 {
  using SafeMath for uint256;

  mapping (address => uint256) private _balances;

  mapping (address => mapping (address => uint256)) private _allowed;

  uint256 private _totalSupply;

  /**
  * @dev Total number of tokens in existence
  */
  function totalSupply() public view returns (uint256) {
    return _totalSupply;
  }

  /**
  * @dev Gets the balance of the specified address.
  * @param owner The address to query the balance of.
  * @return An uint256 representing the amount owned by the passed address.
  */
  function balanceOf(address owner) public view returns (uint256) {
    return _balances[owner];
  }

  /**
   * @dev Function to check the amount of tokens that an owner allowed to a spender.
   * @param owner address The address which owns the funds.
   * @param spender address The address which will spend the funds.
   * @return A uint256 specifying the amount of tokens still available for the spender.
   */
  function allowance(
    address owner,
    address spender
   )
    public
    view
    returns (uint256)
  {
    return _allowed[owner][spender];
  }

  /**
  * @dev Transfer token for a specified address
  * @param to The address to transfer to.
  * @param value The amount to be transferred.
  */
  function transfer(address to, uint256 value) public returns (bool) {
    _transfer(msg.sender, to, value);
    return true;
  }

  /**
   * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
   * Beware that changing an allowance with this method brings the risk that someone may use both the old
   * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
   * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
   * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
   * @param spender The address which will spend the funds.
   * @param value The amount of tokens to be spent.
   */
  function approve(address spender, uint256 value) public returns (bool) {
    require(spender != address(0));

    _allowed[msg.sender][spender] = value;
    emit Approval(msg.sender, spender, value);
    return true;
  }

  /**
   * @dev Transfer tokens from one address to another
   * @param from address The address which you want to send tokens from
   * @param to address The address which you want to transfer to
   * @param value uint256 the amount of tokens to be transferred
   */
  function transferFrom(
    address from,
    address to,
    uint256 value
  )
    public
    returns (bool)
  {
    _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value);
    _transfer(from, to, value);
    return true;
  }

  /**
   * @dev Increase the amount of tokens that an owner allowed to a spender.
   * approve should be called when allowed_[_spender] == 0. To increment
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param spender The address which will spend the funds.
   * @param addedValue The amount of tokens to increase the allowance by.
   */
  function increaseAllowance(
    address spender,
    uint256 addedValue
  )
    public
    returns (bool)
  {
    require(spender != address(0));

    _allowed[msg.sender][spender] = (
      _allowed[msg.sender][spender].add(addedValue));
    emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
    return true;
  }

  /**
   * @dev Decrease the amount of tokens that an owner allowed to a spender.
   * approve should be called when allowed_[_spender] == 0. To decrement
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param spender The address which will spend the funds.
   * @param subtractedValue The amount of tokens to decrease the allowance by.
   */
  function decreaseAllowance(
    address spender,
    uint256 subtractedValue
  )
    public
    returns (bool)
  {
    require(spender != address(0));

    _allowed[msg.sender][spender] = (
      _allowed[msg.sender][spender].sub(subtractedValue));
    emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
    return true;
  }

  /**
  * @dev Transfer token for a specified addresses
  * @param from The address to transfer from.
  * @param to The address to transfer to.
  * @param value The amount to be transferred.
  */
  function _transfer(address from, address to, uint256 value) internal {
    require(to != address(0));

    _balances[from] = _balances[from].sub(value);
    _balances[to] = _balances[to].add(value);
    emit Transfer(from, to, value);
  }

  /**
   * @dev Internal function that mints an amount of the token and assigns it to
   * an account. This encapsulates the modification of balances such that the
   * proper events are emitted.
   * @param account The account that will receive the created tokens.
   * @param value The amount that will be created.
   */
  function _mint(address account, uint256 value) internal {
    require(account != address(0));

    _totalSupply = _totalSupply.add(value);
    _balances[account] = _balances[account].add(value);
    emit Transfer(address(0), account, value);
  }

  /**
   * @dev Internal function that burns an amount of the token of a given
   * account.
   * @param account The account whose tokens will be burnt.
   * @param value The amount that will be burnt.
   */
  function _burn(address account, uint256 value) internal {
    require(account != address(0));

    _totalSupply = _totalSupply.sub(value);
    _balances[account] = _balances[account].sub(value);
    emit Transfer(account, address(0), value);
  }

  /**
   * @dev Internal function that burns an amount of the token of a given
   * account, deducting from the sender's allowance for said account. Uses the
   * internal burn function.
   * @param account The account whose tokens will be burnt.
   * @param value The amount that will be burnt.
   */
  function _burnFrom(address account, uint256 value) internal {
    // Should https://github.com/OpenZeppelin/zeppelin-solidity/issues/707 be accepted,
    // this function needs to emit an event with the updated approval.
    _allowed[account][msg.sender] = _allowed[account][msg.sender].sub(
      value);
    _burn(account, value);
  }
}

pragma solidity ^0.4.24;

import "./IERC20.sol";
import "../../math/SafeMath.sol";

/**
 * @title Standard ERC20 token
 *
 * @dev Implementation of the basic standard token.
 * https://github.com/ethereum/EIPs/blob/master/EIPS/eip-20.md
 * Originally based on code by FirstBlood: https://github.com/Firstbloodio/token/blob/master/smart_contract/FirstBloodToken.sol
 */
contract ERC20 is IERC20 {
  using SafeMath for uint256;

  mapping (address => uint256) private _balances;

  mapping (address => mapping (address => uint256)) private _allowed;

  uint256 private _totalSupply;

  /**
  * @dev Total number of tokens in existence
  */
  function totalSupply() public view returns (uint256) {
    return _totalSupply;
  }

  /**
  * @dev Gets the balance of the specified address.
  * @param owner The address to query the balance of.
  * @return An uint256 representing the amount owned by the passed address.
  */
  function balanceOf(address owner) public view returns (uint256) {
    return _balances[owner];
  }

  /**
   * @dev Function to check the amount of tokens that an owner allowed to a spender.
   * @param owner address The address which owns the funds.
   * @param spender address The address which will spend the funds.
   * @return A uint256 specifying the amount of tokens still available for the spender.
   */
  function allowance(
    address owner,
    address spender
   )
    public
    view
    returns (uint256)
  {
    return _allowed[owner][spender];
  }

  /**
  * @dev Transfer token for a specified address
  * @param to The address to transfer to.
  * @param value The amount to be transferred.
  */
  function transfer(address to, uint256 value) public returns (bool) {
    _transfer(msg.sender, to, value);
    return true;
  }

  /**
   * @dev Approve the passed address to spend the specified amount of tokens on behalf of msg.sender.
   * Beware that changing an allowance with this method brings the risk that someone may use both the old
   * and the new allowance by unfortunate transaction ordering. One possible solution to mitigate this
   * race condition is to first reduce the spender's allowance to 0 and set the desired value afterwards:
   * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
   * @param spender The address which will spend the funds.
   * @param value The amount of tokens to be spent.
   */
  function approve(address spender, uint256 value) public returns (bool) {
    require(spender != address(0));

    _allowed[msg.sender][spender] = value;
    emit Approval(msg.sender, spender, value);
    return true;
  }

  /**
   * @dev Transfer tokens from one address to another
   * @param from address The address which you want to send tokens from
   * @param to address The address which you want to transfer to
   * @param value uint256 the amount of tokens to be transferred
   */
  function transferFrom(
    address from,
    address to,
    uint256 value
  )
    public
    returns (bool)
  {
    _allowed[from][msg.sender] = _allowed[from][msg.sender].sub(value);
    _transfer(from, to, value);
    return true;
  }

  /**
   * @dev Increase the amount of tokens that an owner allowed to a spender.
   * approve should be called when allowed_[_spender] == 0. To increment
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param spender The address which will spend the funds.
   * @param addedValue The amount of tokens to increase the allowance by.
   */
  function increaseAllowance(
    address spender,
    uint256 addedValue
  )
    public
    returns (bool)
  {
    require(spender != address(0));

    _allowed[msg.sender][spender] = (
      _allowed[msg.sender][spender].add(addedValue));
    emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
    return true;
  }

  /**
   * @dev Decrease the amount of tokens that an owner allowed to a spender.
   * approve should be called when allowed_[_spender] == 0. To decrement
   * allowed value is better to use this function to avoid 2 calls (and wait until
   * the first transaction is mined)
   * From MonolithDAO Token.sol
   * @param spender The address which will spend the funds.
   * @param subtractedValue The amount of tokens to decrease the allowance by.
   */
  function decreaseAllowance(
    address spender,
    uint256 subtractedValue
  )
    public
    returns (bool)
  {
    require(spender != address(0));

    _allowed[msg.sender][spender] = (
      _allowed[msg.sender][spender].sub(subtractedValue));
    emit Approval(msg.sender, spender, _allowed[msg.sender][spender]);
    return true;
  }

  /**
  * @dev Transfer token for a specified addresses
  * @param from The address to transfer from.
  * @param to The address to transfer to.
  * @param value The amount to be transferred.
  */
  function _transfer(address from, address to, uint256 value) internal {
    require(to != address(0));

    _balances[from] = _balances[from].sub(value);
    _balances[to] = _balances[to].add(value);
    emit Transfer(from, to, value);
  }

  /**
   * @dev Internal function that mints an amount of the token and assigns it to
   * an account. This encapsulates the modification of balances such that the
   * proper events are emitted.
   * @param account The account that will receive the created tokens.
   * @param value The amount that will be created.
   */
  function _mint(address account, uint256 value) internal {
    require(account != address(0));

    _totalSupply = _totalSupply.add(value);
    _balances[account] = _balances[account].add(value);
    emit Transfer(address(0), account, value);
  }

  /**
   * @dev Internal function that burns an amount of the token of a given
   * account.
   * @param account The account whose tokens will be burnt.
   * @param value The amount that will be burnt.
   */
  function _burn(address account, uint256 value) internal {
    require(account != address(0));

    _totalSupply = _totalSupply.sub(value);
    _balances[account] = _balances[account].sub(value);
    emit Transfer(account, address(0), value);
  }

  /**
   * @dev Internal function that burns an amount of the token of a given
   * account, deducting from the sender's allowance for said account. Uses the
   * internal burn function.
   * @param account The account whose tokens will be burnt.
   * @param value The amount that will be burnt.
   */
  function _burnFrom(address account, uint256 value) internal {
    require(value <= _allowed[account][msg.sender]);

    // Should https://github.com/OpenZeppelin/zeppelin-solidity/issues/707 be accepted,
    // this function needs to emit an event with the updated approval.
    _allowed[account][msg.sender] = _allowed[account][msg.sender].sub(
      value);
    _burn(account, value);
  }
}


Add warning about trading tokens before refundable crowdsale goal is met (#1452)

This attack was reported in https://github.com/OpenZeppelin/openzeppelin-solidity/issues/877

(cherry picked from commit 80458ebc72f1c7c9695416edbe26690f72e406a0)

pragma solidity ^0.4.24;

import "../../math/SafeMath.sol";
import "./FinalizableCrowdsale.sol";
import "../../payment/escrow/RefundEscrow.sol";

/**
 * @title RefundableCrowdsale
 * @dev Extension of Crowdsale contract that adds a funding goal, and
 * the possibility of users getting a refund if goal is not met.
 * WARNING: note that if you allow tokens to be traded before the goal
 * is met, then an attack is possible in which the attacker purchases
 * tokens from the crowdsale and when they sees that the goal is
 * unlikely to be met, they sell their tokens (possibly at a discount).
 * The attacker will be refunded when the crowdsale is finalized, and
 * the users that purchased from them will be left with worthless
 * tokens. There are many possible ways to avoid this, like making the
 * the crowdsale inherit from PostDeliveryCrowdsale, or imposing
 * restrictions on token trading until the crowdsale is finalized.
 * This is being discussed in
 * https://github.com/OpenZeppelin/openzeppelin-solidity/issues/877
 * This contract will be updated when we agree on a general solution
 * for this problem.
 */
contract RefundableCrowdsale is FinalizableCrowdsale {
  using SafeMath for uint256;

  // minimum amount of funds to be raised in weis
  uint256 private _goal;

  // refund escrow used to hold funds while crowdsale is running
  RefundEscrow private _escrow;

  /**
   * @dev Constructor, creates RefundEscrow.
   * @param goal Funding goal
   */
  constructor(uint256 goal) internal {
    require(goal > 0);
    _escrow = new RefundEscrow(wallet());
    _goal = goal;
  }

  /**
   * @return minimum amount of funds to be raised in wei.
   */
  function goal() public view returns(uint256) {
    return _goal;
  }

  /**
   * @dev Investors can claim refunds here if crowdsale is unsuccessful
   * @param beneficiary Whose refund will be claimed.
   */
  function claimRefund(address beneficiary) public {
    require(finalized());
    require(!goalReached());

    _escrow.withdraw(beneficiary);
  }

  /**
   * @dev Checks whether funding goal was reached.
   * @return Whether funding goal was reached
   */
  function goalReached() public view returns (bool) {
    return weiRaised() >= _goal;
  }

  /**
   * @dev escrow finalization task, called when finalize() is called
   */
  function _finalization() internal {
    if (goalReached()) {
      _escrow.close();
      _escrow.beneficiaryWithdraw();
    } else {
      _escrow.enableRefunds();
    }

    super._finalization();
  }

  /**
   * @dev Overrides Crowdsale fund forwarding, sending funds to escrow.
   */
  function _forwardFunds() internal {
    _escrow.deposit.value(msg.value)(msg.sender);
  }

}

pragma solidity ^0.4.24;

import "../../math/SafeMath.sol";
import "./FinalizableCrowdsale.sol";
import "../../payment/escrow/RefundEscrow.sol";

/**
 * @title RefundableCrowdsale
 * @dev Extension of Crowdsale contract that adds a funding goal, and
 * the possibility of users getting a refund if goal is not met.
 */
contract RefundableCrowdsale is FinalizableCrowdsale {
  using SafeMath for uint256;

  // minimum amount of funds to be raised in weis
  uint256 private _goal;

  // refund escrow used to hold funds while crowdsale is running
  RefundEscrow private _escrow;

  /**
   * @dev Constructor, creates RefundEscrow.
   * @param goal Funding goal
   */
  constructor(uint256 goal) internal {
    require(goal > 0);
    _escrow = new RefundEscrow(wallet());
    _goal = goal;
  }

  /**
   * @return minimum amount of funds to be raised in wei.
   */
  function goal() public view returns(uint256) {
    return _goal;
  }

  /**
   * @dev Investors can claim refunds here if crowdsale is unsuccessful
   * @param beneficiary Whose refund will be claimed.
   */
  function claimRefund(address beneficiary) public {
    require(finalized());
    require(!goalReached());

    _escrow.withdraw(beneficiary);
  }

  /**
   * @dev Checks whether funding goal was reached.
   * @return Whether funding goal was reached
   */
  function goalReached() public view returns (bool) {
    return weiRaised() >= _goal;
  }

  /**
   * @dev escrow finalization task, called when finalize() is called
   */
  function _finalization() internal {
    if (goalReached()) {
      _escrow.close();
      _escrow.beneficiaryWithdraw();
    } else {
      _escrow.enableRefunds();
    }

    super._finalization();
  }

  /**
   * @dev Overrides Crowdsale fund forwarding, sending funds to escrow.
   */
  function _forwardFunds() internal {
    _escrow.deposit.value(msg.value)(msg.sender);
  }

}