+
+ /**
+ * Returns set of method signature instances which contains all the methods of the <code>genType</code>
+ * and all the methods of the implemented interfaces.
+ *
+ * @returns set of method signature instances
+ */
+ private static ParameterizedType createMethods(final GeneratedType type, final Set<MethodSignature> methods) {
+ methods.addAll(type.getMethodDefinitions());
+ return collectImplementedMethods(type, methods, type.getImplements());
+ }
+
+ /**
+ * Adds to the <code>methods</code> set all the methods of the <code>implementedIfcs</code>
+ * and recursively their implemented interfaces.
+ *
+ * @param methods set of method signatures
+ * @param implementedIfcs list of implemented interfaces
+ */
+ private static ParameterizedType collectImplementedMethods(final GeneratedType type,
+ final Set<MethodSignature> methods, final List<Type> implementedIfcs) {
+ if (implementedIfcs == null || implementedIfcs.isEmpty()) {
+ return null;
+ }
+
+ ParameterizedType augmentType = null;
+ for (Type implementedIfc : implementedIfcs) {
+ if (implementedIfc instanceof GeneratedType && !(implementedIfc instanceof GeneratedTransferObject)) {
+ final GeneratedType ifc = (GeneratedType) implementedIfc;
+ methods.addAll(ifc.getMethodDefinitions());
+
+ final ParameterizedType t = collectImplementedMethods(type, methods, ifc.getImplements());
+ if (t != null && augmentType == null) {
+ augmentType = t;
+ }
+ } else if (Augmentable.class.getName().equals(implementedIfc.getFullyQualifiedName())) {
+ augmentType = Types.parameterizedTypeFor(AUGMENTATION_RET_TYPE, DefaultType.of(type.getIdentifier()));
+ }
+ }
+
+ return augmentType;
+ }
+
+ /**
+ * Creates set of generated property instances from getter <code>methods</code>.
+ *
+ * @param methods set of method signature instances which should be transformed to list of properties
+ * @return set of generated property instances which represents the getter <code>methods</code>
+ */
+ private static Set<BuilderGeneratedProperty> propertiesFromMethods(final Collection<MethodSignature> methods) {
+ if (methods == null || methods.isEmpty()) {
+ return Collections.emptySet();
+ }
+ final Set<BuilderGeneratedProperty> result = new LinkedHashSet<>();
+ for (MethodSignature m : methods) {
+ final BuilderGeneratedProperty createdField = propertyFromGetter(m);
+ if (createdField != null) {
+ result.add(createdField);
+ }
+ }
+ return result;
+ }
+
+ /**
+ * Creates generated property instance from the getter <code>method</code> name and return type.
+ *
+ * @param method method signature from which is the method name and return type obtained
+ * @return generated property instance for the getter <code>method</code>
+ * @throws IllegalArgumentException <ul>
+ * <li>if the <code>method</code> equals <code>null</code></li>
+ * <li>if the name of the <code>method</code> equals <code>null</code></li>
+ * <li>if the name of the <code>method</code> is empty</li>
+ * <li>if the return type of the <code>method</code> equals <code>null</code></li>
+ * </ul>
+ */
+ private static BuilderGeneratedProperty propertyFromGetter(final MethodSignature method) {
+ checkArgument(method != null);
+ checkArgument(method.getReturnType() != null);
+ checkArgument(method.getName() != null);
+ checkArgument(!method.getName().isEmpty());
+ if (method.isDefault()) {
+ return null;
+ }
+ final String prefix = BindingMapping.getGetterPrefix(Types.BOOLEAN.equals(method.getReturnType()));
+ if (!method.getName().startsWith(prefix)) {
+ return null;
+ }
+
+ final String fieldName = StringExtensions.toFirstLower(method.getName().substring(prefix.length()));
+ return new BuilderGeneratedProperty(fieldName, method);
+ }