protected function copyArrayValues(array $source, array $keys)
    {
        $target = [];
        foreach ($keys as $key => $spec) {
            if (is_int($key)) {
                $key = $spec;
                $spec = null;
            }

            if (!array_key_exists($key, $source)) {
                continue;
            }

            if (null === $spec) {
                $target[$key] = $source[$key];
                continue;
            }

            if (is_string($spec)) {
                $target[$spec][$key] = $source[$key];
                continue;
            }

            if (isset($spec['if']) && $source[$key] !== $spec['if']) {
                continue;
            }

            if (isset($spec['key'])) {
                $targetKeys = is_array($spec['key']) ? $spec['key'] : [$spec['key']];
                $value = isset($spec['value']) ? $spec['value'] : $source[$key];
            } else {
                $targetKeys = $spec;
                $value = $source[$key];
            }

            $tmpTarget =& $target;
            foreach ($targetKeys as $targetKey) {
                if ('*' == $targetKey) {
                    $targetKey = $key;
                }
                if (!isset($tmpTarget[$targetKey])) {
                    $tmpTarget[$targetKey] = [];
                }
                $tmpTarget =& $tmpTarget[$targetKey];
            }

            $tmpTarget = $value;
        }

        return $target;
    }