function startWatching(opts) {
    var chokidarOpts = createChokidarOpts(opts);
    var watcher = chokidar.watch(opts.patterns, chokidarOpts);

    var throttledRun = _.throttle(run, opts.throttle);
    var debouncedRun = _.debounce(throttledRun, opts.debounce);
    watcher.on('all', function(event, path) {
        var description = EVENT_DESCRIPTIONS[event] + ':';

        if (opts.verbose) {
            console.error(description, path);
        } else {
            if (!opts.silent) {
                console.log(event + ':' + path);
            }
        }

        // XXX: commands might be still run concurrently
        if (opts.command) {
            debouncedRun(
                opts.command
                    .replace(/\{path\}/ig, path)
                    .replace(/\{event\}/ig, event)
            );
        }
    });

    watcher.on('error', function(error) {
        console.error('Error:', error);
        console.error(error.stack);
    });

    watcher.once('ready', function() {
        var list = opts.patterns.join('", "');
        if (!opts.silent) {
            console.error('Watching', '"' + list + '" ..');
        }
    });
}