reordered function according to solidity style guide

pragma solidity ^0.4.10;

import "./Base/Owned.sol";
import "./Base/SafeMath.sol";

/**
    @notice This contract implements a simple store that can interact with
    registered customers. Every customer has its own shopping cart.
    @title Retail Store Contract
    @author Harris Brakmic
*/
contract Store is Owned, SafeMath {

    /* Store internals */
    bytes32 public store_name; // store name
    uint256 private store_balance;  // store balance

    mapping (address => Customer) customers;
    mapping (uint256 => Product) products;

    /* Store Events */
    event CustomerRegistered(address customer);
    event CustomerRegistrationFailed(address customer);
    event CustomerDeregistered(address customer);
    event CustomerDeregistrationFailed(address customer);

    event ProductRegistered(uint256 productId);
    event ProductDeregistered(uint256 productId);
    event ProductRegistrationFailed(uint256 productId);
    event ProductDeregistrationFaled(uint256 productId);

    event CartProductInserted(address customer, uint256 prodId, uint256 prodPrice, uint256 completeSum);
    event CartProductInsertionFailed(address customer, uint256 prodId);
    event CartProductRemoved(address customer, uint256 prodId);
    event CartCheckoutCompleted(address customer, uint256 paymentSum);
    event CartCheckoutFailed(address customer, uint256 customerBalance, uint256 paymentSum);
    event CartEmptied(address customer);

    /**
        @notice every customer has an address, name,
        balance and a shopping cart
    */
    struct Customer {
        address adr;
        bytes32 name;
        uint256 balance;
        Cart cart;
    }

    /**
        @notice A shopping cart contains an array of product ids: @products
        and a sum of product prices: @completeSum
        The @completeSum gets automatically updated when customer
        adds or removes products.
    */
    struct Cart {
      uint256[] products;
      uint256 completeSum;
    }

    /**
        @notice Represents a product:
        Product id: @id
        Product name: @name
        Decription: @description
        Amount of items in a single product: @default_amount
    */
    struct Product {
        uint256 id;
        bytes32 name;
        bytes32 description;
        uint256 price;
        uint256 default_amount;
    }

    /**
        @notice Represents a receipt [NOT IN USE]
    */
    struct Receipt {
        InvoiceLine[] lines;
        address customer_address;
    }

    /**
        @notice Represents a single entry describing a single product [NOT IN USE]
    */
    struct InvoiceLine {
        bytes product_id;
        uint256 amount;
        uint256 product_price;
        uint256 total_price;
    }

    /**
        @notice Default constructor
    */
    function Store() {
        owner = msg.sender;
        store_name = "my-retail-store";
        store_balance = 0;
        if (this.balance > 0) throw;
    }

    /**
          @notice Payable fallback
    */
    function() payable {

    }

    /**
          @notice Register a single product
          @param id Product ID
          @param name Product Name
          @param description Product Description
          @param price Product Price
          @param default_amount Default amount of items in a single product
          @return success
    */
    function registerProduct(uint256 id, bytes32 name, bytes32 description,
                             uint256 price, uint256 default_amount)
                                         onlyOwner returns (bool success) {
        var product = Product(id, name, description, price, default_amount);
        if (checkProductValidity(product)) {
            products[id] = product;
            ProductRegistered(id);
            return true;
        }
        ProductRegistrationFailed(id);
        return false;
    }

    /**
          @notice Removes a product from the list
          @param id Product ID
          @return success
    */
    function deregisterProduct(uint256 id) onlyOwner returns (bool success) {
      Product product = products[id];
      if (product.id == id) {
        delete products[id];
        ProductDeregistered(id);
        return true;
      }
      ProductDeregistrationFaled(id);
      return false;
    }

    /**
          @notice Registers a new customer (only store owners)
          @param _address Customer's address
          @param _name Customer's name
          @param _balance Customer's balance
          @return success
    */
    function registerCustomer(address _address, bytes32 _name, uint256 _balance)
                                        onlyOwner returns (bool success) {
      if (_address != address(0)) {
        Customer memory customer = Customer({ adr: _address, name: _name,
                                              balance: _balance,
                                              cart: Cart(new uint256[](0), 0)
                                            });
        customers[_address] = customer;
        CustomerRegistered(_address);
        return true;
      }
      CustomerRegistrationFailed(_address);
      return false;
    }

    /**
        @notice Removes a customer (only store owners)
        @param _address Customer's address
        @return success
    */
    function deregisterCustomer(address _address) onlyOwner
                                                        returns (bool success) {
      Customer customer = customers[_address];
      if (customer.adr != address(0)) {
        delete customers[_address];
        CustomerDeregistered(_address);
        return true;
      }
      CustomerDeregistrationFailed(_address);
      return false;
    }

    /**
        @notice Inserts a product into the shopping cart.
        This function returns a boolean and the position of the
        inserted product.
        The positional information can later be used to directly reference
        the product within the mapping. Solidity mappings aren't interable.
        @param id Product ID
        @return (success, pos_in_prod_mapping)
    */
    function insertProductIntoCart(uint256 id) returns (bool success,
                                                  uint256 pos_in_prod_mapping) {
        Customer cust = customers[msg.sender];
        Product prod = products[id];
        uint256 prods_prev_len = cust.cart.products.length;
        cust.cart.products.push(prod.id);
        uint256 current_sum = cust.cart.completeSum;
        cust.cart.completeSum = safeAdd(current_sum, prod.price);
        if (cust.cart.products.length > prods_prev_len) {
          CartProductInserted(msg.sender, id, prod.price, cust.cart.completeSum);
          return (true, cust.cart.products.length - 1);
        }
        CartProductInsertionFailed(msg.sender, id);
        return (false, 0);
    }

    /**
        @notice Removes a product entry from the shopping cart
        @param prod_pos_in_mapping Product's position in the internal mapping
    */
    function removeProductFromCart(uint256 prod_pos_in_mapping) {
      /*if (msg.sender != owner) {*/
        uint256[] memory new_product_list = new uint256[](customers[msg.sender]
                                                    .cart.products.length - 1);
        var customerProds = customers[msg.sender].cart.products;
        for (uint256 i = 0; i < customerProds.length; i++) {
          if (i != prod_pos_in_mapping) {
            new_product_list[i] = customerProds[i];
          } else {
            customers[msg.sender].cart.completeSum -=
                                               products[customerProds[i]].price;
            CartProductRemoved(msg.sender, customerProds[i]);
          }
        }
        customers[msg.sender].cart.products = new_product_list;
      /*}*/
    }

    /**
        @notice Invokes a checkout process that'll use the current shopping cart to
        transfer balances between the current customer and the store
        @return success
    */
    function checkoutCart() returns (bool success) {
        Customer customer = customers[msg.sender];
        uint256 paymentSum = customer.cart.completeSum;
        if ((customer.balance >= paymentSum) &&
            customer.cart.products.length > 0) {
            customer.balance -= paymentSum;
            customer.cart = Cart(new uint256[](0), 0);
            store_balance += paymentSum;
            CartCheckoutCompleted(msg.sender, paymentSum);
            return true;
        }
        CartCheckoutFailed(msg.sender, customer.balance, paymentSum);
        return false;
    }

    /**
          @notice Empties the shopping cart
          @return success
    */
    function emptyCart() returns (bool success) {
      /*if (msg.sender != owner) {*/
        Customer customer = customers[msg.sender];
        customer.cart = Cart(new uint256[](0), 0);
        CartEmptied(customer.adr);
        return true;
      /*}*/
      /*return false;*/
    }

    /**
          @notice Changes the name of the store
          @param new_store_name New store name
          @return success
    */
    function renameStoreTo(bytes32 new_store_name) onlyOwner
                                                        returns (bool success) {
        if (new_store_name.length != 0 &&
            new_store_name.length <= 32) {
            store_name = new_store_name;
            return true;
        }
        return false;
    }

    /**
          @notice Returns a elements describing a product
          @param id Product ID
          @return (name, description, price, default_amount)
    */
    function getProduct(uint256 id) constant returns (bytes32 name,
                                                      bytes32 description,
                                                      uint256 price,
                                                      uint256 default_amount) {
       return (products[id].name,
               products[id].description,
               products[id].price,
               products[id].default_amount);
    }

    /**
        @notice Returns a list of product ids and a complete sum.
        The caller address must be a registered customer.
        @return (product_ids, complete_sum)
    */
    function getCart() constant returns (uint256[] memory product_ids,
                                                          uint256 complete_sum) {
      Customer customer = customers[msg.sender];
      uint256 len = customer.cart.products.length;
      uint256[] memory ids = new uint256[](len);
      for (uint256 i = 0; i < len; i++) {
        ids[i] = products[i].id;
      }
      return (ids, customer.cart.completeSum);
    }

    /**
          @notice Returns customer's balance
          @return _balance Customer's balance
    */
    function getBalance() constant returns (uint256 _balance) {
      return customers[msg.sender].balance;
    }

    /**
          @notice Returns stores's own balance
          @return store_balance Store's current balance
    */
    function getStoreBalance() onlyOwner constant returns (uint256) {
      return store_balance;
    }

    /**
          @notice Checks product validity
          @param product Product struct
          @return valid
    */
    function checkProductValidity(Product product) private
                                                          returns (bool valid) {
       return (product.price > 0);
    }
}

