protected function checkChangedFiles($restartSlaves = true)
    {
        if ($this->inChangesDetectionCycle) {
            return false;
        }

        $start = microtime(true);
        $hasChanged = false;

        $this->inChangesDetectionCycle = true;

        clearstatcache();

        foreach ($this->filesLastMTime as $filePath => $knownMTime) {
            if (!file_exists($filePath)) {
                continue;
            }

            $actualFileTime = filemtime($filePath);
            $actualFileHash = md5_file($filePath);

            if ($knownMTime !== $actualFileTime && $this->filesLastMd5[$filePath] !== $actualFileHash) {

                // update tracked entry metadata
                $this->filesLastMd5[$filePath] = $actualFileHash;
                $this->filesLastMTime[$filePath] = $actualFileTime;

                $this->output->writeln(
                    sprintf("<info>[%s] File %s has changed.</info>", date('d/M/Y:H:i:s O'), $filePath)
                );
                $hasChanged = true;
                break;
            }
        }

        if ($hasChanged) {
            $this->output->writeln(
                sprintf(
                    "<info>[%s] At least one of %u known files was changed. Reloading workers.</info>",
                    date('d/M/Y:H:i:s O'),
                    count($this->filesLastMTime)
                )
            );

            if ($this->output->isVeryVerbose()) {
                $this->output->writeln(
                    sprintf("Changes detection cycle length = %.3f ms", (microtime(true) - $start) * 1000)
                );
            }

            if ($restartSlaves) {
                $this->restartSlaves();
            }
        }

        $this->inChangesDetectionCycle = false;

        return $hasChanged;
    }