Change mapping to address => computationID => Request

pragma solidity ^0.4.8;
import "./AbstractComputationService.sol";
import "./Judge.sol";

contract Arbiter {
  // Requests can have different status with a default of 0
  // status 100: request is created, no solutions are provided
  // status 200: request for computations send; awaiting results
  // status 300 + n: 0 + n results are in (i.e 301 := 1 result is in)
  // status 400: all results are in
  // status 500: solver and validators match
  // status 600: result send to requester
  // status 700 + n: solver and validators mismatch with n binary encoding of mismatches
  // e.g. status 729: 700 + 16 + 8 + 4 + 1 => verfier 0, 2, 3, 4 indicated a mismatch
  // status 800: dispute resolution started
  // status 801: dispute resolution state 1
  // status 901: dispute resolved; solver correct
  // status 902: dispute resolved; solver incorrect

  address public judge;

  struct Request {
    string input1;
    string input2;
    uint operation;
    address user;
    address solver;
    address[] verifier;
    string resultSolver;
    string[6] resultVerifier;
    uint status;
    bool finished;
  }

  mapping(uint256 => Request) public requests;
  mapping(address => uint256) public currentRequest;

  address[] public service;
  mapping(address => uint) internal serviceIndex;

  event newRequest(uint newRequest);
  event solverFound(address solverFound);
  event verifierFound(address verifierFound);
  event StatusChange(uint status_code);
  event newExecution(uint newExecution);
  event solverExecution(address solverExecution);
  event verifierExecution(address verifierExecution);

  // event thisIndex(uint thisIndex);
  // event step(uint thisStep);
  // event setLength(uint setLength);

  function enableService() {
    uint index;
    service.push(msg.sender);
    index = (service.length - 1);
    serviceIndex[msg.sender] = index;
  }

  function disableService() {
    uint index;
    index = serviceIndex[msg.sender];
    delete service[index];
    serviceIndex[msg.sender] = 0;

    // update service array and index mapping
    if (index < (service.length - 1)) {
      uint next_index;
      uint this_index;
      this_index = index;
      next_index = this_index + 1;

      while (this_index < (service.length - 1)) {
        service[this_index] = service[next_index];
        delete service[next_index];
        this_index++;
        next_index++;
      }
    }
  }

  function requestComputation(string _input1, string _input2, uint _operation, uint _numVerifiers) {
    // testEvent("Request computation started");
    address solver;
    address verifier;
    uint256 computationId;
    uint count = 0;
    uint check;
    uint index;
    uint length = service.length;
    address[] memory remainingService = new address[](length);

    // number of services for potential verifiers minus solver; maximum 6 verifiers
    if (_numVerifiers > (service.length - 1)) throw;
    if (_numVerifiers > 6) throw;

    remainingService = service;

    computationId = rand(0, 2**64);

    currentRequest[msg.sender] = computationId;

    requests[computationId].user = _input1;
    requests[computationId].input1 = _input1;
    requests[computationId].input2 = _input2;
    requests[computationId].operation = _operation;

    newRequest(computationId);

    // select a random solver from the list of computation services
    index = rand(0, length - 1);
    solver = remainingService[index];
    requests[computationId].solver = solver;
    solverFound(solver);

    for (uint i = index; i < length - 1; i++) {
      remainingService[i] = remainingService[i + 1];
    }
    // length-- is a workaround since memory arrays can NOT be resized
    length--;

    // select random verifiers from the list of computation services
    for (uint j = 0; j < _numVerifiers; j++) {
      index = rand(0, length - 1);
      verifier = remainingService[index];
      requests[computationId].verifier[j] = verifier;
      verifierFound(verifier);

      for (uint k = index; k < length - 1; k++) {
        remainingService[k] = remainingService[k + 1];
      }
      length--;
    }

    // status 100: request is created, no solutions are provided
    requests[computationId].status = 100;
    StatusChange(requests[computationId].status);
  }

  function executeComputation() payable {
    computationId = currentRequest[msg.sender];

    newExecution(computationId);
    // send computation request to the solver
    AbstractComputationService mySolver = AbstractComputationService(requests[computationId].solver);
    mySolver.compute.value(10000000000000000).gas(500000)(requests[computationId].input1, requests[computationId].input2, requests[computationId].operation, computationId);
    solverExecution(requests[computationId].solver);

    // send computation request to all verifiers
    for (uint i = 0; i < requests[computationId].verifier.length; i++) {
      AbstractComputationService myVerifier = AbstractComputationService(requests[computationId].verifier[i]);
      myVerifier.compute.value(10000000000000000).gas(500000)(requests[computationId].input1, requests[computationId].input2, requests[computationId].operation, computationId);
      verifierExecution(requests[computationId].verifier[i]);
    }

    // status 200: request for computations send; awaiting results
    requests[computationId].status = 200;
    StatusChange(requests[computationId].status);
  }

  function receiveResults(string _result, uint256 _computationId) {
    uint count = 0;
    // receive results from solvers and verifiers
    if (msg.sender == requests[computationId].solver) {
      requests[computation[_computationId]].resultSolver = _result;
      count = 1;
    } else {
      for (uint i; i < requests[computationId].verifier.length; i++) {
        if (msg.sender == requests[computationId].verifier[i]) {
          requests[computationId].resultVerifier[i] = _result;
          count = 1;
          break;
        }
      }
    }

    // status 300 + n: 0 + n results are in (i.e 301 := 1 result is in)
    if (requests[computationId].status == 200) {
      requests[computationId].status = 300 + count;
    } else {
      requests[computationId].status += count;
    }

    if ((requests[computationId].status - 300) == (1 + requests[computationId].verifier.length)) {
      // status 400: all results are in
      requests[computationId].status = 400;
    }

    StatusChange(requests[computationId].status);
  }

  function compareResults() returns (uint) {
    computationId = currentRequest[msg.sender];

    if (requests[computationId].status != 400) throw;

    uint count = 0;

    for (uint i; i < requests[computationId].verifier.length; i++) {
      if (!(stringsEqual(requests[computationId].resultSolver,requests[computationId].resultVerifier[i]))) {
        count += 2**i;
      }
    }

    if (count == 0) {
      // status 500: solver and validators match
      requests[computationId].status = 500;
    } else {
      // status 700: solver and validators mismatch
      requests[computationId].status = 700 + count;
    }

    return requests[computationId].status;
    StatusChange(requests[computationId].status);
  }

  function requestIndex() {
    computationId = currentRequest[msg.sender];

    // get all verifiers that disagreed with the solver
    uint[] memory verifierIndex;
    uint count = requests[computationId].status - 700;
    uint insert;

    for (uint i = requests[computationId].verifier.length - 1; i >= 0; i--) {
      if (count >= 2**i) {
        insert = verifierIndex.length - 1;
        verifierIndex[insert] = i;
        count -= 2**i;
      }
    }

    // request an index in the result, which is different
    for (uint j = 0; j < verifierIndex.length; j++) {
      AbstractComputationService myVerifier = AbstractComputationService(requests[computationId].verifier[verifierIndex[j]]);
      myVerifier.provideIndex(requests[computationId].resultSolver, requests[computationId].computationId);
    }

    // status 800: dispute resolution started
    requests[computationId].status = 800;
    StatusChange(requests[computationId].status);
  }

  function receiveIndex(uint _index1, uint _index2, uint _operation, uint256 _computationId, bool _end) {
    // receives two coordinates
    uint result;
    bool solverCorrect;

    // check if solver and verifier value differ for given coordinates
    // this is just an integer check

    if (_end) {
      result = stringToUint(requests[computationId].resultSolver);
      Judge myJudge = Judge(judge);
      solverCorrect = myJudge.resolveDispute(_index1, _index2, result, _operation);
      if (solverCorrect) {
        // status 901: dispute resolved; solver correct
        requests[computationId].status = 901;
      } else {
        // status 902: dispute resolved; solver incorrect
        requests[computationId].status = 902;
      }
    }
    StatusChange(requests[computationId].status);
    // TODO: matrix check
  }

  function setJudge(address _judge) {
    judge = _judge;
  }

  function getStatus(address _requester) constant returns (uint status) {
    status = requests[_requester].status;
  }

  function stringToUint(string s) internal constant returns (uint result) {
    bytes memory b = bytes(s);
    uint i;
    result = 0;
    for (i = 0; i < b.length; i++) {
      uint c = uint(b[i]);
      if (c >= 48 && c <= 57) {
          result = result * 10 + (c - 48);
      }
    }
  }

  function stringsEqual(string _a, string _b) internal constant returns (bool) {
    bytes memory a = bytes(_a);
    bytes memory b = bytes(_b);
    if (a.length != b.length) return false;

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

  function rand(uint min, uint max) internal constant returns (uint256 random) {
    uint256 blockValue = uint256(block.blockhash(block.number-1));
    random = uint256(uint256(blockValue)%(min+max));
    return random;
  }
}

pragma solidity ^0.4.8;
import "./AbstractComputationService.sol";
import "./Judge.sol";

contract Arbiter {
  // Requests can have different status with a default of 0
  // status 100: request is created, no solutions are provided
  // status 200: request for computations send; awaiting results
  // status 300 + n: 0 + n results are in (i.e 301 := 1 result is in)
  // status 400: all results are in
  // status 500: solver and validators match
  // status 600: result send to requester
  // status 700 + n: solver and validators mismatch with n binary encoding of mismatches
  // e.g. status 729: 700 + 16 + 8 + 4 + 1 => verfier 0, 2, 3, 4 indicated a mismatch
  // status 800: dispute resolution started
  // status 801: dispute resolution state 1
  // status 901: dispute resolved; solver correct
  // status 902: dispute resolved; solver incorrect

  address public judge;

  struct Request {
    string input1;
    string input2;
    uint operation;
    address user;
    address solver;
    address[] verifier;
    string resultSolver;
    string[6] resultVerifier;
    uint status;
    bool finished;
  }

  mapping(uint256 => Request) public requests;

  address[] public service;
  mapping(address => uint) internal serviceIndex;

  event newRequest(uint newRequest);
  event solverFound(address solverFound);
  event verifierFound(address verifierFound);
  event StatusChange(uint status_code);
  event newExecution(uint newExecution);
  event solverExecution(address solverExecution);
  event verifierExecution(address verifierExecution);

  // event thisIndex(uint thisIndex);
  // event step(uint thisStep);
  // event setLength(uint setLength);

  function enableService() {
    uint index;
    service.push(msg.sender);
    index = (service.length - 1);
    serviceIndex[msg.sender] = index;
  }

  function disableService() {
    uint index;
    index = serviceIndex[msg.sender];
    delete service[index];
    serviceIndex[msg.sender] = 0;

    // update service array and index mapping
    if (index < (service.length - 1)) {
      uint next_index;
      uint this_index;
      this_index = index;
      next_index = this_index + 1;

      while (this_index < (service.length - 1)) {
        service[this_index] = service[next_index];
        delete service[next_index];
        this_index++;
        next_index++;
      }
    }
  }

  function requestComputation(string _input1, string _input2, uint _operation, uint _numVerifiers) {
    // testEvent("Request computation started");
    address solver;
    address verifier;
    uint256 computationId;
    uint count = 0;
    uint check;
    uint index;
    uint length = service.length;
    address[] memory remainingService = new address[](length);

    // number of services for potential verifiers minus solver; maximum 6 verifiers
    if (_numVerifiers > (service.length - 1)) throw;
    if (_numVerifiers > 6) throw;

    remainingService = service;

    computationId = rand(0, 2**64);

    requests[computationId].user = _input1;
    requests[computationId].input1 = _input1;
    requests[computationId].input2 = _input2;
    requests[computationId].operation = _operation;

    newRequest(computationId);

    // select a random solver from the list of computation services
    index = rand(0, length - 1);
    solver = remainingService[index];
    requests[computationId].solver = solver;
    solverFound(solver);

    for (uint i = index; i < length - 1; i++) {
      remainingService[i] = remainingService[i + 1];
    }
    // length-- is a workaround since memory arrays can NOT be resized
    length--;

    // select random verifiers from the list of computation services
    for (uint j = 0; j < _numVerifiers; j++) {
      index = rand(0, length - 1);
      verifier = remainingService[index];
      requests[computationId].verifier[j] = verifier;
      verifierFound(verifier);

      for (uint k = index; k < length - 1; k++) {
        remainingService[k] = remainingService[k + 1];
      }
      length--;
    }

    // status 100: request is created, no solutions are provided
    requests[computationId].status = 100;
    StatusChange(requests[computationId].status);
  }

  function executeComputation() payable {
    newExecution(requests[computationId].computationId);
    // send computation request to the solver
    AbstractComputationService mySolver = AbstractComputationService(requests[msg.sender].solver);
    mySolver.compute.value(10000000000000000).gas(500000)(requests[msg.sender].input1, requests[msg.sender].input2, requests[msg.sender].operation, requests[msg.sender].computationId);
    solverExecution(requests[msg.sender].solver);

    // send computation request to all verifiers
    for (uint i = 0; i < requests[msg.sender].verifier.length; i++) {
      AbstractComputationService myVerifier = AbstractComputationService(requests[msg.sender].verifier[i]);
      myVerifier.compute.value(10000000000000000).gas(500000)(requests[msg.sender].input1, requests[msg.sender].input2, requests[msg.sender].operation, requests[msg.sender].computationId);
      verifierExecution(requests[msg.sender].verifier[i]);
    }

    // status 200: request for computations send; awaiting results
    requests[msg.sender].status = 200;
    StatusChange(requests[msg.sender].status);
  }

  function receiveResults(string _result, uint256 _computationId) {
    uint count = 0;
    // receive results from solvers and verifiers
    if (msg.sender == requests[computation[_computationId]].solver) {
      requests[computation[_computationId]].resultSolver = _result;
      count = 1;
    } else {
      for (uint i; i < requests[computation[_computationId]].verifier.length; i++) {
        if (msg.sender == requests[computation[_computationId]].verifier[i]) {
          requests[computation[_computationId]].resultVerifier[i] = _result;
          count = 1;
          break;
        }
      }
    }

    // status 300 + n: 0 + n results are in (i.e 301 := 1 result is in)
    if (requests[computation[_computationId]].status == 200) {
      requests[computation[_computationId]].status = 300 + count;
    } else {
      requests[computation[_computationId]].status += count;
    }

    if ((requests[computation[_computationId]].status - 300) == (1 + requests[computation[_computationId]].verifier.length)) {
      // status 400: all results are in
      requests[computation[_computationId]].status = 400;
    }

    StatusChange(requests[computation[_computationId]].status);
  }

  function compareResults() returns (uint) {
    if (requests[msg.sender].status != 400) throw;

    uint count = 0;

    for (uint i; i < requests[msg.sender].verifier.length; i++) {
      if (!(stringsEqual(requests[msg.sender].resultSolver,requests[msg.sender].resultVerifier[i]))) {
        count += 2**i;
      }
    }

    if (count == 0) {
      // status 500: solver and validators match
      requests[msg.sender].status = 500;
    } else {
      // status 700: solver and validators mismatch
      requests[msg.sender].status = 700 + count;
    }

    return requests[msg.sender].status;
    StatusChange(requests[msg.sender].status);
  }

  function requestIndex() {
    // get all verifiers that disagreed with the solver
    uint[] memory verifierIndex;
    uint count = requests[msg.sender].status - 700;
    uint insert;

    for (uint i = requests[msg.sender].verifier.length - 1; i >= 0; i--) {
      if (count >= 2**i) {
        insert = verifierIndex.length - 1;
        verifierIndex[insert] = i;
        count -= 2**i;
      }
    }

    // request an index in the result, which is different
    for (uint j = 0; j < verifierIndex.length; j++) {
      AbstractComputationService myVerifier = AbstractComputationService(requests[msg.sender].verifier[verifierIndex[j]]);
      myVerifier.provideIndex(requests[msg.sender].resultSolver, requests[msg.sender].computationId);
    }

    // status 800: dispute resolution started
    requests[msg.sender].status = 800;
    StatusChange(requests[msg.sender].status);
  }

  function receiveIndex(uint _index1, uint _index2, uint _operation, uint256 _computationId, bool _end) {
    // receives two coordinates
    uint result;
    bool solverCorrect;

    // check if solver and verifier value differ for given coordinates
    // this is just an integer check

    if (_end) {
      result = stringToUint(requests[computation[_computationId]].resultSolver);
      Judge myJudge = Judge(judge);
      solverCorrect = myJudge.resolveDispute(_index1, _index2, result, _operation);
      if (solverCorrect) {
        // status 901: dispute resolved; solver correct
        requests[computation[_computationId]].status = 901;
      } else {
        // status 902: dispute resolved; solver incorrect
        requests[computation[_computationId]].status = 902;
      }
    }
    StatusChange(requests[computation[_computationId]].status);
    // TODO: matrix check
  }

  function setJudge(address _judge) {
    judge = _judge;
  }

  function getStatus(address _requester) constant returns (uint status) {
    status = requests[_requester].status;
  }

  function stringToUint(string s) internal constant returns (uint result) {
    bytes memory b = bytes(s);
    uint i;
    result = 0;
    for (i = 0; i < b.length; i++) {
      uint c = uint(b[i]);
      if (c >= 48 && c <= 57) {
          result = result * 10 + (c - 48);
      }
    }
  }

  function stringsEqual(string _a, string _b) internal constant returns (bool) {
    bytes memory a = bytes(_a);
    bytes memory b = bytes(_b);
    if (a.length != b.length) return false;

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

  function rand(uint min, uint max) internal constant returns (uint256 random) {
    uint256 blockValue = uint256(block.blockhash(block.number-1));
    random = uint256(uint256(blockValue)%(min+max));
    return random;
  }
}


remove mew variable and access through ContractRegistry

pragma solidity ^0.4.0;

import "./abstract/AbstractUserRegistry.sol";
import "./abstract/AbstractUser.sol";
import "./abstract/AbstractConceptRegistry.sol";
import "./Assessment.sol";
import "./Math.sol";

/*
@type: contract
@name: Concept
@purpose: To store concept data and create and store information about assessments of this concept
*/
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; //The address of the userRegistry contract
  address conceptRegistry; //The address of the conceptRegistry contract
  uint public maxWeight; //The current highest weight for this assessment
  address[] public owners; //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

  /*
  @type: modifier
  @name: onlyUserRegistry
  @purpose: to only allow the UserRegistry contract to call a function to which this modifier is applied
  */
  modifier onlyUserRegistry()
  {
    if(msg.sender != userRegistry) //checks if msg.sender has the same address as userRegistry
    {
      throw; //throws the function call if not
    }
    _;
  }

  /*
  @type: modifier
  @name: onlyConceptRegistry
  @purpose: to only allow the ConceptRegistry contract to call a function to which this modifier is applied
  */
  modifier onlyConceptRegistry()
  {
    if(msg.sender != conceptRegistry) //checks if msg.sender has the same address as conceptRegistry
    {
      throw; //throws the function call if not
    }
    _;
  }

  /*
  @type: modifier
  @name: onlyThis
  @purpose: to only allow the this contract to call a function to which this modifier is applied
  */
  modifier onlyThis()
  {
    if(msg.sender != address(this)) //Checks if msg.sender is this contract
    {
      throw; //Throws out the function call if it isn't
    }
    _;
  }

  /*
  @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); //The address of the assessment

  /*
  @type: constructor function
  @purpose: To initialize the Concept contract
  @param: string conceptName = the name of the conceptName
  @param: address[] parents = the addresses of the concept's parents
  @param: address userRegistryAddress = the address of the UserRegistry contract
  @param: address conceptRegistry = the address of the ConceptRegistry that spawned this user
  @returns: nothing
  */
  function Concept(address[] _parents, address _userRegistry, address _conceptRegistry)
  {
    parents = _parents; //sets the  parents array
    userRegistry = _userRegistry; //sets the userRegistry address
    conceptRegistry = _conceptRegistry; //sets the conceptRegistry address
  }

  /*
  @type: function
  @purpose: To get the number of owners of this concept
  @returns: The number of users that own this concept in the form of an uint
  */
  function getOwnerLength() constant returns(uint)
  {
    return owners.length;
  }

  /*
  @type: function
  @purpose: To get the number of parents for this concept
  @returns: The number of parents for this concept in the form of an uint
  */
  function getParentsLength() constant returns(uint)
  {
    return parents.length;
  }

  /*
  @type: function
  @purpose: To get the number of children of this concept
  @returns: The number of children of this concept in the form of an uint
  */
  function getChildrenLength() constant returns(uint)
  {
    return children.length;
  }

  /*
  @type: function
  @purpose: To set the first user for this concept
  @param: address firstUser = the address of the first user to own the concept
  @returns: nothing
  */
  function addUser(address user) onlyUserRegistry()
  {
    if(AbstractConceptRegistry(conceptRegistry).mew() == address(this))
    {
      owners.push(user); //If there aren't then firstUser is made to be an owner of this concept
    }
  }

  /*
  @type: function
  @purpose: To add a parent to the concept
  @param: address parentAddress = the address of the new parent concept
  @returns: nothing
  */
  function addParent(address _parent) onlyConceptRegistry()
  {
    parents.push(_parent);
  }

  /*
  @type: function
  @purpose: To add a child to the concept
  @param: address childAddress = the address of the new child concept
  @returns: nothing
  */
  function addChild(address _child) onlyConceptRegistry()
  {
    children.push(_child);
  }

  function getRandomMember(uint seed) returns(address)
  {
    address randomUser = owners[Math.getRandom(seed, owners.length-1)];
    if(AbstractUser(randomUser).availability() && weights[randomUser] > now % maxWeight)
     {
        return randomUser;
     }
    return address(0x0);
  }

  /*
  @type: function
  @purpose: To make a new assessment
  @param: uint time = the time that assessors will have to assess in this assessment
  @param: uint size = the size of the assessment
  @returns: nothing
  */
  function makeAssessment(uint cost, uint size) returns(bool)
  {
    if(size >= 5 && AbstractUserRegistry(userRegistry).balances(msg.sender) >= cost*size) //Checks if the assessment has a size of at least 5
    {
      Assessment newAssessment = new Assessment(msg.sender, userRegistry, conceptRegistry, size, cost); //Makes a new assessment with the given parameters
      assessmentExists[address(newAssessment)] = true; //Sets the assessment's existance to true
      setBalance(msg.sender, AbstractUserRegistry(userRegistry).balances(msg.sender) - cost*size);
      AbstractUser(msg.sender).notification(address(this), 19); //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;
    }
  }

  /*
  @type: function
  @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) //Checks to make sure this function is being callled by the assessment
    {
      if(score > 0)
      {
        owners.push(assessee); //Makes the assessee an owner of this concept
        uint weight = Assessment(assessment).size()*uint(score);
        addOwner(assessee, weight);
        AbstractUser(assessee).setConceptPassed(true);
      }
      AbstractUser(assessee).mapHistory(assessment); //Maps the assessee to the assessment in the user master as part of the assessee's history
      currentScores[assessee] = score; //Maps the assessee to their score
      CompletedAssessment(assessee, score, assessment); //Makes an event with this assessment's data
    }
  }

  /*
  @type: function
  @purpose: To add an owner to a concept and recursively add an owner 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 owner
  @returns: nothing
  */
  function addOwner(address assessee, uint weight)
  {
    owners.push(assessee); //adds the owner 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]).addOwner(assessee, weight/2); //recursively adds owner to all parent concepts but with half the weight
    }
  }

  /*
  @type: function
  @purpose: To pay/charge a user for an assessment
  @param: address user = the user to pay/charge
  @param: int amount = the user's new token balance
  */
  function setBalance(address user, uint amount)
  {
    if(assessmentExists[msg.sender] || msg.sender == address(this)) //Checks if msg.sender is an existing assessment
    {
      AbstractUserRegistry(userRegistry).setBalance(user, amount); //Changes the user's token balance
    }
  }

  /*
  @type: function
  @purpose: to remove this contract
  @param: address receiver = the address of the wallet that will receive of the ether
  @returns: nothing
  */
  function remove(address reciever) onlyThis()
  {
    suicide(reciever);
  }
}

