public static function replace($subject, $search, $replacement, $quoteStrings = false)
    {
        /*
         * Unknown source or item to find or replacement is an empty array?
         * Nothing to do
         */
        if (empty($subject) || empty($search) || [] === $replacement) {
            return $subject;
        }

        $effect = $subject;

        $searchIsString = is_string($search);
        $searchIsArray = is_array($search);

        /*
         * Value to find is neither a string nor an array OR it's an empty string?
         * Nothing to do
         */
        if ((!$searchIsString && !$searchIsArray) || ($searchIsString && '' === $search)) {
            return $effect;
        }

        $replacementIsString = is_string($replacement);
        $replacementIsArray = is_array($replacement);

        $bothAreStrings = $searchIsString && $replacementIsString;
        $bothAreArrays = $searchIsArray && $replacementIsArray;

        if ($quoteStrings) {
            if ($replacementIsString) {
                $replacement = '\'' . $replacement . '\'';
            } elseif ($replacementIsArray) {
                foreach ($replacement as &$item) {
                    if (is_string($item)) {
                        $item = '\'' . $item . '\'';
                    }
                }

                unset($item);
            }
        }

        // 1st step: replace strings, simple operation with strings
        if ($bothAreStrings) {
            $effect = str_replace($search, $replacement, $subject);
        }

        /*
         * 2nd step: replace with regular expressions.
         * Attention. Searched and replacement value should be the same type: strings or arrays.
         */
        if ($effect === $subject && ($bothAreStrings || $bothAreArrays)) {
            /*
             * I have to avoid string that contains spaces only, e.g. "  ".
             * It's required to avoid bug: preg_replace(): Empty regular expression.
             */
            if ($searchIsArray || ($searchIsString && !empty(trim($search)))) {
                $replaced = @preg_replace($search, $replacement, $subject);

                if (null !== $replaced && [] !== $replaced) {
                    $effect = $replaced;
                }
            }
        }

        /*
         * 3rd step: complex replace of the replacement defined as an array.
         * It may be useful when you want to search for a one string and replace the string with multiple values.
         */
        if ($effect === $subject && $searchIsString && $replacementIsArray) {
            $subjectIsArray = is_array($subject);
            $effect = '';

            if ($subjectIsArray) {
                $effect = [];
            }

            $subject = Arrays::makeArray($subject);

            // I have to iterate through the subjects, because explode() function expects strings as both arguments
            // (1st and 2nd)
            foreach ($subject as $subSubject) {
                $subEffect = '';

                $exploded = explode($search, $subSubject);
                $explodedCount = count($exploded);

                foreach ($exploded as $key => $item) {
                    $subEffect .= $item;

                    // The replacement shouldn't be included when the searched string was not found
                    if ($explodedCount > 1 && $key < $explodedCount - 1 && isset($replacement[$key])) {
                        $subEffect .= $replacement[$key];
                    }
                }

                if ($subjectIsArray) {
                    $effect[] = $subEffect;

                    continue;
                }

                $effect .= $subEffect;
            }
        }

        return $effect;
    }