public function remove($key)
    {
        if (!is_string($key) && !is_numeric($key)) {
            throw new InvalidArgumentException(
                'Invalid key name given! Key config to remove must be as a string!'
            );
        }

        if (!$this->exist($key)) {
            return;
        }

        if (($count = preg_match_all('/(?:^[^\[]+)|\[[^]]*\]/', $key, $matches)) > 1) {
            $firstKey = reset($matches[0]);
            $keyName  = $firstKey;
            $tmp      = $this->collection[$keyName];
            if (!is_array($tmp)) {
                return;
            }
            array_shift($matches[0]);
            $unsetPosition = 0;
            foreach ($matches[0] as $keyNum => $keyName) {
                $keyName = trim($keyName, '[]');
                if ($unsetPosition <> $keyNum &&
                    (!is_array($tmp) || ! array_key_exists($keyName, $tmp))
                ) {
                    return;
                }

                $unsetPosition++;
                $tmp = $tmp[$keyName];
            }

            $tmp = $this->collection[$firstKey];
            $currentUnsetPosition = 0;
            // binding anonymous function to handle array reference
            $recursiveUnset = function (
                &$array,
                $unwanted_key
            ) use (
                $unsetPosition,
                &$currentUnsetPosition,
                &$recursiveUnset
            ) {
                $currentUnsetPosition++;
                if ($unsetPosition !== $currentUnsetPosition) {
                    if (array_key_exists($unwanted_key, $array)) {
                        unset($array[$unwanted_key]);
                    }
                    // stop
                    return;
                }
                foreach ($array as &$value) {
                    if (is_array($value)) {
                        $recursiveUnset($value, $unwanted_key);
                    }
                }
            };

            // call closure to binding reference
            $recursiveUnset($tmp, $keyName);
            $this->collection[$firstKey] = $tmp;
            unset($tmp);
            return; // stop
        }

        unset($this->collection[$key]);
    }