pragma solidity ^0.4.10;

import "./Base/Owned.sol";
import "./Base/SafeMath.sol";

/**
    @notice This contract implements a simple store that can interact with
    registered customers. Every customer has its own shopping cart.
    @title Retail Store Contract
    @author Harris Brakmic
*/
contract Store is Owned, SafeMath {

    /* Store internals */
    bytes32 public store_name; // store name
    uint256 private store_balance;  // store balance

    mapping (address => Customer) customers;
    mapping (uint256 => Product) products;

    /* Store Events */
    event CustomerRegistered(address customer);
    event CustomerRegistrationFailed(address customer);
    event CustomerDeregistered(address customer);
    event CustomerDeregistrationFailed(address customer);

    event ProductRegistered(uint256 productId);
    event ProductDeregistered(uint256 productId);
    event ProductRegistrationFailed(uint256 productId);
    event ProductDeregistrationFaled(uint256 productId);

    event CartProductInserted(address customer, uint256 prodId, uint256 prodPrice, uint256 completeSum);
    event CartProductInsertionFailed(address customer, uint256 prodId);
    event CartProductRemoved(address customer, uint256 prodId);
    event CartCheckoutCompleted(address customer, uint256 paymentSum);
    event CartCheckoutFailed(address customer, uint256 customerBalance, uint256 paymentSum);
    event CartEmptied(address customer);

    /**
        @notice every customer has an address, name,
        balance and a shopping cart
    */
    struct Customer {
        address adr;
        bytes32 name;
        uint256 balance;
        Cart cart;
    }
    /**
        @notice A shopping cart contains an array of product ids: @products
        and a sum of product prices: @completeSum
        The @completeSum gets automatically updated when customer
        adds or removes products.
    */
    struct Cart {
      uint256[] products;
      uint256 completeSum;
    }
    /**
        @notice Represents a product:
        Product id: @id
        Product name: @name
        Decription: @description
        Amount of items in a single product: @default_amount
    */
    struct Product {
        uint256 id;
        bytes32 name;
        bytes32 description;
        uint256 price;
        uint256 default_amount;
    }
    /**
        @notice Represents a receipt [NOT IN USE]
    */
    struct Receipt {
        InvoiceLine[] lines;
        address customer_address;
    }
    /**
        @notice Represents a single entry describing a single product [NOT IN USE]
    */
    struct InvoiceLine {
        bytes product_id;
        uint256 amount;
        uint256 product_price;
        uint256 total_price;
    }
    /**
        @notice Default constructor
    */
    function Store() {
        owner = msg.sender;
        store_name = "my-retail-store";
        store_balance = 0;
        if (this.balance > 0) throw;
    }
    /**
          @notice Register a single product
          @param id Product ID
          @param name Product Name
          @param description Product Description
          @param price Product Price
          @param default_amount Default amount of items in a single product
          @return success
    */
    function registerProduct(uint256 id, bytes32 name, bytes32 description,
                             uint256 price, uint256 default_amount)
                                         onlyOwner returns (bool success) {
        var product = Product(id, name, description, price, default_amount);
        if (checkProductValidity(product)) {
            products[id] = product;
            ProductRegistered(id);
            return true;
        }
        ProductRegistrationFailed(id);
        return false;
    }

    /**
          @notice Removes a product from the list
          @param id Product ID
          @return success
    */
    function deregisterProduct(uint256 id) onlyOwner returns (bool success) {
      Product product = products[id];
      if (product.id == id) {
        delete products[id];
        ProductDeregistered(id);
        return true;
      }
      ProductDeregistrationFaled(id);
      return false;
    }

    /**
          @notice Returns a elements describing a product
          @param id Product ID
          @return (name, description, price, default_amount)
    */
    function getProduct(uint256 id) constant returns (bytes32 name,
                                                      bytes32 description,
                                                      uint256 price,
                                                      uint256 default_amount) {
       return (products[id].name,
               products[id].description,
               products[id].price,
               products[id].default_amount);
    }

    /**
          @notice Registers a new customer (only store owners)
          @param _address Customer's address
          @param _name Customer's name
          @param _balance Customer's balance
          @return success
    */
    function registerCustomer(address _address, bytes32 _name, uint256 _balance)
                                        onlyOwner returns (bool success) {
      if (_address != address(0)) {
        Customer memory customer = Customer({ adr: _address, name: _name,
                                              balance: _balance,
                                              cart: Cart(new uint256[](0), 0)
                                            });
        customers[_address] = customer;
        CustomerRegistered(_address);
        return true;
      }
      CustomerRegistrationFailed(_address);
      return false;
    }

    /**
        @notice Removes a customer (only store owners)
        @param _address Customer's address
        @return success
    */
    function deregisterCustomer(address _address) onlyOwner
                                                        returns (bool success) {
      Customer customer = customers[_address];
      if (customer.adr != address(0)) {
        delete customers[_address];
        CustomerDeregistered(_address);
        return true;
      }
      CustomerDeregistrationFailed(_address);
      return false;
    }

    /**
        @notice Inserts a product into the shopping cart.
        This function returns a boolean and the position of the
        inserted product.
        The positional information can later be used to directly reference
        the product within the mapping. Solidity mappings aren't interable.
        @param id Product ID
        @return (success, pos_in_prod_mapping)
    */
    function insertProductIntoCart(uint256 id) returns (bool success,
                                                  uint256 pos_in_prod_mapping) {
        Customer cust = customers[msg.sender];
        Product prod = products[id];
        uint256 prods_prev_len = cust.cart.products.length;
        cust.cart.products.push(prod.id);
        uint256 current_sum = cust.cart.completeSum;
        cust.cart.completeSum = safeAdd(current_sum, prod.price);
        if (cust.cart.products.length > prods_prev_len) {
          CartProductInserted(msg.sender, id, prod.price, cust.cart.completeSum);
          return (true, cust.cart.products.length - 1);
        }
        CartProductInsertionFailed(msg.sender, id);
        return (false, 0);
    }

    /**
        @notice Removes a product entry from the shopping cart
        @param prod_pos_in_mapping Product's position in the internal mapping
    */
    function removeProductFromCart(uint256 prod_pos_in_mapping) {
      /*if (msg.sender != owner) {*/
        uint256[] memory new_product_list = new uint256[](customers[msg.sender]
                                                    .cart.products.length - 1);
        var customerProds = customers[msg.sender].cart.products;
        for (uint256 i = 0; i < customerProds.length; i++) {
          if (i != prod_pos_in_mapping) {
            new_product_list[i] = customerProds[i];
          } else {
            customers[msg.sender].cart.completeSum -=
                                               products[customerProds[i]].price;
            CartProductRemoved(msg.sender, customerProds[i]);
          }
        }
        customers[msg.sender].cart.products = new_product_list;
      /*}*/
    }

    /**
        @notice Returns a list of product ids and a complete sum.
        The caller address must be a registered customer.
        @return (product_ids, complete_sum)
    */
    function getCart() constant returns (uint256[] memory product_ids,
                                                          uint256 complete_sum) {
      Customer customer = customers[msg.sender];
      uint256 len = customer.cart.products.length;
      uint256[] memory ids = new uint256[](len);
      for (uint256 i = 0; i < len; i++) {
        ids[i] = products[i].id;
      }
      return (ids, customer.cart.completeSum);
    }

    /**
        @notice Invokes a checkout process that'll use the current shopping cart to
        transfer balances between the current customer and the store
        @return success
    */
    function checkoutCart() returns (bool success) {
        Customer customer = customers[msg.sender];
        uint256 paymentSum = customer.cart.completeSum;
        if ((customer.balance >= paymentSum) &&
            customer.cart.products.length > 0) {
            customer.balance -= paymentSum;
            customer.cart = Cart(new uint256[](0), 0);
            store_balance += paymentSum;
            CartCheckoutCompleted(msg.sender, paymentSum);
            return true;
        }
        CartCheckoutFailed(msg.sender, customer.balance, paymentSum);
        return false;
    }

    /**
          @notice Empties the shopping cart
          @return success
    */
    function emptyCart() returns (bool success) {
      /*if (msg.sender != owner) {*/
        Customer customer = customers[msg.sender];
        customer.cart = Cart(new uint256[](0), 0);
        CartEmptied(customer.adr);
        return true;
      /*}*/
      /*return false;*/
    }

    /**
          @notice Returns customer's balance
          @return _balance Customer's balance
    */
    function getBalance() constant returns (uint256 _balance) {
      return customers[msg.sender].balance;
    }

    /**
          @notice Returns stores's own balance
          @return store_balance Store's current balance
    */
    function getStoreBalance() onlyOwner constant returns (uint256) {
      return store_balance;
    }

    /**
          @notice Changes the name of the store
          @param new_store_name New store name
          @return success
    */
    function renameStoreTo(bytes32 new_store_name) onlyOwner
                                                        returns (bool success) {
        if (new_store_name.length != 0 &&
            new_store_name.length <= 32) {
            store_name = new_store_name;
            return true;
        }
        return false;
    }

    /**
          @notice Checks product validity
          @param product Product struct
          @return valid
    */
    function checkProductValidity(Product product) private
                                                          returns (bool valid) {
       return (product.price > 0);
    }

    /**
          @notice Payable fallback
    */
    function() payable { }
}


