public static function parse($dotenv, $data = [], $flags = self::FLAG_STRICT)
    {
        if (!is_array($dotenv)) {
            $dotenv = explode("\n", $dotenv);
        }
        $result = (!empty($data)) ? $data : [];

        // nothing to do with empty dotenv
        if (empty($dotenv)) {
            return $result;
        }

        // FLAG_REPLACE_DUPLICATES and FLAG_STRICT are mutually exclusive
        if (($flags & static::FLAG_REPLACE_DUPLICATES) &&  ($flags & static::FLAG_STRICT)) {
            throw new InvalidArgumentException("Can't use FLAG_REPLACE_DUPLICATES and FLAG_STRICT together");
        }

        foreach ($dotenv as $line) {
            $line = trim($line);

            // Disregard comments
            if (strpos($line, '#') === 0) {
                continue;
            }

            // Only use nont-empty lines that look like setters
            if (!preg_match('#^\s*(.+?)=(.*)?$#', $line, $matches)) {
                continue;
            }

            $name = static::normalizeName($matches[1]);

            $value = static::normalizeValue(trim($matches[2]));
            $value = static::resolveNested($value, $result);

            if ($value === "" && ($flags & static::FLAG_SKIP_EMPTY)) {
                continue;
            }

            if (!isset($result[$name]) || ($flags & static::FLAG_REPLACE_DUPLICATES)) {
                $result[$name] = $value;
                continue;
            }

            if ($flags & static::FLAG_STRICT) {
                throw new RuntimeException("Duplicate value found for variable '$name'");
            }
        }

        return $result;
    }