public function which($executable, $fallback = false)
    {
        if (is_string($executable)) {
            if (trim($executable) === '') {
                return $fallback;
            }
        } else {
            return $fallback;
        }
        if (basename($executable) === $executable) {
            $path = getenv("PATH");
        } else {
            $path = dirname($executable);
        }
        $dirSeparator = $this->getSeparator();
        $pathSeparator = $this->getPathSeparator();
        $elements = explode($pathSeparator, $path);
        $amount = count($elements);
        $fstype = Phing::getProperty('host.fstype');
        switch ($fstype) {
            case 'UNIX':
                for ($count = 0; $count < $amount; ++$count) {
                    $file = $elements[$count] . $dirSeparator . $executable;
                    if (file_exists($file) && is_executable($file)) {
                        return $file;
                    }
                }
                break;
            case 'WINDOWS':
                $exts = getenv('PATHEXT');
                if ($exts === false) {
                    $exts = ['.exe', '.bat', '.cmd', '.com'];
                } else {
                    $exts = explode($pathSeparator, $exts);
                }
                for ($count = 0; $count < $amount; $count++) {
                    foreach ($exts as $ext) {
                        $file = $elements[$count] . $dirSeparator . $executable . $ext;
                        // Not all of the extensions above need to be set executable on Windows for them to be executed.
                        // I'm sure there's a joke here somewhere.
                        if (file_exists($file)) {
                            return $file;
                        }
                    }
                }
                break;
        }
        if (file_exists($executable) && is_executable($executable)) {
            return $executable;
        }
        return $fallback;
    }