pragma solidity ^0.4.0;

import "./abstract/AbstractUserRegistry.sol";
import "./abstract/AbstractUser.sol";
import "./Assessment.sol";
import "./Math.sol";

/*
@type: contract
@name: Concept
@purpose: To store concept data and create and store information about assessments of this concept
*/
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; //The address of the userRegistry contract
  address conceptRegistry; //The address of the conceptRegistry contract
  uint public maxWeight; //The current highest weight for this assessment
  address[] public owners; //Those who have earned the concept
  address mew;
  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

  /*
  @type: modifier
  @name: onlyUserRegistry
  @purpose: to only allow the UserRegistry contract to call a function to which this modifier is applied
  */
  modifier onlyUserRegistry()
  {
    if(msg.sender != userRegistry) //checks if msg.sender has the same address as userRegistry
    {
      throw; //throws the function call if not
    }
    _;
  }

  /*
  @type: modifier
  @name: onlyConceptRegistry
  @purpose: to only allow the ConceptRegistry contract to call a function to which this modifier is applied
  */
  modifier onlyConceptRegistry()
  {
    if(msg.sender != conceptRegistry) //checks if msg.sender has the same address as conceptRegistry
    {
      throw; //throws the function call if not
    }
    _;
  }

  /*
  @type: modifier
  @name: onlyThis
  @purpose: to only allow the this contract to call a function to which this modifier is applied
  */
  modifier onlyThis()
  {
    if(msg.sender != address(this)) //Checks if msg.sender is this contract
    {
      throw; //Throws out the function call if it isn't
    }
    _;
  }

  /*
  @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); //The address of the assessment

  /*
  @type: constructor function
  @purpose: To initialize the Concept contract
  @param: string conceptName = the name of the conceptName
  @param: address[] parents = the addresses of the concept's parents
  @param: address userRegistryAddress = the address of the UserRegistry contract
  @param: address conceptRegistry = the address of the ConceptRegistry that spawned this user
  @returns: nothing
  */
  function Concept(address[] _parents, address _userRegistry, address _conceptRegistry)
  {
    parents = _parents; //sets the  parents array
    userRegistry = _userRegistry; //sets the userRegistry address
    conceptRegistry = _conceptRegistry; //sets the conceptRegistry address
  }

  /*
  @type: function
  @purpose: To get the number of owners of this concept
  @returns: The number of users that own this concept in the form of an uint
  */
  function getOwnerLength() constant returns(uint)
  {
    return owners.length;
  }

  /*
  @type: function
  @purpose: To get the number of parents for this concept
  @returns: The number of parents for this concept in the form of an uint
  */
  function getParentsLength() constant returns(uint)
  {
    return parents.length;
  }

  /*
  @type: function
  @purpose: To get the number of children of this concept
  @returns: The number of children of this concept in the form of an uint
  */
  function getChildrenLength() constant returns(uint)
  {
    return children.length;
  }

  /*
  @type: function
  @purpose: To set the first user for this concept
  @param: address firstUser = the address of the first user to own the concept
  @returns: nothing
  */
  function addUser(address user) onlyUserRegistry()
  {
    if(mew == address(0x0))
    {
      owners.push(user); //If there aren't then firstUser is made to be an owner of this concept
    }
  }

  /*
  @type: function
  @purpose: To add a parent to the concept
  @param: address parentAddress = the address of the new parent concept
  @returns: nothing
  */
  function addParent(address _parent) onlyConceptRegistry()
  {
    parents.push(_parent);
  }

  /*
  @type: function
  @purpose: To add a child to the concept
  @param: address childAddress = the address of the new child concept
  @returns: nothing
  */
  function addChild(address _child) onlyConceptRegistry()
  {
    children.push(_child);
  }

  function getRandomMember(uint seed) returns(address)
  {
    address randomUser = owners[Math.getRandom(seed, owners.length-1)];
    if(AbstractUser(randomUser).availability() && weights[randomUser] > now % maxWeight)
     {
        return randomUser;
     }
    return address(0x0);
  }

  /*
  @type: function
  @purpose: To make a new assessment
  @param: uint time = the time that assessors will have to assess in this assessment
  @param: uint size = the size of the assessment
  @returns: nothing
  */
  function makeAssessment(uint cost, uint size) returns(bool)
  {
    if(size >= 5 && AbstractUserRegistry(userRegistry).balances(msg.sender) >= cost*size) //Checks if the assessment has a size of at least 5
    {
      Assessment newAssessment = new Assessment(msg.sender, userRegistry, conceptRegistry, size, cost); //Makes a new assessment with the given parameters
      assessmentExists[address(newAssessment)] = true; //Sets the assessment's existance to true
      setBalance(msg.sender, AbstractUserRegistry(userRegistry).balances(msg.sender) - cost*size);
      AbstractUser(msg.sender).notification(address(this), 19); //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;
    }
  }

  /*
  @type: function
  @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) //Checks to make sure this function is being callled by the assessment
    {
      if(score > 0)
      {
        owners.push(assessee); //Makes the assessee an owner of this concept
        uint weight = Assessment(assessment).size()*uint(score);
        addOwner(assessee, weight);
        AbstractUser(assessee).setConceptPassed(true);
      }
      AbstractUser(assessee).mapHistory(assessment); //Maps the assessee to the assessment in the user master as part of the assessee's history
      currentScores[assessee] = score; //Maps the assessee to their score
      CompletedAssessment(assessee, score, assessment); //Makes an event with this assessment's data
    }
  }

  /*
  @type: function
  @purpose: To add an owner to a concept and recursively add an owner 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 owner
  @returns: nothing
  */
  function addOwner(address assessee, uint weight)
  {
    owners.push(assessee); //adds the owner 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]).addOwner(assessee, weight/2); //recursively adds owner to all parent concepts but with half the weight
    }
  }

  /*
  @type: function
  @purpose: To pay/charge a user for an assessment
  @param: address user = the user to pay/charge
  @param: int amount = the user's new token balance
  */
  function setBalance(address user, uint amount)
  {
    if(assessmentExists[msg.sender] || msg.sender == address(this)) //Checks if msg.sender is an existing assessment
    {
      AbstractUserRegistry(userRegistry).setBalance(user, amount); //Changes the user's token balance
    }
  }

  /*
  @type: function
  @purpose: to remove this contract
  @param: address receiver = the address of the wallet that will receive of the ether
  @returns: nothing
  */
  function remove(address reciever) onlyThis()
  {
    suicide(reciever);
  }
}


