1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
        public object Map(ResolutionContext context, IMappingEngineRunner mapper)
        {
            if (context.TypeMap.CustomMapper != null)
                return UseCustomMapper(context);

            var profileConfiguration = mapper.ConfigurationProvider.GetProfileConfiguration(context.TypeMap.Profile);
            if (context.SourceValue == null && profileConfiguration.MapNullSourceValuesAsNull)
                return AfterMapping(context, null);

            if (context.DestinationValue == null && context.InstanceCache.ContainsKey(context))
                return AfterMapping(context, context.InstanceCache[context]);

            return DoMap(context, mapper);
        }

        private object UseCutomMapper(ResolutionContext context)
        {
            context.TypeMap.BeforeMap(context.SourceValue, null);
            object mappedObject = context.TypeMap.CustomMapper(context);
            return AfterMapping(context, mappedObject);
        }

        private object DoMap(ResolutionContext context, IMappingEngineRunner mapper)
        {
            object mappedObject = GetMappedObject();

            context.TypeMap.BeforeMap(context.SourceValue, mappedObject);
            foreach (PropertyMap propertyMap in context.TypeMap.GetPropertyMaps())
            {
                MapPropertyValue(context, mapper, mappedObject, propertyMap);
            }

            return AfterMapping(context, mappedObject);            
        }

        private object GetMappedObject()
        {
            if (context.DestinationValue != null)
                return context.DestinationValue;

            object mappedObject = mapper.CreateObject(context.DestinationType);
            if (context.SourceValue != null)
                context.InstanceCache.Add(context, mappedObject);

            return mappedObject;
        }

        private object AfterMapping(ResolutionContext context, object mappedObject)
        {
            context.TypeMap.AfterMap(context.SourceValue, mappedObject);
            return mappedObject;
        }