pragma solidity ^0.4.18;


/**
 * @title SafeMath
 * @dev Math operations with safety checks that throw on error
 */
library SafeMath {
  function mul(uint256 a, uint256 b) internal pure returns (uint256) {
    if (a == 0) {
      return 0;
    }
    uint256 c = a * b;
    assert(c / a == b);
    return c;
  }

  function div(uint256 a, uint256 b) internal pure returns (uint256) {
    // assert(b > 0); // Solidity automatically throws when dividing by 0
    uint256 c = a / b;
    // assert(a == b * c + a % b); // There is no case in which this doesn't hold
    return c;
  }

  function sub(uint256 a, uint256 b) internal pure returns (uint256) {
    assert(b <= a);
    return a - b;
  }

  function add(uint256 a, uint256 b) internal pure returns (uint256) {
    uint256 c = a + b;
    assert(c >= a);
    return c;
  }
}


/**
 * @title Ownable
 * @dev The Ownable contract has an owner address, and provides basic authorization control
 * functions, this simplifies the implementation of "user permissions".
 */
contract Ownable {
  address public owner;


  event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);


  /**
   * @dev The Ownable constructor sets the original `owner` of the contract to the sender
   * account.
   */
  function Ownable() public {
    owner = msg.sender;
  }


  /**
   * @dev Throws if called by any account other than the owner.
   */
  modifier onlyOwner() {
    require(msg.sender == owner);
    _;
  }


  /**
   * @dev Allows the current owner to transfer control of the contract to a newOwner.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) public onlyOwner {
    require(newOwner != address(0));
    OwnershipTransferred(owner, newOwner);
    owner = newOwner;
  }

}


/**
 * @title Claimable
 * @dev Extension for the Ownable contract, where the ownership needs to be claimed.
 * This allows the new owner to accept the transfer.
 */
contract Claimable is Ownable {
  address public pendingOwner;

  /**
   * @dev Modifier throws if called by any account other than the pendingOwner.
   */
  modifier onlyPendingOwner() {
    require(msg.sender == pendingOwner);
    _;
  }

  /**
   * @dev Allows the current owner to set the pendingOwner address.
   * @param newOwner The address to transfer ownership to.
   */
  function transferOwnership(address newOwner) onlyOwner public {
    pendingOwner = newOwner;
  }

  /**
   * @dev Allows the pendingOwner address to finalize the transfer.
   */
  function claimOwnership() onlyPendingOwner public {
    OwnershipTransferred(owner, pendingOwner);
    owner = pendingOwner;
    pendingOwner = address(0);
  }
}


/**
 * @title Pausable
 * @dev Base contract which allows children to implement an emergency stop mechanism.
 */
contract Pausable is Ownable {
  event Pause();
  event Unpause();

  bool public paused = false;


  /**
   * @dev Modifier to make a function callable only when the contract is not paused.
   */
  modifier whenNotPaused() {
    require(!paused);
    _;
  }

  /**
   * @dev Modifier to make a function callable only when the contract is paused.
   */
  modifier whenPaused() {
    require(paused);
    _;
  }

  /**
   * @dev called by the owner to pause, triggers stopped state
   */
  function pause() onlyOwner whenNotPaused public {
    paused = true;
    Pause();
  }

  /**
   * @dev called by the owner to unpause, returns to normal state
   */
  function unpause() onlyOwner whenPaused public {
    paused = false;
    Unpause();
  }
}


/**
 * @title ERC20Basic
 * @dev Simpler version of ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/179
 */
contract ERC20Basic {
  uint256 public totalSupply;
  function balanceOf(address who) public view returns (uint256);
  function transfer(address to, uint256 value) public returns (bool);
  event Transfer(address indexed from, address indexed to, uint256 value);
}


/**
 * @title ERC20 interface
 * @dev see https://github.com/ethereum/EIPs/issues/20
 */
contract ERC20 is ERC20Basic {
  function allowance(address owner, address spender) public view returns (uint256);
  function transferFrom(address from, address to, uint256 value) public returns (bool);
  function approve(address spender, uint256 value) public returns (bool);
  event Approval(address indexed owner, address indexed spender, uint256 value);
}