EtherToken refactored

EtherToken refactored

import 'token.sol';

contract EtherToken is Token {
    function EtherToken() Token("Wei", "EthContractWallet") {}

    /* This methods increse your balance according to sended money */
    function loadBalance() {
        token.balanceOf[msg.sender] += msg.value;
        token.total                 += msg.value;
    }

    /* This is the way to withdraw money from token */
    function withdraw(uint _value) {
        if (token.balanceOf[msg.sender] >= _value) {
            token.balanceOf[msg.sender] -= _value;
            token.total                 -= _value;
            msg.sender.send(_value);
        }
    }

    function () {
        // This function gets executed if a
        // transaction with invalid data is sent to
        // the contract or just ether without data.
        // We revert the send so that no-one
        // accidentally loses money when using the
        // contract.
        throw;
    }
}

contract etherToken {
    address public creator;
    string public symbol;
    string public name;
    uint public totalSupply;
    mapping (address => uint) public balanceOf;
    mapping (address => mapping(address => bool)) approveOf;
    mapping (address => mapping(address => bool)) approveOnceOf;
    mapping (address => mapping(address => uint)) approveOnceValueOf;

      /* Events */
    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event AddressApproval(address indexed _address, address indexed _proxy, bool _result);
    event AddressApprovalOnce(address indexed _address, address indexed _proxy, uint256 _value);

    /*Initial */
    function etherToken() {
        creator = msg.sender;
        symbol = "Wei";
        name = "EthContractWallet";
    }

    function getTotalSupply() returns (uint supply) {
        return totalSupply;
    }

    /* Agent function */

    function getBalance(address _account) returns (uint256 balance) {
		balance = 0;
        if (approveOf[_account][msg.sender]) {
			balance = balanceOf[_account];
		}
        return balance;
    }

    function myBalance() returns (uint256 balance) {
		balance = balanceOf[msg.sender];
        return balance;
    }

    function loadBalance() {
        balanceOf[msg.sender] += msg.value;
        totalSupply += msg.value;

    }

    function withdraw(uint256 _value) returns (bool result){
        if (balanceOf[msg.sender] < _value) {return false;}
        if (balanceOf[msg.sender] + _value < balanceOf[msg.sender]) {return false;}
        msg.sender.send(_value);
        return true;

    }

    function transfer(address _to, uint256 _value) returns (bool result) {
        if (balanceOf[msg.sender] < _value) {return false;}
        if (balanceOf[msg.sender] + _value < balanceOf[msg.sender]) {return false;}
        balanceOf[msg.sender] -= _value;
        balanceOf[_to] += _value;
        Transfer(msg.sender, _to, _value);
        return true;
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        if(approveOf[_from][msg.sender])
        {
            if (balanceOf[_from] < _value) {return false;}
            if (balanceOf[_from] + _value < balanceOf[_from]) {return false;}
            balanceOf[_from] -= _value;
            balanceOf[_to] += _value;
            Transfer(_from, _to, _value);
            return true;
        } else if(approveOnceOf[_from][msg.sender] && approveOnceValueOf[_from][msg.sender]<=_value) {
            if (balanceOf[_from] < _value) {return false;}
            if (balanceOf[_from] + _value < balanceOf[_from]) {return false;}
            balanceOf[_from] -= _value;
            balanceOf[_to] += _value;
            Transfer(_from, _to, _value);
            return true;
        }
    }

    function approve(address _address) returns (bool result) {
        approveOf[msg.sender][_address] = true;
        AddressApproval(_address, msg.sender, true);
        return true;
    }

    function unapprove(address _address) returns (bool result) {
        approveOf[msg.sender][_address] = false;
        return true;
    }

    function approveOnce(address _address, uint _maxValue) returns (bool result) {
        approveOnceOf[msg.sender][_address] = true;
        approveOnceValueOf[msg.sender][_address] = _maxValue;
        AddressApprovalOnce(_address, msg.sender, _maxValue);
        return true;
    }

    function unapproveOnce(address _address) returns (bool result) {
        approveOnceOf[msg.sender][_address] = false;
        approveOnceValueOf[msg.sender][_address] = 0;
        return true;
    }

    function isApprovedOnceFor(address _target, address _proxy) returns (uint maxValue) {
        maxValue = approveOnceValueOf[_target][_proxy];
        return maxValue;
    }

    function isApprovedFor(address _target, address _proxy) returns (bool result) {
        result = approveOnceOf[_target][_proxy];
        return result;
    }

    function () {
        // This function gets executed if a
        // transaction with invalid data is sent to
        // the contract or just ether without data.
        // We revert the send so that no-one
        // accidentally loses money when using the
        // contract.
        throw;
    }
}