private <T extends Mergeable> Object mergeProperties( Merge mergeAnnotation, String propertyName, T target, T source) throws MergerException { try { String tag = null; if (mergeAnnotation != null) { tag = mergeAnnotation.value(); } Object targetProperty = PropertyUtils.getProperty(target, propertyName); Object sourceProperty = PropertyUtils.getProperty(source, propertyName); Class propertyType = PropertyUtils.getPropertyType(target, propertyName); Object merged; if (tag != null && target.isGenerated() && target.containsTag(tag)) { merged = sourceProperty; } else { merged = merge(propertyType, targetProperty, sourceProperty); } updateTag(target, tag, merged == null); return merged; } catch (NoSuchMethodException e) { throw new MergerException("NoSuchMethodException while trying to merge", e); } catch (IllegalAccessException e) { throw new MergerException("IllegalAccessException while trying to merge", e); } catch (InvocationTargetException e) { throw new MergerException("InvocationTargetException while trying to merge", e); } }