updated Migrations contract format

updated Migrations contract format

pragma solidity ^0.4.4;

contract Migrations {
    address public owner;
    uint public last_completed_migration;

    modifier restricted() {
        if (msg.sender == owner) _;
    }

    function Migrations() {
        owner = msg.sender;
    }

    function setCompleted(uint completed) restricted {
        last_completed_migration = completed;
    }

    function upgrade(address new_address) restricted {
        Migrations upgraded = Migrations(new_address);
        upgraded.setCompleted(last_completed_migration);
    }
}


int to int8 for scores

int to int8 for scores

import "lib/math.sol";
import "userRegistry.sol";
import "concept.sol";
import "user.sol";
import "conceptRegistry.sol";

contract Assessment
{
  address assessee; //The address of the user being assessed
  address[] assessors;
  address[] finalAssessors; //The assessors who actually give an assessment
  mapping (address => uint) assessorState;
  address[] assessorPool; //The addresses of the user's that the assessors are randomly selected from
  address concept;
  address userRegistry;
  address conceptRegistry;
  address math = 0x90B66E80448eb60938FAed4A738dE0D5b630B2Fd;
  uint public startTime;
  uint public size;
  uint cost;
  uint poolSizeRemaining;
  mapping(address => string[]) public data; //IFFS hashes of data that can be passed between the assessors and the assessee for the assessment to occur
  mapping(address => bytes32) commits;
  mapping(address => uint) stake;
  uint done = 0;
  mapping(address => int8) scores;
  mapping(int => bool) inRewardCluster;
  int8 finalScore;
  event DataSet(address _dataSetter, uint _index);

  /*
  @type: modifier
  @name: onlyConcept
  @purpose: to only allow the Concept contract that spawned this assessment to call a function to which this modifier is applied
  */
  modifier onlyConcept()
  {
    if(msg.sender != concept) //checks if msg.sender is the concept that spawned this assessment
    {
      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: modifier
  @name: onlyAssessorAssessee
  @purpose: to only allow the assessors and assessee to call a function to which this modifier is applied
  */
  modifier onlyAssessorAssessee()
  {
    if(msg.sender != assessee && assessorState[msg.sender] == 0) //Checks if msg.sender has the same address as either the assessee or an assessor
    {
      throw; //Throws the function call if not
    }
    _;
  }

  /*
  @type: modifier
  @name: onlyConceptAssessment
  @purpose: to only allow the this contract or the Concept contract that spawned it to call a function to which this modifier is applied
  */
  modifier onlyConceptAssessment()
  {
    if(msg.sender != address(this) && msg.sender != concept) //Checks if msg.sender has the same address as this contract or the Concept that spawned it
    {
      throw; //Throws the function call if not
    }
    _;
  }

  function Assessment(address assesseeAddress, address userRegistryAddress, address conceptRegistryAddress, uint assessmentSize, uint assessmentCost)
  {
    assessee = assesseeAddress;
    concept = msg.sender;
    userRegistry = userRegistryAddress;
    conceptRegistry = conceptRegistryAddress;
    startTime = block.timestamp;
    size = assessmentSize;
    cost = assessmentCost;
    poolSizeRemaining = size*20;
    User(assessee).notification(concept, 0); //Assessment made
  }

  function cancelAssessment() onlyConceptAssessment()
  {
    Concept(concept).setBalance(assessee, UserRegistry(userRegistry).getBalance(assessee) + cost*size);
    User(assessee).notification(concept, 3); //Assessment Cancled and you have been refunded
    for(uint i = 0; i < assessors.length; i++)
    {
      Concept(concept).setBalance(assessors[i], UserRegistry(userRegistry).getBalance(assessors[i]) + cost);
      User(assessors[i]).notification(concept, 3); //Assessment Cancled and you have been refunded
    }
    suicide(conceptRegistry);
  }

  /*
  @type: function
  @purpose: To recursively set the pool to draw assessors from in the assessment
  @param: address conceptAddress = the concept that assessors are currently being drawn from
  @param: address assessment = the address of the assessment that assessors are being drawn for
  @param: uint seed = the seed number for random number generation
  @param: uint size = the desired size of the assessment
  @returns: nothing
  */
  function setAssessorPool(address conceptAddress, uint seed) onlyConceptAssessment()
  {
    if(Concept(ConceptRegistry(conceptRegistry).mewAddress()).getOwnerLength() < poolSizeRemaining) //Checks if the requested pool size is greater than the number of users in the system
    {
      for(uint i = 0; i < Concept(ConceptRegistry(conceptRegistry).mewAddress()).getOwnerLength(); i++) //If so, all users in the system are added to the pool
      {
        assessorPool.push(Concept(ConceptRegistry(conceptRegistry).mewAddress()).owners(i));
        User(Concept(ConceptRegistry(conceptRegistry).mewAddress()).owners(i)).notification(concept, 1); //Called As A Potential Assessor
        assessorState[Concept(ConceptRegistry(conceptRegistry).mewAddress()).owners(i)] = 1;
      }
      poolSizeRemaining = 0;
    }
    for(uint j = 0; j < Concept(conceptAddress).getOwnerLength() && poolSizeRemaining > 0; j++) //Iterates through all the owners of the concept corresponding to concept address while the remaining amount of user's desired in the pool is greater than 0
    {
      uint numberSet = 0; //initializes a variable to keep track of how many assessors this concept has added to the pool
      if(numberSet < Concept(conceptAddress).getOwnerLength()/10) //Checks if the number of assessors provided by this concept is less than 10% of the owners of the concept
      {
        address randomUser = Concept(conceptAddress).owners(Math(math).getRandom(seed + j, Concept(conceptAddress).getOwnerLength()-1)); //gets a random owner of the concept
        if(User(randomUser).availability() == true && (uint(Concept(conceptAddress).currentScores(randomUser))*Concept(conceptAddress).assessmentSizes(randomUser)) > (now%(uint(Concept(conceptAddress).maxScore())*Concept(conceptAddress).maxSize()))) //Checks if the randomly drawn is available and then puts it through a random check that it has a higher chance of passing if it has had a higher score and a larger assessment
        {
          assessorPool.push(randomUser); //adds the randomly selected user to the assessor pool
          User(randomUser).notification(concept, 1); //Called As A Potential Assessor
          assessorState[randomUser] = 1;
          poolSizeRemaining--; //reduces desired amount of users to be added to the assessor pool by 1
          numberSet++; //increases numberSet by 1
        }
      }
      else
      {
        break; //exits this for loop if 10% or more of the concept owners are in the assessment pool
      }
    }
    for(uint l = 0; l < Concept(conceptAddress).getParentsLength() || l < Concept(conceptAddress).getChildrenLength(); l++) //Recursively calls this function in such a way that the parent and child concepts' owners will be used to potentially populate the assessment pool
    {
      if(l < Concept(conceptAddress).getParentsLength()) //Makes sure there are still parent concepts left to call
      {
        setAssessorPool(Concept(conceptAddress).parentConcepts(l), Math(math).getRandom(seed + l, Concept(conceptAddress).getOwnerLength()-1));
      }
      if(l < Concept(conceptAddress).getChildrenLength()) //Makes sure there are still child concepts left to call
      {
        setAssessorPool(Concept(conceptAddress).childConcepts(l), Math(math).getRandom(seed + l, Concept(conceptAddress).getOwnerLength()-1));
      }
    }
  }

  function confirmAssessor()
  {
    if(block.number - startTime <= 15 && assessorState[msg.sender] == 1 && assessors.length < size && UserRegistry(userRegistry).getBalance(msg.sender) >= cost)
    {
      assessors.push(msg.sender);
      assessorState[msg.sender] = 2;
      stake[msg.sender] = cost;
      Concept(concept).setBalance(msg.sender,UserRegistry(userRegistry).getBalance(msg.sender) - cost);
      User(msg.sender).notification(concept, 2); //Confirmed for assessing, stake has been taken
    }
    if(assessors.length == size)
    {
      notifyStart();
    }
    else if(block.number - startTime > 15 && assessors.length < size)
    {
      cancelAssessment();
    }
  }

  function notifyStart() onlyThis()
  {
    for(uint i = 0; i < assessors.length; i++)
    {
      User(assessors[i]).notification(concept, 4); //Assessment Has Started
    }
    User(assessee).notification(concept, 4); //Assessment Has Started
  }

  function setData(string newData) onlyAssessorAssessee()
  {
    data[msg.sender].push(newData);
    DataSet(msg.sender, data[msg.sender].length - 1);
  }

  function commit(bytes32 hash)
  {
    if(assessorState[msg.sender] == 2)
    {
      commits[msg.sender] = hash;
      assessorState[msg.sender] == 3;
      done++;
      if(done <= size/2)
      {
        startTime = block.number;
      }
    }
    if(done > size/2)
    {
      for(uint i = 0; i < assessors.length; i++)
      {
        if(assessorState[assessors[i]] == 2)
        {
          //burn da stakes
        }
        if(stake[assessors[i]] == 0)
        {
          assessorState[assessors[i]] = 4;
          done++;
        }
      }
    }
    if(done == size)
    {
      for(uint j = 0; j < assessors.length; j++)
      {
        if(assessorState[assessors[j]] == 3)
        {
          User(assessors[j]).notification(concept, 5); //Send in Score
        }
      }
      startTime = block.number;
      done = 0;
    }
  }

  function reveal(int score, bytes16 salt, address assessor)
  {
    if(block.number - startTime <= 10)
    {
      bytes32 hash = sha3(score,salt);
      if(commits[assessor] == hash)
      {
        if(msg.sender == assessor)
        {
          scores[msg.sender] = score;
          assessorState[assessor] = 5;
          done++;
        }
        else
        {
          Concept(concept).setBalance(msg.sender,UserRegistry(userRegistry).getBalance(msg.sender) + stake[assessor]);
          stake[assessor] = 0;
          assessorState[assessor] = 4;
        }
      }
      else if(msg.sender == assessor)
      {
        stake[assessor] = 0;
        assessorState[assessor] = 4;
        done++;
      }
    }
    else
    {
      for(uint i = 0; i < assessors.length; i++)
      {
        if(assessorState[assessors[i]] == 3)
        {
          stake[assessors[i]] = 0;
          assessorState[assessors[i]] = 4;
          done++;
        }
      }
    }
    if(done == size)
    {
      calculateResult();
    }
  }

  function calculateResult() onlyThis()
  {
    mapping(uint => int[]) clusters;
    for(uint j = 0; j < size; j++)
    {
      if(assessorState[assessors[i]] == 5)
      {
        finalAssessors.push(assessors[i]);
      }
    }
    int[] memory score = new int[] (finalAssessors.length);
    uint largestClusterIndex = 0;
    int averageScore;
    for(uint i = 0; i < finalAssessors.length; i++)
    {
      score[i] = scores[finalAssessors[i]];
    }
    int meanAbsoluteDeviation = Math(math).calculateMAD(score,int(finalAssessors.length));
    for(uint l = 0; l < score.length; l++)
    {
      for(uint m = 0; m < score.length; m++)
      {
        if(score[l] - score[m] <= meanAbsoluteDeviation)
        {
          clusters[l].push(score[m]);
        }
      }
      if(clusters[l].length > clusters[largestClusterIndex].length)
      {
        largestClusterIndex = l;
      }
    }
    for(uint o = 0; o < clusters[largestClusterIndex].length; o++)
    {
      averageScore += clusters[largestClusterIndex][o];
      inRewardCluster[clusters[largestClusterIndex][o]] = true;
    }
    averageScore /= int(clusters[largestClusterIndex].length);
    finalScore = averageScore;
    payout(clusters[largestClusterIndex].length);
  }

  function payout(uint largestSize) onlyThis()
  {
    for(uint i = 0; i < size; i++)
    {
      int score = scores[assessors[i]];
      int scoreDistance = ((score - finalScore)*100)/finalScore;
      if(scoreDistance < 0)
      {
        scoreDistance *= -1;
      }
      uint payoutValue = 1; //Figure out new payout algorithm
      if(inRewardCluster[score] == true)
      {
        Concept(concept).setBalance(assessors[i], UserRegistry(userRegistry).getBalance(assessors[i]) + payoutValue);
        User(assessors[i]).notification(concept, 15); //You Have Received Payment For Your Assessment
      }
      if(inRewardCluster[score] == false)
      {
        Concept(concept).setBalance(assessors[i], UserRegistry(userRegistry).getBalance(assessors[i]) - payoutValue);
        User(assessors[i]).notification(concept, 16); //You Have Received A Fine For Your Assessment
      }
    }
    Concept(concept).finishAssessment(finalScore, assessee, address(this));();
  }

}

import "lib/math.sol";
import "userRegistry.sol";
import "concept.sol";
import "user.sol";
import "conceptRegistry.sol";

contract Assessment
{
  address assessee; //The address of the user being assessed
  address[] assessors;
  address[] finalAssessors; //The assessors who actually give an assessment
  mapping (address => uint) assessorState;
  address[] assessorPool; //The addresses of the user's that the assessors are randomly selected from
  address concept;
  address userRegistry;
  address conceptRegistry;
  address math = 0x90B66E80448eb60938FAed4A738dE0D5b630B2Fd;
  uint public startTime;
  uint public size;
  uint cost;
  uint poolSizeRemaining;
  mapping(address => string[]) public data; //IFFS hashes of data that can be passed between the assessors and the assessee for the assessment to occur
  mapping(address => bytes32) commits;
  mapping(address => uint) stake;
  uint done = 0;
  mapping(address => int) scores;
  mapping(int => bool) inRewardCluster;
  int finalScore;
  event DataSet(address _dataSetter, uint _index);

  /*
  @type: modifier
  @name: onlyConcept
  @purpose: to only allow the Concept contract that spawned this assessment to call a function to which this modifier is applied
  */
  modifier onlyConcept()
  {
    if(msg.sender != concept) //checks if msg.sender is the concept that spawned this assessment
    {
      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: modifier
  @name: onlyAssessorAssessee
  @purpose: to only allow the assessors and assessee to call a function to which this modifier is applied
  */
  modifier onlyAssessorAssessee()
  {
    if(msg.sender != assessee && assessorState[msg.sender] == 0) //Checks if msg.sender has the same address as either the assessee or an assessor
    {
      throw; //Throws the function call if not
    }
    _;
  }

  /*
  @type: modifier
  @name: onlyConceptAssessment
  @purpose: to only allow the this contract or the Concept contract that spawned it to call a function to which this modifier is applied
  */
  modifier onlyConceptAssessment()
  {
    if(msg.sender != address(this) && msg.sender != concept) //Checks if msg.sender has the same address as this contract or the Concept that spawned it
    {
      throw; //Throws the function call if not
    }
    _;
  }

  function Assessment(address assesseeAddress, address userRegistryAddress, address conceptRegistryAddress, uint assessmentSize, uint assessmentCost)
  {
    assessee = assesseeAddress;
    concept = msg.sender;
    userRegistry = userRegistryAddress;
    conceptRegistry = conceptRegistryAddress;
    startTime = block.timestamp;
    size = assessmentSize;
    cost = assessmentCost;
    poolSizeRemaining = size*20;
    User(assessee).notification(concept, 0); //Assessment made
  }

  function cancelAssessment() onlyConceptAssessment()
  {
    Concept(concept).setBalance(assessee, UserRegistry(userRegistry).getBalance(assessee) + cost*size);
    User(assessee).notification(concept, 3); //Assessment Cancled and you have been refunded
    for(uint i = 0; i < assessors.length; i++)
    {
      Concept(concept).setBalance(assessors[i], UserRegistry(userRegistry).getBalance(assessors[i]) + cost);
      User(assessors[i]).notification(concept, 3); //Assessment Cancled and you have been refunded
    }
    suicide(conceptRegistry);
  }

  /*
  @type: function
  @purpose: To recursively set the pool to draw assessors from in the assessment
  @param: address conceptAddress = the concept that assessors are currently being drawn from
  @param: address assessment = the address of the assessment that assessors are being drawn for
  @param: uint seed = the seed number for random number generation
  @param: uint size = the desired size of the assessment
  @returns: nothing
  */
  function setAssessorPool(address conceptAddress, uint seed) onlyConceptAssessment()
  {
    if(Concept(ConceptRegistry(conceptRegistry).mewAddress()).getOwnerLength() < poolSizeRemaining) //Checks if the requested pool size is greater than the number of users in the system
    {
      for(uint i = 0; i < Concept(ConceptRegistry(conceptRegistry).mewAddress()).getOwnerLength(); i++) //If so, all users in the system are added to the pool
      {
        assessorPool.push(Concept(ConceptRegistry(conceptRegistry).mewAddress()).owners(i));
        User(Concept(ConceptRegistry(conceptRegistry).mewAddress()).owners(i)).notification(concept, 1); //Called As A Potential Assessor
        assessorState[Concept(ConceptRegistry(conceptRegistry).mewAddress()).owners(i)] = 1;
      }
      poolSizeRemaining = 0;
    }
    for(uint j = 0; j < Concept(conceptAddress).getOwnerLength() && poolSizeRemaining > 0; j++) //Iterates through all the owners of the concept corresponding to concept address while the remaining amount of user's desired in the pool is greater than 0
    {
      uint numberSet = 0; //initializes a variable to keep track of how many assessors this concept has added to the pool
      if(numberSet < Concept(conceptAddress).getOwnerLength()/10) //Checks if the number of assessors provided by this concept is less than 10% of the owners of the concept
      {
        address randomUser = Concept(conceptAddress).owners(Math(math).getRandom(seed + j, Concept(conceptAddress).getOwnerLength()-1)); //gets a random owner of the concept
        if(User(randomUser).availability() == true && (uint(Concept(conceptAddress).currentScores(randomUser))*Concept(conceptAddress).assessmentSizes(randomUser)) > (now%(uint(Concept(conceptAddress).maxScore())*Concept(conceptAddress).maxSize()))) //Checks if the randomly drawn is available and then puts it through a random check that it has a higher chance of passing if it has had a higher score and a larger assessment
        {
          assessorPool.push(randomUser); //adds the randomly selected user to the assessor pool
          User(randomUser).notification(concept, 1); //Called As A Potential Assessor
          assessorState[randomUser] = 1;
          poolSizeRemaining--; //reduces desired amount of users to be added to the assessor pool by 1
          numberSet++; //increases numberSet by 1
        }
      }
      else
      {
        break; //exits this for loop if 10% or more of the concept owners are in the assessment pool
      }
    }
    for(uint l = 0; l < Concept(conceptAddress).getParentsLength() || l < Concept(conceptAddress).getChildrenLength(); l++) //Recursively calls this function in such a way that the parent and child concepts' owners will be used to potentially populate the assessment pool
    {
      if(l < Concept(conceptAddress).getParentsLength()) //Makes sure there are still parent concepts left to call
      {
        setAssessorPool(Concept(conceptAddress).parentConcepts(l), Math(math).getRandom(seed + l, Concept(conceptAddress).getOwnerLength()-1));
      }
      if(l < Concept(conceptAddress).getChildrenLength()) //Makes sure there are still child concepts left to call
      {
        setAssessorPool(Concept(conceptAddress).childConcepts(l), Math(math).getRandom(seed + l, Concept(conceptAddress).getOwnerLength()-1));
      }
    }
  }

  function confirmAssessor()
  {
    if(block.number - startTime <= 15 && assessorState[msg.sender] == 1 && assessors.length < size && UserRegistry(userRegistry).getBalance(msg.sender) >= cost)
    {
      assessors.push(msg.sender);
      assessorState[msg.sender] = 2;
      stake[msg.sender] = cost;
      Concept(concept).setBalance(msg.sender,UserRegistry(userRegistry).getBalance(msg.sender) - cost);
      User(msg.sender).notification(concept, 2); //Confirmed for assessing, stake has been taken
    }
    if(assessors.length == size)
    {
      notifyStart();
    }
    else if(block.number - startTime > 15 && assessors.length < size)
    {
      cancelAssessment();
    }
  }

  function notifyStart() onlyThis()
  {
    for(uint i = 0; i < assessors.length; i++)
    {
      User(assessors[i]).notification(concept, 4); //Assessment Has Started
    }
    User(assessee).notification(concept, 4); //Assessment Has Started
  }

  function setData(string newData) onlyAssessorAssessee()
  {
    data[msg.sender].push(newData);
    DataSet(msg.sender, data[msg.sender].length - 1);
  }

  function commit(bytes32 hash)
  {
    if(assessorState[msg.sender] == 2)
    {
      commits[msg.sender] = hash;
      assessorState[msg.sender] == 3;
      done++;
      if(done <= size/2)
      {
        startTime = block.number;
      }
    }
    if(done > size/2)
    {
      for(uint i = 0; i < assessors.length; i++)
      {
        if(assessorState[assessors[i]] == 2)
        {
          //burn da stakes
        }
        if(stake[assessors[i]] == 0)
        {
          assessorState[assessors[i]] = 4;
          done++;
        }
      }
    }
    if(done == size)
    {
      for(uint j = 0; j < assessors.length; j++)
      {
        if(assessorState[assessors[j]] == 3)
        {
          User(assessors[j]).notification(concept, 5); //Send in Score
        }
      }
      startTime = block.number;
      done = 0;
    }
  }

  function reveal(int score, bytes16 salt, address assessor)
  {
    if(block.number - startTime <= 10)
    {
      bytes32 hash = sha3(score,salt);
      if(commits[assessor] == hash)
      {
        if(msg.sender == assessor)
        {
          scores[msg.sender] = score;
          assessorState[assessor] = 5;
          done++;
        }
        else
        {
          Concept(concept).setBalance(msg.sender,UserRegistry(userRegistry).getBalance(msg.sender) + stake[assessor]);
          stake[assessor] = 0;
          assessorState[assessor] = 4;
        }
      }
      else if(msg.sender == assessor)
      {
        stake[assessor] = 0;
        assessorState[assessor] = 4;
        done++;
      }
    }
    else
    {
      for(uint i = 0; i < assessors.length; i++)
      {
        if(assessorState[assessors[i]] == 3)
        {
          stake[assessors[i]] = 0;
          assessorState[assessors[i]] = 4;
          done++;
        }
      }
    }
    if(done == size)
    {
      calculateResult();
    }
  }

  function calculateResult() onlyThis()
  {
    mapping(uint => int[]) clusters;
    for(uint j = 0; j < size; j++)
    {
      if(assessorState[assessors[i]] == 5)
      {
        finalAssessors.push(assessors[i]);
      }
    }
    int[] memory score = new int[] (finalAssessors.length);
    uint largestClusterIndex = 0;
    int averageScore;
    for(uint i = 0; i < finalAssessors.length; i++)
    {
      score[i] = scores[finalAssessors[i]];
    }
    int meanAbsoluteDeviation = Math(math).calculateMAD(score,int(finalAssessors.length));
    for(uint l = 0; l < score.length; l++)
    {
      for(uint m = 0; m < score.length; m++)
      {
        if(score[l] - score[m] <= meanAbsoluteDeviation)
        {
          clusters[l].push(score[m]);
        }
      }
      if(clusters[l].length > clusters[largestClusterIndex].length)
      {
        largestClusterIndex = l;
      }
    }
    for(uint o = 0; o < clusters[largestClusterIndex].length; o++)
    {
      averageScore += clusters[largestClusterIndex][o];
      inRewardCluster[clusters[largestClusterIndex][o]] = true;
    }
    averageScore /= int(clusters[largestClusterIndex].length);
    finalScore = averageScore;
    payout(clusters[largestClusterIndex].length);
  }

  function payout(uint largestSize) onlyThis()
  {
    for(uint i = 0; i < size; i++)
    {
      int score = scores[assessors[i]];
      int scoreDistance = ((score - finalScore)*100)/finalScore;
      if(scoreDistance < 0)
      {
        scoreDistance *= -1;
      }
      uint payoutValue = 1; //Figure out new payout algorithm
      if(inRewardCluster[score] == true)
      {
        Concept(concept).setBalance(assessors[i], UserRegistry(userRegistry).getBalance(assessors[i]) + payoutValue);
        User(assessors[i]).notification(concept, 15); //You Have Received Payment For Your Assessment
      }
      if(inRewardCluster[score] == false)
      {
        Concept(concept).setBalance(assessors[i], UserRegistry(userRegistry).getBalance(assessors[i]) - payoutValue);
        User(assessors[i]).notification(concept, 16); //You Have Received A Fine For Your Assessment
      }
    }
    Concept(concept).finishAssessment(finalScore, assessee, address(this));();
  }

}


LABX-193 JobDataCore: update constant type to uint


reformat code, remove totalReturnedCredit

pragma solidity ^0.4.11;
import './Owned.sol';
import './Token.sol';
import './SafeMath.sol';

contract Exchange is Owned {

    event onExchangeTokenToEther(address who, uint256 tokenAmount, uint256 etherAmount);

    using SafeMath for uint256;

    Token public token = Token(0xD850942eF8811f2A866692A623011bDE52a462C1);

    // 1 ether = ? tokens
    uint256 public rate = 4025;

    // quota of token for every account that can be exchanged to ether
    uint256 public tokenQuota = 402500 ether;

    // quota of ether for every account that can be exchanged to token
    // uint256 public etherQuota = 100 ether;

    bool public tokenToEtherAllowed = true;
    // bool public etherToTokenAllowed = false;

    // uint256 public totalReturnedCredit;             //returned ven

    // struct QuotaUsed {
    //     uint128 tokens;
    //     uint128 ethers;
    // }
    mapping(address => uint256) accountQuotaUsed;

    function Exchange() {
    }

    function () payable {
    }

    function withdrawEther(address _address,uint256 _amount) onlyOwner {
        require(_address != 0);
        _address.transfer(_amount);
    }

    function withdrawToken(address _address, uint256 _amount) onlyOwner {
        require(_address != 0);
        token.transfer(_address, _amount);
    }

    function quotaUsed(address _account) constant returns(uint256 ) {
        return accountQuotaUsed[_account];
    }

    //tested
    function setRate(uint256 _rate) onlyOwner {
        rate = _rate;
    }

    //tested
    function setTokenQuota(uint256 _quota) onlyOwner {
        tokenQuota = _quota;
    }

    // function setEtherQuota(uint256 _quota) onlyOwner {
    //     etherQuota = _quota;
    // }

    //tested
    function setTokenToEtherAllowed(bool _allowed) onlyOwner {
        tokenToEtherAllowed = _allowed;
    }

    // function setEtherToTokenAllowed(bool _allowed) onlyOwner {
    //     etherToTokenAllowed = _allowed;
    // }

    function receiveApproval(address _from, uint256 _value, address /*_tokenContract*/, bytes /*_extraData*/) {
        exchangeTokenToEther(_from, _value);
    }

    function exchangeTokenToEther(address _from, uint256 _tokenAmount) internal {
        require(tokenToEtherAllowed);
        require(msg.sender == address(token));
        require(!isContract(_from));

        uint256 quota = tokenQuota.sub(accountQuotaUsed[_from]);

        if (_tokenAmount > quota)
            _tokenAmount = quota;

        uint256 balance = token.balanceOf(_from);
        if (_tokenAmount > balance)
            _tokenAmount = balance;

        require(_tokenAmount>0);    //require the token should be above 0

        //require(_tokenAmount > 0.01 ether);
        require(token.transferFrom(_from, this, _tokenAmount));

        accountQuotaUsed[_from] = _tokenAmount.add(accountQuotaUsed[_from]);

        uint256 etherAmount = _tokenAmount / rate;
        require(etherAmount > 0);
        _from.transfer(etherAmount);

        // totalReturnedCredit+=_tokenAmount;

        onExchangeTokenToEther(_from, _tokenAmount, etherAmount);
    }

    //exchange EtherToToken放到fallback函数中
    //TokenToEther
    //    function exchangeEtherToToken() payable {
    //       require(etherToTokenAllowed);
    //        require(!isContract(msg.sender));
    //
    //        uint256 quota = etherQuota.sub(accountQuotaUsed[msg.sender].ethers);

    //        uint256 etherAmount = msg.value;
    //        require(etherAmount >= 0.01 ether && etherAmount <= quota);
    //
    //        uint256 tokenAmount = etherAmount * rate;

    //        accountQuotaUsed[msg.sender].ethers = etherAmount.add(accountQuotaUsed[msg.sender].ethers).toUINT128();

    //        require(token.transfer(msg.sender, tokenAmount));

    //        onExchangeEtherToToken(msg.sender, tokenAmount, etherAmount);
    //    }

    function isContract(address _addr) constant internal returns(bool) {
        uint size;
        if (_addr == 0)
            return false;
        assembly {
            size := extcodesize(_addr)
        }
        return size > 0;
    }
}

pragma solidity ^0.4.11;
import './Owned.sol';
import './Token.sol';
import './SafeMath.sol';

contract Exchange is Owned {

    event onExchangeTokenToEther(address who, uint256 tokenAmount, uint256 etherAmount);

    using SafeMath for uint256;

    Token public token = Token(0xD850942eF8811f2A866692A623011bDE52a462C1);

    // 1 ether = ? tokens
    uint256 public rate = 4025;

    // quota of token for every account that can be exchanged to ether
    uint256 public tokenQuota = 402500 ether;

    // quota of ether for every account that can be exchanged to token
 //   uint256 public etherQuota = 100 ether;

    bool public tokenToEtherAllowed = true;
//    bool public etherToTokenAllowed = false;

    uint256 public totalReturnedCredit;             //returned ven

//    struct QuotaUsed {
//        uint128 tokens;
//        uint128 ethers;
//    }
    mapping(address => uint256) accountQuotaUsed;

    function Exchange() {
    }

    function () payable {
    }

    function withdrawEther(address _address,uint256 _amount) onlyOwner {
        require(_address != 0);
        _address.transfer(_amount);
    }

    function withdrawToken(address _address, uint256 _amount) onlyOwner {
        require(_address != 0);
        token.transfer(_address, _amount);
    }

    function quotaUsed(address _account) constant returns(uint256 ) {
        return accountQuotaUsed[_account];
    }

//tested
    function setRate(uint256 _rate) onlyOwner {
        rate = _rate;
    }

//tested
    function setTokenQuota(uint256 _quota) onlyOwner {
        tokenQuota = _quota;
    }

//    function setEtherQuota(uint256 _quota) onlyOwner {
//        etherQuota = _quota;
//    }

//tested
    function setTokenToEtherAllowed(bool _allowed) onlyOwner {
        tokenToEtherAllowed = _allowed;
    }

//    function setEtherToTokenAllowed(bool _allowed) onlyOwner {
//        etherToTokenAllowed = _allowed;
//    }

    function receiveApproval(address _from, uint256 _value, address /*_tokenContract*/, bytes /*_extraData*/) {
        exchangeTokenToEther(_from, _value);
    }

    function exchangeTokenToEther(address _from, uint256 _tokenAmount) internal {
        require(tokenToEtherAllowed);
        require(msg.sender == address(token));
        require(!isContract(_from));

        uint256 quota = tokenQuota.sub(accountQuotaUsed[_from]);

        if (_tokenAmount > quota)
            _tokenAmount = quota;

        uint256 balance = token.balanceOf(_from);
        if (_tokenAmount > balance)
            _tokenAmount = balance;

        require(_tokenAmount>0);    //require the token should be above 0

        //require(_tokenAmount > 0.01 ether);
        require(token.transferFrom(_from, this, _tokenAmount));

        accountQuotaUsed[_from] = _tokenAmount.add(accountQuotaUsed[_from]);

        uint256 etherAmount = _tokenAmount / rate;
        require(etherAmount > 0);
        _from.transfer(etherAmount);

        totalReturnedCredit+=_tokenAmount;

        onExchangeTokenToEther(_from, _tokenAmount, etherAmount);
    }

    //exchange EtherToToken放到fallback函数中
    //TokenToEther
//    function exchangeEtherToToken() payable {
//       require(etherToTokenAllowed);
//        require(!isContract(msg.sender));
//
//        uint256 quota = etherQuota.sub(accountQuotaUsed[msg.sender].ethers);

//        uint256 etherAmount = msg.value;
//        require(etherAmount >= 0.01 ether && etherAmount <= quota);
//
//        uint256 tokenAmount = etherAmount * rate;

//        accountQuotaUsed[msg.sender].ethers = etherAmount.add(accountQuotaUsed[msg.sender].ethers).toUINT128();

//        require(token.transfer(msg.sender, tokenAmount));

//        onExchangeEtherToToken(msg.sender, tokenAmount, etherAmount);
//    }

    function isContract(address _addr) constant internal returns(bool) {
        uint size;
        if (_addr == 0)
            return false;
        assembly {
            size := extcodesize(_addr)
        }
        return size > 0;
    }
}


external call logic - still missing ExternalRelation.address injection

pragma solidity ^0.4.9;

contract Workflow {

    // zero indexation.
    enum RelationType {
        Include, Exclude, Response, Condition, Milestone //Spawn to be added
    }

    struct ExternalRelation {
        uint32 id;
        address ext;
        RelationType relationType;
    }

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

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

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

        // Access rights:
        address[] whitelist;

        // External relations:
        ExternalRelation[] extRel; // could be made into several lists if large

    }

    event Execution(address sender, uint32 id, bool successful);
    event ExternalEdit(address sender, uint32 id, RelationType typ, bool successful);
    Activity[] activities;
    address owner;
    bytes32 name;

    /// names: array of activity names, where names[i] is the name of activity with id i
    /// included: array of activity included state, where included[i] is the included state of activity with id i
    /// executed: array of activity executed state, where executed[i] is the executed state of activity with id i
    /// pending: array of activity pending state, where pending[i] is the pending state of activity with id i
    /// include: array of include relations. The array is expected to have a structure such that i % 2 = 0 is the FROM activity and i + 1 is the TO activity
    /// exclude: array of exclude relations. The array is expected to have a structure such that i % 2 = 0 is the FROM activity and i + 1 is the TO activity
    /// response: array of response relations. The array is expected to have a structure such that i % 2 = 0 is the FROM activity and i + 1 is the TO activity
    /// condition: array of condition relations. The array is expected to have a structure such that i % 2 = 0 is the TO activity and i + 1 is the FROM activity
    /// milestone: array of milestone relations. The array is expected to have a structure such that i % 2 = 0 is the TO activity and i + 1 is the FROM activity
    function Workflow (
        bytes32 wfName,
        bytes32[] names,
        bool[] included,
        bool[] executed,
        bool[] pending,
        uint32[] include,
        uint32[] exclude,
        uint32[] response,
        uint32[] condition,
        uint32[] milestone,
        // External relations:
        uint32[] localId,
        uint32[] externalId,
        address[] workflowAddress,
        uint32[] relationType

    ) {
        name = wfName;
        owner = msg.sender;

        activities.length = names.length;

        for (var i = 0; i < names.length; i++) {
            activities[i].name      = names[i];
            activities[i].included  = included[i];
            activities[i].executed  = executed[i];
            activities[i].pending   = pending[i];
        }

        // We expect all relation arrays are formed such that i % 2 = 0 is where the data is to be stored, and i+1 is the data that is to be stored there
        for (i = 0; i < include.length; i++)
            activities[include[i++]].include.push(include[i]);
        for (i = 0; i < exclude.length; i++)
            activities[exclude[i++]].exclude.push(exclude[i]);
        for (i = 0; i < response.length; i++)
            activities[response[i++]].response.push(response[i]);
        for (i = 0; i < condition.length; i++)
            activities[condition[i++]].condition.push(condition[i]);
        for (i = 0; i < milestone.length; i++)
            activities[milestone[i++]].milestone.push(milestone[i]);

        // External relation creation
        for (i = 0; i < localId.length; i++)
            activities[localId[i]].extRel.push(ExternalRelation(externalId[i], workflowAddress[i], RelationType(relationType[i])));

    }

    function addToWhitelist(uint32 id, address actor){
        if(msg.sender != owner)
            throw;

        activities[id].whitelist.push(actor);
    }

    function logFail(uint32 id) private {
        Execution(msg.sender, id, false);
    }

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

        if(a.whitelist.length > 0) {
            for (var i = 0; i < a.whitelist.length; i++)
                if(a.whitelist[i] == msg.sender)
                    break;

            if(i == a.whitelist.length){
                logFail(id);
                return;
            }
        }

        if(!a.included){
            logFail(id);
            return;
        }

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

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

        // External checks
        for (i = 0; i < a.extRel.length; i++) {
            if(a.extRel[i].relationType == RelationType.Condition || a.extRel[i].relationType == RelationType.Milestone){
                // Maybe check if wf address is valid?
                Workflow wf = Workflow(a.extRel[i].ext);
                if(!wf.relationFulfilled(a.extRel[i].id, a.extRel[i].relationType)) {
                    logFail(id);
                    return;
                }
            }
        }

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

        for (i = 0; i < a.exclude.length; i++)
            activities[a.exclude[i]].included = false;

        for (i = 0; i < a.response.length; i++)
            activities[a.response[i]].pending = true;

        // External state changes
        for (i = 0; i < a.extRel.length; i++){
            if( a.extRel[i].relationType == RelationType.Include ||
                a.extRel[i].relationType == RelationType.Exclude ||
                a.extRel[i].relationType == RelationType.Response) {
                    wf = Workflow(a.extRel[i].ext);
                    wf.externalStateChange(a.extRel[i].id, a.extRel[i].relationType);
            }
        }

        // Effect on executing activity
        a.executed = true;
        a.pending = false;
        Execution(msg.sender, id, true);

    }

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

        selfdestruct(owner);
    }

    // Functions meant for external activity state interaction, to enable interworkflow communication
    function externalStateChange (uint32 actId, RelationType relTyp) {

        // Authorization: Assuming that calling contract address is in activity whitelist
        if(activities[actId].whitelist.length > 0) {
            for (var i = 0; i < activities[actId].whitelist.length; i++)
                if(activities[actId].whitelist[i] == msg.sender)
                    break;

            if(i == activities[actId].whitelist.length){
                //ExternalEdit(msg.sender, actId, relTyp, false); // comment in for debug
                //return; // comment in for debug
                throw; // Comment out for debug
            }
        }

        if(relTyp == RelationType.Include) activities[actId].included = true;
        if(relTyp == RelationType.Exclude) activities[actId].included = false;
        if(relTyp == RelationType.Response) activities[actId].pending = true;
        ExternalEdit(msg.sender, actId, relTyp, true);

    }

    // returns true if calling activity is executable according to specified relation type
    function relationFulfilled (uint32 actId, RelationType relTyp) returns (bool) {

        // Condition logic
        if(relTyp == RelationType.Condition)
            return !activities[actId].included || activities[actId].executed;

        // Milestone logic
        else if(relTyp == RelationType.Milestone)
            return !activities[actId].included || !activities[actId].pending;

        // Default case given non-valid relation
        return false;
    }

}

pragma solidity ^0.4.9;

contract Workflow {

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

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

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

        // Access rights:
        address[] whitelist;
    }

    event Execution(address sender, uint32 id, bool successful);
    Activity[] activities;
    address owner;

    /// names: array of activity names, where names[i] is the name of activity with id i
    /// included: array of activity included state, where included[i] is the included state of activity with id i
    /// executed: array of activity executed state, where executed[i] is the executed state of activity with id i
    /// pending: array of activity pending state, where pending[i] is the pending state of activity with id i
    /// include: array of include relations. The array is expected to have a structure such that i % 2 = 0 is the FROM activity and i + 1 is the TO activity
    /// exclude: array of exclude relations. The array is expected to have a structure such that i % 2 = 0 is the FROM activity and i + 1 is the TO activity
    /// response: array of response relations. The array is expected to have a structure such that i % 2 = 0 is the FROM activity and i + 1 is the TO activity
    /// condition: array of condition relations. The array is expected to have a structure such that i % 2 = 0 is the TO activity and i + 1 is the FROM activity
    /// milestone: array of milestone relations. The array is expected to have a structure such that i % 2 = 0 is the TO activity and i + 1 is the FROM activity
    function Workflow (
        bytes32[] names,
        bool[] included,
        bool[] executed,
        bool[] pending,
        uint32[] include,
        uint32[] exclude,
        uint32[] response,
        uint32[] condition,
        uint32[] milestone
    ) {
        owner = msg.sender;

        activities.length = names.length;

        for (var i = 0; i < names.length; i++) {
            activities[i].name      = names[i];
            activities[i].included  = included[i];
            activities[i].executed  = executed[i];
            activities[i].pending   = pending[i];
        }

        // We expect all relation arrays are formed such that i % 2 = 0 is where the data is to be stored, and i+1 is the data that is to be stored there
        for (i = 0; i < include.length; i++)
            activities[include[i++]].include.push(include[i]);
        for (i = 0; i < exclude.length; i++)
            activities[exclude[i++]].exclude.push(exclude[i]);
        for (i = 0; i < response.length; i++)
            activities[response[i++]].response.push(response[i]);
        for (i = 0; i < condition.length; i++)
            activities[condition[i++]].condition.push(condition[i]);
        for (i = 0; i < milestone.length; i++)
            activities[milestone[i++]].milestone.push(milestone[i]);

    }

    function addToWhitelist(uint32 id, address actor){
        if(msg.sender != owner)
            throw;

        activities[id].whitelist.push(actor);
    }

    function failWith(uint32 id) private {
        Execution(msg.sender, id, false);
        throw;
    }

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

        if(a.whitelist.length > 0) {
            for (var i = 0; i < a.whitelist.length; i++)
                if(a.whitelist[i] == msg.sender)
                    break;

            if(i == a.whitelist.length)
                failWith(id);
        }

        if(!a.included)
            failWith(id);

        for (i = 0; i < a.condition.length; i++)
            if(!activities[a.condition[i]].executed && activities[a.condition[i]].included)
                failWith(id);

        for (i = 0; i < a.condition.length; i++)
            if(activities[a.milestone[i]].pending && activities[a.condition[i]].included)
                failWith(id);

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

        for (i = 0; i < a.exclude.length; i++)
            activities[a.exclude[i]].included = false;

        for (i = 0; i < a.response.length; i++)
            activities[a.response[i]].pending = true;

        // Effect on executing activity
        a.executed = true;
        a.pending = false;
        Execution(msg.sender, id, true);

    }

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

        selfdestruct(owner);
    }

}


