def iterate_non_primitives(item, &block)
      case
      when item == nil then item
      when item.one_of?(false, true) then item
      when item.is_a?(Array) then item.map { |element| iterate_non_primitives(element, &block) }
      when item.is_a?(Exception) then item
      when item.is_a?(Float) then item
      when item.is_a?(Hash)
        item.map{ |key, value| [iterate_non_primitives(key, &block), iterate_non_primitives(value, &block)] }.to_h
      when item.is_a?(Integer) then item
      when item.is_a?(String) then item
      else
        yield(item)
      end
    end
def iterate_non_primitives(item, &block)
      case
      when item == nil then item
      when item.one_of?(false, true) then item
      when item.is_a?(Array) then item.map { |element| iterate_non_primitives(element, &block) }
      when item.is_a?(Exception) then item
      when item.is_a?(Float) then item
      when item.is_a?(Hash)
        item.map{ |key, value| [iterate_non_primitives(key, &block), iterate_non_primitives(value, &block)] }.to_h
      when item.is_a?(Integer) then item
      when item.is_a?(String) then item
      else
        yield(item)
      end
    end
Iterate non primitive items replacing them with returned values.
 {LocalReference}s are converted property sets with an +origin+ of +local+ and {RemoteReference}s to +remote+.
 Primitives are unchanged.
 @param reference [::Array<::Array,::Boolean,::Exception,ExposedObject,::Float,Hash,#origin#id,::Integer,nil,Reference,::String>]
 @yield called for items that are not primitives
 @yieldparam item [ExposedObject,#origin#id,Reference]
 @yieldreturn [Object] item to replace the current item
 @return the original item with any replacements made