contract Controller is AbstractSweeperList {
    address public owner;
    address public authorizedCaller;

    //destination defaults to same as owner
    //but is separate to allow never exposing cold storage
    address public destination; 

    bool public halted;

    event LogNewWallet(uint _customer, address receiver);
    event LogSweep(address from, address token, uint amount);
    event LogFailedSweep(address from, address token, uint amount);
    
    modifier onlyOwner() {
        if (msg.sender != owner) throw; 
        _;
    }

    modifier onlyAuthorizedCaller() {
        if (msg.sender != authorizedCaller) throw; 
        _;
    }

    modifier onlyAdmins() {
        if (msg.sender != authorizedCaller && msg.sender != owner) throw; 
        _;
    }

    function Controller() 
    {
        owner = msg.sender;
        destination = msg.sender;
        authorizedCaller = msg.sender;
    }

    function changeAuthorizedCaller(address _newCaller) onlyOwner {
        authorizedCaller = _newCaller;
    }

    function changeDestination(address _dest) onlyOwner {
        destination = _dest;
    }

    function changeOwner(address _owner) onlyOwner {
        owner = _owner;
    }

    function makeWallet(uint _customer) onlyAdmins returns (address wallet)  {
        wallet = address(new UserWallet(this));
        LogNewWallet(_customer, wallet);
    }

    //assuming halt because caller is compromised
    //so let caller stop for speed, only owner can restart

    function halt() onlyAdmins {
        halted = true;
    }

    function start() onlyOwner {
        halted = false;
    }

    //***********
    //SweeperList
    //***********
    address public defaultSweeper = address(new DefaultSweeper(this));
    mapping (address => address) sweepers;

    function addSweeper(address _token, address _sweeper) onlyOwner {
        sweepers[_token] = _sweeper;
    }

    function sweeperOf(address _token) returns (address) {
        address sweeper = sweepers[_token];
        if (sweeper == 0) sweeper = defaultSweeper;
        return sweeper;
    }

    function logSweep(address from, address token, uint amount) {
        LogSweep(from, token, amount);
    }
    function logFailedSweep(address from, address token, uint amount) {
        LogFailedSweep(from, token, amount);
    }
}
function halt() onlyAdmins {
        halted = true;
    }
//assuming halt because caller is compromised
//so let caller stop for speed, only owner can restart