rename variable in getAssessors for readability

pragma solidity ^0.4.0;

import "userRegistry.sol";
import "assessment.sol";
import "user.sol";
import "math.sol";
import "conceptRegistry.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 math = 0x90B66E80448eb60938FAed4A738dE0D5b630B2Fd;
  address mew;
  mapping (address => int) public currentScores; //The most recent score of a user
  mapping (address => uint) public assessmentSizes; //The most recent size of an assessment taken by 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
    }
    _;
  }

  modifier isAssessmentOrConcept()
  {
    if(!(assessmentExists[msg.sender] || ConceptRegistry(conceptRegistry).conceptExists(msg.sender)))
    {
      throw;
    }
    _;
  }

  /*
  @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 getAssessors(uint num, uint seed, address assessment) isAssessmentOrConcept()
  {
    uint numberOfAssessorsCalled = 0;
    for(uint i = 0; i < owners.length; i++)
    {
      address randomUser = owners[Math(math).getRandom(seed + i, owners.length-1)]; //gets a random owner of the concept
      if(User(randomUser).availability() && weights[randomUser] > now % maxWeight) //Checks if the randomly drawn is available and then puts it through a random check that it has a higher chance of passing if it has had a higher score and a larger assessment
      {
        if(Assessment(assessment).addAssessorToPool(randomUser))
        {
          numberOfAssessorsCalled++;
        }
      }
      if(numberOfAssessorsCalled > owners.length/10)
      {
        break;
      }
    }
    if(num > numberOfAssessorsCalled)
    {
      for(uint k = 0; k < parents.length; k++)
      {
        Concept(parents[k]).getAssessors((num - numberOfAssessorsCalled)/parents.length + 1, seed + now % k, assessment);
      }
    }
  }

  /*
  @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 && UserRegistry(userRegistry).getBalance(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, UserRegistry(userRegistry).getBalance(msg.sender) - cost*size);
      User(msg.sender).notification(address(this), 19); //You have been charged for your assessment
      return true;
    }
    else
    {
      return false;
    }
  }

  /*
  @type: function
  @purpose: To start the assessment process
  @param: address assessment = the address of the assessment
  @returns: nothing
  */
  function startAssessment(address assessment)
  {
    if(block.number - Assessment(assessment).startTime() <= 10) //Checks if this function is being called 4 to 6 blocks after the block in which the assessment was created
    {
      Assessment(assessment).setAssessorPool(block.number); //Calls the function to set the assessor pool
    }
    else
    {
      Assessment(assessment).cancelAssessment(); //If this function is called too early or too late the assessment is cancelled
    }
  }

  /*
  @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);
        User(assessee).setConceptPassed(true);
      }
      User(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
      assessmentSizes[assessee] = Assessment(assessment).size(); //Maps the assessee to the assessment size
      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] == true) //Checks if msg.sender is an existing assessment
    {
      UserRegistry(userRegistry).mapBalance(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 "userRegistry.sol";
import "assessment.sol";
import "user.sol";
import "math.sol";
import "conceptRegistry.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 math = 0x90B66E80448eb60938FAed4A738dE0D5b630B2Fd;
  address mew;
  mapping (address => int) public currentScores; //The most recent score of a user
  mapping (address => uint) public assessmentSizes; //The most recent size of an assessment taken by 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
    }
    _;
  }

  modifier isAssessmentOrConcept()
  {
    if(!(assessmentExists[msg.sender] || ConceptRegistry(conceptRegistry).conceptExists(msg.sender)))
    {
      throw;
    }
    _;
  }

  /*
  @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 getAssessors(uint num, uint seed, address assessment) isAssessmentOrConcept()
  {
    uint j = 0;
    for(uint i = 0; i < owners.length; i++)
    {
      address randomUser = owners[Math(math).getRandom(seed + i, owners.length-1)]; //gets a random owner of the concept
      if(User(randomUser).availability() && weights[randomUser] > now % maxWeight) //Checks if the randomly drawn is available and then puts it through a random check that it has a higher chance of passing if it has had a higher score and a larger assessment
      {
        if(Assessment(assessment).addAssessorToPool(randomUser))
        {
          j++;
        }
      }
      if(j > owners.length/10)
      {
        break;
      }
    }
    if(num > j)
    {
      for(uint k = 0; k < parents.length; k++)
      {
        Concept(parents[k]).getAssessors((num - j)/parents.length + 1, seed + now % k, assessment);
      }
    }
  }

  /*
  @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 && UserRegistry(userRegistry).getBalance(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, UserRegistry(userRegistry).getBalance(msg.sender) - cost*size);
      User(msg.sender).notification(address(this), 19); //You have been charged for your assessment
      return true;
    }
    else
    {
      return false;
    }
  }

  /*
  @type: function
  @purpose: To start the assessment process
  @param: address assessment = the address of the assessment
  @returns: nothing
  */
  function startAssessment(address assessment)
  {
    if(block.number - Assessment(assessment).startTime() <= 10) //Checks if this function is being called 4 to 6 blocks after the block in which the assessment was created
    {
      Assessment(assessment).setAssessorPool(block.number); //Calls the function to set the assessor pool
    }
    else
    {
      Assessment(assessment).cancelAssessment(); //If this function is called too early or too late the assessment is cancelled
    }
  }

  /*
  @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);
        User(assessee).setConceptPassed(true);
      }
      User(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
      assessmentSizes[assessee] = Assessment(assessment).size(); //Maps the assessee to the assessment size
      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] == true) //Checks if msg.sender is an existing assessment
    {
      UserRegistry(userRegistry).mapBalance(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);
  }
}