Fixes #3309: Support deep merging of hash and array structures in smart class parameters

This relates to feature 3636 which states a couple of changes to the way `lookup_keys` work
I'm creating a PR to get comments of this part of the change and to see that I'm in the right direction
This method is hard to read (not you fault) and you're adding more complexity. Therefore I'd consider doing some refactorings. First - you can extract `values[key_id][name]` into some variable so you don't have to repeat it on every line. 

Then you can use hash with default values `values = Hash.new {|h, k| h[k] = {}; values[:new_key][name] = triplet` so you avoid `hash[key_id] ||= {}` lines.

Furthermore you don't have to store values_for_deep_merge in this complex hash format. I'd suggest using array OpenStruct or Struct instance for keeping value, index, element and element_name. Then calling `hash_deep_merge` that will generate values in desired hash structure. The benefit is that `hash_deep_merge` will be much easier to read. Ideally I'd use OpenStruct in whole `values_hash` method and convert the result into hash at the end (maybe some convert method).

Also I think you should compute values inside `when "hash"` branch, not looking at `values_for_deep_merge` outside of hash context in unless condition (this will also eliminate the need of `values_for_deep_merge` being global to the whole method).

Last but not least, I'd split this method so the actual evaluation is separated per type so we'd have methods like update_array_matcher, update_hash_matcher, update_generic_matcher which can be tested separately.

Let me know if I should elaborate any of previous refactorings. This file would deserves many other improvements but these are not related to the PR.