Copyright 2013 Dario Castañé. All rights reserved. Copyright 2009 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.
Based on src/pkg/reflect/deepequal.go from official golang's stdlib.

package mergo

import (
	
	
)
Errors reported by Mergo when it finds invalid arguments.
var (
	ErrNilArguments                = errors.New("src and dst must not be nil")
	ErrDifferentArgumentsTypes     = errors.New("src and dst must be of same type")
	ErrNotSupported                = errors.New("only structs and maps are supported")
	ErrExpectedMapAsDestination    = errors.New("dst was expected to be a map")
	ErrExpectedStructAsDestination = errors.New("dst was expected to be a struct")
)
During deepMerge, must keep track of checks that are in progress. The comparison algorithm assumes that all checks in progress are true when it reencounters them. Visited are stored in a map indexed by 17 * a1 + a2;
From src/pkg/encoding/json/encode.go.
func ( reflect.Value) bool {
	switch .Kind() {
	case reflect.Array, reflect.Map, reflect.Slice, reflect.String:
		return .Len() == 0
	case reflect.Bool:
		return !.Bool()
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		return .Int() == 0
	case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64, reflect.Uintptr:
		return .Uint() == 0
	case reflect.Float32, reflect.Float64:
		return .Float() == 0
	case reflect.Interface, reflect.Ptr:
		if .IsNil() {
			return true
		}
		return (.Elem())
	case reflect.Func:
		return .IsNil()
	case reflect.Invalid:
		return true
	}
	return false
}

func (,  interface{}) (,  reflect.Value,  error) {
	if  == nil ||  == nil {
		 = ErrNilArguments
		return
	}
	 = reflect.ValueOf().Elem()
	if .Kind() != reflect.Struct && .Kind() != reflect.Map {
		 = ErrNotSupported
		return
	}
We check if vSrc is a pointer to dereference it.
	if .Kind() == reflect.Ptr {
		 = .Elem()
	}
	return
}
Traverses recursively both values, assigning src's fields values to dst. The map argument tracks comparisons that have already been seen, which allows short circuiting on recursive types.
func (,  reflect.Value,  map[uintptr]*visit,  int) ( error) {
	if .CanAddr() {
		 := .UnsafeAddr()
		 := 17 * 
		 := []
		 := .Type()
		for  := ;  != nil;  = .next {
			if .ptr ==  && .typ ==  {
				return nil
			}
Remember, remember...
		[] = &visit{, , }
	}
	return // TODO refactor