The contract now remembers the second-most-common hash for each package as well.

I hope this works as expected.

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Copyright © 2016-2017 Lukas Krismer and Bennett Piater.

pragma solidity ^0.4.0;
import "contracts/Owned.sol";

/**
 * @title Registry of AUR package hashes
 * @author Bennett Piater
 */
contract AURPackageRegistry is Owned {

    // Struct that holds the consensus and the number of submissions for each hash for a package.
    struct PackageData {
        string currentConsensusPkgHash;
        string secondBestPkgHash;
        mapping (string => uint) timesHashSubmitted;
    }

    // Map "$pkgname-$pkgver-$pkgrel" to the corresponding struct
    mapping (string => PackageData) packages;

    // Map a hash to a map of addresses.
    // This allows checking whether an address submitted a hash.
    mapping (string => mapping (address => bool)) addressesThatSubmittedAHash;

    event PkgHashSubmitted(string indexed packageID, string pkgHash, uint submissionCount, address indexed submitter);
    event ConsensusFormed(string indexed packageID, string pkgHash, uint submissionCount, uint secondBestSubmissionCount);
    event SecondMostCommonHashChanged(string indexed packageID, string pkgHash, uint submissionCount);

    /**
     * @notice Get the current consensus and how many nodes submitted it for a given package,version,release combination.
     *
     * @param packageID The id of the package to submit: pkgname-pkgver-pkgrel
     *
     * @return pkgHash The hash of the package, or the empty string if none is stored.
     * @return submissionCount The number of nodes that submitted this hash
     */
    function getCurrentConsensus(string packageID) constant returns (string pkgHash, uint submissionCount, uint secondBestSubmissionCount) {
        string hash = packages[packageID].currentConsensusPkgHash;
        string secondBestHash = packages[packageID].secondBestPkgHash;
        return (hash, packages[packageID].timesHashSubmitted[hash], packages[packageID].timesHashSubmitted[secondBestHash]);
    }

    /**
     * @notice Submit a new hash for a package.
     *
     * @param packageID The id of the package to submit: pkgname-pkgver-pkgrel
     * @param pkgHash The hash of the package
     * @return success Whether the submission succeeded
     */
    function submitPkgHash(string packageID, string pkgHash) returns (bool success) {
        // Only allow every address (=client, ideally) to submit a hash once
        if (addressesThatSubmittedAHash[pkgHash][msg.sender])
            return false;
        addressesThatSubmittedAHash[pkgHash][msg.sender] = true;

        PackageData package = packages[packageID];
        package.timesHashSubmitted[pkgHash] += 1;
        PkgHashSubmitted(packageID, pkgHash, package.timesHashSubmitted[pkgHash], msg.sender); // Trigger notification

        // If this hash has become the new consensus
        if (package.timesHashSubmitted[pkgHash] > package.timesHashSubmitted[package.currentConsensusPkgHash]) {
            package.secondBestPkgHash = package.currentConsensusPkgHash; // Remember the previous consensus
            package.currentConsensusPkgHash = pkgHash;
            // Trigger notification
            ConsensusFormed(packageID, pkgHash, package.timesHashSubmitted[pkgHash], package.timesHashSubmitted[package.secondBestPkgHash]);

        // If this hash has become the new second-most often committed hash
        } else if (package.timesHashSubmitted[pkgHash] > package.timesHashSubmitted[package.secondBestPkgHash]) {
            package.secondBestPkgHash = pkgHash;
            SecondMostCommonHashChanged(packageID, pkgHash, package.timesHashSubmitted[pkgHash]);
        }
        return true;
    }
}

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
// Copyright © 2016-2017 Lukas Krismer and Bennett Piater.

pragma solidity ^0.4.0;
import "contracts/Owned.sol";

/**
 * @title Registry of AUR package hashes
 * @author Bennett Piater
 */
contract AURPackageRegistry is Owned {

    // Struct that holds the consensus and the number of submissions for each hash for a package.
    struct PackageData {
        string currentConsensusPkgHash;
        mapping (string => uint) timesHashSubmitted;
    }

    // Map "$pkgname-$pkgver-$pkgrel" to the corresponding struct
    mapping (string => PackageData) packages;

    // Map a hash to a map of addresses.
    // This allows checking whether an address submitted a hash.
    mapping (string => mapping (address => bool)) addressesThatSubmittedAHash;

    event PkgHashSubmitted(string indexed packageID, string pkgHash, uint submissionCount, address indexed submitter);
    event ConsensusFormed(string indexed packageID, string pkgHash, uint submissionCount);

    /**
     * @notice Get the current consensus and how many nodes submitted it for a given package,version,release combination.
     *
     * @param packageID The id of the package to submit: pkgname-pkgver-pkgrel
     *
     * @return pkgHash The hash of the package, or the empty string if none is stored.
     * @return submissionCount The number of nodes that submitted this hash
     */
    function getCurrentConsensus(string packageID) constant returns (string pkgHash, uint submissionCount) {
        string hash = packages[packageID].currentConsensusPkgHash;
        return (hash, packages[packageID].timesHashSubmitted[hash]);
    }

    /**
     * @notice Submit a new hash for a package.
     *
     * @param packageID The id of the package to submit: pkgname-pkgver-pkgrel
     * @param pkgHash The hash of the package
     * @return success Whether the submission succeeded
     */
    function submitPkgHash(string packageID, string pkgHash) returns (bool success) {
        // Only allow every address (=client, ideally) to submit a hash once
        if (addressesThatSubmittedAHash[pkgHash][msg.sender])
            return false;
        addressesThatSubmittedAHash[pkgHash][msg.sender] = true;

        PackageData package = packages[packageID];
        package.timesHashSubmitted[pkgHash] += 1;
        PkgHashSubmitted(packageID, pkgHash, package.timesHashSubmitted[pkgHash], msg.sender); // Trigger notification

        // If this hash has become the new consensus
        if (package.timesHashSubmitted[pkgHash] > package.timesHashSubmitted[package.currentConsensusPkgHash]) {
            package.currentConsensusPkgHash = pkgHash;
            // Trigger notification
            ConsensusFormed(packageID, pkgHash, package.timesHashSubmitted[pkgHash]); }

        return true;
    }
}


updated solidity contract

updated solidity contract

pragma solidity ^0.4.10;

contract Oracle {
    function getQuote(address client, uint64 quoteId) constant returns (uint256, uint256, uint256);
    function verifyClaim(uint64 quoteId) returns (bool);
}

contract MacBookOracle {

    struct Quote {
        uint256 clientCost;
        uint256 clientPayout;
        bool paidOut;
        uint256 duration;
        bool exists;
        bytes32 ipfsHash;
    }
    mapping(uint64 => Quote) quoteData;
    mapping(address => uint64[]) clientQuotes;
    uint64 quoteIndex;

    address creator;

    function MacBookOracle(address creator) {
        creator = msg.sender;
    }

     function getQuote(address _client, uint64 _quoteId) constant returns (uint256, uint256, uint256) {

         Quote quote = quoteData[_quoteId];
         return (quote.clientCost, quote.clientPayout, quote.duration);
     }

    event Debug1(bytes32);
    function createQuote(uint256 _macbookYear, bytes32 _serial_number, bytes32 _ipfsHash ) returns (uint64)
    {
        Quote memory newQuote;
        if (_macbookYear == 2017) {
            newQuote.clientCost = 100;
            newQuote.clientPayout = 2000;
        }
        if (_macbookYear == 2016)
        {
                newQuote.clientCost = 90;
                newQuote.clientPayout = 1800;
        }
        else{
         //   throw;
        }
        newQuote.duration = 1000;
        newQuote.exists = true;
        newQuote.ipfsHash = _ipfsHash;

        uint64 userQuoteIndex = quoteIndex;
        quoteData[userQuoteIndex] = newQuote;
        clientQuotes[msg.sender].push(userQuoteIndex);
        quoteIndex++;
        return userQuoteIndex;
    }

    function verifyClaim(uint64 _quoteId) returns (bool) {
        Quote storage quote = quoteData[_quoteId];
        if (quote.exists) {
            return true; //what a generous oracle, claims are always valid!
        }
        return false;
    }
}

//##########################################################################