/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure.
 * To use this library you can add a `using SafeERC20 for ERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
  function safeTransfer(ERC20Basic token, address to, uint256 value) internal {
    assert(token.transfer(to, value));
  }

  function safeTransferFrom(ERC20 token, address from, address to, uint256 value) internal {
    assert(token.transferFrom(from, to, value));
  }

  function safeApprove(ERC20 token, address spender, uint256 value) internal {
    assert(token.approve(spender, value));
  }
}


/**
 * @title Contracts that should be able to recover tokens
 * @author SylTi
 * @dev This allow a contract to recover any ERC20 token received in a contract by transferring the balance to the contract owner.
 * This will prevent any accidental loss of tokens.
 */
contract CanReclaimToken is Ownable {
  using SafeERC20 for ERC20Basic;

  /**
   * @dev Reclaim all ERC20Basic compatible tokens
   * @param token ERC20Basic The address of the token contract
   */
  function reclaimToken(ERC20Basic token) external onlyOwner {
    uint256 balance = token.balanceOf(this);
    token.safeTransfer(owner, balance);
  }

}


/// @title Interface for contracts conforming to ERC-721: Deed Standard
/// @author William Entriken (https://phor.net), et al.
/// @dev Specification at https://github.com/ethereum/EIPs/pull/841 (DRAFT)
interface ERC721 {

    // COMPLIANCE WITH ERC-165 (DRAFT) /////////////////////////////////////////

    /// @dev ERC-165 (draft) interface signature for itself
    // bytes4 internal constant INTERFACE_SIGNATURE_ERC165 = // 0x01ffc9a7
    //     bytes4(keccak256('supportsInterface(bytes4)'));

    /// @dev ERC-165 (draft) interface signature for ERC721
    // bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = // 0xda671b9b
    //     bytes4(keccak256('ownerOf(uint256)')) ^
    //     bytes4(keccak256('countOfDeeds()')) ^
    //     bytes4(keccak256('countOfDeedsByOwner(address)')) ^
    //     bytes4(keccak256('deedOfOwnerByIndex(address,uint256)')) ^
    //     bytes4(keccak256('approve(address,uint256)')) ^
    //     bytes4(keccak256('takeOwnership(uint256)'));

    /// @notice Query a contract to see if it supports a certain interface
    /// @dev Returns `true` the interface is supported and `false` otherwise,
    ///  returns `true` for INTERFACE_SIGNATURE_ERC165 and
    ///  INTERFACE_SIGNATURE_ERC721, see ERC-165 for other interface signatures.
    function supportsInterface(bytes4 _interfaceID) external pure returns (bool);

    // PUBLIC QUERY FUNCTIONS //////////////////////////////////////////////////

    /// @notice Find the owner of a deed
    /// @param _deedId The identifier for a deed we are inspecting
    /// @dev Deeds assigned to zero address are considered destroyed, and
    ///  queries about them do throw.
    /// @return The non-zero address of the owner of deed `_deedId`, or `throw`
    ///  if deed `_deedId` is not tracked by this contract
    function ownerOf(uint256 _deedId) external view returns (address _owner);

    /// @notice Count deeds tracked by this contract
    /// @return A count of the deeds tracked by this contract, where each one of
    ///  them has an assigned and queryable owner
    function countOfDeeds() public view returns (uint256 _count);

    /// @notice Count all deeds assigned to an owner
    /// @dev Throws if `_owner` is the zero address, representing destroyed deeds.
    /// @param _owner An address where we are interested in deeds owned by them
    /// @return The number of deeds owned by `_owner`, possibly zero
    function countOfDeedsByOwner(address _owner) public view returns (uint256 _count);

    /// @notice Enumerate deeds assigned to an owner
    /// @dev Throws if `_index` >= `countOfDeedsByOwner(_owner)` or if
    ///  `_owner` is the zero address, representing destroyed deeds.
    /// @param _owner An address where we are interested in deeds owned by them
    /// @param _index A counter between zero and `countOfDeedsByOwner(_owner)`,
    ///  inclusive
    /// @return The identifier for the `_index`th deed assigned to `_owner`,
    ///   (sort order not specified)
    function deedOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256 _deedId);

    // TRANSFER MECHANISM //////////////////////////////////////////////////////

    /// @dev This event emits when ownership of any deed changes by any
    ///  mechanism. This event emits when deeds are created (`from` == 0) and
    ///  destroyed (`to` == 0). Exception: during contract creation, any
    ///  transfers may occur without emitting `Transfer`.
    event Transfer(address indexed from, address indexed to, uint256 indexed deedId);

    /// @dev This event emits on any successful call to
    ///  `approve(address _spender, uint256 _deedId)`. Exception: does not emit
    ///  if an owner revokes approval (`_to` == 0x0) on a deed with no existing
    ///  approval.
    event Approval(address indexed owner, address indexed approved, uint256 indexed deedId);

    /// @notice Approve a new owner to take your deed, or revoke approval by
    ///  setting the zero address. You may `approve` any number of times while
    ///  the deed is assigned to you, only the most recent approval matters.
    /// @dev Throws if `msg.sender` does not own deed `_deedId` or if `_to` ==
    ///  `msg.sender`.
    /// @param _deedId The deed you are granting ownership of
    function approve(address _to, uint256 _deedId) external;

    /// @notice Become owner of a deed for which you are currently approved
    /// @dev Throws if `msg.sender` is not approved to become the owner of
    ///  `deedId` or if `msg.sender` currently owns `_deedId`.
    /// @param _deedId The deed that is being transferred
    function takeOwnership(uint256 _deedId) external;
    
    // SPEC EXTENSIONS /////////////////////////////////////////////////////////
    
    /// @notice Transfer a deed to a new owner.
    /// @dev Throws if `msg.sender` does not own deed `_deedId` or if
    ///  `_to` == 0x0.
    /// @param _to The address of the new owner.
    /// @param _deedId The deed you are transferring.
    function transfer(address _to, uint256 _deedId) external;
}


/// @title Metadata extension to ERC-721 interface
/// @author William Entriken (https://phor.net)
/// @dev Specification at https://github.com/ethereum/EIPs/pull/841 (DRAFT)
interface ERC721Metadata {

    /// @dev ERC-165 (draft) interface signature for ERC721
    // bytes4 internal constant INTERFACE_SIGNATURE_ERC721Metadata = // 0x2a786f11
    //     bytes4(keccak256('name()')) ^
    //     bytes4(keccak256('symbol()')) ^
    //     bytes4(keccak256('deedUri(uint256)'));

    /// @notice A descriptive name for a collection of deeds managed by this
    ///  contract
    /// @dev Wallets and exchanges MAY display this to the end user.
    function name() public pure returns (string _deedName);

    /// @notice An abbreviated name for deeds managed by this contract
    /// @dev Wallets and exchanges MAY display this to the end user.
    function symbol() public pure returns (string _deedSymbol);

    /// @notice A distinct URI (RFC 3986) for a given token.
    /// @dev If:
    ///  * The URI is a URL
    ///  * The URL is accessible
    ///  * The URL points to a valid JSON file format (ECMA-404 2nd ed.)
    ///  * The JSON base element is an object
    ///  then these names of the base element SHALL have special meaning:
    ///  * "name": A string identifying the item to which `_deedId` grants
    ///    ownership
    ///  * "description": A string detailing the item to which `_deedId` grants
    ///    ownership
    ///  * "image": A URI pointing to a file of image/* mime type representing
    ///    the item to which `_deedId` grants ownership
    ///  Wallets and exchanges MAY display this to the end user.
    ///  Consider making any images at a width between 320 and 1080 pixels and
    ///  aspect ratio between 1.91:1 and 4:5 inclusive.
    function deedUri(uint256 _deedId) external pure returns (string _uri);
}


/// @dev Implements access control to the DWorld contract.
contract DWorldAccessControl is Claimable, Pausable, CanReclaimToken {
    address public cfoAddress;

    function DWorldAccessControl() public {
        // The creator of the contract is the initial CFO.
        cfoAddress = msg.sender;
    }
    
    /// @dev Access modifier for CFO-only functionality.
    modifier onlyCFO() {
        require(msg.sender == cfoAddress);
        _;
    }

    /// @dev Assigns a new address to act as the CFO. Only available to the current contract owner.
    /// @param _newCFO The address of the new CFO.
    function setCFO(address _newCFO) external onlyOwner {
        require(_newCFO != address(0));

        cfoAddress = _newCFO;
    }
}


/// @dev Defines base data structures for DWorld.
contract DWorldBase is DWorldAccessControl {
    using SafeMath for uint256;
    
    /// @dev All minted plots (array of plot identifiers). There are
    /// 2^16 * 2^16 possible plots (covering the entire world), thus
    /// 32 bits are required. This fits in a uint32. Storing
    /// the identifiers as uint32 instead of uint256 makes storage
    /// cheaper. (The impact of this in mappings is less noticeable,
    /// and using uint32 in the mappings below actually *increases*
    /// gas cost for minting).
    uint32[] public plots;
    
    mapping (uint256 => address) identifierToOwner;
    mapping (uint256 => address) identifierToApproved;
    mapping (address => uint256) ownershipDeedCount;
    
    // Boolean indicating whether the plot was bought before the migration.
    mapping (uint256 => bool) public identifierIsOriginal;
    
    /// @dev Event fired when a plot's data are changed. The plot
    /// data are not stored in the contract directly, instead the
    /// data are logged to the block. This gives significant
    /// reductions in gas requirements (~75k for minting with data
    /// instead of ~180k). However, it also means plot data are
    /// not available from *within* other contracts.
    event SetData(uint256 indexed deedId, string name, string description, string imageUrl, string infoUrl);
    
    /// @notice Get all minted plots.
    function getAllPlots() external view returns(uint32[]) {
        return plots;
    }
    
    /// @dev Represent a 2D coordinate as a single uint.
    /// @param x The x-coordinate.
    /// @param y The y-coordinate.
    function coordinateToIdentifier(uint256 x, uint256 y) public pure returns(uint256) {
        require(validCoordinate(x, y));
        
        return (y << 16) + x;
    }
    
    /// @dev Turn a single uint representation of a coordinate into its x and y parts.
    /// @param identifier The uint representation of a coordinate.
    function identifierToCoordinate(uint256 identifier) public pure returns(uint256 x, uint256 y) {
        require(validIdentifier(identifier));
    
        y = identifier >> 16;
        x = identifier - (y << 16);
    }
    
    /// @dev Test whether the coordinate is valid.
    /// @param x The x-part of the coordinate to test.
    /// @param y The y-part of the coordinate to test.
    function validCoordinate(uint256 x, uint256 y) public pure returns(bool) {
        return x < 65536 && y < 65536; // 2^16
    }
    
    /// @dev Test whether an identifier is valid.
    /// @param identifier The identifier to test.
    function validIdentifier(uint256 identifier) public pure returns(bool) {
        return identifier < 4294967296; // 2^16 * 2^16
    }
    
    /// @dev Set a plot's data.
    /// @param identifier The identifier of the plot to set data for.
    function _setPlotData(uint256 identifier, string name, string description, string imageUrl, string infoUrl) internal {
        SetData(identifier, name, description, imageUrl, infoUrl);
    }
}


/// @dev Holds deed functionality such as approving and transferring. Implements ERC721.
contract DWorldDeed is DWorldBase, ERC721, ERC721Metadata {
    
    /// @notice Name of the collection of deeds (non-fungible token), as defined in ERC721Metadata.
    function name() public pure returns (string _deedName) {
        _deedName = "DWorld Plots";
    }
    
    /// @notice Symbol of the collection of deeds (non-fungible token), as defined in ERC721Metadata.
    function symbol() public pure returns (string _deedSymbol) {
        _deedSymbol = "DWP";
    }
    
    /// @dev ERC-165 (draft) interface signature for itself
    bytes4 internal constant INTERFACE_SIGNATURE_ERC165 = // 0x01ffc9a7
        bytes4(keccak256('supportsInterface(bytes4)'));

    /// @dev ERC-165 (draft) interface signature for ERC721
    bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = // 0xda671b9b
        bytes4(keccak256('ownerOf(uint256)')) ^
        bytes4(keccak256('countOfDeeds()')) ^
        bytes4(keccak256('countOfDeedsByOwner(address)')) ^
        bytes4(keccak256('deedOfOwnerByIndex(address,uint256)')) ^
        bytes4(keccak256('approve(address,uint256)')) ^
        bytes4(keccak256('takeOwnership(uint256)'));
        
    /// @dev ERC-165 (draft) interface signature for ERC721
    bytes4 internal constant INTERFACE_SIGNATURE_ERC721Metadata = // 0x2a786f11
        bytes4(keccak256('name()')) ^
        bytes4(keccak256('symbol()')) ^
        bytes4(keccak256('deedUri(uint256)'));
    
    /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165).
    /// Returns true for any standardized interfaces implemented by this contract.
    /// (ERC-165 and ERC-721.)
    function supportsInterface(bytes4 _interfaceID) external pure returns (bool) {
        return (
            (_interfaceID == INTERFACE_SIGNATURE_ERC165)
            || (_interfaceID == INTERFACE_SIGNATURE_ERC721)
            || (_interfaceID == INTERFACE_SIGNATURE_ERC721Metadata)
        );
    }
    
    /// @dev Checks if a given address owns a particular plot.
    /// @param _owner The address of the owner to check for.
    /// @param _deedId The plot identifier to check for.
    function _owns(address _owner, uint256 _deedId) internal view returns (bool) {
        return identifierToOwner[_deedId] == _owner;
    }
    
    /// @dev Approve a given address to take ownership of a deed.
    /// @param _from The address approving taking ownership.
    /// @param _to The address to approve taking ownership.
    /// @param _deedId The identifier of the deed to give approval for.
    function _approve(address _from, address _to, uint256 _deedId) internal {
        identifierToApproved[_deedId] = _to;
        
        // Emit event.
        Approval(_from, _to, _deedId);
    }
    
    /// @dev Checks if a given address has approval to take ownership of a deed.
    /// @param _claimant The address of the claimant to check for.
    /// @param _deedId The identifier of the deed to check for.
    function _approvedFor(address _claimant, uint256 _deedId) internal view returns (bool) {
        return identifierToApproved[_deedId] == _claimant;
    }
    
    /// @dev Assigns ownership of a specific deed to an address.
    /// @param _from The address to transfer the deed from.
    /// @param _to The address to transfer the deed to.
    /// @param _deedId The identifier of the deed to transfer.
    function _transfer(address _from, address _to, uint256 _deedId) internal {
        // The number of plots is capped at 2^16 * 2^16, so this cannot
        // be overflowed.
        ownershipDeedCount[_to]++;
        
        // Transfer ownership.
        identifierToOwner[_deedId] = _to;
        
        // When a new deed is minted, the _from address is 0x0, but we
        // do not track deed ownership of 0x0.
        if (_from != address(0)) {
            ownershipDeedCount[_from]--;
            
            // Clear taking ownership approval.
            delete identifierToApproved[_deedId];
        }
        
        // Emit the transfer event.
        Transfer(_from, _to, _deedId);
    }
    
    // ERC 721 implementation
    
    /// @notice Returns the total number of deeds currently in existence.
    /// @dev Required for ERC-721 compliance.
    function countOfDeeds() public view returns (uint256) {
        return plots.length;
    }
    
    /// @notice Returns the number of deeds owned by a specific address.
    /// @param _owner The owner address to check.
    /// @dev Required for ERC-721 compliance
    function countOfDeedsByOwner(address _owner) public view returns (uint256) {
        return ownershipDeedCount[_owner];
    }
    
    /// @notice Returns the address currently assigned ownership of a given deed.
    /// @dev Required for ERC-721 compliance.
    function ownerOf(uint256 _deedId) external view returns (address _owner) {
        _owner = identifierToOwner[_deedId];

        require(_owner != address(0));
    }
    
    /// @notice Approve a given address to take ownership of a deed.
    /// @param _to The address to approve taking owernship.
    /// @param _deedId The identifier of the deed to give approval for.
    /// @dev Required for ERC-721 compliance.
    function approve(address _to, uint256 _deedId) external whenNotPaused {
        uint256[] memory _deedIds = new uint256[](1);
        _deedIds[0] = _deedId;
        
        approveMultiple(_to, _deedIds);
    }
    
    /// @notice Approve a given address to take ownership of multiple deeds.
    /// @param _to The address to approve taking ownership.
    /// @param _deedIds The identifiers of the deeds to give approval for.
    function approveMultiple(address _to, uint256[] _deedIds) public whenNotPaused {
        // Ensure the sender is not approving themselves.
        require(msg.sender != _to);
    
        for (uint256 i = 0; i < _deedIds.length; i++) {
            uint256 _deedId = _deedIds[i];
            
            // Require the sender is the owner of the deed.
            require(_owns(msg.sender, _deedId));
            
            // Perform the approval.
            _approve(msg.sender, _to, _deedId);
        }
    }
    
    /// @notice Transfer a deed to another address. If transferring to a smart
    /// contract be VERY CAREFUL to ensure that it is aware of ERC-721, or your
    /// deed may be lost forever.
    /// @param _to The address of the recipient, can be a user or contract.
    /// @param _deedId The identifier of the deed to transfer.
    /// @dev Required for ERC-721 compliance.
    function transfer(address _to, uint256 _deedId) external whenNotPaused {
        uint256[] memory _deedIds = new uint256[](1);
        _deedIds[0] = _deedId;
        
        transferMultiple(_to, _deedIds);
    }
    
    /// @notice Transfers multiple deeds to another address. If transferring to
    /// a smart contract be VERY CAREFUL to ensure that it is aware of ERC-721,
    /// or your deeds may be lost forever.
    /// @param _to The address of the recipient, can be a user or contract.
    /// @param _deedIds The identifiers of the deeds to transfer.
    function transferMultiple(address _to, uint256[] _deedIds) public whenNotPaused {
        // Safety check to prevent against an unexpected 0x0 default.
        require(_to != address(0));
        
        // Disallow transfers to this contract to prevent accidental misuse.
        require(_to != address(this));
    
        for (uint256 i = 0; i < _deedIds.length; i++) {
            uint256 _deedId = _deedIds[i];
            
            // One can only transfer their own plots.
            require(_owns(msg.sender, _deedId));

            // Transfer ownership
            _transfer(msg.sender, _to, _deedId);
        }
    }
    
    /// @notice Transfer a deed owned by another address, for which the calling
    /// address has previously been granted transfer approval by the owner.
    /// @param _deedId The identifier of the deed to be transferred.
    /// @dev Required for ERC-721 compliance.
    function takeOwnership(uint256 _deedId) external whenNotPaused {
        uint256[] memory _deedIds = new uint256[](1);
        _deedIds[0] = _deedId;
        
        takeOwnershipMultiple(_deedIds);
    }
    
    /// @notice Transfer multiple deeds owned by another address, for which the
    /// calling address has previously been granted transfer approval by the owner.
    /// @param _deedIds The identifier of the deed to be transferred.
    function takeOwnershipMultiple(uint256[] _deedIds) public whenNotPaused {
        for (uint256 i = 0; i < _deedIds.length; i++) {
            uint256 _deedId = _deedIds[i];
            address _from = identifierToOwner[_deedId];
            
            // Check for transfer approval
            require(_approvedFor(msg.sender, _deedId));

            // Reassign ownership (also clears pending approvals and emits Transfer event).
            _transfer(_from, msg.sender, _deedId);
        }
    }
    
    /// @notice Returns a list of all deed identifiers assigned to an address.
    /// @param _owner The owner whose deeds we are interested in.
    /// @dev This method MUST NEVER be called by smart contract code. It's very
    /// expensive and is not supported in contract-to-contract calls as it returns
    /// a dynamic array (only supported for web3 calls).
    function deedsOfOwner(address _owner) external view returns(uint256[]) {
        uint256 deedCount = countOfDeedsByOwner(_owner);

        if (deedCount == 0) {
            // Return an empty array.
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](deedCount);
            uint256 totalDeeds = countOfDeeds();
            uint256 resultIndex = 0;
            
            for (uint256 deedNumber = 0; deedNumber < totalDeeds; deedNumber++) {
                uint256 identifier = plots[deedNumber];
                if (identifierToOwner[identifier] == _owner) {
                    result[resultIndex] = identifier;
                    resultIndex++;
                }
            }

            return result;
        }
    }
    
    /// @notice Returns a deed identifier of the owner at the given index.
    /// @param _owner The address of the owner we want to get a deed for.
    /// @param _index The index of the deed we want.
    function deedOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256) {
        // The index should be valid.
        require(_index < countOfDeedsByOwner(_owner));

        // Loop through all plots, accounting the number of plots of the owner we've seen.
        uint256 seen = 0;
        uint256 totalDeeds = countOfDeeds();
        
        for (uint256 deedNumber = 0; deedNumber < totalDeeds; deedNumber++) {
            uint256 identifier = plots[deedNumber];
            if (identifierToOwner[identifier] == _owner) {
                if (seen == _index) {
                    return identifier;
                }
                
                seen++;
            }
        }
    }
    
    /// @notice Returns an (off-chain) metadata url for the given deed.
    /// @param _deedId The identifier of the deed to get the metadata
    /// url for.
    /// @dev Implementation of optional ERC-721 functionality.
    function deedUri(uint256 _deedId) external pure returns (string uri) {
        require(validIdentifier(_deedId));
    
        var (x, y) = identifierToCoordinate(_deedId);
    
        // Maximum coordinate length in decimals is 5 (65535)
        uri = "https://dworld.io/plot/xxxxx/xxxxx";
        bytes memory _uri = bytes(uri);
        
        for (uint256 i = 0; i < 5; i++) {
            _uri[27 - i] = byte(48 + (x / 10 ** i) % 10);
            _uri[33 - i] = byte(48 + (y / 10 ** i) % 10);
        }
    }
}


/// @dev Holds functionality for finance related to plots.
contract DWorldFinance is DWorldDeed {
    /// Total amount of Ether yet to be paid to auction beneficiaries.
    uint256 public outstandingEther = 0 ether;
    
    /// Amount of Ether yet to be paid per beneficiary.
    mapping (address => uint256) public addressToEtherOwed;
    
    /// Base price for unclaimed plots.
    uint256 public unclaimedPlotPrice = 0.0125 ether;
    
    /// Dividend per plot surrounding a new claim, in 1/1000th of percentages
    /// of the base unclaimed plot price.
    uint256 public claimDividendPercentage = 50000;
    
    /// Percentage of the buyout price that goes towards dividends.
    uint256 public buyoutDividendPercentage = 5000;
    
    /// Buyout fee in 1/1000th of a percentage.
    uint256 public buyoutFeePercentage = 3500;
    
    /// Number of free claims per address.
    mapping (address => uint256) freeClaimAllowance;
    
    /// Initial price paid for a plot.
    mapping (uint256 => uint256) public initialPricePaid;
    
    /// Current plot price.
    mapping (uint256 => uint256) public identifierToBuyoutPrice;
    
    /// Boolean indicating whether the plot has been bought out at least once.
    mapping (uint256 => bool) identifierToBoughtOutOnce;
    
    /// @dev Event fired when dividend is paid for a new plot claim.
    event ClaimDividend(address indexed from, address indexed to, uint256 deedIdFrom, uint256 indexed deedIdTo, uint256 dividend);
    
    /// @dev Event fired when a buyout is performed.
    event Buyout(address indexed buyer, address indexed seller, uint256 indexed deedId, uint256 winnings, uint256 totalCost, uint256 newPrice);
    
    /// @dev Event fired when dividend is paid for a buyout.
    event BuyoutDividend(address indexed from, address indexed to, uint256 deedIdFrom, uint256 indexed deedIdTo, uint256 dividend);
    
    /// @dev Event fired when the buyout price is manually changed for a plot.
    event SetBuyoutPrice(uint256 indexed deedId, uint256 newPrice);
    
    /// @dev The time after which buyouts will be enabled. Set in the DWorldCore constructor.
    uint256 public buyoutsEnabledFromTimestamp;
    
    /// @notice Sets the new price for unclaimed plots.
    /// @param _unclaimedPlotPrice The new price for unclaimed plots.
    function setUnclaimedPlotPrice(uint256 _unclaimedPlotPrice) external onlyCFO {
        unclaimedPlotPrice = _unclaimedPlotPrice;
    }
    
    /// @notice Sets the new dividend percentage for unclaimed plots.
    /// @param _claimDividendPercentage The new dividend percentage for unclaimed plots.
    function setClaimDividendPercentage(uint256 _claimDividendPercentage) external onlyCFO {
        // Claim dividend percentage must be 10% at the least.
        // Claim dividend percentage may be 100% at the most.
        require(10000 <= _claimDividendPercentage && _claimDividendPercentage <= 100000);
        
        claimDividendPercentage = _claimDividendPercentage;
    }
    
    /// @notice Sets the new dividend percentage for buyouts.
    /// @param _buyoutDividendPercentage The new dividend percentage for buyouts.
    function setBuyoutDividendPercentage(uint256 _buyoutDividendPercentage) external onlyCFO {
        // Buyout dividend must be 2% at the least.
        // Buyout dividend percentage may be 12.5% at the most.
        require(2000 <= _buyoutDividendPercentage && _buyoutDividendPercentage <= 12500);
        
        buyoutDividendPercentage = _buyoutDividendPercentage;
    }
    
    /// @notice Sets the new fee percentage for buyouts.
    /// @param _buyoutFeePercentage The new fee percentage for buyouts.
    function setBuyoutFeePercentage(uint256 _buyoutFeePercentage) external onlyCFO {
        // Buyout fee may be 5% at the most.
        require(0 <= _buyoutFeePercentage && _buyoutFeePercentage <= 5000);
        
        buyoutFeePercentage = _buyoutFeePercentage;
    }
    
    /// @notice The claim dividend to be paid for each adjacent plot, and
    /// as a flat dividend for each buyout.
    function claimDividend() public view returns (uint256) {
        return unclaimedPlotPrice.mul(claimDividendPercentage).div(100000);
    }
    
    /// @notice Set the free claim allowance for an address.
    /// @param addr The address to set the free claim allowance for.
    /// @param allowance The free claim allowance to set.
    function setFreeClaimAllowance(address addr, uint256 allowance) external onlyCFO {
        freeClaimAllowance[addr] = allowance;
    }
    
    /// @notice Get the free claim allowance of an address.
    /// @param addr The address to get the free claim allowance of.
    function freeClaimAllowanceOf(address addr) external view returns (uint256) {
        return freeClaimAllowance[addr];
    }
    
    /// @dev Assign balance to an account.
    /// @param addr The address to assign balance to.
    /// @param amount The amount to assign.
    function _assignBalance(address addr, uint256 amount) internal {
        addressToEtherOwed[addr] = addressToEtherOwed[addr].add(amount);
        outstandingEther = outstandingEther.add(amount);
    }
    
    /// @dev Find the _claimed_ plots surrounding a plot.
    /// @param _deedId The identifier of the plot to get the surrounding plots for.
    function _claimedSurroundingPlots(uint256 _deedId) internal view returns (uint256[] memory) {
        var (x, y) = identifierToCoordinate(_deedId);
        
        // Find all claimed surrounding plots.
        uint256 claimed = 0;
        
        // Create memory buffer capable of holding all plots.
        uint256[] memory _plots = new uint256[](8);
        
        // Loop through all neighbors.
        for (int256 dx = -1; dx <= 1; dx++) {
            for (int256 dy = -1; dy <= 1; dy++) {
                if (dx == 0 && dy == 0) {
                    // Skip the center (i.e., the plot itself).
                    continue;
                }
                
                // Get the coordinates of this neighboring identifier.
                uint256 neighborIdentifier = coordinateToIdentifier(
                    uint256(int256(x) + dx) % 65536,
                    uint256(int256(y) + dy) % 65536
                );
                
                if (identifierToOwner[neighborIdentifier] != 0x0) {
                    _plots[claimed] = neighborIdentifier;
                    claimed++;
                }
            }
        }
        
        // Memory arrays cannot be resized, so copy all
        // plots from the buffer to the plot array.
        uint256[] memory plots = new uint256[](claimed);
        
        for (uint256 i = 0; i < claimed; i++) {
            plots[i] = _plots[i];
        }
        
        return plots;
    }
    
    /// @dev Assign claim dividend to an address.
    /// @param _from The address who paid the dividend.
    /// @param _to The dividend beneficiary.
    /// @param _deedIdFrom The identifier of the deed the dividend is being paid for.
    /// @param _deedIdTo The identifier of the deed the dividend is being paid to.
    function _assignClaimDividend(address _from, address _to, uint256 _deedIdFrom, uint256 _deedIdTo) internal {
        uint256 _claimDividend = claimDividend();
        
        // Trigger event.
        ClaimDividend(_from, _to, _deedIdFrom, _deedIdTo, _claimDividend);
        
        // Assign the dividend.
        _assignBalance(_to, _claimDividend);
    }

    /// @dev Calculate and assign the dividend payable for the new plot claim.
    /// A new claim pays dividends to all existing surrounding plots.
    /// @param _deedId The identifier of the new plot to calculate and assign dividends for.
    /// Assumed to be valid.
    function _calculateAndAssignClaimDividends(uint256 _deedId)
        internal
        returns (uint256 totalClaimDividend)
    {
        // Get existing surrounding plots.
        uint256[] memory claimedSurroundingPlots = _claimedSurroundingPlots(_deedId);
        
        // Keep track of the claim dividend.
        uint256 _claimDividend = claimDividend();
        totalClaimDividend = 0;
        
        // Assign claim dividend.
        for (uint256 i = 0; i < claimedSurroundingPlots.length; i++) {
            if (identifierToOwner[claimedSurroundingPlots[i]] != msg.sender) {
                totalClaimDividend = totalClaimDividend.add(_claimDividend);
                _assignClaimDividend(msg.sender, identifierToOwner[claimedSurroundingPlots[i]], _deedId, claimedSurroundingPlots[i]);
            }
        }
    }
    
    /// @dev Calculate the next buyout price given the current total buyout cost.
    /// @param totalCost The current total buyout cost.
    function nextBuyoutPrice(uint256 totalCost) public pure returns (uint256) {
        if (totalCost < 0.05 ether) {
            return totalCost * 2;
        } else if (totalCost < 0.2 ether) {
            return totalCost * 170 / 100; // * 1.7
        } else if (totalCost < 0.5 ether) {
            return totalCost * 150 / 100; // * 1.5
        } else {
            return totalCost.mul(125).div(100); // * 1.25
        }
    }
    
    /// @notice Get the buyout cost for a given plot.
    /// @param _deedId The identifier of the plot to get the buyout cost for.
    function buyoutCost(uint256 _deedId) external view returns (uint256) {
        // The current buyout price.
        uint256 price = identifierToBuyoutPrice[_deedId];
    
        // Get existing surrounding plots.
        uint256[] memory claimedSurroundingPlots = _claimedSurroundingPlots(_deedId);
    
        // The total cost is the price plus flat rate dividends based on claim dividends.
        uint256 flatDividends = claimDividend().mul(claimedSurroundingPlots.length);
        return price.add(flatDividends);
    }
    
    /// @dev Assign the proceeds of the buyout.
    /// @param _deedId The identifier of the plot that is being bought out.
    function _assignBuyoutProceeds(
        address currentOwner,
        uint256 _deedId,
        uint256[] memory claimedSurroundingPlots,
        uint256 currentOwnerWinnings,
        uint256 totalDividendPerBeneficiary,
        uint256 totalCost
    )
        internal
    {
        // Calculate and assign the current owner's winnings.
        
        Buyout(msg.sender, currentOwner, _deedId, currentOwnerWinnings, totalCost, nextBuyoutPrice(totalCost));
        _assignBalance(currentOwner, currentOwnerWinnings);
        
        // Assign dividends to owners of surrounding plots.
        for (uint256 i = 0; i < claimedSurroundingPlots.length; i++) {
            address beneficiary = identifierToOwner[claimedSurroundingPlots[i]];
            BuyoutDividend(msg.sender, beneficiary, _deedId, claimedSurroundingPlots[i], totalDividendPerBeneficiary);
            _assignBalance(beneficiary, totalDividendPerBeneficiary);
        }
    }
    
    /// @dev Calculate and assign the proceeds from the buyout.
    /// @param currentOwner The current owner of the plot that is being bought out.
    /// @param _deedId The identifier of the plot that is being bought out.
    /// @param claimedSurroundingPlots The surrounding plots that have been claimed.
    function _calculateAndAssignBuyoutProceeds(address currentOwner, uint256 _deedId, uint256[] memory claimedSurroundingPlots)
        internal 
        returns (uint256 totalCost)
    {
        // The current price.
        uint256 price = identifierToBuyoutPrice[_deedId];
    
        // The total cost is the price plus flat rate dividends based on claim dividends.
        uint256 flatDividends = claimDividend().mul(claimedSurroundingPlots.length);
        totalCost = price.add(flatDividends);
        
        // Calculate the variable dividends based on the buyout price
        // (only to be paid if there are surrounding plots).
        uint256 variableDividends = price.mul(buyoutDividendPercentage).div(100000);
        
        // Calculate fees.
        uint256 fee = price.mul(buyoutFeePercentage).div(100000);
        
        // Calculate and assign buyout proceeds.
        uint256 currentOwnerWinnings = price.sub(fee);
        
        uint256 totalDividendPerBeneficiary;
        if (claimedSurroundingPlots.length > 0) {
            // If there are surrounding plots, variable dividend is to be paid
            // based on the buyout price..
            currentOwnerWinnings = currentOwnerWinnings.sub(variableDividends);
            
            // Calculate the dividend per surrounding plot.
            totalDividendPerBeneficiary = flatDividends.add(variableDividends) / claimedSurroundingPlots.length;
        }
        
        _assignBuyoutProceeds(
            currentOwner,
            _deedId,
            claimedSurroundingPlots,
            currentOwnerWinnings,
            totalDividendPerBeneficiary,
            totalCost
        );
    }
    
    /// @notice Buy the current owner out of the plot.
    function buyout(uint256 _deedId) external payable whenNotPaused {
        buyoutWithData(_deedId, "", "", "", "");
    }
    
    /// @notice Buy the current owner out of the plot.
    function buyoutWithData(uint256 _deedId, string name, string description, string imageUrl, string infoUrl)
        public
        payable
        whenNotPaused 
    {
        // Buyouts must be enabled.
        require(buyoutsEnabledFromTimestamp <= block.timestamp);
    
        address currentOwner = identifierToOwner[_deedId];
    
        // The plot must be owned before it can be bought out.
        require(currentOwner != 0x0);
        
        // Get existing surrounding plots.
        uint256[] memory claimedSurroundingPlots = _claimedSurroundingPlots(_deedId);
        
        // Assign the buyout proceeds and retrieve the total cost.
        uint256 totalCost = _calculateAndAssignBuyoutProceeds(currentOwner, _deedId, claimedSurroundingPlots);
        
        // Ensure the message has enough value.
        require(msg.value >= totalCost);
        
        // Transfer the plot.
        _transfer(currentOwner, msg.sender, _deedId);
        
        // Set the plot data
        SetData(_deedId, name, description, imageUrl, infoUrl);
        
        // Calculate and set the new plot price.
        identifierToBuyoutPrice[_deedId] = nextBuyoutPrice(totalCost);
        
        // Indicate the plot has been bought out at least once
        if (!identifierToBoughtOutOnce[_deedId]) {
            identifierToBoughtOutOnce[_deedId] = true;
        }
        
        // Calculate the excess Ether sent.
        // msg.value is greater than or equal to totalCost,
        // so this cannot underflow.
        uint256 excess = msg.value - totalCost;
        
        if (excess > 0) {
            // Refund any excess Ether (not susceptible to re-entry attack, as
            // the owner is assigned before the transfer takes place).
            msg.sender.transfer(excess);
        }
    }
    
    /// @notice Calculate the maximum initial buyout price for a plot.
    /// @param _deedId The identifier of the plot to get the maximum initial buyout price for.
    function maximumInitialBuyoutPrice(uint256 _deedId) public view returns (uint256) {
        // The initial buyout price can be set to 4x the initial plot price
        // (or 100x for the original pre-migration plots).
        uint256 mul = 4;
        
        if (identifierIsOriginal[_deedId]) {
            mul = 100;
        }
        
        return initialPricePaid[_deedId].mul(mul);
    }
    
    /// @notice Test whether a buyout price is valid.
    /// @param _deedId The identifier of the plot to test the buyout price for.
    /// @param price The buyout price to test.
    function validInitialBuyoutPrice(uint256 _deedId, uint256 price) public view returns (bool) {        
        return (price >= unclaimedPlotPrice && price <= maximumInitialBuyoutPrice(_deedId));
    }
    
    /// @notice Manually set the initial buyout price of a plot.
    /// @param _deedId The identifier of the plot to set the buyout price for.
    /// @param price The value to set the buyout price to.
    function setInitialBuyoutPrice(uint256 _deedId, uint256 price) public whenNotPaused {
        // One can only set the buyout price of their own plots.
        require(_owns(msg.sender, _deedId));
        
        // The initial buyout price can only be set if the plot has never been bought out before.
        require(!identifierToBoughtOutOnce[_deedId]);
        
        // The buyout price must be valid.
        require(validInitialBuyoutPrice(_deedId, price));
        
        // Set the buyout price.
        identifierToBuyoutPrice[_deedId] = price;
        
        // Trigger the buyout price event.
        SetBuyoutPrice(_deedId, price);
    }
}


/// @dev Holds functionality for minting new plot deeds.
contract DWorldMinting is DWorldFinance {       
    /// @notice Buy an unclaimed plot.
    /// @param _deedId The unclaimed plot to buy.
    /// @param _buyoutPrice The initial buyout price to set on the plot.
    function claimPlot(uint256 _deedId, uint256 _buyoutPrice) external payable whenNotPaused {
        claimPlotWithData(_deedId, _buyoutPrice, "", "", "", "");
    }
       
    /// @notice Buy an unclaimed plot.
    /// @param _deedId The unclaimed plot to buy.
    /// @param _buyoutPrice The initial buyout price to set on the plot.
    /// @param name The name to give the plot.
    /// @param description The description to add to the plot.
    /// @param imageUrl The image url for the plot.
    /// @param infoUrl The info url for the plot.
    function claimPlotWithData(uint256 _deedId, uint256 _buyoutPrice, string name, string description, string imageUrl, string infoUrl) public payable whenNotPaused {
        uint256[] memory _deedIds = new uint256[](1);
        _deedIds[0] = _deedId;
        
        claimPlotMultipleWithData(_deedIds, _buyoutPrice, name, description, imageUrl, infoUrl);
    }
    
    /// @notice Buy unclaimed plots.
    /// @param _deedIds The unclaimed plots to buy.
    /// @param _buyoutPrice The initial buyout price to set on the plot.
    function claimPlotMultiple(uint256[] _deedIds, uint256 _buyoutPrice) external payable whenNotPaused {
        claimPlotMultipleWithData(_deedIds, _buyoutPrice, "", "", "", "");
    }
    
    /// @notice Buy unclaimed plots.
    /// @param _deedIds The unclaimed plots to buy.
    /// @param _buyoutPrice The initial buyout price to set on the plot.
    /// @param name The name to give the plots.
    /// @param description The description to add to the plots.
    /// @param imageUrl The image url for the plots.
    /// @param infoUrl The info url for the plots.
    function claimPlotMultipleWithData(uint256[] _deedIds, uint256 _buyoutPrice, string name, string description, string imageUrl, string infoUrl) public payable whenNotPaused {
        uint256 buyAmount = _deedIds.length;
        uint256 etherRequired;
        if (freeClaimAllowance[msg.sender] > 0) {
            // The sender has a free claim allowance.
            if (freeClaimAllowance[msg.sender] > buyAmount) {
                // Subtract from allowance.
                freeClaimAllowance[msg.sender] -= buyAmount;
                
                // No ether is required.
                etherRequired = 0;
            } else {
                uint256 freeAmount = freeClaimAllowance[msg.sender];
                
                // The full allowance has been used.
                delete freeClaimAllowance[msg.sender];
                
                // The subtraction cannot underflow, as freeAmount <= buyAmount.
                etherRequired = unclaimedPlotPrice.mul(buyAmount - freeAmount);
            }
        } else {
            // The sender does not have a free claim allowance.
            etherRequired = unclaimedPlotPrice.mul(buyAmount);
        }
        
        uint256 offset = plots.length;
        
        // Allocate additional memory for the plots array
        // (this is more efficient than .push-ing each individual
        // plot, as that requires multiple dynamic allocations).
        plots.length = plots.length.add(_deedIds.length);
        
        for (uint256 i = 0; i < _deedIds.length; i++) { 
            uint256 _deedId = _deedIds[i];
            require(validIdentifier(_deedId));
            
            // The plot must be unowned (a plot deed cannot be transferred to
            // 0x0, so once a plot is claimed it will always be owned by a
            // non-zero address).
            require(identifierToOwner[_deedId] == address(0));
            
            // Create the plot
            plots[offset + i] = uint32(_deedId);
            
            // Transfer the new plot to the sender.
            _transfer(address(0), msg.sender, _deedId);
            
            // Set the plot data.
            _setPlotData(_deedId, name, description, imageUrl, infoUrl);
            
            // Calculate and assign claim dividends.
            uint256 claimDividends = _calculateAndAssignClaimDividends(_deedId);
            etherRequired = etherRequired.add(claimDividends);
            
            // Set the initial price paid for the plot.
            initialPricePaid[_deedId] = unclaimedPlotPrice.add(claimDividends);
            
            // Set the initial buyout price. Throws if it does not succeed.
            setInitialBuyoutPrice(_deedId, _buyoutPrice);
        }
        
        // Ensure enough ether is supplied.
        require(msg.value >= etherRequired);
        
        // Calculate the excess ether sent
        // msg.value is greater than or equal to etherRequired,
        // so this cannot underflow.
        uint256 excess = msg.value - etherRequired;
        
        if (excess > 0) {
            // Refund any excess ether (not susceptible to re-entry attack, as
            // the owner is assigned before the transfer takes place).
            msg.sender.transfer(excess);
        }
    }
}


/// @title The internal clock auction functionality.
/// Inspired by CryptoKitties' clock auction
contract ClockAuctionBase {

    // Address of the ERC721 contract this auction is linked to.
    ERC721 public deedContract;

    // Fee per successful auction in 1/1000th of a percentage.
    uint256 public fee;
    
    // Total amount of ether yet to be paid to auction beneficiaries.
    uint256 public outstandingEther = 0 ether;
    
    // Amount of ether yet to be paid per beneficiary.
    mapping (address => uint256) public addressToEtherOwed;
    
    /// @dev Represents a deed auction.
    /// Care has been taken to ensure the auction fits in
    /// two 256-bit words.
    struct Auction {
        address seller;
        uint128 startPrice;
        uint128 endPrice;
        uint64 duration;
        uint64 startedAt;
    }

    mapping (uint256 => Auction) identifierToAuction;
    
    // Events
    event AuctionCreated(address indexed seller, uint256 indexed deedId, uint256 startPrice, uint256 endPrice, uint256 duration);
    event AuctionSuccessful(address indexed buyer, uint256 indexed deedId, uint256 totalPrice);
    event AuctionCancelled(uint256 indexed deedId);
    
    /// @dev Modifier to check whether the value can be stored in a 64 bit uint.
    modifier fitsIn64Bits(uint256 _value) {
        require (_value == uint256(uint64(_value)));
        _;
    }
    
    /// @dev Modifier to check whether the value can be stored in a 128 bit uint.
    modifier fitsIn128Bits(uint256 _value) {
        require (_value == uint256(uint128(_value)));
        _;
    }
    
    function ClockAuctionBase(address _deedContractAddress, uint256 _fee) public {
        deedContract = ERC721(_deedContractAddress);
        
        // Contract must indicate support for ERC721 through its interface signature.
        require(deedContract.supportsInterface(0xda671b9b));
        
        // Fee must be between 0 and 100%.
        require(0 <= _fee && _fee <= 100000);
        fee = _fee;
    }
    
    /// @dev Checks whether the given auction is active.
    /// @param auction The auction to check for activity.
    function _activeAuction(Auction storage auction) internal view returns (bool) {
        return auction.startedAt > 0;
    }
    
    /// @dev Put the deed into escrow, thereby taking ownership of it.
    /// @param _deedId The identifier of the deed to place into escrow.
    function _escrow(uint256 _deedId) internal {
        // Throws if the transfer fails
        deedContract.takeOwnership(_deedId);
    }
    
    /// @dev Create the auction.
    /// @param _deedId The identifier of the deed to create the auction for.
    /// @param auction The auction to create.
    function _createAuction(uint256 _deedId, Auction auction) internal {
        // Add the auction to the auction mapping.
        identifierToAuction[_deedId] = auction;
        
        // Trigger auction created event.
        AuctionCreated(auction.seller, _deedId, auction.startPrice, auction.endPrice, auction.duration);
    }
    
    /// @dev Bid on an auction.
    /// @param _buyer The address of the buyer.
    /// @param _value The value sent by the sender (in ether).
    /// @param _deedId The identifier of the deed to bid on.
    function _bid(address _buyer, uint256 _value, uint256 _deedId) internal {
        Auction storage auction = identifierToAuction[_deedId];
        
        // The auction must be active.
        require(_activeAuction(auction));
        
        // Calculate the auction's current price.
        uint256 price = _currentPrice(auction);
        
        // Make sure enough funds were sent.
        require(_value >= price);
        
        address seller = auction.seller;
    
        if (price > 0) {
            uint256 totalFee = _calculateFee(price);
            uint256 proceeds = price - totalFee;
            
            // Assign the proceeds to the seller.
            // We do not send the proceeds directly, as to prevent
            // malicious sellers from denying auctions (and burning
            // the buyer's gas).
            _assignProceeds(seller, proceeds);
        }
        
        AuctionSuccessful(_buyer, _deedId, price);
        
        // The bid was won!
        _winBid(seller, _buyer, _deedId, price);
        
        // Remove the auction (we do this at the end, as
        // winBid might require some additional information
        // that will be removed when _removeAuction is
        // called. As we do not transfer funds here, we do
        // not have to worry about re-entry attacks.
        _removeAuction(_deedId);
    }

    /// @dev Perform the bid win logic (in this case: transfer the deed).
    /// @param _seller The address of the seller.
    /// @param _winner The address of the winner.
    /// @param _deedId The identifier of the deed.
    /// @param _price The price the auction was bought at.
    function _winBid(address _seller, address _winner, uint256 _deedId, uint256 _price) internal {
        _transfer(_winner, _deedId);
    }
    
    /// @dev Cancel an auction.
    /// @param _deedId The identifier of the deed for which the auction should be cancelled.
    /// @param auction The auction to cancel.
    function _cancelAuction(uint256 _deedId, Auction auction) internal {
        // Remove the auction
        _removeAuction(_deedId);
        
        // Transfer the deed back to the seller
        _transfer(auction.seller, _deedId);
        
        // Trigger auction cancelled event.
        AuctionCancelled(_deedId);
    }
    
    /// @dev Remove an auction.
    /// @param _deedId The identifier of the deed for which the auction should be removed.
    function _removeAuction(uint256 _deedId) internal {
        delete identifierToAuction[_deedId];
    }
    
    /// @dev Transfer a deed owned by this contract to another address.
    /// @param _to The address to transfer the deed to.
    /// @param _deedId The identifier of the deed.
    function _transfer(address _to, uint256 _deedId) internal {
        // Throws if the transfer fails
        deedContract.transfer(_to, _deedId);
    }
    
    /// @dev Assign proceeds to an address.
    /// @param _to The address to assign proceeds to.
    /// @param _value The proceeds to assign.
    function _assignProceeds(address _to, uint256 _value) internal {
        outstandingEther += _value;
        addressToEtherOwed[_to] += _value;
    }
    
    /// @dev Calculate the current price of an auction.
    function _currentPrice(Auction storage _auction) internal view returns (uint256) {
        require(now >= _auction.startedAt);
        
        uint256 secondsPassed = now - _auction.startedAt;
        
        if (secondsPassed >= _auction.duration) {
            return _auction.endPrice;
        } else {
            // Negative if the end price is higher than the start price!
            int256 totalPriceChange = int256(_auction.endPrice) - int256(_auction.startPrice);
            
            // Calculate the current price based on the total change over the entire
            // auction duration, and the amount of time passed since the start of the
            // auction.
            int256 currentPriceChange = totalPriceChange * int256(secondsPassed) / int256(_auction.duration);
            
            // Calculate the final price. Note this once again
            // is representable by a uint256, as the price can
            // never be negative.
            int256 price = int256(_auction.startPrice) + currentPriceChange;
            
            // This never throws.
            assert(price >= 0);
            
            return uint256(price);
        }
    }
    
    /// @dev Calculate the fee for a given price.
    /// @param _price The price to calculate the fee for.
    function _calculateFee(uint256 _price) internal view returns (uint256) {
        // _price is guaranteed to fit in a uint128 due to the createAuction entry
        // modifiers, so this cannot overflow.
        return _price * fee / 100000;
    }
}


contract ClockAuction is ClockAuctionBase, Pausable {
    function ClockAuction(address _deedContractAddress, uint256 _fee) 
        ClockAuctionBase(_deedContractAddress, _fee)
        public
    {}
    
    /// @notice Update the auction fee.
    /// @param _fee The new fee.
    function setFee(uint256 _fee) external onlyOwner {
        require(0 <= _fee && _fee <= 100000);
    
        fee = _fee;
    }
    
    /// @notice Get the auction for the given deed.
    /// @param _deedId The identifier of the deed to get the auction for.
    /// @dev Throws if there is no auction for the given deed.
    function getAuction(uint256 _deedId) external view returns (
            address seller,
            uint256 startPrice,
            uint256 endPrice,
            uint256 duration,
            uint256 startedAt
        )
    {
        Auction storage auction = identifierToAuction[_deedId];
        
        // The auction must be active
        require(_activeAuction(auction));
        
        return (
            auction.seller,
            auction.startPrice,
            auction.endPrice,
            auction.duration,
            auction.startedAt
        );
    }

    /// @notice Create an auction for a given deed.
    /// Must previously have been given approval to take ownership of the deed.
    /// @param _deedId The identifier of the deed to create an auction for.
    /// @param _startPrice The starting price of the auction.
    /// @param _endPrice The ending price of the auction.
    /// @param _duration The duration in seconds of the dynamic pricing part of the auction.
    function createAuction(uint256 _deedId, uint256 _startPrice, uint256 _endPrice, uint256 _duration)
        public
        fitsIn128Bits(_startPrice)
        fitsIn128Bits(_endPrice)
        fitsIn64Bits(_duration)
        whenNotPaused
    {
        // Get the owner of the deed to be auctioned
        address deedOwner = deedContract.ownerOf(_deedId);
    
        // Caller must either be the deed contract or the owner of the deed
        // to prevent abuse.
        require(
            msg.sender == address(deedContract) ||
            msg.sender == deedOwner
        );
    
        // The duration of the auction must be at least 60 seconds.
        require(_duration >= 60);
    
        // Throws if placing the deed in escrow fails (the contract requires
        // transfer approval prior to creating the auction).
        _escrow(_deedId);
        
        // Auction struct
        Auction memory auction = Auction(
            deedOwner,
            uint128(_startPrice),
            uint128(_endPrice),
            uint64(_duration),
            uint64(now)
        );
        
        _createAuction(_deedId, auction);
    }
    
    /// @notice Cancel an auction
    /// @param _deedId The identifier of the deed to cancel the auction for.
    function cancelAuction(uint256 _deedId) external whenNotPaused {
        Auction storage auction = identifierToAuction[_deedId];
        
        // The auction must be active.
        require(_activeAuction(auction));
        
        // The auction can only be cancelled by the seller
        require(msg.sender == auction.seller);
        
        _cancelAuction(_deedId, auction);
    }
    
    /// @notice Bid on an auction.
    /// @param _deedId The identifier of the deed to bid on.
    function bid(uint256 _deedId) external payable whenNotPaused {
        // Throws if the bid does not succeed.
        _bid(msg.sender, msg.value, _deedId);
    }
    
    /// @dev Returns the current price of an auction.
    /// @param _deedId The identifier of the deed to get the currency price for.
    function getCurrentPrice(uint256 _deedId) external view returns (uint256) {
        Auction storage auction = identifierToAuction[_deedId];
        
        // The auction must be active.
        require(_activeAuction(auction));
        
        return _currentPrice(auction);
    }
    
    /// @notice Withdraw ether owed to a beneficiary.
    /// @param beneficiary The address to withdraw the auction balance for.
    function withdrawAuctionBalance(address beneficiary) external {
        // The sender must either be the beneficiary or the core deed contract.
        require(
            msg.sender == beneficiary ||
            msg.sender == address(deedContract)
        );
        
        uint256 etherOwed = addressToEtherOwed[beneficiary];
        
        // Ensure ether is owed to the beneficiary.
        require(etherOwed > 0);
         
        // Set ether owed to 0   
        delete addressToEtherOwed[beneficiary];
        
        // Subtract from total outstanding balance. etherOwed is guaranteed
        // to be less than or equal to outstandingEther, so this cannot
        // underflow.
        outstandingEther -= etherOwed;
        
        // Transfer ether owed to the beneficiary (not susceptible to re-entry
        // attack, as the ether owed is set to 0 before the transfer takes place).
        beneficiary.transfer(etherOwed);
    }
    
    /// @notice Withdraw (unowed) contract balance.
    function withdrawFreeBalance() external {
        // Calculate the free (unowed) balance. This never underflows, as
        // outstandingEther is guaranteed to be less than or equal to the
        // contract balance.
        uint256 freeBalance = this.balance - outstandingEther;
        
        address deedContractAddress = address(deedContract);

        require(
            msg.sender == owner ||
            msg.sender == deedContractAddress
        );
        
        deedContractAddress.transfer(freeBalance);
    }
}


/// @dev Defines base data structures for DWorld.
contract OriginalDWorldBase is DWorldAccessControl {
    using SafeMath for uint256;
    
    /// @dev All minted plots (array of plot identifiers). There are
    /// 2^16 * 2^16 possible plots (covering the entire world), thus
    /// 32 bits are required. This fits in a uint32. Storing
    /// the identifiers as uint32 instead of uint256 makes storage
    /// cheaper. (The impact of this in mappings is less noticeable,
    /// and using uint32 in the mappings below actually *increases*
    /// gas cost for minting).
    uint32[] public plots;
    
    mapping (uint256 => address) identifierToOwner;
    mapping (uint256 => address) identifierToApproved;
    mapping (address => uint256) ownershipDeedCount;
    
    /// @dev Event fired when a plot's data are changed. The plot
    /// data are not stored in the contract directly, instead the
    /// data are logged to the block. This gives significant
    /// reductions in gas requirements (~75k for minting with data
    /// instead of ~180k). However, it also means plot data are
    /// not available from *within* other contracts.
    event SetData(uint256 indexed deedId, string name, string description, string imageUrl, string infoUrl);
    
    /// @notice Get all minted plots.
    function getAllPlots() external view returns(uint32[]) {
        return plots;
    }
    
    /// @dev Represent a 2D coordinate as a single uint.
    /// @param x The x-coordinate.
    /// @param y The y-coordinate.
    function coordinateToIdentifier(uint256 x, uint256 y) public pure returns(uint256) {
        require(validCoordinate(x, y));
        
        return (y << 16) + x;
    }
    
    /// @dev Turn a single uint representation of a coordinate into its x and y parts.
    /// @param identifier The uint representation of a coordinate.
    function identifierToCoordinate(uint256 identifier) public pure returns(uint256 x, uint256 y) {
        require(validIdentifier(identifier));
    
        y = identifier >> 16;
        x = identifier - (y << 16);
    }
    
    /// @dev Test whether the coordinate is valid.
    /// @param x The x-part of the coordinate to test.
    /// @param y The y-part of the coordinate to test.
    function validCoordinate(uint256 x, uint256 y) public pure returns(bool) {
        return x < 65536 && y < 65536; // 2^16
    }
    
    /// @dev Test whether an identifier is valid.
    /// @param identifier The identifier to test.
    function validIdentifier(uint256 identifier) public pure returns(bool) {
        return identifier < 4294967296; // 2^16 * 2^16
    }
    
    /// @dev Set a plot's data.
    /// @param identifier The identifier of the plot to set data for.
    function _setPlotData(uint256 identifier, string name, string description, string imageUrl, string infoUrl) internal {
        SetData(identifier, name, description, imageUrl, infoUrl);
    }
}


/// @dev Holds deed functionality such as approving and transferring. Implements ERC721.
contract OriginalDWorldDeed is OriginalDWorldBase, ERC721, ERC721Metadata {
    
    /// @notice Name of the collection of deeds (non-fungible token), as defined in ERC721Metadata.
    function name() public pure returns (string _deedName) {
        _deedName = "DWorld Plots";
    }
    
    /// @notice Symbol of the collection of deeds (non-fungible token), as defined in ERC721Metadata.
    function symbol() public pure returns (string _deedSymbol) {
        _deedSymbol = "DWP";
    }
    
    /// @dev ERC-165 (draft) interface signature for itself
    bytes4 internal constant INTERFACE_SIGNATURE_ERC165 = // 0x01ffc9a7
        bytes4(keccak256('supportsInterface(bytes4)'));

    /// @dev ERC-165 (draft) interface signature for ERC721
    bytes4 internal constant INTERFACE_SIGNATURE_ERC721 = // 0xda671b9b
        bytes4(keccak256('ownerOf(uint256)')) ^
        bytes4(keccak256('countOfDeeds()')) ^
        bytes4(keccak256('countOfDeedsByOwner(address)')) ^
        bytes4(keccak256('deedOfOwnerByIndex(address,uint256)')) ^
        bytes4(keccak256('approve(address,uint256)')) ^
        bytes4(keccak256('takeOwnership(uint256)'));
        
    /// @dev ERC-165 (draft) interface signature for ERC721
    bytes4 internal constant INTERFACE_SIGNATURE_ERC721Metadata = // 0x2a786f11
        bytes4(keccak256('name()')) ^
        bytes4(keccak256('symbol()')) ^
        bytes4(keccak256('deedUri(uint256)'));
    
    /// @notice Introspection interface as per ERC-165 (https://github.com/ethereum/EIPs/issues/165).
    /// Returns true for any standardized interfaces implemented by this contract.
    /// (ERC-165 and ERC-721.)
    function supportsInterface(bytes4 _interfaceID) external pure returns (bool) {
        return (
            (_interfaceID == INTERFACE_SIGNATURE_ERC165)
            || (_interfaceID == INTERFACE_SIGNATURE_ERC721)
            || (_interfaceID == INTERFACE_SIGNATURE_ERC721Metadata)
        );
    }
    
    /// @dev Checks if a given address owns a particular plot.
    /// @param _owner The address of the owner to check for.
    /// @param _deedId The plot identifier to check for.
    function _owns(address _owner, uint256 _deedId) internal view returns (bool) {
        return identifierToOwner[_deedId] == _owner;
    }
    
    /// @dev Approve a given address to take ownership of a deed.
    /// @param _from The address approving taking ownership.
    /// @param _to The address to approve taking ownership.
    /// @param _deedId The identifier of the deed to give approval for.
    function _approve(address _from, address _to, uint256 _deedId) internal {
        identifierToApproved[_deedId] = _to;
        
        // Emit event.
        Approval(_from, _to, _deedId);
    }
    
    /// @dev Checks if a given address has approval to take ownership of a deed.
    /// @param _claimant The address of the claimant to check for.
    /// @param _deedId The identifier of the deed to check for.
    function _approvedFor(address _claimant, uint256 _deedId) internal view returns (bool) {
        return identifierToApproved[_deedId] == _claimant;
    }
    
    /// @dev Assigns ownership of a specific deed to an address.
    /// @param _from The address to transfer the deed from.
    /// @param _to The address to transfer the deed to.
    /// @param _deedId The identifier of the deed to transfer.
    function _transfer(address _from, address _to, uint256 _deedId) internal {
        // The number of plots is capped at 2^16 * 2^16, so this cannot
        // be overflowed.
        ownershipDeedCount[_to]++;
        
        // Transfer ownership.
        identifierToOwner[_deedId] = _to;
        
        // When a new deed is minted, the _from address is 0x0, but we
        // do not track deed ownership of 0x0.
        if (_from != address(0)) {
            ownershipDeedCount[_from]--;
            
            // Clear taking ownership approval.
            delete identifierToApproved[_deedId];
        }
        
        // Emit the transfer event.
        Transfer(_from, _to, _deedId);
    }
    
    // ERC 721 implementation
    
    /// @notice Returns the total number of deeds currently in existence.
    /// @dev Required for ERC-721 compliance.
    function countOfDeeds() public view returns (uint256) {
        return plots.length;
    }
    
    /// @notice Returns the number of deeds owned by a specific address.
    /// @param _owner The owner address to check.
    /// @dev Required for ERC-721 compliance
    function countOfDeedsByOwner(address _owner) public view returns (uint256) {
        return ownershipDeedCount[_owner];
    }
    
    /// @notice Returns the address currently assigned ownership of a given deed.
    /// @dev Required for ERC-721 compliance.
    function ownerOf(uint256 _deedId) external view returns (address _owner) {
        _owner = identifierToOwner[_deedId];

        require(_owner != address(0));
    }
    
    /// @notice Approve a given address to take ownership of a deed.
    /// @param _to The address to approve taking owernship.
    /// @param _deedId The identifier of the deed to give approval for.
    /// @dev Required for ERC-721 compliance.
    function approve(address _to, uint256 _deedId) external whenNotPaused {
        uint256[] memory _deedIds = new uint256[](1);
        _deedIds[0] = _deedId;
        
        approveMultiple(_to, _deedIds);
    }
    
    /// @notice Approve a given address to take ownership of multiple deeds.
    /// @param _to The address to approve taking ownership.
    /// @param _deedIds The identifiers of the deeds to give approval for.
    function approveMultiple(address _to, uint256[] _deedIds) public whenNotPaused {
        // Ensure the sender is not approving themselves.
        require(msg.sender != _to);
    
        for (uint256 i = 0; i < _deedIds.length; i++) {
            uint256 _deedId = _deedIds[i];
            
            // Require the sender is the owner of the deed.
            require(_owns(msg.sender, _deedId));
            
            // Perform the approval.
            _approve(msg.sender, _to, _deedId);
        }
    }
    
    /// @notice Transfer a deed to another address. If transferring to a smart
    /// contract be VERY CAREFUL to ensure that it is aware of ERC-721, or your
    /// deed may be lost forever.
    /// @param _to The address of the recipient, can be a user or contract.
    /// @param _deedId The identifier of the deed to transfer.
    /// @dev Required for ERC-721 compliance.
    function transfer(address _to, uint256 _deedId) external whenNotPaused {
        uint256[] memory _deedIds = new uint256[](1);
        _deedIds[0] = _deedId;
        
        transferMultiple(_to, _deedIds);
    }
    
    /// @notice Transfers multiple deeds to another address. If transferring to
    /// a smart contract be VERY CAREFUL to ensure that it is aware of ERC-721,
    /// or your deeds may be lost forever.
    /// @param _to The address of the recipient, can be a user or contract.
    /// @param _deedIds The identifiers of the deeds to transfer.
    function transferMultiple(address _to, uint256[] _deedIds) public whenNotPaused {
        // Safety check to prevent against an unexpected 0x0 default.
        require(_to != address(0));
        
        // Disallow transfers to this contract to prevent accidental misuse.
        require(_to != address(this));
    
        for (uint256 i = 0; i < _deedIds.length; i++) {
            uint256 _deedId = _deedIds[i];
            
            // One can only transfer their own plots.
            require(_owns(msg.sender, _deedId));

            // Transfer ownership
            _transfer(msg.sender, _to, _deedId);
        }
    }
    
    /// @notice Transfer a deed owned by another address, for which the calling
    /// address has previously been granted transfer approval by the owner.
    /// @param _deedId The identifier of the deed to be transferred.
    /// @dev Required for ERC-721 compliance.
    function takeOwnership(uint256 _deedId) external whenNotPaused {
        uint256[] memory _deedIds = new uint256[](1);
        _deedIds[0] = _deedId;
        
        takeOwnershipMultiple(_deedIds);
    }
    
    /// @notice Transfer multiple deeds owned by another address, for which the
    /// calling address has previously been granted transfer approval by the owner.
    /// @param _deedIds The identifier of the deed to be transferred.
    function takeOwnershipMultiple(uint256[] _deedIds) public whenNotPaused {
        for (uint256 i = 0; i < _deedIds.length; i++) {
            uint256 _deedId = _deedIds[i];
            address _from = identifierToOwner[_deedId];
            
            // Check for transfer approval
            require(_approvedFor(msg.sender, _deedId));

            // Reassign ownership (also clears pending approvals and emits Transfer event).
            _transfer(_from, msg.sender, _deedId);
        }
    }
    
    /// @notice Returns a list of all deed identifiers assigned to an address.
    /// @param _owner The owner whose deeds we are interested in.
    /// @dev This method MUST NEVER be called by smart contract code. It's very
    /// expensive and is not supported in contract-to-contract calls as it returns
    /// a dynamic array (only supported for web3 calls).
    function deedsOfOwner(address _owner) external view returns(uint256[]) {
        uint256 deedCount = countOfDeedsByOwner(_owner);

        if (deedCount == 0) {
            // Return an empty array.
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](deedCount);
            uint256 totalDeeds = countOfDeeds();
            uint256 resultIndex = 0;
            
            for (uint256 deedNumber = 0; deedNumber < totalDeeds; deedNumber++) {
                uint256 identifier = plots[deedNumber];
                if (identifierToOwner[identifier] == _owner) {
                    result[resultIndex] = identifier;
                    resultIndex++;
                }
            }

            return result;
        }
    }
    
    /// @notice Returns a deed identifier of the owner at the given index.
    /// @param _owner The address of the owner we want to get a deed for.
    /// @param _index The index of the deed we want.
    function deedOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256) {
        // The index should be valid.
        require(_index < countOfDeedsByOwner(_owner));

        // Loop through all plots, accounting the number of plots of the owner we've seen.
        uint256 seen = 0;
        uint256 totalDeeds = countOfDeeds();
        
        for (uint256 deedNumber = 0; deedNumber < totalDeeds; deedNumber++) {
            uint256 identifier = plots[deedNumber];
            if (identifierToOwner[identifier] == _owner) {
                if (seen == _index) {
                    return identifier;
                }
                
                seen++;
            }
        }
    }
    
    /// @notice Returns an (off-chain) metadata url for the given deed.
    /// @param _deedId The identifier of the deed to get the metadata
    /// url for.
    /// @dev Implementation of optional ERC-721 functionality.
    function deedUri(uint256 _deedId) external pure returns (string uri) {
        require(validIdentifier(_deedId));
    
        var (x, y) = identifierToCoordinate(_deedId);
    
        // Maximum coordinate length in decimals is 5 (65535)
        uri = "https://dworld.io/plot/xxxxx/xxxxx";
        bytes memory _uri = bytes(uri);
        
        for (uint256 i = 0; i < 5; i++) {
            _uri[27 - i] = byte(48 + (x / 10 ** i) % 10);
            _uri[33 - i] = byte(48 + (y / 10 ** i) % 10);
        }
    }
}


/// @dev Migrate original data from the old contract.
contract DWorldUpgrade is DWorldMinting {
    OriginalDWorldDeed originalContract;
    ClockAuction originalSaleAuction;
    ClockAuction originalRentAuction;
    
    /// @notice Keep track of whether we have finished migrating.
    bool public migrationFinished = false;
    
    /// @dev Keep track of how many plots have been transferred so far.
    uint256 migrationNumPlotsTransferred = 0;
    
    function DWorldUpgrade(
        address originalContractAddress,
        address originalSaleAuctionAddress,
        address originalRentAuctionAddress
    )
        public
    {
        if (originalContractAddress != 0) {
            _startMigration(originalContractAddress, originalSaleAuctionAddress, originalRentAuctionAddress);
        } else {
            migrationFinished = true;
        }
    }
    
    /// @dev Migrate data from the original contract. Assumes the original
    /// contract is paused, and remains paused for the duration of the
    /// migration.
    /// @param originalContractAddress The address of the original contract.
    function _startMigration(
        address originalContractAddress,
        address originalSaleAuctionAddress,
        address originalRentAuctionAddress
    )
        internal
    {
        // Set contracts.
        originalContract = OriginalDWorldDeed(originalContractAddress);
        originalSaleAuction = ClockAuction(originalSaleAuctionAddress);
        originalRentAuction = ClockAuction(originalRentAuctionAddress);
        
        // Start paused.
        paused = true;
        
        // Get count of original plots.
        uint256 numPlots = originalContract.countOfDeeds();
        
        // Allocate storage for the plots array (this is more
        // efficient than .push-ing each individual plot, as
        // that requires multiple dynamic allocations).
        plots.length = numPlots;
    }
    
    function migrationStep(uint256 numPlotsTransfer) external onlyOwner whenPaused {
        // Migration must not be finished yet.
        require(!migrationFinished);
    
        // Get count of original plots.
        uint256 numPlots = originalContract.countOfDeeds();
    
        // Loop through plots and assign to original owner.
        uint256 i;
        for (i = migrationNumPlotsTransferred; i < numPlots && i < migrationNumPlotsTransferred + numPlotsTransfer; i++) {
            uint32 _deedId = originalContract.plots(i);
            
            // Set plot.
            plots[i] = _deedId;
            
            // Get the original owner and transfer.
            address owner = originalContract.ownerOf(_deedId);
            
            // If the owner of the plot is an auction contract,
            // get the actual owner of the plot.
            address seller;
            if (owner == address(originalSaleAuction)) {
                (seller, ) = originalSaleAuction.getAuction(_deedId);
                owner = seller;
            } else if (owner == address(originalRentAuction)) {
                (seller, ) = originalRentAuction.getAuction(_deedId);
                owner = seller;
            }
            
            _transfer(address(0), owner, _deedId);
            
            // Set the initial price paid for the plot.
            initialPricePaid[_deedId] = 0.0125 ether;
            
            // The initial buyout price.
            uint256 _initialBuyoutPrice = 0.050 ether;
            
            // Set the initial buyout price.
            identifierToBuyoutPrice[_deedId] = _initialBuyoutPrice;
            
            // Trigger the buyout price event.
            SetBuyoutPrice(_deedId, _initialBuyoutPrice);
            
            // Mark the plot as being an original.
            identifierIsOriginal[_deedId] = true;
        }
        
        migrationNumPlotsTransferred += i;
        
        // Finished migration.
        if (i == numPlots) {
            migrationFinished = true;
        }
    }
}


/// @dev Implements highest-level DWorld functionality.
contract DWorldCore is DWorldUpgrade {
    /// If this contract is broken, this will be used to publish the address at which an upgraded contract can be found
    address public upgradedContractAddress;
    event ContractUpgrade(address upgradedContractAddress);

    function DWorldCore(
        address originalContractAddress,
        address originalSaleAuctionAddress,
        address originalRentAuctionAddress,
        uint256 buyoutsEnabledAfterHours
    )
        DWorldUpgrade(originalContractAddress, originalSaleAuctionAddress, originalRentAuctionAddress)
        public 
    {
        buyoutsEnabledFromTimestamp = block.timestamp + buyoutsEnabledAfterHours * 3600;
    }
    
    /// @notice Only to be used when this contract is significantly broken,
    /// and an upgrade is required.
    function setUpgradedContractAddress(address _upgradedContractAddress) external onlyOwner whenPaused {
        upgradedContractAddress = _upgradedContractAddress;
        ContractUpgrade(_upgradedContractAddress);
    }

    /// @notice Set the data associated with a plot.
    function setPlotData(uint256 _deedId, string name, string description, string imageUrl, string infoUrl)
        public
        whenNotPaused
    {
        // The sender requesting the data update should be
        // the owner.
        require(_owns(msg.sender, _deedId));
    
        // Set the data
        _setPlotData(_deedId, name, description, imageUrl, infoUrl);
    }
    
    /// @notice Set the data associated with multiple plots.
    function setPlotDataMultiple(uint256[] _deedIds, string name, string description, string imageUrl, string infoUrl)
        external
        whenNotPaused
    {
        for (uint256 i = 0; i < _deedIds.length; i++) {
            uint256 _deedId = _deedIds[i];
        
            setPlotData(_deedId, name, description, imageUrl, infoUrl);
        }
    }
    
    /// @notice Withdraw Ether owed to the sender.
    function withdrawBalance() external {
        uint256 etherOwed = addressToEtherOwed[msg.sender];
        
        // Ensure Ether is owed to the sender.
        require(etherOwed > 0);
         
        // Set Ether owed to 0.
        delete addressToEtherOwed[msg.sender];
        
        // Subtract from total outstanding balance. etherOwed is guaranteed
        // to be less than or equal to outstandingEther, so this cannot
        // underflow.
        outstandingEther -= etherOwed;
        
        // Transfer Ether owed to the sender (not susceptible to re-entry
        // attack, as the Ether owed is set to 0 before the transfer takes place).
        msg.sender.transfer(etherOwed);
    }
    
    /// @notice Withdraw (unowed) contract balance.
    function withdrawFreeBalance() external onlyCFO {
        // Calculate the free (unowed) balance. This never underflows, as
        // outstandingEther is guaranteed to be less than or equal to the
        // contract balance.
        uint256 freeBalance = this.balance - outstandingEther;
        
        cfoAddress.transfer(freeBalance);
    }
}