// Contract: InstaConnectors
// Target function: function removeFromList(address _connector) internal
pragma solidity ^0.6.0;

/**
 * @title InstaConnectors
 * @dev Registry for Connectors.
 */


interface IndexInterface {
    function master() external view returns (address);
}


contract DSMath {

    function add(uint x, uint y) internal pure returns (uint z) {
        require((z = x + y) >= x, "ds-math-add-overflow");
    }

    function sub(uint x, uint y) internal pure returns (uint z) {
        require((z = x - y) <= x, "ds-math-sub-underflow");
    }

}

contract Controllers is DSMath {

    event LogAddController(address addr);
    event LogRemoveController(address addr);

     // The InstaIndex Address.
    address public constant instaIndex = 0x1c503F1544500C05da80cd326D97342f2B13a732;

    // Enabled Cheif(Address of Cheif => bool).
    mapping(address => bool) public chief;
    // Enabled Connectors(Connector Address => bool).
    mapping(address => bool) public connectors;
    // Enbled Static Connectors(Connector Address => bool).
    mapping(address => bool) public staticConnectors;

    /**
    * @dev Throws if the sender not is Master Address from InstaIndex
    * or Enabled Cheif.
    */
    modifier isChief {
        require(chief[msg.sender] || msg.sender == IndexInterface(instaIndex).master(), "not-an-chief");
        _;
    }

    /**
     * @dev Enable a Cheif.
     * @param _userAddress Cheif Address.
    */
    function enableChief(address _userAddress) external isChief {
        chief[_userAddress] = true;
        emit LogAddController(_userAddress);
    }

    /**
     * @dev Disables a Cheif.
     * @param _userAddress Cheif Address.
    */
    function disableChief(address _userAddress) external isChief {
        delete chief[_userAddress];
        emit LogRemoveController(_userAddress);
    }

}


contract LinkedList is Controllers {

    event LogEnable(address indexed connector);
    event LogDisable(address indexed connector);
    event LogEnableStatic(address indexed connector);

    // Connectors Count.
    uint public count;
    // First enabled Connector Address.
    address public first;
    // Last enabled Connector Address.
    address public last;
    // Connectors List(Address of Connector => List(Previous and Next Enabled Connector)).
    mapping (address => List) public list;

    struct List {
        address prev;
        address next;
    }


    /**
     * @dev Add Connector to Connector's Linked List.
     * @param _connector Connector Address.
    */
    function addToList(address _connector) internal {
        if (last != address(0)) {
            list[_connector].prev = last;
            list[last].next = _connector;
        }
        if (first == address(0)) {
            first = _connector;
        }
        last = _connector;
        count = add(count, 1);

        emit LogEnable(_connector);
    }