public function title($sep = null)
    {
        if(is_null($sep)){
            return  new self(
                mb_convert_case($this->value, MB_CASE_TITLE, C::ENCODING)
            );
        }

        $str_prov = mb_convert_case(
            mb_strtolower(
                mb_strtolower($this->value, C::ENCODING),
                C::ENCODING
            ),
            MB_CASE_TITLE,
            C::ENCODING
        );
        

        if($sep instanceof A || $sep instanceof H){
            $arrs = array_values($sep->array); //beware of H case
        } elseif(is_array($sep)){
            $arrs = $sep;
        } elseif($sep instanceof S){
            $arrs = preg_split('//ui', $sep->string);
        } elseif(is_scalar($sep)){
            $arrs = preg_split('//ui', $sep);
        } else {
            throw \InvalidArgumentException(
                'Given seperator has not good type.'
            );
        }

        $str_out  = $str_prov;
        $int_length  = mb_strlen($str_prov, C::ENCODING);

        $prev_idx = null;
        $arr_to_change = array();

        for ($i = 0; $i < $int_length; $i++) {
            $letter = mb_substr($str_prov, $i, 1, C::ENCODING);

            foreach($arrs as $new_sep){
                if ($letter == "$new_sep") {
                    $prev_idx = $i;
                    break;
                }
            }

            if (!is_null($prev_idx) && ($i == $prev_idx + 1)) {
                $arr_to_change[$i] = $letter;
            }
        }

        foreach ($arr_to_change as $idx => $letter) {
            $str_tmp  = mb_substr($str_out, 0, $idx, C::ENCODING);
            $str_tmp .= mb_strtoupper($letter, C::ENCODING);
            $str_tmp .= mb_substr($str_out, $idx+1, $int_length, C::ENCODING);

            $str_out = $str_tmp;
            unset($str_tmp);
        }

        return new self($str_out);
    }