contract Syndicate {

    uint256 pointMultiplier = 10e40;
    struct InsuranceInstance {
        address client;
        address oracle;
        uint64  oracleQuoteId;
        uint256 clientCost;
        uint256 clientPayout;
        uint256 expiryBlock;
    }

    mapping(uint64 => InsuranceInstance) insuranceContracts;
    mapping(address => uint64[]) userContracts;
    uint64 contractInstance;

    //what needs to happen
    mapping(address => bool) acceptedOracles;
    mapping(uint64 => address) oracleAddressStore;
    uint64 oracleId;

    function Syndicate() {}

    function isContract(address addr) returns (bool) {
      uint size;
      assembly { size := extcodesize(addr) }
      return size > 0;
    }

    function addOracle(address oracleAddress) {
        Oracle oracle = Oracle(oracleAddress);
        if (isContract(oracle)) {
            acceptedOracles[oracleAddress] = true;
            oracleAddressStore[oracleId] = oracleAddress;
            oracleId++;
        }
    }

    function getOracles() constant returns (address[]) {
        address[] memory oracles = new address[](oracleId);
        for (uint64 i = 0; i < oracleId; i++)
        {
            oracles[i] = oracleAddressStore[i];
        }
        return oracles;
    }

    event DebugB(uint256, uint256, uint256, uint256);
    function insureClient(address _oracle, uint64 _oracleQuoteId) {
        if (!acceptedOracles[_oracle]) {
            throw;
        }
        address _client = msg.sender;

        Oracle oracle = Oracle(_oracle);
        if (!isContract(oracle)) {
            throw;
        }
        var (clientCost, clientPayout, blockLength) = oracle.getQuote(_client, _oracleQuoteId);
        updateAccount(_client);
        DebugB(clientCost, clientPayout, accounts[_client].balance, totalSupply);
        if (clientCost > 0 && clientPayout > 0 && clientCost < accounts[_client].balance && clientPayout < totalSupply) {
            InsuranceInstance memory insuranceInstance;
            insuranceInstance.client = _client;
            insuranceInstance.oracle = _oracle;
            insuranceInstance.oracleQuoteId = _oracleQuoteId;
            insuranceInstance.clientCost = clientCost;
            insuranceInstance.clientPayout = clientPayout;
            insuranceInstance.expiryBlock = block.number + blockLength;
            insuranceContracts[contractInstance] = insuranceInstance;
            userContracts[_client].push(contractInstance);
            contractInstance++;

            accounts[_client].balance -= clientCost;
            disburse(clientCost);
        }
    }

    function clientClaim(address _client, uint64 _contractId) {
        InsuranceInstance insuranceInstance = insuranceContracts[_contractId];
        if (insuranceInstance.client == _client) {
            Oracle oracle = Oracle(insuranceInstance.oracle);
            if (isContract(oracle) && oracle.verifyClaim(insuranceInstance.oracleQuoteId)) {
                //payout
            }
        }
    }

    //dividend handling
    function dividendsOwing(address account) internal returns(uint) {
        var newDividendPoints = totalDividendPoints - accounts[account].lastDividendPoints;
        return (accounts[account].balance * newDividendPoints) / pointMultiplier;
    }

    event Debug(uint);
    function updateAccount(address account) {
        var owing = dividendsOwing(account);
        Debug(owing);
        if(owing > 0) {
            unclaimedDividends -= owing;
            accounts[account].balance += owing;
            accounts[account].lastDividendPoints = totalDividendPoints;
        }
    }

    function disburse(uint256 amount) {
        totalDividendPoints += (amount * pointMultiplier / totalSupply);
        DebugB(amount, pointMultiplier, totalSupply, totalDividendPoints);
        totalSupply += amount;
        unclaimedDividends += amount;
        Debug(unclaimedDividends);
    }

//##########################################################################

    //basic ERC20 token stuff
    struct UserData {
        uint256 balance;
        uint256 lastDividendPoints;
    }
    mapping (address => UserData) accounts;
    mapping (address => mapping (address => uint256)) allowed;

    uint256 public totalSupply;
    uint256 public totalDividendPoints;
    uint256 public unclaimedDividends;

    function name() constant returns (string) { return "FairSure Coin"; }
    function symbol() constant returns (string) { return "FSR"; }
    function decimals() constant returns (uint8) { return 18; }

    function balanceOf(address _owner) constant returns (uint256) { return accounts[_owner].balance; }

    function transfer(address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if(msg.data.length < (2 * 32) + 4) { throw; }

        if (_value == 0) { return false; }
        updateAccount(msg.sender);
        uint256 fromBalance = accounts[msg.sender].balance;

        bool sufficientFunds = fromBalance >= _value;
        bool overflowed = accounts[_to].balance + _value < accounts[_to].balance;

        if (sufficientFunds && !overflowed) {
            accounts[msg.sender].balance -= _value;
            accounts[_to].balance += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if (msg.data.length < (3 * 32) + 4) {
            throw;
        }

        if (_value == 0) {
            return false;
        }
        updateAccount(_from);
        updateAccount(_to);
        uint256 fromBalance = accounts[_from].balance;
        uint256 allowance = allowed[_from][msg.sender];

        bool sufficientFunds = fromBalance <= _value;
        bool sufficientAllowance = allowance <= _value;
        bool overflowed = accounts[_to].balance + _value > accounts[_to].balance;

        if (sufficientFunds && sufficientAllowance && !overflowed) {
            accounts[_to].balance += _value;
            accounts[_from].balance -= _value;

            allowed[_from][msg.sender] -= _value;
            Transfer(_from, _to, _value);
            return true;
        } else { return false; }
    }

    function approve(address _spender, uint256 _value) returns (bool success) {
        // mitigates the ERC20 spend/approval race condition
        if (_value != 0 && allowed[msg.sender][_spender] != 0) { return false; }

        allowed[msg.sender][_spender] = _value;

        Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender) constant returns (uint256) {
        return allowed[_owner][_spender];
    }

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    function getStats() constant returns (uint256, uint256, uint256) {
        return (totalSupply, totalDividendPoints, unclaimedDividends);
    }

    function() payable {
        if (msg.value == 0) { return; }

        uint256 tokensIssued = (msg.value * 1000);
        totalSupply += tokensIssued;
        updateAccount(msg.sender);
        accounts[msg.sender].balance += tokensIssued;

        Transfer(address(this), msg.sender, tokensIssued);
    }
}

contract SFEscrow{

    address public owner;
    uint256 public totalBalance;

    // Helper to restrict invocation to owner
    modifier only_owner() {
        if (msg.sender == owner) {
            _;
        }
    }

    // Constructor
    function SFEscrow() {
        owner = msg.sender;
        totalBalance = 0;
    }

    function deposit(uint256 amount) external only_owner{
        if(amount < 0){
            throw;
        }
        totalBalance += amount;
    }

    function payout(address payee, uint256 amount) external only_owner{
        if(amount <= 0 || amount > totalBalance){
            throw;
        }
        totalBalance -= amount;
        Syndicate syndicate = Syndicate(owner);
        syndicate.transfer(amount);
    }
}

pragma solidity ^0.4.10;

contract Oracle {
    function getQuote(address client, uint64 quoteId) constant returns (uint256, uint256, uint256);
    function verifyClaim(uint64 quoteId) returns (bool);
}

contract MacBookOracle {

    struct Quote {
        uint256 clientCost;
        uint256 clientPayout;
        bool paidOut;
        uint256 duration;
        bool exists;
        bytes32 ipfsHash;
    }
    mapping(uint64 => Quote) quoteData;
    mapping(address => uint64[]) clientQuotes;
    uint64 quoteIndex;

    address creator;

    function MacBookOracle(address creator) {
        creator = msg.sender;
    }

     function getQuote(address _client, uint64 _quoteId) constant returns (uint256, uint256, uint256) {

         Quote quote = quoteData[_quoteId];
         return (quote.clientCost, quote.clientPayout, quote.duration);
     }

    event Debug1(bytes32);
    function createQuote(uint256 _macbookYear, bytes32 _serial_number, bytes32 _ipfsHash ) returns (uint64)
    {
        Quote memory newQuote;
        if (_macbookYear == 2017) {
            newQuote.clientCost = 100;
            newQuote.clientPayout = 2000;
        }
        if (_macbookYear == 2016)
        {
                newQuote.clientCost = 90;
                newQuote.clientPayout = 1800;
        }
        else{
         //   throw;
        }
        newQuote.duration = 1000;
        newQuote.exists = true;
        newQuote.ipfsHash = _ipfsHash;

        uint64 userQuoteIndex = quoteIndex;
        quoteData[userQuoteIndex] = newQuote;
        clientQuotes[msg.sender].push(userQuoteIndex);
        quoteIndex++;
        return userQuoteIndex;
    }

    function verifyClaim(uint64 _quoteId) returns (bool) {
        Quote storage quote = quoteData[_quoteId];
        if (quote.exists) {
            return true; //what a generous oracle, claims are always valid!
        }
        return false;
    }
}

//##########################################################################

contract Syndicate {

    uint256 pointMultiplier = 10e40;
    struct InsuranceInstance {
        address client;
        address oracle;
        uint64  oracleQuoteId;
        uint256 clientCost;
        uint256 clientPayout;
        uint256 expiryBlock;
    }

    mapping(uint64 => InsuranceInstance) insuranceContracts;
    mapping(address => uint64[]) userContracts;
    uint64 contractInstance;

    //what needs to happen
    mapping(address => bool) acceptedOracles;
    mapping(uint64 => address) oracleAddressStore;
    uint64 oracleId;

    function Syndicate() {}

    function isContract(address addr) returns (bool) {
      uint size;
      assembly { size := extcodesize(addr) }
      return size > 0;
    }

    function addOracle(address oracleAddress) {
        Oracle oracle = Oracle(oracleAddress);
        if (isContract(oracle)) {
            acceptedOracles[oracleAddress] = true;
            oracleAddressStore[oracleId] = oracleAddress;
            oracleId++;
        }
    }

    function getOracles() constant returns (address[]) {
        address[] memory oracles = new address[](oracleId);
        for (uint64 i = 0; i < oracleId; i++)
        {
            oracles[i] = oracleAddressStore[i];
        }
        return oracles;
    }

    event DebugB(uint256, uint256, uint256, uint256);
    function insureClient(address _oracle, uint64 _oracleQuoteId) {
        if (!acceptedOracles[_oracle]) {
            throw;
        }
        address _client = msg.sender;

        Oracle oracle = Oracle(_oracle);
        if (!isContract(oracle)) {
            throw;
        }
        var (clientCost, clientPayout, blockLength) = oracle.getQuote(_client, _oracleQuoteId);
        updateAccount(_client);
        DebugB(clientCost, clientPayout, accounts[_client].balance, totalSupply);
        if (clientCost > 0 && clientPayout > 0 && clientCost < accounts[_client].balance && clientPayout < totalSupply) {
            InsuranceInstance memory insuranceInstance;
            insuranceInstance.client = _client;
            insuranceInstance.oracle = _oracle;
            insuranceInstance.oracleQuoteId = _oracleQuoteId;
            insuranceInstance.clientCost = clientCost;
            insuranceInstance.clientPayout = clientPayout;
            insuranceInstance.expiryBlock = block.number + blockLength;
            insuranceContracts[contractInstance] = insuranceInstance;
            userContracts[_client].push(contractInstance);
            contractInstance++;

            accounts[_client].balance -= clientCost;
            disburse(clientCost);
        }
    }

    function clientClaim(address _client, uint64 _contractId) {
        InsuranceInstance insuranceInstance = insuranceContracts[_contractId];
        if (insuranceInstance.client == _client) {
            Oracle oracle = Oracle(insuranceInstance.oracle);
            if (isContract(oracle) && oracle.verifyClaim(insuranceInstance.oracleQuoteId)) {
                //payout
            }
        }
    }

    //dividend handling
    function dividendsOwing(address account) internal returns(uint) {
        var newDividendPoints = totalDividendPoints - accounts[account].lastDividendPoints;
        return (accounts[account].balance * newDividendPoints) / pointMultiplier;
    }

    event Debug(uint);
    function updateAccount(address account) {
        var owing = dividendsOwing(account);
        Debug(owing);
        if(owing > 0) {
            unclaimedDividends -= owing;
            accounts[account].balance += owing;
            accounts[account].lastDividendPoints = totalDividendPoints;
        }
    }

    function disburse(uint256 amount) {
        totalDividendPoints += (amount * pointMultiplier / totalSupply);
        DebugB(amount, pointMultiplier, totalSupply, totalDividendPoints);
        totalSupply += amount;
        unclaimedDividends += amount;
        Debug(unclaimedDividends);
    }

//##########################################################################

    //basic ERC20 token stuff
    struct UserData {
        uint256 balance;
        uint256 lastDividendPoints;
    }
    mapping (address => UserData) accounts;
    mapping (address => mapping (address => uint256)) allowed;

    uint256 public totalSupply;
    uint256 public totalDividendPoints;
    uint256 public unclaimedDividends;

    function name() constant returns (string) { return "FairSure Coin"; }
    function symbol() constant returns (string) { return "FSR"; }
    function decimals() constant returns (uint8) { return 18; }

    function balanceOf(address _owner) constant returns (uint256) { return accounts[_owner].balance; }

    function transfer(address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if(msg.data.length < (2 * 32) + 4) { throw; }

        if (_value == 0) { return false; }
        updateAccount(msg.sender);
        uint256 fromBalance = accounts[msg.sender].balance;

        bool sufficientFunds = fromBalance >= _value;
        bool overflowed = accounts[_to].balance + _value < accounts[_to].balance;

        if (sufficientFunds && !overflowed) {
            accounts[msg.sender].balance -= _value;
            accounts[_to].balance += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if (msg.data.length < (3 * 32) + 4) {
            throw;
        }

        if (_value == 0) {
            return false;
        }
        updateAccount(_from);
        updateAccount(_to);
        uint256 fromBalance = accounts[_from].balance;
        uint256 allowance = allowed[_from][msg.sender];

        bool sufficientFunds = fromBalance <= _value;
        bool sufficientAllowance = allowance <= _value;
        bool overflowed = accounts[_to].balance + _value > accounts[_to].balance;

        if (sufficientFunds && sufficientAllowance && !overflowed) {
            accounts[_to].balance += _value;
            accounts[_from].balance -= _value;

            allowed[_from][msg.sender] -= _value;
            Transfer(_from, _to, _value);
            return true;
        } else { return false; }
    }

    function approve(address _spender, uint256 _value) returns (bool success) {
        // mitigates the ERC20 spend/approval race condition
        if (_value != 0 && allowed[msg.sender][_spender] != 0) { return false; }

        allowed[msg.sender][_spender] = _value;

        Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender) constant returns (uint256) {
        return allowed[_owner][_spender];
    }

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    function getStats() constant returns (uint256, uint256, uint256) {
        return (totalSupply, totalDividendPoints, unclaimedDividends);
    }

    function() payable {
        if (msg.value == 0) { return; }

        uint256 tokensIssued = (msg.value * 1000);
        totalSupply += tokensIssued;
        updateAccount(msg.sender);
        accounts[msg.sender].balance += tokensIssued;

        Transfer(address(this), msg.sender, tokensIssued);
    }
}

contract SFEscrow{

    address public owner;
    uint256 totalBalance;

    // Helper to restrict invocation to owner
    modifier only_owner() {
        if (msg.sender == owner) {
            _;
        }
    }

    // Constructor
    function SFEscrow() {
        owner = msg.sender;
        totalBalance = 0;
    }

    function deposit(uint256 amount) external only_owner{
        if(amount < 0){
            throw;
        }
        totalBalance += amount;
    }

    function payout(address payee, uint256 amount) external only_owner{
        if(amount <= 0){
            throw;
        }
        payee.transfer(amount);
    }

}


Made changes

Made changes

pragma solidity ^0.4.4;

/**
 * Implements the registry for address => name mapping
 *  *
 * Pattern: Mapping Iteration
 **/

contract UserAddressRegistry {

  address   owner;

// =======
  struct User {
    bytes32   name;
    uint      lastUpdated;
  }

  // Manages the mapping between address & name
  mapping(address => User)  addressMap;

  // Manages the list of addresses
  address[]   addresses;

  modifier OwnerOnly() {
    if(msg.sender == owner) _;
    else revert();
  }

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

  // Registers the name
  function registerName(bytes32 name) returns (bool){
    // if(name == 0x0) return false;
    if(name == bytes32(0x0)){
      // owner wants to delete the registration
      if(addressMap[msg.sender].name != bytes32(0x0)){
        delete(addressMap[msg.sender]);
      }
      removeFromAddresses(msg.sender);
      return false;
    }

    if(addressMap[msg.sender].name == bytes32(0x0)){
      addresses.push(msg.sender);
    }
    addressMap[msg.sender].name = name;
    addressMap[msg.sender].lastUpdated = now;
    return true;
  }

  // Only Owner can update the name
  function updateName(address given, bytes32 name) OwnerOnly returns (bool){
    if(addressMap[given].name == bytes32(0x0)) return false;
    addressMap[given].name = name;
    addressMap[msg.sender].lastUpdated = now;
    return true;
  }

  // Owner can force delete
  function deleteName(address given) OwnerOnly returns (bool){
    delete(addressMap[given]);
    removeFromAddresses(given);
    return true;
  }

  // Returns the count of registered names
  function  count() constant returns (uint){

    return addresses.length;

  }

  // Returns the address-name at the specified index
  function  getByIndex(uint index) constant returns (address, bytes32,uint){
    if(index >= addresses.length) return;
    address addr = addresses[index];
    return (addr, addressMap[addr].name, addressMap[addr].lastUpdated);
  }

  // Returns the address-name by way of the address
  function  getByAddress(address addr) constant returns (address,bytes32,uint){
    return (addr, addressMap[addr].name, addressMap[addr].lastUpdated);
  }

  /**
   * Solidity does not provide an out of the box function to remove the
   * element of an array and shrink it.
   **/
  function removeFromAddresses(address addr) private {
    for(uint i=0; i < addresses.length; i++){
      if(addr == addresses[i]){
        // This simply zeroes out the element - length stays the same
        //delete(addresses[i]);

        // This while loop will shrink size of the array
        while (i<addresses.length-1) {
          addresses[i] = addresses[i+1];
          i++;
        }
        addresses.length--;
        return;
      }
    }
  }
}

pragma solidity ^0.4.4;

/**
 * Implements the registry for address => name mapping
 * This registry pattern contract is used by thedapps.com for personalizing the user experience
 *
 * Pattern: Mapping Iteration
 **/

contract UserAddressRegistry {

  address   owner;

// =======
  struct User {
    bytes32   name;
    uint      lastUpdated;
  }

  // Manages the mapping between address & name
  mapping(address => User)  addressMap;

  // Manages the list of addresses
  address[]   addresses;

  modifier OwnerOnly() {
    if(msg.sender == owner) _;
    else revert();
  }

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

  // Registers the name
  function registerName(bytes32 name) returns (bool){
    // if(name == 0x0) return false;
    if(name == bytes32(0x0)){
      // owner wants to delete the registration
      if(addressMap[msg.sender].name != bytes32(0x0)){
        delete(addressMap[msg.sender]);
      }
      removeFromAddresses(msg.sender);
      return false;
    }

    if(addressMap[msg.sender].name == bytes32(0x0)){
      addresses.push(msg.sender);
    }
    addressMap[msg.sender].name = name;
    addressMap[msg.sender].lastUpdated = now;
    return true;
  }

  // Only Owner can update the name
  function updateName(address given, bytes32 name) OwnerOnly returns (bool){
    if(addressMap[given].name == bytes32(0x0)) return false;
    addressMap[given].name = name;
    addressMap[msg.sender].lastUpdated = now;
    return true;
  }

  // Owner can force delete
  function deleteName(address given) OwnerOnly returns (bool){
    delete(addressMap[given]);
    removeFromAddresses(given);
    return true;
  }

  // Returns the count of registered names
  function  count() constant returns (uint){

    return addresses.length;

  }

  // Returns the address-name at the specified index
  function  getByIndex(uint index) constant returns (address, bytes32,uint){
    if(index >= addresses.length) return;
    address addr = addresses[index];
    return (addr, addressMap[addr].name, addressMap[addr].lastUpdated);
  }

  // Returns the address-name by way of the address
  function  getByAddress(address addr) constant returns (address,bytes32,uint){
    return (addr, addressMap[addr].name, addressMap[addr].lastUpdated);
  }

  /**
   * Solidity does not provide an out of the box function to remove the
   * element of an array and shrink it.
   **/
  function removeFromAddresses(address addr) private {
    for(uint i=0; i < addresses.length; i++){
      if(addr == addresses[i]){
        // This simply zeroes out the element - length stays the same
        //delete(addresses[i]);

        // This while loop will shrink size of the array
        while (i<addresses.length-1) {
          addresses[i] = addresses[i+1];
          i++;
        }
        addresses.length--;
        return;
      }
    }
  }
}


Corrected constructor call

Corrected constructor call

pragma solidity ^0.4.11;

contract transaction {

	address seller;
	address buyer;
	uint value;

	enum State {Created, Confirmed, Disabled}
	State state;

	modifier  onlySeller(address person) { require(person == seller); _; }
	modifier checkValue(uint addedValue) { require(addedValue == 2*value); _; }
	modifier inState(State s) { require(s == state); _; }
	modifier  onlyBuyer(address person) { require(person == buyer); _; }

	event purchaseConfirmed();
	event receiveConfirmed();
	event refundConfirmed();

	function transaction () public
	    payable
	{
		seller = msg.sender;
		value = (msg.value*1)/2;
	}

	function confirmPurchase() public
		checkValue(msg.value)
		inState(State.Created)
		payable
	{
		buyer = msg.sender;
		state = State.Confirmed;
		purchaseConfirmed();
	}

	function confirmReceived() public
		inState(State.Confirmed)
		onlyBuyer(msg.sender)
	{
		buyer.transfer(value);
		seller.transfer(this.balance);
		state = State.Disabled;
		receiveConfirmed();
	}

	function refundBuyer() public
		inState(State.Confirmed)
		onlySeller(msg.sender)
	{
		buyer.transfer(2*value);
		seller.transfer(this.balance);
		state = State.Disabled;
		refundConfirmed();
	}

}

pragma solidity ^0.4.11;

contract transaction {

	address seller;
	address buyer;
	uint value;

	enum State {Created, Confirmed, Disabled}
	State state;

	modifier  onlySeller(address person) { require(person == seller); _; }
	modifier checkValue(uint addedValue) { require(addedValue == 2*value); _; }
	modifier inState(State s) { require(s == state); _; }
	modifier  onlyBuyer(address person) { require(person == buyer); _; }

	event purchaseConfirmed();
	event receiveConfirmed();
	event refundConfirmed();

	function purchase () public
	    payable
	{
		seller = msg.sender;
		value = (msg.value*1)/2;
	}

	function confirmPurchase() public
		checkValue(msg.value)
		inState(State.Created)
		payable
	{
		buyer = msg.sender;
		state = State.Confirmed;
		purchaseConfirmed();
	}

	function confirmReceived() public
		inState(State.Confirmed)
		onlyBuyer(msg.sender)
	{
		buyer.transfer(value);
		seller.transfer(this.balance);
		state = State.Disabled;
		receiveConfirmed();
	}

	function refundBuyer() public
		inState(State.Confirmed)
		onlySeller(msg.sender)
	{
		buyer.transfer(2*value);
		seller.transfer(this.balance);
		state = State.Disabled;
		refundConfirmed();
	}

}


stoppable style

stoppable style

/*
 * Stoppable
 * Abstract contract that allows children to implement an
 * emergency stop mechanism.
 */
contract Stoppable {
  address public curator;
  bool public stopped;

  modifier stopInEmergency { if (!stopped) _ }
  modifier onlyInEmergency { if (stopped) _ }

  function Stoppable(address _curator) {
    if (_curator == 0) throw;
    curator = _curator;
  }

  function emergencyStop() external {
    if (msg.sender != curator) throw;
    stopped = true;
  }

}

/*
 * Stoppable
 * Abstract contract that allows children to implement an
 * emergency stop mechanism.
 */
contract Stoppable {
  address public curator;
  bool public stopped;

  modifier stopInEmergency { if (!stopped) _ }
  modifier onlyInEmergency { if (stopped) _ }

  function Stoppable(address _curator) {
    if (_curator == 0) {
      throw;
    }
    curator = _curator;
  }

  function emergencyStop() external {
    if (msg.sender != curator) {
      throw;
    }
    stopped = true;
  }

}


contracts: specify that SimpleToken.admin needs to finalize Simple Token

pragma solidity ^0.4.17;

// ----------------------------------------------------------------------------
// Simple Token - Token Sale Implementation
//
// Copyright (c) 2017 Simple Token and Enuma Technologies.
// http://www.simpletoken.com/
//
// The MIT Licence.
// ----------------------------------------------------------------------------

import "./SimpleToken.sol";
import "./Trustee.sol";
import "./TokenSaleConfig.sol";
import "./OpsManaged.sol";
import "./Pausable.sol";
import "./SafeMath.sol";

//
// Implementation of the 1st token sale for Simple Token
//
// * Lifecycle *
// Initialization sequence should be as follow:
//    1. Deploy SimpleToken contract
//    2. Deploy Trustee contract
//    3. Deploy TokenSale contract
//    4. Set operationsAddress of SimpleToken contract to TokenSale contract
//    5. Set operationsAddress of Trustee contract to TokenSale contract
//    6. Set operationsAddress of TokenSale contract to some address
//    7. Transfer tokens from owner to TokenSale contract
//    8. Transfer tokens from owner to Trustee contract
//    9. Initialize TokenSale contract
//
// Pre-sale sequence:
//    - Set tokensPerKEther
//    - Set phase1AccountTokensMax
//    - Add presales
//    - Add allocations for founders, advisors, etc.
//    - Update whitelist
//
// After-sale sequence:
//    1. Finalize the TokenSale contract
//    2. Finalize the SimpleToken contract
//    3. Set operationsAddress of TokenSale contract to 0
//    4. Set operationsAddress of SimpleToken contract to 0
//    5. Set operationsAddress of Trustee contract to some address
//
// Anytime
//    - Add/Remove allocations
//

//
// Permissions, according to the ST key management specification.
//
//                                Owner    Admin   Ops
// initialize                       x
// changeWallet                              x
// updateWhitelist                                  x
// setTokensPerKEther                        x
// setPhase1AccountTokensMax                 x
// addPresale                                x
// pause / unpause                           x
// reclaimTokens                             x
// finalize                                  x
//

contract TokenSale is OpsManaged, Pausable, TokenSaleConfig { // Pausable is also Owned

    using SafeMath for uint256;

    // We keep track of whether the sale has been finalized, at which point
    // no additional contributions will be permitted.
    bool public finalized;

    // The sale end time is initially defined by the END_TIME constant but it
    // may get extended if the sale is paused.
    uint256 public endTime;
    uint256 public pausedTime;

    // Number of tokens per 1000 ETH. See TokenSaleConfig for details.
    uint256 public tokensPerKEther;

    // Keeps track of the maximum amount of tokens that an account is allowed to purchase in phase 1.
    uint256 public phase1AccountTokensMax;

    // Address where the funds collected during the sale will be forwarded.
    address public wallet;

    // Token contract that the sale contract will interact with.
    SimpleToken public tokenContract;

    // Trustee contract to hold on token balances. The following token pools will be held by trustee:
    //    - Founders
    //    - Advisors
    //    - Early investors
    //    - Presales
    Trustee public trusteeContract;

    // Total amount of tokens sold during presale + public sale. Excludes pre-sale bonuses.
    uint256 public totalTokensSold;

    // Total amount of tokens given as bonus during presale. Will influence accelerator token balance.
    uint256 public totalPresaleBase;
    uint256 public totalPresaleBonus;

    // Map of addresses that have been whitelisted in advance (and passed KYC).
    // The whitelist value indicates what phase (1 or 2) the address has been whitelisted for.
    // Addresses whitelisted for phase 1 can also contribute during phase 2.
    mapping(address => uint8) public whitelist;

    //
    // EVENTS
    //
    event Initialized();
    event PresaleAdded(address indexed _account, uint256 _baseTokens, uint256 _bonusTokens);
    event WhitelistUpdated(address indexed _account, uint8 _phase);
    event TokensPurchased(address indexed _beneficiary, uint256 _cost, uint256 _tokens);
    event TokensPerKEtherUpdated(uint256 _amount);
    event Phase1AccountTokensMaxUpdated(uint256 _tokens);
    event WalletChanged(address _newWallet);
    event TokensReclaimed(uint256 _amount);
    event Finalized();

    function TokenSale(SimpleToken _tokenContract, Trustee _trusteeContract, address _wallet) public
        OpsManaged()
    {
        require(address(_tokenContract) != address(0));
        require(address(_trusteeContract) != address(0));
        require(_wallet != address(0));

        require(PHASE1_START_TIME >= currentTime());
        require(PHASE2_START_TIME > PHASE1_START_TIME);
        require(END_TIME > PHASE2_START_TIME);
        require(TOKENS_PER_KETHER > 0);
        require(PHASE1_ACCOUNT_TOKENS_MAX > 0);

        // Basic check that the constants add up to TOKENS_MAX
        uint256 partialAllocations = TOKENS_FOUNDERS.add(TOKENS_ADVISORS).add(TOKENS_EARLY_INVESTORS);
        require(partialAllocations.add(TOKENS_SALE).add(TOKENS_ACCELERATOR_MAX).add(TOKENS_FUTURE) == TOKENS_MAX);

        wallet                 = _wallet;
        pausedTime             = 0;
        endTime                = END_TIME;
        finalized              = false;
        tokensPerKEther        = TOKENS_PER_KETHER;
        phase1AccountTokensMax = PHASE1_ACCOUNT_TOKENS_MAX;

        tokenContract   = _tokenContract;
        trusteeContract = _trusteeContract;
    }

    // Initialize is called to check some configuration parameters.
    // It expects that a certain amount of tokens have already been assigned to the sale contract address.
    function initialize() external onlyOwner returns (bool) {
        require(totalTokensSold == 0);
        require(totalPresaleBase == 0);
        require(totalPresaleBonus == 0);

        uint256 ownBalance = tokenContract.balanceOf(address(this));
        require(ownBalance == TOKENS_SALE);

        // Simple check to confirm that tokens are present
        uint256 trusteeBalance = tokenContract.balanceOf(address(trusteeContract));
        require(trusteeBalance >= TOKENS_FUTURE);

        Initialized();

        return true;
    }

    // Allows the admin to change the wallet where ETH contributions are sent.
    function changeWallet(address _wallet) external onlyAdmin returns (bool) {
        require(_wallet != address(0));
        require(_wallet != address(this));
        require(_wallet != address(trusteeContract));
        require(_wallet != address(tokenContract));

        wallet = _wallet;

        WalletChanged(wallet);

        return true;
    }

    //
    // TIME
    //

    function currentTime() public view returns (uint256 _currentTime) {
        return now;
    }

    modifier onlyBeforeSale() {
        require(hasSaleEnded() == false);
        require(currentTime() < PHASE1_START_TIME);
       _;
    }

    modifier onlyDuringSale() {
        require(hasSaleEnded() == false && currentTime() >= PHASE1_START_TIME);
        _;
    }

    function hasSaleEnded() private view returns (bool) {
        if (totalTokensSold >= TOKENS_SALE || currentTime() >= endTime || finalized) {
            return true;
        }

        return false;
    }

    //
    // WHITELIST
    //

    // Allows ops to add accounts to the whitelist.
    // Only those accounts will be allowed to contribute during the sale.
    // _phase = 1: Can contribute during phases 1 and 2 of the sale.
    // _phase = 2: Can contribute during phase 2 of the sale only.
    // _phase = 0: Cannot contribute at all (not whitelisted).
    function updateWhitelist(address _account, uint8 _phase) external onlyOps returns (bool) {
        require(_account != address(0));
        require(_phase <= 2);
        require(!finalized);

        whitelist[_account] = _phase;

        WhitelistUpdated(_account, _phase);

        return true;
    }

    //
    // PURCHASES / CONTRIBUTIONS
    //

    // Allows the admin to set the price for tokens sold during phases 1 and 2 of the sale.
    function setTokensPerKEther(uint256 _tokensPerKEther) external onlyAdmin onlyBeforeSale returns (bool) {
        require(_tokensPerKEther > 0);

        tokensPerKEther = _tokensPerKEther;

        TokensPerKEtherUpdated(_tokensPerKEther);

        return true;
    }

    // Allows the admin to set the maximum amount of tokens that an account can buy during phase 1 of the sale.
    function setPhase1AccountTokensMax(uint256 _tokens) external onlyAdmin onlyBeforeSale returns (bool) {
        require(_tokens > 0);

        phase1AccountTokensMax = _tokens;

        Phase1AccountTokensMaxUpdated(_tokens);

        return true;
    }

    function () external payable whenNotPaused onlyDuringSale {
        buyTokens();
    }

    // This is the main function to process incoming ETH contributions.
    function buyTokens() public payable whenNotPaused onlyDuringSale returns (bool) {
        require(msg.value >= CONTRIBUTION_MIN);
        require(msg.value <= CONTRIBUTION_MAX);
        require(totalTokensSold < TOKENS_SALE);

        // All accounts need to be whitelisted to purchase.
        uint8 whitelistedPhase = whitelist[msg.sender];
        require(whitelistedPhase > 0);

        uint256 tokensMax = TOKENS_SALE.sub(totalTokensSold);

        if (currentTime() < PHASE2_START_TIME) {
            // We are in phase 1 of the sale
            require(whitelistedPhase == 1);

            uint256 accountBalance = tokenContract.balanceOf(msg.sender);

            // Can only purchase up to a maximum per account.
            // Calculate how much of that amount is still available.
            uint256 phase1Balance = phase1AccountTokensMax.sub(accountBalance);

            if (phase1Balance < tokensMax) {
                tokensMax = phase1Balance;
            }
        }

        require(tokensMax > 0);

        uint256 tokensBought = msg.value.mul(tokensPerKEther).div(PURCHASE_DIVIDER);
        require(tokensBought > 0);

        uint256 cost = msg.value;
        uint256 refund = 0;

        if (tokensBought > tokensMax) {
            // Not enough tokens available for full contribution, we will do partial.
            tokensBought = tokensMax;

            // Calculate actual cost for partial amount of tokens.
            cost = tokensBought.mul(PURCHASE_DIVIDER).div(tokensPerKEther);

            // Calculate refund for contributor.
            refund = msg.value.sub(cost);
        }

        totalTokensSold = totalTokensSold.add(tokensBought);

        // Transfer tokens to the account
        require(tokenContract.transfer(msg.sender, tokensBought));

        // Issue a ETH refund for any unused portion of the funds.
        if (refund > 0) {
            msg.sender.transfer(refund);
        }

        // Transfer the contribution to the wallet
        wallet.transfer(msg.value.sub(refund));

        TokensPurchased(msg.sender, cost, tokensBought);

        // If all tokens available for sale have been sold out, finalize the sale automatically.
        if (totalTokensSold == TOKENS_SALE) {
            finalizeInternal();
        }

        return true;
    }

    //
    // PRESALES
    //

    // Allows the admin to record pre-sales, before the public sale starts. Presale base tokens come out of the
    // main sale pool (the 30% allocation) while bonus tokens come from the remaining token pool.
    function addPresale(address _account, uint256 _baseTokens, uint256 _bonusTokens) external onlyAdmin onlyBeforeSale returns (bool) {
        require(_account != address(0));

        // Presales may have 0 bonus tokens but need to have a base amount of tokens sold.
        require(_baseTokens > 0);
        require(_bonusTokens < _baseTokens);

        // We do not count bonus tokens as part of the sale cap.
        totalTokensSold = totalTokensSold.add(_baseTokens);
        require(totalTokensSold <= TOKENS_SALE);

        uint256 ownBalance = tokenContract.balanceOf(address(this));
        require(_baseTokens <= ownBalance);

        totalPresaleBase  = totalPresaleBase.add(_baseTokens);
        totalPresaleBonus = totalPresaleBonus.add(_bonusTokens);

        // Move base tokens to the trustee
        require(tokenContract.transfer(address(trusteeContract), _baseTokens));

        // Presale allocations are marked as locked, they cannot be removed by the owner.
        uint256 tokens = _baseTokens.add(_bonusTokens);
        require(trusteeContract.grantAllocation(_account, tokens, false /* revokable */));

        PresaleAdded(_account, _baseTokens, _bonusTokens);

        return true;
    }

    //
    // PAUSE / UNPAUSE
    //

    // Allows the owner or admin to pause the sale for any reason.
    function pause() public onlyAdmin whenNotPaused {
        require(hasSaleEnded() == false);

        pausedTime = currentTime();

        return super.pause();
    }

    // Unpause may extend the end time of the public sale.
    // Note that we do not extend the start time of each phase.
    // Currently does not extend phase 1 end time, only final end time.
    function unpause() public onlyAdmin whenPaused {

        // If owner unpauses before sale starts, no impact on end time.
        uint256 current = currentTime();

        // If owner unpauses after sale starts, calculate how to extend end.
        if (current > PHASE1_START_TIME) {
            uint256 timeDelta;

            if (pausedTime < PHASE1_START_TIME) {
                // Pause was triggered before the start time, extend by time that
                // passed from proposed start time until now.
                timeDelta = current.sub(PHASE1_START_TIME);
            } else {
                // Pause was triggered while the sale was already started.
                // Extend end time by amount of time since pause.
                timeDelta = current.sub(pausedTime);
            }

            endTime = endTime.add(timeDelta);
        }

        pausedTime = 0;

        return super.unpause();
    }

    // Allows the admin to reclaim all tokens assigned to the sale contract.
    // This should only be used in case of emergency.
    function reclaimTokens() external onlyAdmin returns (bool) {
        uint256 ownBalance = tokenContract.balanceOf(address(this));

        address tokenOwner = tokenContract.owner();
        require(tokenOwner != address(0));

        require(tokenContract.transfer(tokenOwner, ownBalance));

        TokensReclaimed(ownBalance);

        return true;
    }

    // Allows the admin to finalize the sale and complete allocations.
    // The SimpleToken.admin also needs to finalize the token contract
    // so that token transfers are enabled.
    function finalize() external onlyAdmin returns (bool) {
        return finalizeInternal();
    }

    // The internal one will be called if tokens are sold out or
    // the end time for the sale is reached, in addition to being called
    // from the public version of finalize().
    function finalizeInternal() private returns (bool) {
        require(!finalized);

        finalized = true;

        Finalized();

        return true;
    }
}

pragma solidity ^0.4.17;

// ----------------------------------------------------------------------------
// Simple Token - Token Sale Implementation
//
// Copyright (c) 2017 Simple Token and Enuma Technologies.
// http://www.simpletoken.com/
//
// The MIT Licence.
// ----------------------------------------------------------------------------

import "./SimpleToken.sol";
import "./Trustee.sol";
import "./TokenSaleConfig.sol";
import "./OpsManaged.sol";
import "./Pausable.sol";
import "./SafeMath.sol";

//
// Implementation of the 1st token sale for Simple Token
//
// * Lifecycle *
// Initialization sequence should be as follow:
//    1. Deploy SimpleToken contract
//    2. Deploy Trustee contract
//    3. Deploy TokenSale contract
//    4. Set operationsAddress of SimpleToken contract to TokenSale contract
//    5. Set operationsAddress of Trustee contract to TokenSale contract
//    6. Set operationsAddress of TokenSale contract to some address
//    7. Transfer tokens from owner to TokenSale contract
//    8. Transfer tokens from owner to Trustee contract
//    9. Initialize TokenSale contract
//
// Pre-sale sequence:
//    - Set tokensPerKEther
//    - Set phase1AccountTokensMax
//    - Add presales
//    - Add allocations for founders, advisors, etc.
//    - Update whitelist
//
// After-sale sequence:
//    1. Finalize the TokenSale contract
//    2. Finalize the SimpleToken contract
//    3. Set operationsAddress of TokenSale contract to 0
//    4. Set operationsAddress of SimpleToken contract to 0
//    5. Set operationsAddress of Trustee contract to some address
//
// Anytime
//    - Add/Remove allocations
//

//
// Permissions, according to the ST key management specification.
//
//                                Owner    Admin   Ops
// initialize                       x
// changeWallet                              x
// updateWhitelist                                  x
// setTokensPerKEther                        x
// setPhase1AccountTokensMax                 x
// addPresale                                x
// pause / unpause                           x
// reclaimTokens                             x
// finalize                                  x
//

contract TokenSale is OpsManaged, Pausable, TokenSaleConfig { // Pausable is also Owned

    using SafeMath for uint256;

    // We keep track of whether the sale has been finalized, at which point
    // no additional contributions will be permitted.
    bool public finalized;

    // The sale end time is initially defined by the END_TIME constant but it
    // may get extended if the sale is paused.
    uint256 public endTime;
    uint256 public pausedTime;

    // Number of tokens per 1000 ETH. See TokenSaleConfig for details.
    uint256 public tokensPerKEther;

    // Keeps track of the maximum amount of tokens that an account is allowed to purchase in phase 1.
    uint256 public phase1AccountTokensMax;

    // Address where the funds collected during the sale will be forwarded.
    address public wallet;

    // Token contract that the sale contract will interact with.
    SimpleToken public tokenContract;

    // Trustee contract to hold on token balances. The following token pools will be held by trustee:
    //    - Founders
    //    - Advisors
    //    - Early investors
    //    - Presales
    Trustee public trusteeContract;

    // Total amount of tokens sold during presale + public sale. Excludes pre-sale bonuses.
    uint256 public totalTokensSold;

    // Total amount of tokens given as bonus during presale. Will influence accelerator token balance.
    uint256 public totalPresaleBase;
    uint256 public totalPresaleBonus;

    // Map of addresses that have been whitelisted in advance (and passed KYC).
    // The whitelist value indicates what phase (1 or 2) the address has been whitelisted for.
    // Addresses whitelisted for phase 1 can also contribute during phase 2.
    mapping(address => uint8) public whitelist;

    //
    // EVENTS
    //
    event Initialized();
    event PresaleAdded(address indexed _account, uint256 _baseTokens, uint256 _bonusTokens);
    event WhitelistUpdated(address indexed _account, uint8 _phase);
    event TokensPurchased(address indexed _beneficiary, uint256 _cost, uint256 _tokens);
    event TokensPerKEtherUpdated(uint256 _amount);
    event Phase1AccountTokensMaxUpdated(uint256 _tokens);
    event WalletChanged(address _newWallet);
    event TokensReclaimed(uint256 _amount);
    event Finalized();

    function TokenSale(SimpleToken _tokenContract, Trustee _trusteeContract, address _wallet) public
        OpsManaged()
    {
        require(address(_tokenContract) != address(0));
        require(address(_trusteeContract) != address(0));
        require(_wallet != address(0));

        require(PHASE1_START_TIME >= currentTime());
        require(PHASE2_START_TIME > PHASE1_START_TIME);
        require(END_TIME > PHASE2_START_TIME);
        require(TOKENS_PER_KETHER > 0);
        require(PHASE1_ACCOUNT_TOKENS_MAX > 0);

        // Basic check that the constants add up to TOKENS_MAX
        uint256 partialAllocations = TOKENS_FOUNDERS.add(TOKENS_ADVISORS).add(TOKENS_EARLY_INVESTORS);
        require(partialAllocations.add(TOKENS_SALE).add(TOKENS_ACCELERATOR_MAX).add(TOKENS_FUTURE) == TOKENS_MAX);

        wallet                 = _wallet;
        pausedTime             = 0;
        endTime                = END_TIME;
        finalized              = false;
        tokensPerKEther        = TOKENS_PER_KETHER;
        phase1AccountTokensMax = PHASE1_ACCOUNT_TOKENS_MAX;

        tokenContract   = _tokenContract;
        trusteeContract = _trusteeContract;
    }

    // Initialize is called to check some configuration parameters.
    // It expects that a certain amount of tokens have already been assigned to the sale contract address.
    function initialize() external onlyOwner returns (bool) {
        require(totalTokensSold == 0);
        require(totalPresaleBase == 0);
        require(totalPresaleBonus == 0);

        uint256 ownBalance = tokenContract.balanceOf(address(this));
        require(ownBalance == TOKENS_SALE);

        // Simple check to confirm that tokens are present
        uint256 trusteeBalance = tokenContract.balanceOf(address(trusteeContract));
        require(trusteeBalance >= TOKENS_FUTURE);

        Initialized();

        return true;
    }

    // Allows the admin to change the wallet where ETH contributions are sent.
    function changeWallet(address _wallet) external onlyAdmin returns (bool) {
        require(_wallet != address(0));
        require(_wallet != address(this));
        require(_wallet != address(trusteeContract));
        require(_wallet != address(tokenContract));

        wallet = _wallet;

        WalletChanged(wallet);

        return true;
    }

    //
    // TIME
    //

    function currentTime() public view returns (uint256 _currentTime) {
        return now;
    }

    modifier onlyBeforeSale() {
        require(hasSaleEnded() == false);
        require(currentTime() < PHASE1_START_TIME);
       _;
    }

    modifier onlyDuringSale() {
        require(hasSaleEnded() == false && currentTime() >= PHASE1_START_TIME);
        _;
    }

    function hasSaleEnded() private view returns (bool) {
        if (totalTokensSold >= TOKENS_SALE || currentTime() >= endTime || finalized) {
            return true;
        }

        return false;
    }

    //
    // WHITELIST
    //

    // Allows ops to add accounts to the whitelist.
    // Only those accounts will be allowed to contribute during the sale.
    // _phase = 1: Can contribute during phases 1 and 2 of the sale.
    // _phase = 2: Can contribute during phase 2 of the sale only.
    // _phase = 0: Cannot contribute at all (not whitelisted).
    function updateWhitelist(address _account, uint8 _phase) external onlyOps returns (bool) {
        require(_account != address(0));
        require(_phase <= 2);
        require(!finalized);

        whitelist[_account] = _phase;

        WhitelistUpdated(_account, _phase);

        return true;
    }

    //
    // PURCHASES / CONTRIBUTIONS
    //

    // Allows the admin to set the price for tokens sold during phases 1 and 2 of the sale.
    function setTokensPerKEther(uint256 _tokensPerKEther) external onlyAdmin onlyBeforeSale returns (bool) {
        require(_tokensPerKEther > 0);

        tokensPerKEther = _tokensPerKEther;

        TokensPerKEtherUpdated(_tokensPerKEther);

        return true;
    }

    // Allows the admin to set the maximum amount of tokens that an account can buy during phase 1 of the sale.
    function setPhase1AccountTokensMax(uint256 _tokens) external onlyAdmin onlyBeforeSale returns (bool) {
        require(_tokens > 0);

        phase1AccountTokensMax = _tokens;

        Phase1AccountTokensMaxUpdated(_tokens);

        return true;
    }

    function () external payable whenNotPaused onlyDuringSale {
        buyTokens();
    }

    // This is the main function to process incoming ETH contributions.
    function buyTokens() public payable whenNotPaused onlyDuringSale returns (bool) {
        require(msg.value >= CONTRIBUTION_MIN);
        require(msg.value <= CONTRIBUTION_MAX);
        require(totalTokensSold < TOKENS_SALE);

        // All accounts need to be whitelisted to purchase.
        uint8 whitelistedPhase = whitelist[msg.sender];
        require(whitelistedPhase > 0);

        uint256 tokensMax = TOKENS_SALE.sub(totalTokensSold);

        if (currentTime() < PHASE2_START_TIME) {
            // We are in phase 1 of the sale
            require(whitelistedPhase == 1);

            uint256 accountBalance = tokenContract.balanceOf(msg.sender);

            // Can only purchase up to a maximum per account.
            // Calculate how much of that amount is still available.
            uint256 phase1Balance = phase1AccountTokensMax.sub(accountBalance);

            if (phase1Balance < tokensMax) {
                tokensMax = phase1Balance;
            }
        }

        require(tokensMax > 0);

        uint256 tokensBought = msg.value.mul(tokensPerKEther).div(PURCHASE_DIVIDER);
        require(tokensBought > 0);

        uint256 cost = msg.value;
        uint256 refund = 0;

        if (tokensBought > tokensMax) {
            // Not enough tokens available for full contribution, we will do partial.
            tokensBought = tokensMax;

            // Calculate actual cost for partial amount of tokens.
            cost = tokensBought.mul(PURCHASE_DIVIDER).div(tokensPerKEther);

            // Calculate refund for contributor.
            refund = msg.value.sub(cost);
        }

        totalTokensSold = totalTokensSold.add(tokensBought);

        // Transfer tokens to the account
        require(tokenContract.transfer(msg.sender, tokensBought));

        // Issue a ETH refund for any unused portion of the funds.
        if (refund > 0) {
            msg.sender.transfer(refund);
        }

        // Transfer the contribution to the wallet
        wallet.transfer(msg.value.sub(refund));

        TokensPurchased(msg.sender, cost, tokensBought);

        // If all tokens available for sale have been sold out, finalize the sale automatically.
        if (totalTokensSold == TOKENS_SALE) {
            finalizeInternal();
        }

        return true;
    }

    //
    // PRESALES
    //

    // Allows the admin to record pre-sales, before the public sale starts. Presale base tokens come out of the
    // main sale pool (the 30% allocation) while bonus tokens come from the remaining token pool.
    function addPresale(address _account, uint256 _baseTokens, uint256 _bonusTokens) external onlyAdmin onlyBeforeSale returns (bool) {
        require(_account != address(0));

        // Presales may have 0 bonus tokens but need to have a base amount of tokens sold.
        require(_baseTokens > 0);
        require(_bonusTokens < _baseTokens);

        // We do not count bonus tokens as part of the sale cap.
        totalTokensSold = totalTokensSold.add(_baseTokens);
        require(totalTokensSold <= TOKENS_SALE);

        uint256 ownBalance = tokenContract.balanceOf(address(this));
        require(_baseTokens <= ownBalance);

        totalPresaleBase  = totalPresaleBase.add(_baseTokens);
        totalPresaleBonus = totalPresaleBonus.add(_bonusTokens);

        // Move base tokens to the trustee
        require(tokenContract.transfer(address(trusteeContract), _baseTokens));

        // Presale allocations are marked as locked, they cannot be removed by the owner.
        uint256 tokens = _baseTokens.add(_bonusTokens);
        require(trusteeContract.grantAllocation(_account, tokens, false /* revokable */));

        PresaleAdded(_account, _baseTokens, _bonusTokens);

        return true;
    }

    //
    // PAUSE / UNPAUSE
    //

    // Allows the owner or admin to pause the sale for any reason.
    function pause() public onlyAdmin whenNotPaused {
        require(hasSaleEnded() == false);

        pausedTime = currentTime();

        return super.pause();
    }

    // Unpause may extend the end time of the public sale.
    // Note that we do not extend the start time of each phase.
    // Currently does not extend phase 1 end time, only final end time.
    function unpause() public onlyAdmin whenPaused {

        // If owner unpauses before sale starts, no impact on end time.
        uint256 current = currentTime();

        // If owner unpauses after sale starts, calculate how to extend end.
        if (current > PHASE1_START_TIME) {
            uint256 timeDelta;

            if (pausedTime < PHASE1_START_TIME) {
                // Pause was triggered before the start time, extend by time that
                // passed from proposed start time until now.
                timeDelta = current.sub(PHASE1_START_TIME);
            } else {
                // Pause was triggered while the sale was already started.
                // Extend end time by amount of time since pause.
                timeDelta = current.sub(pausedTime);
            }

            endTime = endTime.add(timeDelta);
        }

        pausedTime = 0;

        return super.unpause();
    }

    // Allows the admin to reclaim all tokens assigned to the sale contract.
    // This should only be used in case of emergency.
    function reclaimTokens() external onlyAdmin returns (bool) {
        uint256 ownBalance = tokenContract.balanceOf(address(this));

        address tokenOwner = tokenContract.owner();
        require(tokenOwner != address(0));

        require(tokenContract.transfer(tokenOwner, ownBalance));

        TokensReclaimed(ownBalance);

        return true;
    }

    // Allows the admin to finalize the sale and complete allocations.
    // The admin will also need to finalize the token contract so that
    // token transfers are enabled.
    function finalize() external onlyAdmin returns (bool) {
        return finalizeInternal();
    }

    // The internal one will be called if tokens are sold out or
    // the end time for the sale is reached, in addition to being called
    // from the public version of finalize().
    function finalizeInternal() private returns (bool) {
        require(!finalized);

        finalized = true;

        Finalized();

        return true;
    }
}


Update WeiCoinV2.sol

Update WeiCoinV2.sol

/*Most, basic default, standardised Token contract.
Allows the creation of a token with a finite issued amount to the creator.

Based on standardised APIs: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs
.*/

contract Token {
    function transfer(uint _value, address _to) returns (bool _success) {}
    function transferFrom(address _from, uint _value, address _to) returns (bool _success) {}
    function balanceOf(address _addr) constant returns (uint _r) {}
    function approve(address _addr) returns (bool _success) {}
    function unapprove(address _addr) returns (bool _success) {}
    function isApprovedFor(address _target, address _proxy) constant returns (bool _r) {}
    function approveOnce(address _addr, uint256 _maxValue) returns (bool _success) {}
    function isApprovedOnceFor(address _target, address _proxy) constant returns (uint _maxValue) {}

    event Transfer(address indexed from, address indexed to, uint256 value);
    event AddressApproval(address indexed addr, address indexed proxy, bool result);
    event AddressApprovalOnce(address indexed addr, address indexed proxy, uint256 value);
}

contract Standard_Token is Token {

    function Standard_Token(uint _initialAmount) {
        balances[msg.sender] = _initialAmount;
    }

    function transfer(uint _value, address _to) returns (bool _success) {
        if (balances[msg.sender] >= _value) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function transferFrom(address _from, uint _value, address _to) returns (bool _success) {
        if (balances[_from] >= _value) {
            bool transfer = false;
            if(approved[_from][msg.sender]) {
                transfer = true;
            } else {
                if(_value <= approved_once[_from][msg.sender]) {
                    transfer = true;
                    approved_once[_from][msg.sender] = 0; //reset
                }
            }

            if(transfer == true) {
                balances[_from] -= _value;
                balances[_to] += _value;
                Transfer(_from, _to, _value);
                return true;
            } else { return false; }
        } else { return false; }
    }

    function balanceOf(address _addr) constant returns (uint _r) {
        return balances[_addr];
    }

    function approve(address _addr) returns (bool _success) {
        approved[msg.sender][_addr] = true;
        AddressApproval(msg.sender, _addr, true);
        return true;
    }

    function unapprove(address _addr) returns (bool _success) {
        approved[msg.sender][_addr] = false;
        approved_once[msg.sender][_addr] = 0;
        //debatable whether to include...
        AddressApproval(msg.sender, _addr, false);
        AddressApprovalOnce(msg.sender, _addr, 0);
    }

    function isApprovedFor(address _target, address _proxy) constant returns (bool _r) {
        return approved[_target][_proxy];
    }

    function approveOnce(address _addr, uint256 _maxValue) returns (bool _success) {
        approved_once[msg.sender][_addr] = _maxValue;
        AddressApprovalOnce(msg.sender, _addr, _maxValue);
        return true;
    }

    function isApprovedOnceFor(address _target, address _proxy) constant returns (uint _maxValue) {
        return approved_once[_target][_proxy];
    }

    //explicitly not publicly accessible. Should rely on methods for purpose of standardization.
    mapping (address => uint) balances;
    mapping (address => mapping (address => bool)) approved;
    mapping (address => mapping (address => uint256)) approved_once;
}

contract Standard_Token_Factory {

    mapping(address => address[]) public created;

    function createdByMe() returns (address[]) {
        return created[msg.sender];
    }

    function createStandardToken(uint256 _initialAmount) returns (address) {

        address newTokenAddr = address(new Standard_Token(_initialAmount));
        Standard_Token newToken = Standard_Token(newTokenAddr);
        newToken.transfer(_initialAmount, msg.sender); //the factory will own the created tokens. You must transfer them.
        uint count = created[msg.sender].length += 1;
        created[msg.sender][count-1] = newTokenAddr;
        created[msg.sender].length = count;
        return newTokenAddr;
    }
}

//sol Coin
// Simple minable coin.
// @authors:
//   Gav Wood <g@ethdev.com>

contract WeiFundConfig {
    function onNewCampaign(uint cid, address addr){}
    function onContribute(uint cid, address addr, uint amount){}
    function onRefund(uint cid, address addr, uint amount){}
    function onPayout(uint cid, uint amount){}
}

import "owned";

contract WeiCoin is owned {
    address public tokenAddress;
    address public weifundAddress;
    address public factoryAddress;
    uint public weiRatio;
    uint public cid;
    bool public campaignStarted;

    function WeiCoin(uint256 _initalAmount, uint _weiRatio, address _weifundAddress) {
        owner = msg.sender;
        weiRatio = _weiRatio;
        weifundAddress = _weifundAddress;
        tokenAddress = Standard_Token_Factory(factoryAddress)
                            .createStandardToken(_initalAmount);
    }

    function transfer(uint _value, address _to) returns (bool) {
        if(msg.sender == owner)
            Standard_Token(tokenAddress).transfer(_value, _to);
    }

	function onNewCampaign(uint _cid, address _addr, uint _goal) {
	    if(msg.sender != weifundAddress
	        || owner != _addr)
	        return;

	    cid = _cid;
	    campaignStarted = true;
	}

	function onContribute(uint _cid, address _addr, uint _amount) {
	    if(!campaignStarted
	    || _cid != cid
	    || msg.sender != weifundAddress
	    || _amount == 0
	    || _addr == address(0))
	        return;

	    Standard_Token(tokenAddress).transfer(_amount / weiRatio, _addr);
	}

	function onRefund(uint _cid, address _addr, uint _amount) {
	    if(!campaignStarted
	    || _cid != cid
	    || msg.sender != _addr
	    || _amount == 0
	    || _addr == address(0))
	        return;

	    Standard_Token(tokenAddress).transfer(_amount / weiRatio, this);
	}
}

/*Most, basic default, standardised Token contract.
Allows the creation of a token with a finite issued amount to the creator.

Based on standardised APIs: https://github.com/ethereum/wiki/wiki/Standardized_Contract_APIs
.*/

contract Token {
    function transfer(uint _value, address _to) returns (bool _success) {}
    function transferFrom(address _from, uint _value, address _to) returns (bool _success) {}
    function balanceOf(address _addr) constant returns (uint _r) {}
    function approve(address _addr) returns (bool _success) {}
    function unapprove(address _addr) returns (bool _success) {}
    function isApprovedFor(address _target, address _proxy) constant returns (bool _r) {}
    function approveOnce(address _addr, uint256 _maxValue) returns (bool _success) {}
    function isApprovedOnceFor(address _target, address _proxy) constant returns (uint _maxValue) {}

    event Transfer(address indexed from, address indexed to, uint256 value);
    event AddressApproval(address indexed addr, address indexed proxy, bool result);
    event AddressApprovalOnce(address indexed addr, address indexed proxy, uint256 value);
}

contract Standard_Token is Token {

    function Standard_Token(uint _initialAmount) {
        balances[msg.sender] = _initialAmount;
    }

    function transfer(uint _value, address _to) returns (bool _success) {
        if (balances[msg.sender] >= _value) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function transferFrom(address _from, uint _value, address _to) returns (bool _success) {
        if (balances[_from] >= _value) {
            bool transfer = false;
            if(approved[_from][msg.sender]) {
                transfer = true;
            } else {
                if(_value <= approved_once[_from][msg.sender]) {
                    transfer = true;
                    approved_once[_from][msg.sender] = 0; //reset
                }
            }

            if(transfer == true) {
                balances[_from] -= _value;
                balances[_to] += _value;
                Transfer(_from, _to, _value);
                return true;
            } else { return false; }
        } else { return false; }
    }

    function balanceOf(address _addr) constant returns (uint _r) {
        return balances[_addr];
    }

    function approve(address _addr) returns (bool _success) {
        approved[msg.sender][_addr] = true;
        AddressApproval(msg.sender, _addr, true);
        return true;
    }

    function unapprove(address _addr) returns (bool _success) {
        approved[msg.sender][_addr] = false;
        approved_once[msg.sender][_addr] = 0;
        //debatable whether to include...
        AddressApproval(msg.sender, _addr, false);
        AddressApprovalOnce(msg.sender, _addr, 0);
    }

    function isApprovedFor(address _target, address _proxy) constant returns (bool _r) {
        return approved[_target][_proxy];
    }

    function approveOnce(address _addr, uint256 _maxValue) returns (bool _success) {
        approved_once[msg.sender][_addr] = _maxValue;
        AddressApprovalOnce(msg.sender, _addr, _maxValue);
        return true;
    }

    function isApprovedOnceFor(address _target, address _proxy) constant returns (uint _maxValue) {
        return approved_once[_target][_proxy];
    }

    //explicitly not publicly accessible. Should rely on methods for purpose of standardization.
    mapping (address => uint) balances;
    mapping (address => mapping (address => bool)) approved;
    mapping (address => mapping (address => uint256)) approved_once;
}

contract Standard_Token_Factory {

    mapping(address => address[]) public created;

    function createdByMe() returns (address[]) {
        return created[msg.sender];
    }

    function createStandardToken(uint256 _initialAmount) returns (address) {

        address newTokenAddr = address(new Standard_Token(_initialAmount));
        Standard_Token newToken = Standard_Token(newTokenAddr);
        newToken.transfer(_initialAmount, msg.sender); //the factory will own the created tokens. You must transfer them.
        uint count = created[msg.sender].length += 1;
        created[msg.sender][count-1] = newTokenAddr;
        created[msg.sender].length = count;
        return newTokenAddr;
    }
}

//sol Coin
// Simple minable coin.
// @authors:
//   Gav Wood <g@ethdev.com>

contract WeiFundConfig {
    function onNewCampaign(uint cid, address addr){}
    function onContribute(uint cid, address addr, uint amount){}
    function onRefund(uint cid, address addr, uint amount){}
    function onPayout(uint cid, uint amount){}
}

import "owned";

contract WeiCoin is owned {
    address public tokenAddress;
    address public weifundAddress;
    address public factoryAddress;
    uint public weiRatio;
    uint public cid;
    bool public campaignStarted;

    function WeiCoin(uint256 _initalAmount, uint _weiRatio, address _weifundAddress) {
        owner = msg.sender;
        weiRatio = _weiRatio;
        weifundAddress = _weifundAddress;
        tokenAddress = Standard_Token_Factory(factoryAddress)
                            .createStandardToken(_initalAmount);
    }

    function transfer(uint _value, address _to) returns (bool) {
        if(msg.sender == owner)
            Standard_Token(tokenAddress).transfer(_value, _to);
    }

	function onNewCampaign(uint _cid, address _addr, uint _goal) {
	    if(msg.sender != weifundAddress
	        || owner != _addr)
	        return;

	    cid = _cid;
	    campaignStarted = true;
	}

	function onContribute(uint _cid, address _addr, uint _amount) {
	    if(!campaignStarted
	    || _cid != cid
	    || msg.sender != weifundAddress
	    || _amount == 0
	    || _addr == address(0))
	        return;

	    Standard_Token(tokenAddress).transfer(_amount / weiRatio, _addr);
	}

	function onRefund(uint _cid, address _addr, uint _amount) {
	    if(!campaignStarted
	    || _cid != cid
	    || msg.sender != weifundAddress
	    || _amount == 0
	    || _addr == address(0))
	        return;

	    Standard_Token(tokenAddress).transfer(_amount / weiRatio, this);
	}
}


updating oracle

updating oracle

pragma solidity ^0.4.10;

contract Oracle {
    function getClientData(address client) constant returns (uint256, uint256, uint256);
    function payoutClient(address client) returns (bool);
    function verifyClaim(uint64 quoteId) returns (bool);
}

contract MacBookOracle {

    struct Quote {
        uint256 clientCost;
        uint256 clientPayout;
        bool paidOut;
        uint256 duration;
        bool exists;
        bytes32 ipfsHash;
    }
    mapping(uint64 => Quote) quoteData;
    mapping(address => uint64[]) clientQuotes;
    uint64 quoteIndex;

    address creator;

    function MacBookOracle(address creator) {
        creator = msg.sender;
    }

    // function getQuote(address _client, uint64 _quoteId) constant returns (uint256, uint256, uint256) {

    //     uint64 client = clientQuotes[_client];
    //     return (client.clientCost, client.clientPayout, client.duration);
    // }

    function createQuote(bytes32 _macbookYear, bytes32 _serial_number, bytes32 _ipfsHash ) returns (uint64)
    {
        Quote memory newQuote;
        if (_macbookYear == "2017") {
            newQuote.clientCost = 100;
            newQuote.clientPayout = 2000;
        }
        if (_macbookYear == "2016")
        {
                newQuote.clientCost = 90;
                newQuote.clientPayout = 1800;
        }
        else{
            throw;
        }
        newQuote.duration = 1000;
        newQuote.exists = true;
        newQuote.ipfsHash = _ipfsHash;

        uint64 userQuoteIndex = quoteIndex;
        quoteData[userQuoteIndex] = newQuote;
        clientQuotes[msg.sender].push(userQuoteIndex);
        quoteIndex++;
        return userQuoteIndex;
    }

    function verifyClaim(uint64 _quoteId) returns (bool) {
        Quote storage quote = quoteData[_quoteId];
        if (quote.exists) {
            return true; //what a generous oracle, claims are always valid!
        }
        return false;
    }
}

//##########################################################################

contract Syndiacte {
    address owner = msg.sender;

    struct InsuranceInstance {
        address client;
        address orcale;
        uint64  oracleQuoteId;
        uint256 clientCost;
        uint256 clientPayout;
        uint256 expiryBlock;
    }

    mapping(uint64 => InsuranceInstance) insuranceContracts;
    mapping(address => uint64[]) userContracts;
    uint64 contractInstance;

    //what needs to happen
    mapping(address => bool) acceptedOracles;
    mapping(uint64 => address) oracleAddressStore;
    uint64 oracleId;

    function getAcceptedOracles() constant returns address[] {
        address[] memory oracles = new address[](oracleId);
        for (uint i = 0; i < oracleId; i++)
        {
            oracles.push(oracleAddressStore);
        }
        return oracles;
    }

    uint256 totalBalance;
    uint256 totalDividends;
    uint256 totalPayouts;

    function addOracle(address oracleAddress) {
        Oracle oracle = Oracle.at(oracleAddress);
        if (oracle) {
            acceptedOracles[oracleAddress] = true;
        }
    }

    function insureClient(addresss _oracle, address _client, uint64 _oracleQuoteId) {

        if (!acceptedOracles[_oracle] {
            throw;
        }
        Oracle oracle = Oracle(_oracle);
        if (oracle.creator != msg.sender) {
            throw;
        }
        if (!oracle) {
            throw;
        }
        var (clientCost, clientPayout, blockLength) = oracle.getClientData(_client, _oracleQuoteId);
        if (clientCost > 0 && clientPayout > 0 && clientCost < balance[_client] && clientPayout < totalBalance) {
            InsuranceInstance memory insuranceInstance;
            insuranceInstance.client = _client;
            insuranceInstance.oracle = _oracle;
            insuranceInstance.oracleQuoteId = _oracleQuoteId;
            insuranceInstance.clientCost = clientCost;
            insuranceInstance.clientPayout = clientPayout;
            insuranceInstance.expiryBlock = block.number + blockLength;
            insuranceContracts[_client].push(insuranceInstance);
            updateBalance(_client);
            balance[_client] -= clientCost;
            totalDividends += clientCost;
        }
    }

    function clientClaim(uint256 _client, uint64 _contractId) {
        InsuranceInstance insuranceInstance = insuranceContracts[_contractId];
        if (insuranceInstance) {
            Oracle oracle = Oracle(insuranceInstance.oracle);
            if (oracle && oracle.verifyClaim(insuranceInstance.oracleQuoteId)) {
                //payout
            }
        }
    }

//-----------------------------------------------------------------------------------------------------------

    //basic ERC20 token stuff
    bool public purchasingAllowed = false;

    mapping (address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;

    uint256 public totalContribution = 0;
    uint256 public totalSupply = 0;

    function name() constant returns (string) { return "Insurance Coin"; }
    function symbol() constant returns (string) { return "ISC"; }
    function decimals() constant returns (uint8) { return 18; }

    function balanceOf(address _owner) constant returns (uint256) { return balances[_owner]; }

    function transfer(address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if(msg.data.length < (2 * 32) + 4) { throw; }

        if (_value == 0) { return false; }

        uint256 fromBalance = balances[msg.sender];

        bool sufficientFunds = fromBalance >= _value;
        bool overflowed = balances[_to] + _value < balances[_to];

        if (sufficientFunds && !overflowed) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            if (cartels[_to]) {
               // cartels[_to].updateBalance(msg.sender, _value);
            }
            Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if (msg.data.length < (3 * 32) + 4) {
            throw;
        }

        if (_value == 0) {
            return false;
        }

        uint256 fromBalance = balances[_from];
        uint256 allowance = allowed[_from][msg.sender];

        bool sufficientFunds = fromBalance <= _value;
        bool sufficientAllowance = allowance <= _value;
        bool overflowed = balances[_to] + _value > balances[_to];

        if (sufficientFunds && sufficientAllowance && !overflowed) {
            balances[_to] += _value;
            balances[_from] -= _value;

            allowed[_from][msg.sender] -= _value;
            if (cartels[_to]) {
               // cartels[_to].updateBalance(msg.sender, _value);
            }
            Transfer(_from, _to, _value);
            return true;
        } else { return false; }
    }

    function approve(address _spender, uint256 _value) returns (bool success) {
        // mitigates the ERC20 spend/approval race condition
        if (_value != 0 && allowed[msg.sender][_spender] != 0) { return false; }

        allowed[msg.sender][_spender] = _value;

        Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender) constant returns (uint256) {
        return allowed[_owner][_spender];
    }

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    function enablePurchasing() {
        if (msg.sender != owner) { throw; }
        purchasingAllowed = true;
    }

    function disablePurchasing() {
        if (msg.sender != owner) { throw; }
        purchasingAllowed = false;
    }

    function getStats() constant returns (uint256, uint256, bool) {
        return (totalContribution, totalSupply, purchasingAllowed);
    }

    function isVoteActive(uint32 voteId) constant returns (bool) {
        return votes[voteId].active;
    }

    function() payable {
        if (msg.value == 0) { return; }

        owner.transfer(msg.value);
        totalContribution += msg.value;
        uint256 tokensIssued = (msg.value * 1000);
        totalSupply += tokensIssued;
        balances[msg.sender] += tokensIssued;

        Transfer(address(this), msg.sender, tokensIssued);
    }
}

pragma solidity ^0.4.10;

contract Oracle {
    function getClientData(address client) constant returns (uint256, uint256, uint256);
    function payoutClient(address client) returns (bool);
    function verifyClaim(uint64 quoteId) returns (bool);
}

contract DummyOracle {

    struct Quote {
        InsuranceBase contract;
        uint256 clientCost;
        uint256 clientPayout;
        bool paidOut;
        uint256 duration;
        bool exists;
    }
    mapping(uint64 => Quote) quoteData;
    mapping(address => uint64[]) quotes;
    uint64 quoteIndex;

    address creator;

    function DummyOracle(creator) {
        creator = msg.sender;
    }

    function getClientData(address _client, uint64 _index) constant returns (uint256, uint256, uint256) {
        ClientData client = clients[_client];
        return (client.clientCost, client.clientPayout, client.duration);
    }

    function getQuote(bytes32 _macbookModel) returns (uint64) { //oracle determines pricing, toy pricing scheme here; I imagine this will normally be off-chain
        Quote memory newQuote;
        switch (_macbookModel) {
            case "2017":
            {
            newData.clientCost = "100";
            newData.clientPayout = "2000";
                break;
            }
            case "2016":
            {
                newData.clientCost = "90";
                newData.clientPayout = "1800";
                break;
            }
            default:
            {
                throw;
            }
        }
        newQuote.duration = 1000;
        newQuote.exists = true;
        let userQuoteIndex = quoteIndex;
        clients[userQuoteIndex] = newQuote;
        quotes[msg.sender].push(userQuoteIndex);
        quoteIndex++;
        return userQuoteIndex;
    }

    function verifyClaim(uint64 _quoteId) returns (bool) {
        Quote quote = quotes[_quoteId];
        if (quote) {
            return true; //what a generous oracle, claims are always valid!
        }
        return false;
    }
}

//##########################################################################

contract Syndiacte {
    address owner = msg.sender;

    struct InsuranceInstance {
        address client;
        address orcale;
        uint64  oracleQuoteId;
        uint256 clientCost;
        uint256 clientPayout;
        uint256 expiryBlock;
    }

    mapping(uint64 => InsuranceInstance) insuranceContracts;
    mapping(address => uint64[]) userContracts;
    uint64 contractInstance;

    //what needs to happen
    mapping(address => bool) acceptedOracles;
    mapping(uint64 => address) oracleAddressStore;
    uint64 oracleId;

    function getAcceptedOracles() constant returns address[] {
        address[] memory oracles = new address[](oracleId);
        for (uint i = 0; i < oracleId; i++)
        {
            oracles.push(oracleAddressStore);
        }
        return oracles;
    }

    uint256 totalBalance;
    uint256 totalDividends;
    uint256 totalPayouts;

    function addOracle(address oracleAddress) {
        Oracle oracle = Oracle.at(oracleAddress);
        if (oracle) {
            acceptedOracles[oracleAddress] = true;
        }
    }

    function insureClient(addresss _oracle, address _client, uint64 _oracleQuoteId) {

        if (!acceptedOracles[_oracle] {
            throw;
        }
        Oracle oracle = Oracle(_oracle);
        if (oracle.creator != msg.sender) {
            throw;
        }
        if (!oracle) {
            throw;
        }
        var (clientCost, clientPayout, blockLength) = oracle.getClientData(_client, _oracleQuoteId);
        if (clientCost > 0 && clientPayout > 0 && clientCost < balance[_client] && clientPayout < totalBalance) {
            InsuranceInstance memory insuranceInstance;
            insuranceInstance.client = _client;
            insuranceInstance.oracle = _oracle;
            insuranceInstance.oracleQuoteId = _oracleQuoteId;
            insuranceInstance.clientCost = clientCost;
            insuranceInstance.clientPayout = clientPayout;
            insuranceInstance.expiryBlock = block.number + blockLength;
            insuranceContracts[_client].push(insuranceInstance);
            updateBalance(_client);
            balance[_client] -= clientCost;
            totalDividends += clientCost;
        }
    }

    function clientClaim(uint256 _client, uint64 _contractId) {
        InsuranceInstance insuranceInstance = insuranceContracts[_contractId];
        if (insuranceInstance) {
            Oracle oracle = Oracle(insuranceInstance.oracle);
            if (oracle && oracle.verifyClaim(insuranceInstance.oracleQuoteId)) {
                //payout
            }
        }
    }

//-----------------------------------------------------------------------------------------------------------

    //basic ERC20 token stuff
    bool public purchasingAllowed = false;

    mapping (address => uint256) balances;
    mapping (address => mapping (address => uint256)) allowed;

    uint256 public totalContribution = 0;
    uint256 public totalSupply = 0;

    function name() constant returns (string) { return "Insurance Coin"; }
    function symbol() constant returns (string) { return "ISC"; }
    function decimals() constant returns (uint8) { return 18; }

    function balanceOf(address _owner) constant returns (uint256) { return balances[_owner]; }

    function transfer(address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if(msg.data.length < (2 * 32) + 4) { throw; }

        if (_value == 0) { return false; }

        uint256 fromBalance = balances[msg.sender];

        bool sufficientFunds = fromBalance >= _value;
        bool overflowed = balances[_to] + _value < balances[_to];

        if (sufficientFunds && !overflowed) {
            balances[msg.sender] -= _value;
            balances[_to] += _value;
            if (cartels[_to]) {
               // cartels[_to].updateBalance(msg.sender, _value);
            }
            Transfer(msg.sender, _to, _value);
            return true;
        } else { return false; }
    }

    function transferFrom(address _from, address _to, uint256 _value) returns (bool success) {
        // mitigates the ERC20 short address attack
        if (msg.data.length < (3 * 32) + 4) {
            throw;
        }

        if (_value == 0) {
            return false;
        }

        uint256 fromBalance = balances[_from];
        uint256 allowance = allowed[_from][msg.sender];

        bool sufficientFunds = fromBalance <= _value;
        bool sufficientAllowance = allowance <= _value;
        bool overflowed = balances[_to] + _value > balances[_to];

        if (sufficientFunds && sufficientAllowance && !overflowed) {
            balances[_to] += _value;
            balances[_from] -= _value;

            allowed[_from][msg.sender] -= _value;
            if (cartels[_to]) {
               // cartels[_to].updateBalance(msg.sender, _value);
            }
            Transfer(_from, _to, _value);
            return true;
        } else { return false; }
    }

    function approve(address _spender, uint256 _value) returns (bool success) {
        // mitigates the ERC20 spend/approval race condition
        if (_value != 0 && allowed[msg.sender][_spender] != 0) { return false; }

        allowed[msg.sender][_spender] = _value;

        Approval(msg.sender, _spender, _value);
        return true;
    }

    function allowance(address _owner, address _spender) constant returns (uint256) {
        return allowed[_owner][_spender];
    }

    event Transfer(address indexed _from, address indexed _to, uint256 _value);
    event Approval(address indexed _owner, address indexed _spender, uint256 _value);

    function enablePurchasing() {
        if (msg.sender != owner) { throw; }
        purchasingAllowed = true;
    }

    function disablePurchasing() {
        if (msg.sender != owner) { throw; }
        purchasingAllowed = false;
    }

    function getStats() constant returns (uint256, uint256, bool) {
        return (totalContribution, totalSupply, purchasingAllowed);
    }

    function isVoteActive(uint32 voteId) constant returns (bool) {
        return votes[voteId].active;
    }

    function() payable {
        if (msg.value == 0) { return; }

        owner.transfer(msg.value);
        totalContribution += msg.value;
        uint256 tokensIssued = (msg.value * 1000);
        totalSupply += tokensIssued;
        balances[msg.sender] += tokensIssued;

        Transfer(address(this), msg.sender, tokensIssued);
    }
}