1 /*
2  * Copyright 2014 - 2020 Rafael Winterhalter
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */

16 package net.bytebuddy.dynamic;
17
18 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
19 import net.bytebuddy.ClassFileVersion;
20 import net.bytebuddy.asm.AsmVisitorWrapper;
21 import net.bytebuddy.build.HashCodeAndEqualsPlugin;
22 import net.bytebuddy.description.annotation.AnnotationDescription;
23 import net.bytebuddy.description.annotation.AnnotationList;
24 import net.bytebuddy.description.annotation.AnnotationValue;
25 import net.bytebuddy.description.field.FieldDescription;
26 import net.bytebuddy.description.method.MethodDescription;
27 import net.bytebuddy.description.method.ParameterDescription;
28 import net.bytebuddy.description.method.ParameterList;
29 import net.bytebuddy.description.modifier.*;
30 import net.bytebuddy.description.type.*;
31 import net.bytebuddy.dynamic.loading.ClassLoadingStrategy;
32 import net.bytebuddy.dynamic.loading.InjectionClassLoader;
33 import net.bytebuddy.dynamic.scaffold.*;
34 import net.bytebuddy.implementation.*;
35 import net.bytebuddy.implementation.attribute.*;
36 import net.bytebuddy.implementation.auxiliary.AuxiliaryType;
37 import net.bytebuddy.implementation.bytecode.ByteCodeAppender;
38 import net.bytebuddy.matcher.ElementMatcher;
39 import net.bytebuddy.matcher.LatentMatcher;
40 import net.bytebuddy.pool.TypePool;
41 import net.bytebuddy.utility.CompoundList;
42 import net.bytebuddy.jar.asm.Opcodes;
43
44 import java.io.*;
45 import java.lang.annotation.Annotation;
46 import java.lang.reflect.*;
47 import java.security.AccessController;
48 import java.security.PrivilegedAction;
49 import java.util.*;
50 import java.util.jar.*;
51
52 import static net.bytebuddy.matcher.ElementMatchers.*;
53
54 /**
55  * A dynamic type that is created at runtime, usually as the result of applying a
56  * {@link net.bytebuddy.dynamic.DynamicType.Builder} or as the result of an
57  * {@link net.bytebuddy.implementation.auxiliary.AuxiliaryType}.
58  * <p>&nbsp;</p>
59  * Note that the {@link TypeDescription}s will represent their
60  * unloaded forms and therefore differ from the loaded types, especially with regards to annotations.
61  */

62 public interface DynamicType {
63
64     /**
65      * <p>
66      * Returns a description of this dynamic type.
67      * </p>
68      * <p>
69      * <b>Note</b>: This description will most likely differ from the binary representation of this type. Normally,
70      * annotations and intercepted methods are not added to this type description.
71      * </p>
72      *
73      * @return A description of this dynamic type.
74      */

75     TypeDescription getTypeDescription();
76
77     /**
78      * Returns a byte array representing this dynamic type. This byte array might be reused by this dynamic type and
79      * must therefore not be altered.
80      *
81      * @return A byte array of the type's binary representation.
82      */

83     byte[] getBytes();
84
85     /**
86      * <p>
87      * Returns a map of all auxiliary types that are required for making use of the main type.
88      * </p>
89      * <p>
90      * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
91      * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
92      * </p>
93      *
94      * @return A map of all auxiliary types by their descriptions to their binary representation.
95      */

96     Map<TypeDescription, byte[]> getAuxiliaryTypes();
97
98     /**
99      * Returns all types that are implied by this dynamic type.
100      *
101      * @return A mapping from all type descriptions, the actual type and its auxiliary types to their binary
102      * representation
103      */

104     Map<TypeDescription, byte[]> getAllTypes();
105
106     /**
107      * <p>
108      * Returns a map of all loaded type initializers for the main type and all auxiliary types, if any.
109      * </p>
110      * <p>
111      * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
112      * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
113      * </p>
114      *
115      * @return A mapping of all types' descriptions to their loaded type initializers.
116      */

117     Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers();
118
119     /**
120      * Checks if a dynamic type requires some form of explicit type initialization, either for itself or for one
121      * of its auxiliary types, if any. This is the case when this dynamic type was defined to delegate method calls
122      * to a specific instance which is stored in a field of the created type. If this class serialized, it could not
123      * be used without its loaded type initializers since the field value represents a specific runtime context.
124      *
125      * @return {@code trueif this type requires explicit type initialization.
126      */

127     boolean hasAliveLoadedTypeInitializers();
128
129     /**
130      * <p>
131      * Saves a dynamic type in a given folder using the Java class file format while respecting the naming conventions
132      * for saving compiled Java classes. All auxiliary types, if any, are saved in the same directory. The resulting
133      * folder structure will resemble the structure that is required for Java run times, i.e. each folder representing
134      * a segment of the package name. If the specified {@code folder} does not yet exist, it is created during the
135      * call of this method.
136      * </p>
137      * <p>
138      * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
139      * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
140      * </p>
141      *
142      * @param folder The base target folder for storing this dynamic type and its auxiliary types, if any.
143      * @return A map of type descriptions pointing to files with their stored binary representations within {@code folder}.
144      * @throws IOException Thrown if the underlying file operations cause an {@code IOException}.
145      */

146     Map<TypeDescription, File> saveIn(File folder) throws IOException;
147
148     /**
149      * Injects the types of this dynamic type into a given <i>jar</i> file. Any pre-existent type with the same name
150      * is overridden during injection. The resulting jar is going to be a recreation of the original jar and not a
151      * patched version with a new central directory. No directory entries are added to the generated jar.
152      *
153      * @param sourceJar The original jar file.
154      * @param targetJar The {@code source} jar file with the injected contents.
155      * @return The {@code target} jar file.
156      * @throws IOException If an I/O exception occurs while injecting from the source into the target.
157      */

158     File inject(File sourceJar, File targetJar) throws IOException;
159
160     /**
161      * Injects the types of this dynamic type into a given <i>jar</i> file. Any pre-existent type with the same name
162      * is overridden during injection. The resulting jar is going to be a recreation of the original jar and not a
163      * patched version with a new central directory. No directory entries are added to the generated jar.
164      *
165      * @param jar The jar file to replace with an injected version.
166      * @return The {@code jar} file.
167      * @throws IOException If an I/O exception occurs while injecting into the jar.
168      */

169     File inject(File jar) throws IOException;
170
171     /**
172      * Saves the contents of this dynamic type inside a <i>jar</i> file. The folder of the given {@code file} must
173      * exist prior to calling this method. The jar file is created with a simple manifest that only contains a version
174      * number. No directory entries are added to the generated jar.
175      *
176      * @param file The target file to which the <i>jar</i> is written to.
177      * @return The given {@code file}.
178      * @throws IOException If an I/O exception occurs while writing the file.
179      */

180     File toJar(File file) throws IOException;
181
182     /**
183      * Saves the contents of this dynamic type inside a <i>jar</i> file. The folder of the given {@code file} must
184      * exist prior to calling this method. No directory entries are added to the generated jar.
185      *
186      * @param file     The target file to which the <i>jar</i> is written to.
187      * @param manifest The manifest of the created <i>jar</i>.
188      * @return The given {@code file}.
189      * @throws IOException If an I/O exception occurs while writing the file.
190      */

191     File toJar(File file, Manifest manifest) throws IOException;
192
193     /**
194      * A builder for creating a dynamic type.
195      *
196      * @param <T> A loaded type that the built type is guaranteed to be a subclass of.
197      */

198     interface Builder<T> {
199
200         /**
201          * Applies the supplied {@link AsmVisitorWrapper} onto the {@link net.bytebuddy.jar.asm.ClassVisitor} during building a dynamic type.
202          * Using an ASM visitor, it is possible to manipulate byte code directly. Byte Buddy does not validate directly created byte code
203          * and it remains the responsibility of the visitor's implementor to generate legal byte code. If several ASM visitor wrappers
204          * are registered, they are applied on top of another in their registration order.
205          *
206          * @param asmVisitorWrapper The ASM visitor wrapper to apply during
207          * @return A new builder that is equal to this builder and applies the ASM visitor wrapper.
208          */

209         Builder<T> visit(AsmVisitorWrapper asmVisitorWrapper);
210
211         /**
212          * Names the dynamic type by the supplied name. The name needs to be fully qualified and in the binary format (packages separated
213          * by dots: {@code foo.Bar}). A type's package determines what other types are visible to the instrumented type and what methods
214          * can be overridden or be represented in method signatures or as field types.
215          *
216          * @param name The fully qualified name of the generated class in a binary format.
217          * @return A new builder that is equal to this builder but with the instrumented type named by the supplied name.
218          */

219         Builder<T> name(String name);
220
221         /**
222          * Adds a suffix to the current type name without changing the type's package.
223          *
224          * @param suffix The suffix to append to the current type name.
225          * @return A new builder that is equal to this builder but with the instrumented type named suffixed by the supplied suffix.
226          */

227         Builder<T> suffix(String suffix);
228
229         /**
230          * Defines the supplied modifiers as the modifiers of the instrumented type.
231          *
232          * @param modifierContributor The modifiers of the instrumented type.
233          * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
234          */

235         Builder<T> modifiers(ModifierContributor.ForType... modifierContributor);
236
237         /**
238          * Defines the supplied modifiers as the modifiers of the instrumented type.
239          *
240          * @param modifierContributors The modifiers of the instrumented type.
241          * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
242          */

243         Builder<T> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors);
244
245         /**
246          * Defines the supplied modifiers as the modifiers of the instrumented type.
247          *
248          * @param modifiers The modifiers of the instrumented type.
249          * @return A new builder that is equal to this builder but with the supplied modifiers applied onto the instrumented type.
250          */

251         Builder<T> modifiers(int modifiers);
252
253         /**
254          * Merges the supplied modifier contributors with the modifiers of the instrumented type and defines them as the instrumented
255          * type's new modifiers.
256          *
257          * @param modifierContributor The modifiers of the instrumented type.
258          * @return A new builder that is equal to this builder but with the supplied modifiers merged into the instrumented type's modifiers.
259          */

260         Builder<T> merge(ModifierContributor.ForType... modifierContributor);
261
262         /**
263          * Merges the supplied modifier contributors with the modifiers of the instrumented type and defines them as the instrumented
264          * type's new modifiers.
265          *
266          * @param modifierContributors The modifiers of the instrumented type.
267          * @return A new builder that is equal to this builder but with the supplied modifiers merged into the instrumented type's modifiers.
268          */

269         Builder<T> merge(Collection<? extends ModifierContributor.ForType> modifierContributors);
270
271         /**
272          * <p>
273          * Defines this type as a top-level type that is not declared by another type or enclosed by another member.
274          * </p>
275          * <p>
276          * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
277          * </p>
278          * <p>
279          * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
280          * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
281          * consistent among the definitions of connected types.
282          * </p>
283          *
284          * @return A new builder that is equal to this builder but without any declaration of a a declared or enclosed type.
285          */

286         Builder<T> topLevelType();
287
288         /**
289          * <p>
290          * Defines this type as an inner type of the supplied type. Without any additional configuration, the type declaration is defined
291          * as a local type.
292          * </p>
293          * <p>
294          * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
295          * </p>
296          * <p>
297          * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
298          * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
299          * consistent among the definitions of connected types.
300          * </p>
301          *
302          * @param type The type to declare as the built type's outer type.
303          * @return A new builder that is equal to this builder with the supplied type as the built type's outer type.
304          */

305         InnerTypeDefinition.ForType<T> innerTypeOf(Class<?> type);
306
307         /**
308          * <p>
309          * Defines this type as an inner type of the supplied type. Without any additional configuration, the type declaration is
310          * defined as a local type.
311          * </p>
312          * <p>
313          * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
314          * </p>
315          * <p>
316          * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
317          * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
318          * consistent among the definitions of connected types.
319          * </p>
320          *
321          * @param type The type to declare as the built type's outer type.
322          * @return A new builder that is equal to this builder with the supplied type as the built type's outer type.
323          */

324         InnerTypeDefinition.ForType<T> innerTypeOf(TypeDescription type);
325
326         /**
327          * <p>
328          * Defines this type as an inner type that was declared within the supplied method.  Without any additional configuration, the type
329          * declaration is defined as a local type.
330          * </p>
331          * <p>
332          * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
333          * </p>
334          * <p>
335          * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
336          * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
337          * consistent among the definitions of connected types.
338          * </p>
339          *
340          * @param method The method to declare as the built type's declaring method.
341          * @return A new builder that is equal to this builder with the supplied method as the built type's declaring method.
342          */

343         InnerTypeDefinition<T> innerTypeOf(Method method);
344
345         /**
346          * <p>
347          * Defines this type as an inner type that was declared within the supplied constructor. Without any additional configuration, the type
348          * declaration is defined as a local type.
349          * </p>
350          * <p>
351          * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
352          * </p>
353          * <p>
354          * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
355          * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
356          * consistent among the definitions of connected types.
357          * </p>
358          *
359          * @param constructor The constructor to declare as the built type's declaring method.
360          * @return A new builder that is equal to this builder with the supplied method as the built type's declaring constructor.
361          */

362         InnerTypeDefinition<T> innerTypeOf(Constructor<?> constructor);
363
364         /**
365          * <p>
366          * Defines this type as an inner type that was declared within the supplied method or constructor. Without any additional configuration,
367          * the type declaration is defined as a local type.
368          * </p>
369          * <p>
370          * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
371          * </p>
372          * <p>
373          * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
374          * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
375          * consistent among the definitions of connected types.
376          * </p>
377          *
378          * @param methodDescription The method or constructor to declare as the built type's declaring method.
379          * @return A new builder that is equal to this builder with the supplied method as the built type's declaring method or constructor.
380          */

381         InnerTypeDefinition<T> innerTypeOf(MethodDescription.InDefinedShape methodDescription);
382
383         /**
384          * <p>
385          * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
386          * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
387          * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
388          * </p>
389          * <p>
390          * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
391          * </p>
392          * <p>
393          * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
394          * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
395          * consistent among the definitions of connected types.
396          * </p>
397          *
398          * @param type The types being declared.
399          * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
400          */

401         Builder<T> declaredTypes(Class<?>... type);
402
403         /**
404          * <p>
405          * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
406          * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
407          * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
408          * </p>
409          * <p>
410          * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
411          * </p>
412          * <p>
413          * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
414          * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
415          * consistent among the definitions of connected types.
416          * </p>
417          *
418          * @param type The types being declared.
419          * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
420          */

421         Builder<T> declaredTypes(TypeDescription... type);
422
423         /**
424          * <p>
425          * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
426          * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
427          * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
428          * </p>
429          * <p>
430          * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
431          * </p>
432          * <p>
433          * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
434          * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
435          * consistent among the definitions of connected types.
436          * </p>
437          *
438          * @param types The types being declared.
439          * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
440          */

441         Builder<T> declaredTypes(List<? extends Class<?>> types);
442
443         /**
444          * <p>
445          * Defines this type as an the outer type of the supplied types. Using this method, it is possible to add inner type declarations
446          * for anonymous or local types which are not normally exposed by type descriptions. Doing so, it is however possible to indicate to
447          * Byte Buddy that the required attributes for such an inner type declaration should be added to a class file.
448          * </p>
449          * <p>
450          * <b>Important</b>: Changing the declaration hierarchy of a type has no influence on the nest mate hierarchy.
451          * </p>
452          * <p>
453          * <b>Warning</b>: By changing this type's declaration, any other type will not change its declaration of enclosing members or
454          * declared types about any nesting of a declaration. It is the responsibility of the user of this API to keep such declarations
455          * consistent among the definitions of connected types.
456          * </p>
457          *
458          * @param types The types being declared.
459          * @return A new builder that is equal to this builder with the supplied types being declared by the built type.
460          */

461         Builder<T> declaredTypes(Collection<? extends TypeDescription> types);
462
463         /**
464          * <p>
465          * Defines this type as self-hosted, i.e. as only being a nest mate of itself.
466          * </p>
467          * <p>
468          * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
469          * </p>
470          * <p>
471          * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
472          * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
473          * consistent among the definitions of connected types.
474          * </p>
475          *
476          * @return A new builder that is equal to this builder but where the built type is a self-hosted nest mate.
477          */

478         Builder<T> noNestMate();
479
480         /**
481          * <p>
482          * Defines this type as a nest member of the supplied type as a nest host.
483          * </p>
484          * <p>
485          * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
486          * </p>
487          * <p>
488          * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
489          * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
490          * consistent among the definitions of connected types.
491          * </p>
492          *
493          * @param type The nest host.
494          * @return A new builder that is equal to this builder but where the built type is a nest member of the supplied host.
495          */

496         Builder<T> nestHost(Class<?> type);
497
498         /**
499          * <p>
500          * Defines this type as a nest member of the supplied type as a nest host.
501          * </p>
502          * <p>
503          * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
504          * </p>
505          * <p>
506          * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
507          * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
508          * consistent among the definitions of connected types.
509          * </p>
510          *
511          * @param type The nest host.
512          * @return A new builder that is equal to this builder but where the built type is a nest member of the supplied host.
513          */

514         Builder<T> nestHost(TypeDescription type);
515
516         /**
517          * <p>
518          * Defines this type as a nest host for the supplied types.
519          * </p>
520          * <p>
521          * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
522          * </p>
523          * <p>
524          * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
525          * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
526          * consistent among the definitions of connected types.
527          * </p>
528          *
529          * @param type The nest members.
530          * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
531          */

532         Builder<T> nestMembers(Class<?>... type);
533
534         /**
535          * <p>
536          * Defines this type as a nest host for the supplied types.
537          * </p>
538          * <p>
539          * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
540          * </p>
541          * <p>
542          * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
543          * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
544          * consistent among the definitions of connected types.
545          * </p>
546          *
547          * @param type The nest members.
548          * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
549          */

550         Builder<T> nestMembers(TypeDescription... type);
551
552         /**
553          * <p>
554          * Defines this type as a nest host for the supplied types.
555          * </p>
556          * <p>
557          * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
558          * </p>
559          * <p>
560          * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
561          * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
562          * consistent among the definitions of connected types.
563          * </p>
564          *
565          * @param types The nest members.
566          * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
567          */

568         Builder<T> nestMembers(List<? extends Class<?>> types);
569
570         /**
571          * <p>
572          * Defines this type as a nest host for the supplied types.
573          * </p>
574          * <p>
575          * <b>Important</b>: Changing the nest mate hierarchy of a type has no influence on the declaration hierarchy.
576          * </p>
577          * <p>
578          * <b>Warning</b>: Changing nest mate hierarchies always requires changing a member and its host or a host and all its members.
579          * Otherwise, the runtime will not accept further nest mates. It is the responsibility of the user of this API to keep such declarations
580          * consistent among the definitions of connected types.
581          * </p>
582          *
583          * @param types The nest members.
584          * @return A new builder that is equal to this builder but where the built type is a nest host of the supplied types.
585          */

586         Builder<T> nestMembers(Collection<? extends TypeDescription> types);
587
588         /**
589          * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
590          * this type was not previously sealed, only the supplied subclasses are permitted.
591          *
592          * @param type The permitted subclasses.
593          * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
594          */

595         Builder<T> permittedSubclass(Class<?>... type);
596
597         /**
598          * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
599          * this type was not previously sealed, only the supplied subclasses are permitted.
600          *
601          * @param type The permitted subclasses.
602          * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
603          */

604         Builder<T> permittedSubclass(TypeDescription... type);
605
606         /**
607          * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
608          * this type was not previously sealed, only the supplied subclasses are permitted.
609          *
610          * @param types The permitted subclasses.
611          * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
612          */

613         Builder<T> permittedSubclass(List<? extends Class<?>> types);
614
615         /**
616          * Defines this type to allow the supplied permitted subclasses additionally to any prior permitted subclasses. If
617          * this type was not previously sealed, only the supplied subclasses are permitted.
618          *
619          * @param types The permitted subclasses.
620          * @return A new builder that is equal to this builder but where the built type permits the supplied subclasses.
621          */

622         Builder<T> permittedSubclass(Collection<? extends TypeDescription> types);
623
624         /**
625          * Unseales this type.
626          *
627          * @return A new builder that is equal to this builder but where the built type does not restrain its permitted subclasses.
628          */

629         Builder<T> unsealed();
630
631         /**
632          * Applies the given type attribute appender onto the instrumented type. Using a type attribute appender, it is possible to append
633          * any type of meta data to a type, not only Java {@link Annotation}s.
634          *
635          * @param typeAttributeAppender The type attribute appender to apply.
636          * @return A new builder that is equal to this builder but with the supplied type attribute appender applied to the instrumented type.
637          */

638         Builder<T> attribute(TypeAttributeAppender typeAttributeAppender);
639
640         /**
641          * Annotates the instrumented type with the supplied annotations.
642          *
643          * @param annotation The annotations to add to the instrumented type.
644          * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
645          */

646         Builder<T> annotateType(Annotation... annotation);
647
648         /**
649          * Annotates the instrumented type with the supplied annotations.
650          *
651          * @param annotations The annotations to add to the instrumented type.
652          * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
653          */

654         Builder<T> annotateType(List<? extends Annotation> annotations);
655
656         /**
657          * Annotates the instrumented type with the supplied annotations.
658          *
659          * @param annotation The annotations to add to the instrumented type.
660          * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
661          */

662         Builder<T> annotateType(AnnotationDescription... annotation);
663
664         /**
665          * Annotates the instrumented type with the supplied annotations.
666          *
667          * @param annotations The annotations to add to the instrumented type.
668          * @return A new builder that is equal to this builder but with the annotations added to the instrumented type.
669          */

670         Builder<T> annotateType(Collection<? extends AnnotationDescription> annotations);
671
672         /**
673          * <p>
674          * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
675          * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
676          * are explicitly ignored.
677          * </p>
678          * <p>
679          * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link Class} values are implemented
680          * as raw types if they declare type variables or an owner type.
681          * </p>
682          *
683          * @param interfaceType The interface types to implement.
684          * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
685          */

686         MethodDefinition.ImplementationDefinition.Optional<T> implement(Type... interfaceType);
687
688         /**
689          * <p>
690          * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
691          * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
692          * are explicitly ignored.
693          * </p>
694          * <p>
695          * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link Class} values are implemented
696          * as raw types if they declare type variables or an owner type.
697          * </p>
698          *
699          * @param interfaceTypes The interface types to implement.
700          * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
701          */

702         MethodDefinition.ImplementationDefinition.Optional<T> implement(List<? extends Type> interfaceTypes);
703
704         /**
705          * <p>
706          * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
707          * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
708          * are explicitly ignored.
709          * </p>
710          * <p>
711          * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link TypeDescription} values are
712          * implemented as raw types if they declare type variables or an owner type.
713          * </p>
714          *
715          * @param interfaceType The interface types to implement.
716          * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
717          */

718         MethodDefinition.ImplementationDefinition.Optional<T> implement(TypeDefinition... interfaceType);
719
720         /**
721          * <p>
722          * Implements the supplied interfaces for the instrumented type. Optionally, it is possible to define the
723          * methods that are defined by the interfaces or the interfaces' super interfaces. This excludes methods that
724          * are explicitly ignored.
725          * </p>
726          * <p>
727          * <b>Note</b>: This methods implements the supplied types <i>as is</i>, i.e. any {@link TypeDescription} values are
728          * implemented as raw types if they declare type variables or an owner type.
729          * </p>
730          *
731          * @param interfaceTypes The interface types to implement.
732          * @return A new builder that is equal to this builder but with the interfaces implemented by the instrumented type.
733          */

734         MethodDefinition.ImplementationDefinition.Optional<T> implement(Collection<? extends TypeDefinition> interfaceTypes);
735
736         /**
737          * <p>
738          * Executes the supplied byte code appender within the beginning of the instrumented type's type initializer. The
739          * supplied byte code appender <b>must not return</b> from the method. If several byte code appenders are supplied,
740          * they are executed within their application order.
741          * </p>
742          * <p>
743          * This method should only be used for preparing an instrumented type with a specific configuration. Normally,
744          * a byte code appender is applied via Byte Buddy's standard API by invoking {@link Builder#invokable(ElementMatcher)}
745          * using the {@link net.bytebuddy.matcher.ElementMatchers#isTypeInitializer()} matcher.
746          * </p>
747          *
748          * @param byteCodeAppender The byte code appender to execute within the instrumented type's type initializer.
749          * @return A new builder that is equal to this builder but with the supplied byte code appender being executed within
750          * the instrumented type's type initializer.
751          */

752         Builder<T> initializer(ByteCodeAppender byteCodeAppender);
753
754         /**
755          * Executes the supplied loaded type initializer when loading the created instrumented type. If several loaded
756          * type initializers are supplied, each loaded type initializer is executed in its registration order.
757          *
758          * @param loadedTypeInitializer The loaded type initializer to execute upon loading the instrumented type.
759          * @return A new builder that is equal to this builder but with the supplied loaded type initializer executed upon
760          * loading the instrumented type.
761          */

762         Builder<T> initializer(LoadedTypeInitializer loadedTypeInitializer);
763
764         /**
765          * Explicitly requires another dynamic type for the creation of this type.
766          *
767          * @param type                 The type to require.
768          * @param binaryRepresentation The type's binary representation.
769          * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
770          */

771         Builder<T> require(TypeDescription type, byte[] binaryRepresentation);
772
773         /**
774          * Explicitly requires another dynamic type for the creation of this type.
775          *
776          * @param type                 The type to require.
777          * @param binaryRepresentation The type's binary representation.
778          * @param typeInitializer      The type's loaded type initializer.
779          * @return A new builder that is equal to this builder but which explicitly requires the supplied type.
780          */

781         Builder<T> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer);
782
783         /**
784          * Explicitly requires other dynamic types for the creation of this type.
785          *
786          * @param auxiliaryType The required dynamic types.
787          * @return A new builder that is equal to this builder but which explicitly requires the supplied types.
788          */

789         Builder<T> require(DynamicType... auxiliaryType);
790
791         /**
792          * Explicitly requires other dynamic types for the creation of this type.
793          *
794          * @param auxiliaryTypes The required dynamic types.
795          * @return A new builder that is equal to this builder but which explicitly requires the supplied types.
796          */

797         Builder<T> require(Collection<DynamicType> auxiliaryTypes);
798
799         /**
800          * Defines the supplied type variable without any bounds as a type variable of the instrumented type.
801          *
802          * @param symbol The type variable's symbol.
803          * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
804          */

805         TypeVariableDefinition<T> typeVariable(String symbol);
806
807         /**
808          * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
809          *
810          * @param symbol The type variable's symbol.
811          * @param bound  The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
812          *               should be equal to the currently instrumented type.
813          * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
814          */

815         TypeVariableDefinition<T> typeVariable(String symbol, Type... bound);
816
817         /**
818          * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
819          *
820          * @param symbol The type variable's symbol.
821          * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
822          *               should be equal to the currently instrumented type.
823          * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
824          */

825         TypeVariableDefinition<T> typeVariable(String symbol, List<? extends Type> bounds);
826
827         /**
828          * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
829          *
830          * @param symbol The type variable's symbol.
831          * @param bound  The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
832          *               should be equal to the currently instrumented type.
833          * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
834          */

835         TypeVariableDefinition<T> typeVariable(String symbol, TypeDefinition... bound);
836
837         /**
838          * Defines the supplied type variable with the given bound as a type variable of the instrumented type.
839          *
840          * @param symbol The type variable's symbol.
841          * @param bounds The type variable's upper bounds. Can also be {@link net.bytebuddy.dynamic.TargetType} if the bound type
842          *               should be equal to the currently instrumented type.
843          * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
844          */

845         TypeVariableDefinition<T> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
846
847         /**
848          * Transforms any type variable that is defined by this type if it is matched by the supplied matcher.
849          *
850          * @param matcher     The matcher to decide what type variables to transform.
851          * @param transformer The transformer to apply to the matched type variables.
852          * @return A new builder that is equal to this builder but with the supplied transformer applied to all type variables.
853          */

854         Builder<T> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer);
855
856         /**
857          * Defines the specified field as a field of the built dynamic type.
858          *
859          * @param name                The name of the field.
860          * @param type                The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
861          *                            should be equal to the currently instrumented type.
862          * @param modifierContributor The modifiers of the field.
863          * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
864          * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
865          */

866         FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, ModifierContributor.ForField... modifierContributor);
867
868         /**
869          * Defines the specified field as a field of the built dynamic type.
870          *
871          * @param name                 The name of the field.
872          * @param type                 The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
873          *                             should be equal to the currently instrumented type.
874          * @param modifierContributors The modifiers of the field.
875          * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
876          * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
877          */

878         FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, Collection<? extends ModifierContributor.ForField> modifierContributors);
879
880         /**
881          * Defines the specified field as a field of the built dynamic type.
882          *
883          * @param name      The name of the field.
884          * @param type      The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
885          *                  should be equal to the currently instrumented type.
886          * @param modifiers The modifiers of the field.
887          * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
888          * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
889          */

890         FieldDefinition.Optional.Valuable<T> defineField(String name, Type type, int modifiers);
891
892         /**
893          * Defines the specified field as a field of the built dynamic type.
894          *
895          * @param name                The name of the field.
896          * @param type                The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
897          *                            should be equal to the currently instrumented type.
898          * @param modifierContributor The modifiers of the field.
899          * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
900          * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
901          */

902         FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor);
903
904         /**
905          * Defines the specified field as a field of the built dynamic type.
906          *
907          * @param name                 The name of the field.
908          * @param type                 The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
909          *                             should be equal to the currently instrumented type.
910          * @param modifierContributors The modifiers of the field.
911          * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
912          * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
913          */

914         FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors);
915
916         /**
917          * Defines the specified field as a field of the built dynamic type.
918          *
919          * @param name      The name of the field.
920          * @param type      The type of the field. Can also be {@link net.bytebuddy.dynamic.TargetType} if the field type
921          *                  should be equal to the currently instrumented type.
922          * @param modifiers The modifiers of the field.
923          * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
924          * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
925          */

926         FieldDefinition.Optional.Valuable<T> defineField(String name, TypeDefinition type, int modifiers);
927
928         /**
929          * Defines a field that is similar to the supplied field but without copying any annotations on the field.
930          *
931          * @param field The field to imitate as a field of the instrumented type.
932          * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
933          * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
934          */

935         FieldDefinition.Optional.Valuable<T> define(Field field);
936
937         /**
938          * Defines a field that is similar to the supplied field but without copying any annotations on the field.
939          *
940          * @param field The field to imitate as a field of the instrumented type.
941          * @return A new builder that is equal to this builder but with the given field defined for the instrumented type.
942          * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
943          */

944         FieldDefinition.Optional.Valuable<T> define(FieldDescription field);
945
946         /**
947          * Defines a privatestaticfinal field for a serial version UID of the given value.
948          *
949          * @param serialVersionUid The serial version UID to define as a value.
950          * @return A new builder that is equal to this builder but with the given type variable defined for the instrumented type.
951          * Furthermore, it is possible to optionally define a value, annotations or custom attributes for the field.
952          */

953         FieldDefinition.Optional<T> serialVersionUid(long serialVersionUid);
954
955         /**
956          * <p>
957          * Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
958          * default value, annotations or custom attributes.
959          * </p>
960          * <p>
961          * When a type is redefined or rebased, any annotations that the field declared previously is preserved
962          * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
963          * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
964          * altered, annotation retention must be disabled.
965          * </p>
966          * <p>
967          * If a field is already matched by a previously specified field matcher, the new field definition gets precedence
968          * over the previous definition, i.e. the previous field definition is no longer applied.
969          * </p>
970          *
971          * @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
972          * @return A builder that allows for changing a field's definition.
973          */

974         FieldDefinition.Valuable<T> field(ElementMatcher<? super FieldDescription> matcher);
975
976         /**
977          * <p>
978          * Matches a field that is already declared by the instrumented type. This gives opportunity to change that field's
979          * default value, annotations or custom attributes. Using a latent matcher gives opportunity to resolve an
980          * {@link ElementMatcher} based on the instrumented type before applying the matcher.
981          * </p>
982          * <p>
983          * When a type is redefined or rebased, any annotations that the field declared previously is preserved
984          * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
985          * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
986          * altered, annotation retention must be disabled.
987          * </p>
988          * <p>
989          * If a field is already matched by a previously specified field matcher, the new field definition gets precedence
990          * over the previous definition, i.e. the previous field definition is no longer applied.
991          * </p>
992          *
993          * @param matcher The matcher that determines what declared fields are affected by the subsequent specification.
994          * @return A builder that allows for changing a field's definition.
995          */

996         FieldDefinition.Valuable<T> field(LatentMatcher<? super FieldDescription> matcher);
997
998         /**
999          * <p>
1000          * Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
1001          * remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
1002          * </p>
1003          * <p>
1004          * When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
1005          * is to be ignored, this matcher is no longer executed.
1006          * </p>
1007          *
1008          * @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
1009          * @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
1010          * instrumentation.
1011          */

1012         Builder<T> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods);
1013
1014         /**
1015          * <p>
1016          * Specifies to exclude any method that is matched by the supplied matcher from instrumentation. Previously supplied matchers
1017          * remain valid after supplying a new matcher, i.e. any method that is matched by a previously supplied matcher is always ignored.
1018          * Using a latent matcher gives opportunity to resolve an {@link ElementMatcher} based on the instrumented type before applying the
1019          * matcher.
1020          * </p>
1021          * <p>
1022          * When ignoring a type, previously registered matchers are applied before this matcher. If a previous matcher indicates that a type
1023          * is to be ignored, this matcher is no longer executed.
1024          * </p>
1025          *
1026          * @param ignoredMethods The matcher for determining what methods to exclude from instrumentation.
1027          * @return A new builder that is equal to this builder but that is excluding any method that is matched by the supplied matcher from
1028          * instrumentation.
1029          */

1030         Builder<T> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods);
1031
1032         /**
1033          * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1034          * type variables can be defined in subsequent steps.
1035          *
1036          * @param name                The name of the method.
1037          * @param returnType          The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1038          *                            should be equal to the currently instrumented type.
1039          * @param modifierContributor The method's modifiers.
1040          * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1041          */

1042         MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor);
1043
1044         /**
1045          * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1046          * type variables can be defined in subsequent steps.
1047          *
1048          * @param name                 The name of the method.
1049          * @param returnType           The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1050          *                             should be equal to the currently instrumented type.
1051          * @param modifierContributors The method's modifiers.
1052          * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1053          */

1054         MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1055
1056         /**
1057          * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1058          * type variables can be defined in subsequent steps.
1059          *
1060          * @param name       The name of the method.
1061          * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1062          *                   should be equal to the currently instrumented type.
1063          * @param modifiers  The method's modifiers.
1064          * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1065          */

1066         MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, Type returnType, int modifiers);
1067
1068         /**
1069          * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1070          * type variables can be defined in subsequent steps.
1071          *
1072          * @param name                The name of the method.
1073          * @param returnType          The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1074          *                            should be equal to the currently instrumented type.
1075          * @param modifierContributor The method's modifiers.
1076          * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1077          */

1078         MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor);
1079
1080         /**
1081          * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1082          * type variables can be defined in subsequent steps.
1083          *
1084          * @param name                 The name of the method.
1085          * @param returnType           The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1086          *                             should be equal to the currently instrumented type.
1087          * @param modifierContributors The method's modifiers.
1088          * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1089          */

1090         MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1091
1092         /**
1093          * Defines the specified method to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1094          * type variables can be defined in subsequent steps.
1095          *
1096          * @param name       The name of the method.
1097          * @param returnType The method's return type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the return type
1098          *                   should be equal to the currently instrumented type.
1099          * @param modifiers  The method's modifiers.
1100          * @return A builder that allows for further defining the method, either by adding more properties or by defining an implementation.
1101          */

1102         MethodDefinition.ParameterDefinition.Initial<T> defineMethod(String name, TypeDefinition returnType, int modifiers);
1103
1104         /**
1105          * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1106          * type variables can be defined in subsequent steps.
1107          *
1108          * @param modifierContributor The constructor's modifiers.
1109          * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1110          */

1111         MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(ModifierContributor.ForMethod... modifierContributor);
1112
1113         /**
1114          * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1115          * type variables can be defined in subsequent steps.
1116          *
1117          * @param modifierContributors The constructor's modifiers.
1118          * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1119          */

1120         MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors);
1121
1122         /**
1123          * Defines the specified constructor to be declared by the instrumented type. Method parameters or parameter types, declared exceptions and
1124          * type variables can be defined in subsequent steps.
1125          *
1126          * @param modifiers The constructor's modifiers.
1127          * @return A builder that allows for further defining the constructor, either by adding more properties or by defining an implementation.
1128          */

1129         MethodDefinition.ParameterDefinition.Initial<T> defineConstructor(int modifiers);
1130
1131         /**
1132          * Defines a method that is similar to the supplied method but without copying any annotations of the method or method parameters.
1133          *
1134          * @param method The method to imitate as a method of the instrumented type.
1135          * @return A builder that allows for defining an implementation for the method.
1136          */

1137         MethodDefinition.ImplementationDefinition<T> define(Method method);
1138
1139         /**
1140          * Defines a constructor that is similar to the supplied constructor but without copying any annotations of the constructor or
1141          * constructor parameters.
1142          *
1143          * @param constructor The constructor to imitate as a method of the instrumented type.
1144          * @return A builder that allows for defining an implementation for the constructor.
1145          */

1146         MethodDefinition.ImplementationDefinition<T> define(Constructor<?> constructor);
1147
1148         /**
1149          * Defines a method or constructor that is similar to the supplied method description but without copying any annotations of
1150          * the method/constructor or method/constructor parameters.
1151          *
1152          * @param methodDescription The method description to imitate as a method or constructor of the instrumented type.
1153          * @return A builder that allows for defining an implementation for the method or constructor.
1154          */

1155         MethodDefinition.ImplementationDefinition<T> define(MethodDescription methodDescription);
1156
1157         /**
1158          * Defines a Java bean property with the specified name.
1159          *
1160          * @param name The name of the property.
1161          * @param type The property type.
1162          * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1163          */

1164         FieldDefinition.Optional<T> defineProperty(String name, Type type);
1165
1166         /**
1167          * Defines a Java bean property with the specified name.
1168          *
1169          * @param name     The name of the property.
1170          * @param type     The property type.
1171          * @param readOnly {@code trueif the property is read only, i.e. no setter should be defined and the field should be {@code final}.
1172          * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1173          */

1174         FieldDefinition.Optional<T> defineProperty(String name, Type type, boolean readOnly);
1175
1176         /**
1177          * Defines a Java bean property with the specified name.
1178          *
1179          * @param name The name of the property.
1180          * @param type The property type.
1181          * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1182          */

1183         FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type);
1184
1185         /**
1186          * Defines a Java bean property with the specified name.
1187          *
1188          * @param name     The name of the property.
1189          * @param type     The property type.
1190          * @param readOnly {@code trueif the property is read only, i.e. no setter should be defined and the field should be {@code final}.
1191          * @return A builder that defines the specified property where the field holding the property can be refined by subsequent steps.
1192          */

1193         FieldDefinition.Optional<T> defineProperty(String name, TypeDefinition type, boolean readOnly);
1194
1195         /**
1196          * <p>
1197          * Matches a method that is already declared or inherited by the instrumented type. This gives opportunity to change or to
1198          * override that method's implementation, default value, annotations or custom attributes. It is also possible to make
1199          * a method abstract.
1200          * </p>
1201          * <p>
1202          * When a type is redefined or rebased, any annotations that the method declared previously is preserved
1203          * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1204          * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1205          * altered, annotation retention must be disabled.
1206          * </p>
1207          * <p>
1208          * If a method is already matched by a previously specified matcher, the new method definition gets precedence
1209          * over the previous definition, i.e. the previous method definition is no longer applied.
1210          * </p>
1211          * <p>
1212          * Note that the specified definition does never apply for methods that are explicitly ignored.
1213          * </p>
1214          *
1215          * @param matcher The matcher that determines what methods are affected by the subsequent specification.
1216          * @return A builder that allows for changing a method's or constructor's definition.
1217          */

1218         MethodDefinition.ImplementationDefinition<T> method(ElementMatcher<? super MethodDescription> matcher);
1219
1220         /**
1221          * <p>
1222          * Matches a constructor that is already declared by the instrumented type. This gives opportunity to change that constructor's
1223          * implementation, default value, annotations or custom attributes.
1224          * </p>
1225          * <p>
1226          * When a type is redefined or rebased, any annotations that the constructor declared previously is preserved
1227          * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1228          * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1229          * altered, annotation retention must be disabled.
1230          * </p>
1231          * <p>
1232          * If a constructor is already matched by a previously specified matcher, the new constructor definition gets precedence
1233          * over the previous definition, i.e. the previous constructor definition is no longer applied.
1234          * </p>
1235          * <p>
1236          * Note that the specified definition does never apply for methods that are explicitly ignored.
1237          * </p>
1238          *
1239          * @param matcher The matcher that determines what constructors are affected by the subsequent specification.
1240          * @return A builder that allows for changing a method's or constructor's definition.
1241          */

1242         MethodDefinition.ImplementationDefinition<T> constructor(ElementMatcher<? super MethodDescription> matcher);
1243
1244         /**
1245          * <p>
1246          * Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
1247          * opportunity to change or to override that method's or constructor's implementation, default value, annotations
1248          * or custom attributes. It is also possible to make a method abstract.
1249          * </p>
1250          * <p>
1251          * When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
1252          * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1253          * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1254          * altered, annotation retention must be disabled.
1255          * </p>
1256          * <p>
1257          * If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
1258          * over the previous definition, i.e. the previous definition is no longer applied.
1259          * </p>
1260          * <p>
1261          * Note that the specified definition does never apply for methods that are explicitly ignored.
1262          * </p>
1263          * <p>
1264          * <b>Important</b>: It is possible to instrument the dynamic type's initializer. Depending on the used {@link TypeResolutionStrategy},
1265          * the type initializer might be run <b>before</b> Byte Buddy could apply any {@link LoadedTypeInitializer}s which are
1266          * responsible for preparing the instrumented type prior to the initializer's execution. For preparing the type prior to
1267          * executing the initializer, an {@link TypeResolutionStrategy.Active} resolver must be chosen.
1268          * </p>
1269          *
1270          * @param matcher The matcher that determines what methods or constructors are affected by the subsequent specification.
1271          * @return A builder that allows for changing a method's or constructor's definition.
1272          */

1273         MethodDefinition.ImplementationDefinition<T> invokable(ElementMatcher<? super MethodDescription> matcher);
1274
1275         /**
1276          * <p>
1277          * Matches a method or constructor that is already declared or inherited by the instrumented type. This gives
1278          * opportunity to change or to override that method's or constructor's implementation, default value, annotations
1279          * or custom attributes. It is also possible to make a method abstract. Using a latent matcher gives opportunity
1280          * to resolve an {@link ElementMatcher} based on the instrumented type before applying the matcher.
1281          * </p>
1282          * <p>
1283          * When a type is redefined or rebased, any annotations that the method or constructor declared previously is preserved
1284          * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1285          * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1286          * altered, annotation retention must be disabled.
1287          * </p>
1288          * <p>
1289          * If a method or constructor is already matched by a previously specified matcher, the new definition gets precedence
1290          * over the previous definition, i.e. the previous definition is no longer applied.
1291          * </p>
1292          * <p>
1293          * Note that the specified definition does never apply for methods that are explicitly ignored.
1294          * </p>
1295          * <p>
1296          * <b>Important</b>: It is possible to instrument the dynamic type's initializer. Depending on the used {@link TypeResolutionStrategy},
1297          * the type initializer might be run <b>before</b> Byte Buddy could apply any {@link LoadedTypeInitializer}s which are
1298          * responsible for preparing the instrumented type prior to the initializer's execution. For preparing the type prior to
1299          * executing the initializer, an {@link TypeResolutionStrategy.Active} resolver must be chosen.
1300          * </p>
1301          *
1302          * @param matcher The matcher that determines what declared methods or constructors are affected by the subsequent specification.
1303          * @return A builder that allows for changing a method's or constructor's definition.
1304          */

1305         MethodDefinition.ImplementationDefinition<T> invokable(LatentMatcher<? super MethodDescription> matcher);
1306
1307         /**
1308          * Implements {@link Object#hashCode()} and {@link Object#equals(Object)} methods for the instrumented type if those
1309          * methods are not declared as {@code final} by a super class. The implementations do not consider any implementations
1310          * of a super class and compare a class field by field without considering synthetic fields.
1311          *
1312          * @return A new type builder that defines {@link Object#hashCode()} and {@link Object#equals(Object)} methods accordingly.
1313          */

1314         Builder<T> withHashCodeEquals();
1315
1316         /**
1317          * Implements a {@link Object#toString()} method for the instrumented type if such a method is not declared as {@code final}
1318          * by a super class. The implementation prefixes the string with the simple class name and prints each non-synthetic field's
1319          * value after the field's name.
1320          *
1321          * @return A new type builder that defines {@link Object#toString()} method accordingly.
1322          */

1323         Builder<T> withToString();
1324
1325         /**
1326          * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1327          * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1328          *
1329          * @param name The record component's name.
1330          * @param type The record component's type.
1331          * @return A new builder that is equal to this builder but also defines the supplied record component.
1332          */

1333         RecordComponentDefinition.Optional<T> defineRecordComponent(String name, Type type);
1334
1335         /**
1336          * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1337          * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1338          *
1339          * @param name The record component's name.
1340          * @param type The record component's type.
1341          * @return A new builder that is equal to this builder but also defines the supplied record component.
1342          */

1343         RecordComponentDefinition.Optional<T> defineRecordComponent(String name, TypeDefinition type);
1344
1345         /**
1346          * Defines a new record component. Note that this does not add or change implementations for a field, an accessor
1347          * to this field or a constructor unless {@link net.bytebuddy.ByteBuddy#makeRecord()} is used.
1348          *
1349          * @param recordComponentDescription A description of the record component to immitate.
1350          * @return A new builder that is equal to this builder but also defines the supplied record component.
1351          */

1352         RecordComponentDefinition.Optional<T> define(RecordComponentDescription recordComponentDescription);
1353
1354         /**
1355          * <p>
1356          * Matches a record component that is already declared by the instrumented type. This gives opportunity to change that
1357          * record component's annotations or custom attributes.
1358          * </p>
1359          * <p>
1360          * When a type is redefined or rebased, any annotations that the field declared previously is preserved
1361          * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1362          * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1363          * altered, annotation retention must be disabled.
1364          * </p>
1365          * <p>
1366          * If a record component is already matched by a previously specified record component matcher, the new record component
1367          * definition gets precedence over the previous definition, i.e. the previous record component definition is no longer applied.
1368          * </p>
1369          *
1370          * @param matcher The matcher that determines what declared record components are affected by the subsequent specification.
1371          * @return A builder that allows for changing a record component's definition.
1372          */

1373         RecordComponentDefinition<T> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher);
1374
1375         /**
1376          * <p>
1377          * Matches a record component that is already declared by the instrumented type. This gives opportunity to change that
1378          * record component's annotations or custom attributes.
1379          * </p>
1380          * <p>
1381          * When a type is redefined or rebased, any annotations that the field declared previously is preserved
1382          * <i>as it is</i> if Byte Buddy is configured to retain such annotations by
1383          * {@link net.bytebuddy.implementation.attribute.AnnotationRetention#ENABLED}. If any existing annotations should be
1384          * altered, annotation retention must be disabled.
1385          * </p>
1386          * <p>
1387          * If a record component is already matched by a previously specified record component matcher, the new record component
1388          * definition gets precedence over the previous definition, i.e. the previous record component definition is no longer applied.
1389          * </p>
1390          *
1391          * @param matcher The matcher that determines what declared record components are affected by the subsequent specification.
1392          * @return A builder that allows for changing a record component's definition.
1393          */

1394         RecordComponentDefinition<T> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher);
1395
1396         /**
1397          * <p>
1398          * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1399          * </p>
1400          * <p>
1401          * Other than {@link DynamicType.Builder#make(TypePool)}, this method supplies a context-dependant type pool to the underlying class writer.
1402          * Supplying a type pool only makes sense if custom byte code is created by adding a custom {@link AsmVisitorWrapper} where ASM might be
1403          * required to compute stack map frames by processing information over any mentioned type's class hierarchy.
1404          * </p>
1405          * <p>
1406          * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1407          * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1408          * executing the initializer must rely on such an initializer.
1409          * </p>
1410          *
1411          * @return An unloaded dynamic type representing the type specified by this builder.
1412          */

1413         DynamicType.Unloaded<T> make();
1414
1415         /**
1416          * <p>
1417          * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1418          * </p>
1419          * <p>
1420          * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1421          * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1422          * executing the initializer must rely on such an initializer.
1423          * </p>
1424          *
1425          * @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
1426          * @return An unloaded dynamic type representing the type specified by this builder.
1427          */

1428         DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy);
1429
1430         /**
1431          * <p>
1432          * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1433          * </p>
1434          * <p>
1435          * The dynamic type is initialized using a {@link TypeResolutionStrategy.Passive} strategy. Using this strategy, no
1436          * {@link LoadedTypeInitializer} is run during the execution of the type's initializer such that no {@link Implementation} used for
1437          * executing the initializer must rely on such an initializer.
1438          * </p>
1439          *
1440          * @param typePool A type pool that is used for computing stack map frames by the underlying class writer, if required.
1441          * @return An unloaded dynamic type representing the type specified by this builder.
1442          */

1443         DynamicType.Unloaded<T> make(TypePool typePool);
1444
1445         /**
1446          * Creates the dynamic type this builder represents. If the specified dynamic type is not legal, an {@link IllegalStateException} is thrown.
1447          *
1448          * @param typeResolutionStrategy The type resolution strategy to use for the created type's initialization.
1449          * @param typePool               A type pool that is used for computing stack map frames by the underlying class writer, if required.
1450          * @return An unloaded dynamic type representing the type specified by this builder.
1451          */

1452         DynamicType.Unloaded<T> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool);
1453
1454         /**
1455          * Returns a {@link TypeDescription} for the currently built type.
1456          *
1457          * @return A {@link TypeDescription} for the currently built type.
1458          */

1459         TypeDescription toTypeDescription();
1460
1461         /**
1462          * An inner type definition for defining a type that is contained within another type, method or constructor.
1463          *
1464          * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1465          */

1466         interface InnerTypeDefinition<S> extends Builder<S> {
1467
1468             /**
1469              * Defines this inner type declaration as an anonymous type.
1470              *
1471              * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a anonymous type.
1472              */

1473             Builder<S> asAnonymousType();
1474
1475             /**
1476              * An inner type definition for defining a type that is contained within another type.
1477              *
1478              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1479              */

1480             interface ForType<U> extends InnerTypeDefinition<U> {
1481
1482                 /**
1483                  * Defines this inner type declaration as a member type.
1484                  *
1485                  * @return A new builder that is equal to this type builder but that defines the previous inner type definition as a member type.
1486                  */

1487                 Builder<U> asMemberType();
1488             }
1489         }
1490
1491         /**
1492          * A builder for a type variable definition.
1493          *
1494          * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1495          */

1496         interface TypeVariableDefinition<S> extends Builder<S> {
1497
1498             /**
1499              * Annotates the previously defined type variable with the supplied annotations.
1500              *
1501              * @param annotation The annotations to declare on the previously defined type variable.
1502              * @return A new builder that is equal to this builder but with the given annotations declared
1503              * on the previously defined type variable.
1504              */

1505             TypeVariableDefinition<S> annotateTypeVariable(Annotation... annotation);
1506
1507             /**
1508              * Annotates the previously defined type variable with the supplied annotations.
1509              *
1510              * @param annotations The annotations to declare on the previously defined type variable.
1511              * @return A new builder that is equal to this builder but with the given annotations declared
1512              * on the previously defined type variable.
1513              */

1514             TypeVariableDefinition<S> annotateTypeVariable(List<? extends Annotation> annotations);
1515
1516             /**
1517              * Annotates the previously defined type variable with the supplied annotations.
1518              *
1519              * @param annotation The annotations to declare on the previously defined type variable.
1520              * @return A new builder that is equal to this builder but with the given annotations declared
1521              * on the previously defined type variable.
1522              */

1523             TypeVariableDefinition<S> annotateTypeVariable(AnnotationDescription... annotation);
1524
1525             /**
1526              * Annotates the previously defined type variable with the supplied annotations.
1527              *
1528              * @param annotations The annotations to declare on the previously defined type variable.
1529              * @return A new builder that is equal to this builder but with the given annotations declared
1530              * on the previously defined type variable.
1531              */

1532             TypeVariableDefinition<S> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
1533
1534             /**
1535              * An abstract base implementation of a type variable definition.
1536              *
1537              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1538              */

1539             abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements TypeVariableDefinition<U> {
1540
1541                 /**
1542                  * {@inheritDoc}
1543                  */

1544                 public TypeVariableDefinition<U> annotateTypeVariable(Annotation... annotation) {
1545                     return annotateTypeVariable(Arrays.asList(annotation));
1546                 }
1547
1548                 /**
1549                  * {@inheritDoc}
1550                  */

1551                 public TypeVariableDefinition<U> annotateTypeVariable(List<? extends Annotation> annotations) {
1552                     return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
1553                 }
1554
1555                 /**
1556                  * {@inheritDoc}
1557                  */

1558                 public TypeVariableDefinition<U> annotateTypeVariable(AnnotationDescription... annotation) {
1559                     return annotateTypeVariable(Arrays.asList(annotation));
1560                 }
1561             }
1562         }
1563
1564         /**
1565          * A builder for a field definition.
1566          *
1567          * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1568          */

1569         interface FieldDefinition<S> {
1570
1571             /**
1572              * Annotates the previously defined or matched field with the supplied annotations.
1573              *
1574              * @param annotation The annotations to declare on the previously defined or matched field.
1575              * @return A new builder that is equal to this builder but with the given annotations declared
1576              * on the previously defined or matched field.
1577              */

1578             FieldDefinition.Optional<S> annotateField(Annotation... annotation);
1579
1580             /**
1581              * Annotates the previously defined or matched field with the supplied annotations.
1582              *
1583              * @param annotations The annotations to declare on the previously defined or matched field.
1584              * @return A new builder that is equal to this builder but with the given annotations declared
1585              * on the previously defined or matched field.
1586              */

1587             FieldDefinition.Optional<S> annotateField(List<? extends Annotation> annotations);
1588
1589             /**
1590              * Annotates the previously defined or matched field with the supplied annotations.
1591              *
1592              * @param annotation The annotations to declare on the previously defined or matched field.
1593              * @return A new builder that is equal to this builder but with the given annotations declared
1594              * on the previously defined or matched field.
1595              */

1596             FieldDefinition.Optional<S> annotateField(AnnotationDescription... annotation);
1597
1598             /**
1599              * Annotates the previously defined or matched field with the supplied annotations.
1600              *
1601              * @param annotations The annotations to declare on the previously defined or matched field.
1602              * @return A new builder that is equal to this builder but with the given annotations declared
1603              * on the previously defined or matched field.
1604              */

1605             FieldDefinition.Optional<S> annotateField(Collection<? extends AnnotationDescription> annotations);
1606
1607             /**
1608              * Applies the supplied attribute appender factory onto the previously defined or matched field.
1609              *
1610              * @param fieldAttributeAppenderFactory The field attribute appender factory that should be applied on the
1611              *                                      previously defined or matched field.
1612              * @return A new builder that is equal to this builder but with the supplied field attribute appender factory
1613              * applied to the previously defined or matched field.
1614              */

1615             FieldDefinition.Optional<S> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory);
1616
1617             /**
1618              * Applies the supplied transformer onto the previously defined or matched field. The transformed
1619              * field is written <i>as it is</i> and it not subject to any validations.
1620              *
1621              * @param transformer The transformer to apply to the previously defined or matched field.
1622              * @return A new builder that is equal to this builder but with the supplied field transformer
1623              * applied to the previously defined or matched field.
1624              */

1625             FieldDefinition.Optional<S> transform(Transformer<FieldDescription> transformer);
1626
1627             /**
1628              * A builder for a field definition that allows for defining a value.
1629              *
1630              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1631              */

1632             interface Valuable<U> extends FieldDefinition<U> {
1633
1634                 /**
1635                  * <p>
1636                  * Defines the supplied {@code boolean} value as a default value of the previously defined or matched field. The value can only
1637                  * be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int}. For non-boolean
1638                  * fields, the field's value is set to {@code 0} for {@code false} or {@code 1} for {@code true}.
1639                  * </p>
1640                  * <p>
1641                  * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1642                  * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1643                  * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1644                  * </p>
1645                  *
1646                  * @param value The value to define as a default value of the defined field.
1647                  * @return A new builder that is equal to this builder but with the given default value declared for the
1648                  * previously defined or matched field.
1649                  */

1650                 FieldDefinition.Optional<U> value(boolean value);
1651
1652                 /**
1653                  * <p>
1654                  * Defines the supplied {@code int} value as a default value of the previously defined or matched field. The value can only
1655                  * be set for numeric fields of type {@code boolean}, {@code byte}, {@code short}, {@code char} or {@code int} where the
1656                  * value must be within the numeric type's range. The {@code boolean} type is regarded as a numeric type with the possible
1657                  * values of {@code 0} and {@code 1} representing {@code false} and {@code true}.
1658                  * </p>
1659                  * <p>
1660                  * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1661                  * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1662                  * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1663                  * </p>
1664                  *
1665                  * @param value The value to define as a default value of the defined field.
1666                  * @return A new builder that is equal to this builder but with the given default value declared for the
1667                  * previously defined or matched field.
1668                  */

1669                 FieldDefinition.Optional<U> value(int value);
1670
1671                 /**
1672                  * <p>
1673                  * Defines the supplied {@code long} value as a default value of the previously defined or matched field.
1674                  * </p>
1675                  * <p>
1676                  * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1677                  * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1678                  * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1679                  * </p>
1680                  *
1681                  * @param value The value to define as a default value of the defined field.
1682                  * @return A new builder that is equal to this builder but with the given default value declared for the
1683                  * previously defined or matched field.
1684                  */

1685                 FieldDefinition.Optional<U> value(long value);
1686
1687                 /**
1688                  * <p>
1689                  * Defines the supplied {@code float} value as a default value of the previously defined or matched field.
1690                  * </p>
1691                  * <p>
1692                  * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1693                  * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1694                  * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1695                  * </p>
1696                  *
1697                  * @param value The value to define as a default value of the defined field.
1698                  * @return A new builder that is equal to this builder but with the given default value declared for the
1699                  * previously defined or matched field.
1700                  */

1701                 FieldDefinition.Optional<U> value(float value);
1702
1703                 /**
1704                  * <p>
1705                  * Defines the supplied {@code double} value as a default value of the previously defined or matched field.
1706                  * </p>
1707                  * <p>
1708                  * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1709                  * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1710                  * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1711                  * </p>
1712                  *
1713                  * @param value The value to define as a default value of the defined field.
1714                  * @return A new builder that is equal to this builder but with the given default value declared for the
1715                  * previously defined or matched field.
1716                  */

1717                 FieldDefinition.Optional<U> value(double value);
1718
1719                 /**
1720                  * <p>
1721                  * Defines the supplied {@link String} value as a default value of the previously defined or matched field.
1722                  * </p>
1723                  * <p>
1724                  * <b>Important</b>: A default value in a Java class file defines a field's value prior to the class's initialization. This value
1725                  * is only visible to code if the field is declared {@code static}. A default value can also be set for non-static fields where
1726                  * the value is not visible to code. The Java compiler only defines such values for {@code final} fields.
1727                  * </p>
1728                  *
1729                  * @param value The value to define as a default value of the defined field.
1730                  * @return A new builder that is equal to this builder but with the given default value declared for the
1731                  * previously defined or matched field.
1732                  */

1733                 FieldDefinition.Optional<U> value(String value);
1734             }
1735
1736             /**
1737              * A builder for an optional field definition.
1738              *
1739              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1740              */

1741             interface Optional<U> extends FieldDefinition<U>, Builder<U> {
1742
1743                 /**
1744                  * A builder for an optional field definition that allows for defining a value.
1745                  *
1746                  * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1747                  */

1748                 interface Valuable<V> extends FieldDefinition.Valuable<V>, Optional<V> {
1749
1750                     /**
1751                      * An abstract base implementation of an optional field definition that allows for defining a value.
1752                      *
1753                      * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1754                      */

1755                     abstract class AbstractBase<U> extends Optional.AbstractBase<U> implements Optional.Valuable<U> {
1756
1757                         /**
1758                          * {@inheritDoc}
1759                          */

1760                         public FieldDefinition.Optional<U> value(boolean value) {
1761                             return defaultValue(value ? 1 : 0);
1762                         }
1763
1764                         /**
1765                          * {@inheritDoc}
1766                          */

1767                         public FieldDefinition.Optional<U> value(int value) {
1768                             return defaultValue(value);
1769                         }
1770
1771                         /**
1772                          * {@inheritDoc}
1773                          */

1774                         public FieldDefinition.Optional<U> value(long value) {
1775                             return defaultValue(value);
1776                         }
1777
1778                         /**
1779                          * {@inheritDoc}
1780                          */

1781                         public FieldDefinition.Optional<U> value(float value) {
1782                             return defaultValue(value);
1783                         }
1784
1785                         /**
1786                          * {@inheritDoc}
1787                          */

1788                         public FieldDefinition.Optional<U> value(double value) {
1789                             return defaultValue(value);
1790                         }
1791
1792                         /**
1793                          * {@inheritDoc}
1794                          */

1795                         public FieldDefinition.Optional<U> value(String value) {
1796                             if (value == null) {
1797                                 throw new IllegalArgumentException("Cannot set null as a default value");
1798                             }
1799                             return defaultValue(value);
1800                         }
1801
1802                         /**
1803                          * Defines the supplied value as a default value of the previously defined or matched field.
1804                          *
1805                          * @param defaultValue The value to define as a default value of the defined field.
1806                          * @return A new builder that is equal to this builder but with the given default value declared for the
1807                          * previously defined or matched field.
1808                          */

1809                         protected abstract FieldDefinition.Optional<U> defaultValue(Object defaultValue);
1810
1811                         /**
1812                          * An adapter for an optional field definition that allows for defining a value.
1813                          *
1814                          * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
1815                          */

1816                         @HashCodeAndEqualsPlugin.Enhance
1817                         private abstract static class Adapter<V> extends Optional.Valuable.AbstractBase<V> {
1818
1819                             /**
1820                              * The field attribute appender factory to apply.
1821                              */

1822                             protected final FieldAttributeAppender.Factory fieldAttributeAppenderFactory;
1823
1824                             /**
1825                              * The field transformer to apply.
1826                              */

1827                             protected final Transformer<FieldDescription> transformer;
1828
1829                             /**
1830                              * The field's default value or {@code nullif no value is to be defined.
1831                              */

1832                             @HashCodeAndEqualsPlugin.ValueHandling(HashCodeAndEqualsPlugin.ValueHandling.Sort.REVERSE_NULLABILITY)
1833                             protected final Object defaultValue;
1834
1835                             /**
1836                              * Creates a new field adapter.
1837                              *
1838                              * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
1839                              * @param transformer                   The field transformer to apply.
1840                              * @param defaultValue                  The field's default value or {@code nullif no value is to be defined.
1841                              */

1842                             protected Adapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
1843                                               Transformer<FieldDescription> transformer,
1844                                               Object defaultValue) {
1845                                 this.fieldAttributeAppenderFactory = fieldAttributeAppenderFactory;
1846                                 this.transformer = transformer;
1847                                 this.defaultValue = defaultValue;
1848                             }
1849
1850                             /**
1851                              * {@inheritDoc}
1852                              */

1853                             public FieldDefinition.Optional<V> attribute(FieldAttributeAppender.Factory fieldAttributeAppenderFactory) {
1854                                 return materialize(new FieldAttributeAppender.Factory.Compound(this.fieldAttributeAppenderFactory, fieldAttributeAppenderFactory), transformer, defaultValue);
1855                             }
1856
1857                             /**
1858                              * {@inheritDoc}
1859                              */

1860                             @SuppressWarnings("unchecked"// In absence of @SafeVarargs
1861                             public FieldDefinition.Optional<V> transform(Transformer<FieldDescription> transformer) {
1862                                 return materialize(fieldAttributeAppenderFactory, new Transformer.Compound<FieldDescription>(this.transformer, transformer), defaultValue);
1863                             }
1864
1865                             @Override
1866                             protected FieldDefinition.Optional<V> defaultValue(Object defaultValue) {
1867                                 return materialize(fieldAttributeAppenderFactory, transformer, defaultValue);
1868                             }
1869
1870                             /**
1871                              * Creates a new optional field definition for which all of the supplied values are represented.
1872                              *
1873                              * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
1874                              * @param transformer                   The field transformer to apply.
1875                              * @param defaultValue                  The field's default value or {@code nullif no value is to be defined.
1876                              * @return A new field definition that represents the supplied values.
1877                              */

1878                             protected abstract FieldDefinition.Optional<V> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
1879                                                                                        Transformer<FieldDescription> transformer,
1880                                                                                        Object defaultValue);
1881                         }
1882                     }
1883                 }
1884
1885                 /**
1886                  * An abstract base implementation for an optional field definition.
1887                  *
1888                  * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
1889                  */

1890                 abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements FieldDefinition.Optional<U> {
1891
1892                     /**
1893                      * {@inheritDoc}
1894                      */

1895                     public FieldDefinition.Optional<U> annotateField(Annotation... annotation) {
1896                         return annotateField(Arrays.asList(annotation));
1897                     }
1898
1899                     /**
1900                      * {@inheritDoc}
1901                      */

1902                     public FieldDefinition.Optional<U> annotateField(List<? extends Annotation> annotations) {
1903                         return annotateField(new AnnotationList.ForLoadedAnnotations(annotations));
1904                     }
1905
1906                     /**
1907                      * {@inheritDoc}
1908                      */

1909                     public FieldDefinition.Optional<U> annotateField(AnnotationDescription... annotation) {
1910                         return annotateField(Arrays.asList(annotation));
1911                     }
1912                 }
1913             }
1914         }
1915
1916         /**
1917          * A builder for a method definition.
1918          *
1919          * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
1920          */

1921         interface MethodDefinition<S> extends Builder<S> {
1922
1923             /**
1924              * Annotates the previously defined or matched method with the supplied annotations.
1925              *
1926              * @param annotation The annotations to declare on the previously defined or matched method.
1927              * @return A new builder that is equal to this builder but with the given annotations declared
1928              * on the previously defined or matched method.
1929              */

1930             MethodDefinition<S> annotateMethod(Annotation... annotation);
1931
1932             /**
1933              * Annotates the previously defined or matched method with the supplied annotations.
1934              *
1935              * @param annotations The annotations to declare on the previously defined or matched method.
1936              * @return A new builder that is equal to this builder but with the given annotations declared
1937              * on the previously defined or matched method.
1938              */

1939             MethodDefinition<S> annotateMethod(List<? extends Annotation> annotations);
1940
1941             /**
1942              * Annotates the previously defined or matched method with the supplied annotations.
1943              *
1944              * @param annotation The annotations to declare on the previously defined or matched method.
1945              * @return A new builder that is equal to this builder but with the given annotations declared
1946              * on the previously defined or matched method.
1947              */

1948             MethodDefinition<S> annotateMethod(AnnotationDescription... annotation);
1949
1950             /**
1951              * Annotates the previously defined or matched method with the supplied annotations.
1952              *
1953              * @param annotations The annotations to declare on the previously defined or matched method.
1954              * @return A new builder that is equal to this builder but with the given annotations declared
1955              * on the previously defined or matched method.
1956              */

1957             MethodDefinition<S> annotateMethod(Collection<? extends AnnotationDescription> annotations);
1958
1959             /**
1960              * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
1961              *
1962              * @param index      The parameter's index.
1963              * @param annotation The annotations to declare on the previously defined or matched method.
1964              * @return A new builder that is equal to this builder but with the given annotations declared
1965              * on the previously defined or matched method's parameter of the given index.
1966              */

1967             MethodDefinition<S> annotateParameter(int index, Annotation... annotation);
1968
1969             /**
1970              * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
1971              *
1972              * @param index       The parameter's index.
1973              * @param annotations The annotations to declare on the previously defined or matched method.
1974              * @return A new builder that is equal to this builder but with the given annotations declared
1975              * on the previously defined or matched method's parameter of the given index.
1976              */

1977             MethodDefinition<S> annotateParameter(int index, List<? extends Annotation> annotations);
1978
1979             /**
1980              * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
1981              *
1982              * @param index      The parameter's index.
1983              * @param annotation The annotations to declare on the previously defined or matched method.
1984              * @return A new builder that is equal to this builder but with the given annotations declared
1985              * on the previously defined or matched method's parameter of the given index.
1986              */

1987             MethodDefinition<S> annotateParameter(int index, AnnotationDescription... annotation);
1988
1989             /**
1990              * Annotates the parameter of the given index of the previously defined or matched method with the supplied annotations.
1991              *
1992              * @param index       The parameter's index.
1993              * @param annotations The annotations to declare on the previously defined or matched method.
1994              * @return A new builder that is equal to this builder but with the given annotations declared
1995              * on the previously defined or matched method's parameter of the given index.
1996              */

1997             MethodDefinition<S> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations);
1998
1999             /**
2000              * Applies the supplied method attribute appender factory onto the previously defined or matched method.
2001              *
2002              * @param methodAttributeAppenderFactory The method attribute appender factory that should be applied on the
2003              *                                       previously defined or matched method.
2004              * @return A new builder that is equal to this builder but with the supplied method attribute appender factory
2005              * applied to the previously defined or matched method.
2006              */

2007             MethodDefinition<S> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory);
2008
2009             /**
2010              * Applies the supplied transformer onto the previously defined or matched method. The transformed
2011              * method is written <i>as it is</i> and it not subject to any validations.
2012              *
2013              * @param transformer The transformer to apply to the previously defined or matched method.
2014              * @return A new builder that is equal to this builder but with the supplied transformer
2015              * applied to the previously defined or matched method.
2016              */

2017             MethodDefinition<S> transform(Transformer<MethodDescription> transformer);
2018
2019             /**
2020              * A builder for a method definition with a receiver type.
2021              *
2022              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2023              */

2024             interface ReceiverTypeDefinition<U> extends MethodDefinition<U> {
2025
2026                 /**
2027                  * Defines the supplied (annotated) receiver type for the previously defined or matched method.
2028                  *
2029                  * @param receiverType The receiver type to define on the previously defined or matched method.
2030                  * @return A new builder that is equal to this builder but with the given type defined as the
2031                  * receiver on the previously defined or matched method.
2032                  */

2033                 MethodDefinition<U> receiverType(AnnotatedElement receiverType);
2034
2035                 /**
2036                  * Defines the supplied (annotated) receiver type for the previously defined or matched method.
2037                  *
2038                  * @param receiverType The receiver type to define on the previously defined or matched method.
2039                  * @return A new builder that is equal to this builder but with the given type defined as the
2040                  * receiver on the previously defined or matched method.
2041                  */

2042                 MethodDefinition<U> receiverType(TypeDescription.Generic receiverType);
2043
2044                 /**
2045                  * An abstract base implementation of a method definition that can accept a receiver type.
2046                  *
2047                  * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2048                  */

2049                 abstract class AbstractBase<V> extends MethodDefinition.AbstractBase<V> implements ReceiverTypeDefinition<V> {
2050
2051                     /**
2052                      * {@inheritDoc}
2053                      */

2054                     public MethodDefinition<V> receiverType(AnnotatedElement receiverType) {
2055                         return receiverType(TypeDescription.Generic.AnnotationReader.DISPATCHER.resolve(receiverType));
2056                     }
2057                 }
2058             }
2059
2060             /**
2061              * A builder for defining an implementation of a method.
2062              *
2063              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2064              */

2065             interface ImplementationDefinition<U> {
2066
2067                 /**
2068                  * Implements the previously defined or matched method by the supplied implementation. A method interception
2069                  * is typically implemented in one of the following ways:
2070                  * <ol>
2071                  * <li>If a method is declared by the instrumented type and the type builder creates a subclass or redefinition,
2072                  * any preexisting method is replaced by the given implementation. Any previously defined implementation is lost.</li>
2073                  * <li>If a method is declared by the instrumented type and the type builder creates a rebased version of the
2074                  * instrumented type, the original method is preserved within a private, synthetic method within the instrumented
2075                  * type. The original method therefore remains invokeable and is treated as the direct super method of the new
2076                  * method. When rebasing a type, it therefore becomes possible to invoke a non-virtual method's super method
2077                  * when a preexisting method body is replaced.</li>
2078                  * <li>If a virtual method is inherited from a super type, it is overridden. The overridden method is available
2079                  * for super method invocation.</li>
2080                  * </ol>
2081                  *
2082                  * @param implementation The implementation for implementing the previously defined or matched method.
2083                  * @return A new builder where the previously defined or matched method is implemented by the
2084                  * supplied implementation.
2085                  */

2086                 MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation);
2087
2088                 /**
2089                  * Defines the previously defined or matched method not to declare a method body. This implies the
2090                  * method to be {@code abstract} unless it was already declared to be {@code native}.
2091                  *
2092                  * @return A new builder where the previously defined or matched method is implemented to be abstract.
2093                  */

2094                 MethodDefinition.ReceiverTypeDefinition<U> withoutCode();
2095
2096                 /**
2097                  * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
2098                  * value must be supplied in its unloaded state, i.e. enumerations as {@link net.bytebuddy.description.enumeration.EnumerationDescription},
2099                  * types as {@link TypeDescription} and annotations as {@link AnnotationDescription}. For supplying loaded types, use
2100                  * {@link ImplementationDefinition#defaultValue(Object, Class)} must be used.
2101                  *
2102                  * @param annotationValue The value to be defined as a default value.
2103                  * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
2104                  */

2105                 MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue);
2106
2107                 /**
2108                  * Defines the previously defined or matched method to return the supplied value as an annotation default value. The
2109                  * value must be supplied in its loaded state paired with the property type of the value.
2110                  *
2111                  * @param value The value to be defined as a default value.
2112                  * @param type  The type of the annotation property.
2113                  * @param <W>   The type of the annotation property.
2114                  * @return A builder where the previously defined or matched method is implemented to return an annotation default value.
2115                  */

2116                 <W> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(W value, Class<? extends W> type);
2117
2118                 /**
2119                  * A builder for optionally defining an implementation of a method.
2120                  *
2121                  * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2122                  */

2123                 interface Optional<V> extends ImplementationDefinition<V>, Builder<V> {
2124                     /* union type */
2125                 }
2126
2127                 /**
2128                  * An abstract base implementation for a builder optionally defining an implementation of a method.
2129                  *
2130                  * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2131                  */

2132                 abstract class AbstractBase<V> implements ImplementationDefinition<V> {
2133
2134                     /**
2135                      * {@inheritDoc}
2136                      */

2137                     public <W> MethodDefinition.ReceiverTypeDefinition<V> defaultValue(W value, Class<? extends W> type) {
2138                         return defaultValue(AnnotationDescription.ForLoadedAnnotation.asValue(value, type));
2139                     }
2140                 }
2141             }
2142
2143             /**
2144              * A builder for defining an implementation of a method and optionally defining a type variable.
2145              *
2146              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2147              */

2148             interface TypeVariableDefinition<U> extends ImplementationDefinition<U> {
2149
2150                 /**
2151                  * Defines a method variable to be declared by the currently defined method. The defined method variable does not define any bounds.
2152                  *
2153                  * @param symbol The symbol of the type variable.
2154                  * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2155                  */

2156                 Annotatable<U> typeVariable(String symbol);
2157
2158                 /**
2159                  * Defines a method variable to be declared by the currently defined method.
2160                  *
2161                  * @param symbol The symbol of the type variable.
2162                  * @param bound  The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2163                  *               if a bound type should be equal to the currently instrumented type.
2164                  * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2165                  */

2166                 Annotatable<U> typeVariable(String symbol, Type... bound);
2167
2168                 /**
2169                  * Defines a method variable to be declared by the currently defined method.
2170                  *
2171                  * @param symbol The symbol of the type variable.
2172                  * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2173                  *               if a bound type should be equal to the currently instrumented type.
2174                  * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2175                  */

2176                 Annotatable<U> typeVariable(String symbol, List<? extends Type> bounds);
2177
2178                 /**
2179                  * Defines a method variable to be declared by the currently defined method.
2180                  *
2181                  * @param symbol The symbol of the type variable.
2182                  * @param bound  The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2183                  *               if a bound type should be equal to the currently instrumented type.
2184                  * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2185                  */

2186                 Annotatable<U> typeVariable(String symbol, TypeDefinition... bound);
2187
2188                 /**
2189                  * Defines a method variable to be declared by the currently defined method.
2190                  *
2191                  * @param symbol The symbol of the type variable.
2192                  * @param bounds The bounds of the type variables. Can also be {@link net.bytebuddy.dynamic.TargetType} for any type
2193                  *               if a bound type should be equal to the currently instrumented type.
2194                  * @return A new builder that is equal to the current builder but where the currently defined method declares the specified type variable.
2195                  */

2196                 Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds);
2197
2198                 /**
2199                  * A builder for optionally defining an annotation for a type variable.
2200                  *
2201                  * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2202                  */

2203                 interface Annotatable<V> extends TypeVariableDefinition<V> {
2204
2205                     /**
2206                      * Annotates the previously defined type variable with the supplied annotations.
2207                      *
2208                      * @param annotation The annotations to declare on the previously defined type variable.
2209                      * @return A new builder that is equal to this builder but with the given annotations declared
2210                      * on the previously defined type variable.
2211                      */

2212                     Annotatable<V> annotateTypeVariable(Annotation... annotation);
2213
2214                     /**
2215                      * Annotates the previously defined type variable with the supplied annotations.
2216                      *
2217                      * @param annotations The annotations to declare on the previously defined type variable.
2218                      * @return A new builder that is equal to this builder but with the given annotations declared
2219                      * on the previously defined type variable.
2220                      */

2221                     Annotatable<V> annotateTypeVariable(List<? extends Annotation> annotations);
2222
2223                     /**
2224                      * Annotates the previously defined type variable with the supplied annotations.
2225                      *
2226                      * @param annotation The annotations to declare on the previously defined type variable.
2227                      * @return A new builder that is equal to this builder but with the given annotations declared
2228                      * on the previously defined type variable.
2229                      */

2230                     Annotatable<V> annotateTypeVariable(AnnotationDescription... annotation);
2231
2232                     /**
2233                      * Annotates the previously defined type variable with the supplied annotations.
2234                      *
2235                      * @param annotations The annotations to declare on the previously defined type variable.
2236                      * @return A new builder that is equal to this builder but with the given annotations declared
2237                      * on the previously defined type variable.
2238                      */

2239                     Annotatable<V> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations);
2240
2241                     /**
2242                      * An abstract base implementation for defining an annotation on a parameter.
2243                      *
2244                      * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2245                      */

2246                     abstract class AbstractBase<W> extends TypeVariableDefinition.AbstractBase<W> implements Annotatable<W> {
2247
2248                         /**
2249                          * {@inheritDoc}
2250                          */

2251                         public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(Annotation... annotation) {
2252                             return annotateTypeVariable(Arrays.asList(annotation));
2253                         }
2254
2255                         /**
2256                          * {@inheritDoc}
2257                          */

2258                         public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(List<? extends Annotation> annotations) {
2259                             return annotateTypeVariable(new AnnotationList.ForLoadedAnnotations(annotations));
2260                         }
2261
2262                         /**
2263                          * {@inheritDoc}
2264                          */

2265                         public TypeVariableDefinition.Annotatable<W> annotateTypeVariable(AnnotationDescription... annotation) {
2266                             return annotateTypeVariable(Arrays.asList(annotation));
2267                         }
2268
2269                         /**
2270                          * An adapter implementation for an annotatable type variable definition.
2271                          *
2272                          * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
2273                          */

2274                         protected abstract static class Adapter<X> extends TypeVariableDefinition.Annotatable.AbstractBase<X> {
2275
2276                             /**
2277                              * {@inheritDoc}
2278                              */

2279                             public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2280                                 return materialize().typeVariable(symbol, bounds);
2281                             }
2282
2283                             /**
2284                              * {@inheritDoc}
2285                              */

2286                             public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2287                                 return materialize().intercept(implementation);
2288                             }
2289
2290                             /**
2291                              * {@inheritDoc}
2292                              */

2293                             public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2294                                 return materialize().withoutCode();
2295                             }
2296
2297                             /**
2298                              * {@inheritDoc}
2299                              */

2300                             public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
2301                                 return materialize().defaultValue(annotationValue);
2302                             }
2303
2304                             /**
2305                              * {@inheritDoc}
2306                              */

2307                             public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
2308                                 return materialize().defaultValue(value, type);
2309                             }
2310
2311                             /**
2312                              * Materializes this instance as a parameter definition with the currently defined properties.
2313                              *
2314                              * @return A parameter definition with the currently defined properties.
2315                              */

2316                             protected abstract MethodDefinition.ParameterDefinition<X> materialize();
2317                         }
2318                     }
2319                 }
2320
2321                 /**
2322                  * An abstract base implementation for defining an implementation of a method and optionally defining a type variable.
2323                  *
2324                  * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2325                  */

2326                 abstract class AbstractBase<V> extends ImplementationDefinition.AbstractBase<V> implements TypeVariableDefinition<V> {
2327
2328                     /**
2329                      * {@inheritDoc}
2330                      */

2331                     public Annotatable<V> typeVariable(String symbol) {
2332                         return typeVariable(symbol, Collections.singletonList(Object.class));
2333                     }
2334
2335                     /**
2336                      * {@inheritDoc}
2337                      */

2338                     public Annotatable<V> typeVariable(String symbol, Type... bound) {
2339                         return typeVariable(symbol, Arrays.asList(bound));
2340                     }
2341
2342                     /**
2343                      * {@inheritDoc}
2344                      */

2345                     public Annotatable<V> typeVariable(String symbol, List<? extends Type> bounds) {
2346                         return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
2347                     }
2348
2349                     /**
2350                      * {@inheritDoc}
2351                      */

2352                     public Annotatable<V> typeVariable(String symbol, TypeDefinition... bound) {
2353                         return typeVariable(symbol, Arrays.asList(bound));
2354                     }
2355                 }
2356             }
2357
2358             /**
2359              * A builder for defining an implementation of a method and optionally defining a type variable or thrown exception.
2360              *
2361              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2362              */

2363             interface ExceptionDefinition<U> extends TypeVariableDefinition<U> {
2364
2365                 /**
2366                  * Defines a method variable to be declared by the currently defined method.
2367                  *
2368                  * @param type The type of the exception being declared by the currently defined method.
2369                  * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2370                  */

2371                 ExceptionDefinition<U> throwing(Type... type);
2372
2373                 /**
2374                  * Defines a method variable to be declared by the currently defined method.
2375                  *
2376                  * @param types The type of the exception being declared by the currently defined method.
2377                  * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2378                  */

2379                 ExceptionDefinition<U> throwing(List<? extends Type> types);
2380
2381                 /**
2382                  * Defines a method variable to be declared by the currently defined method.
2383                  *
2384                  * @param type The type of the exception being declared by the currently defined method.
2385                  * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2386                  */

2387                 ExceptionDefinition<U> throwing(TypeDefinition... type);
2388
2389                 /**
2390                  * Defines a method variable to be declared by the currently defined method.
2391                  *
2392                  * @param types The type of the exception being declared by the currently defined method.
2393                  * @return A new builder that is equal to the current builder but where the currently defined method declares the specified exception type.
2394                  */

2395                 ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types);
2396
2397                 /**
2398                  * An abstract base implementation for defining an implementation of a method and optionally defining a type variable or thrown exception.
2399                  *
2400                  * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2401                  */

2402                 abstract class AbstractBase<V> extends TypeVariableDefinition.AbstractBase<V> implements ExceptionDefinition<V> {
2403
2404                     /**
2405                      * {@inheritDoc}
2406                      */

2407                     public ExceptionDefinition<V> throwing(Type... type) {
2408                         return throwing(Arrays.asList(type));
2409                     }
2410
2411                     /**
2412                      * {@inheritDoc}
2413                      */

2414                     public ExceptionDefinition<V> throwing(List<? extends Type> types) {
2415                         return throwing(new TypeList.Generic.ForLoadedTypes(types));
2416                     }
2417
2418                     /**
2419                      * {@inheritDoc}
2420                      */

2421                     public ExceptionDefinition<V> throwing(TypeDefinition... type) {
2422                         return throwing(Arrays.asList(type));
2423                     }
2424                 }
2425             }
2426
2427             /**
2428              * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
2429              *
2430              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2431              */

2432             interface ParameterDefinition<U> extends ExceptionDefinition<U> {
2433
2434                 /**
2435                  * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2436                  *
2437                  * @param type                The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2438                  *                            should be equal to the currently instrumented type.
2439                  * @param name                The parameter's name.
2440                  * @param modifierContributor The parameter's modifiers.
2441                  * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2442                  */

2443                 Annotatable<U> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor);
2444
2445                 /**
2446                  * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2447                  *
2448                  * @param type                 The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2449                  *                             should be equal to the currently instrumented type.
2450                  * @param name                 The parameter's name.
2451                  * @param modifierContributors The parameter's modifiers.
2452                  * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2453                  */

2454                 Annotatable<U> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors);
2455
2456                 /**
2457                  * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2458                  *
2459                  * @param type      The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2460                  *                  should be equal to the currently instrumented type.
2461                  * @param name      The parameter's name.
2462                  * @param modifiers The parameter's modifiers.
2463                  * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2464                  */

2465                 Annotatable<U> withParameter(Type type, String name, int modifiers);
2466
2467                 /**
2468                  * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2469                  *
2470                  * @param type                The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2471                  *                            should be equal to the currently instrumented type.
2472                  * @param name                The parameter's name.
2473                  * @param modifierContributor The parameter's modifiers.
2474                  * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2475                  */

2476                 Annotatable<U> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor);
2477
2478                 /**
2479                  * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2480                  *
2481                  * @param type                 The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2482                  *                             should be equal to the currently instrumented type.
2483                  * @param name                 The parameter's name.
2484                  * @param modifierContributors The parameter's modifiers.
2485                  * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2486                  */

2487                 Annotatable<U> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors);
2488
2489                 /**
2490                  * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2491                  *
2492                  * @param type      The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2493                  *                  should be equal to the currently instrumented type.
2494                  * @param name      The parameter's name.
2495                  * @param modifiers The parameter's modifiers.
2496                  * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2497                  */

2498                 Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers);
2499
2500                 /**
2501                  * A builder for optionally defining an annotation on a parameter.
2502                  *
2503                  * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2504                  */

2505                 interface Annotatable<V> extends ParameterDefinition<V> {
2506
2507                     /**
2508                      * Annotates the previously defined parameter with the specified annotations.
2509                      *
2510                      * @param annotation The annotations to declare on the previously defined parameter.
2511                      * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2512                      * the specified annotations.
2513                      */

2514                     Annotatable<V> annotateParameter(Annotation... annotation);
2515
2516                     /**
2517                      * Annotates the previously defined parameter with the specified annotations.
2518                      *
2519                      * @param annotations The annotations to declare on the previously defined parameter.
2520                      * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2521                      * the specified annotations.
2522                      */

2523                     Annotatable<V> annotateParameter(List<? extends Annotation> annotations);
2524
2525                     /**
2526                      * Annotates the previously defined parameter with the specified annotations.
2527                      *
2528                      * @param annotation The annotations to declare on the previously defined parameter.
2529                      * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2530                      * the specified annotations.
2531                      */

2532                     Annotatable<V> annotateParameter(AnnotationDescription... annotation);
2533
2534                     /**
2535                      * Annotates the previously defined parameter with the specified annotations.
2536                      *
2537                      * @param annotations The annotations to declare on the previously defined parameter.
2538                      * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2539                      * the specified annotations.
2540                      */

2541                     Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
2542
2543                     /**
2544                      * An abstract base implementation for defining an annotation on a parameter.
2545                      *
2546                      * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2547                      */

2548                     abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Annotatable<W> {
2549
2550                         /**
2551                          * {@inheritDoc}
2552                          */

2553                         public ParameterDefinition.Annotatable<W> annotateParameter(Annotation... annotation) {
2554                             return annotateParameter(Arrays.asList(annotation));
2555                         }
2556
2557                         /**
2558                          * {@inheritDoc}
2559                          */

2560                         public ParameterDefinition.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
2561                             return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
2562                         }
2563
2564                         /**
2565                          * {@inheritDoc}
2566                          */

2567                         public ParameterDefinition.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
2568                             return annotateParameter(Arrays.asList(annotation));
2569                         }
2570
2571                         /**
2572                          * An adapter implementation for defining an annotation on a parameter.
2573                          *
2574                          * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
2575                          */

2576                         protected abstract static class Adapter<X> extends ParameterDefinition.Annotatable.AbstractBase<X> {
2577
2578                             /**
2579                              * {@inheritDoc}
2580                              */

2581                             public ParameterDefinition.Annotatable<X> withParameter(TypeDefinition type, String name, int modifiers) {
2582                                 return materialize().withParameter(type, name, modifiers);
2583                             }
2584
2585                             /**
2586                              * {@inheritDoc}
2587                              */

2588                             public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
2589                                 return materialize().throwing(types);
2590                             }
2591
2592                             /**
2593                              * {@inheritDoc}
2594                              */

2595                             public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2596                                 return materialize().typeVariable(symbol, bounds);
2597                             }
2598
2599                             /**
2600                              * {@inheritDoc}
2601                              */

2602                             public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2603                                 return materialize().intercept(implementation);
2604                             }
2605
2606                             /**
2607                              * {@inheritDoc}
2608                              */

2609                             public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2610                                 return materialize().withoutCode();
2611                             }
2612
2613                             /**
2614                              * {@inheritDoc}
2615                              */

2616                             public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
2617                                 return materialize().defaultValue(annotationValue);
2618                             }
2619
2620                             /**
2621                              * {@inheritDoc}
2622                              */

2623                             public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
2624                                 return materialize().defaultValue(value, type);
2625                             }
2626
2627                             /**
2628                              * Materializes this instance as a parameter definition with the currently defined properties.
2629                              *
2630                              * @return A parameter definition with the currently defined properties.
2631                              */

2632                             protected abstract MethodDefinition.ParameterDefinition<X> materialize();
2633                         }
2634                     }
2635                 }
2636
2637                 /**
2638                  * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or a parameter type.
2639                  *
2640                  * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2641                  */

2642                 interface Simple<V> extends ExceptionDefinition<V> {
2643
2644                     /**
2645                      * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2646                      *
2647                      * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2648                      *             should be equal to the currently instrumented type.
2649                      * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2650                      */

2651                     Annotatable<V> withParameter(Type type);
2652
2653                     /**
2654                      * Defines the specified parameter for the currently defined method as the last parameter of the currently defined method.
2655                      *
2656                      * @param type The parameter's type. Can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2657                      *             should be equal to the currently instrumented type.
2658                      * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameter.
2659                      */

2660                     Annotatable<V> withParameter(TypeDefinition type);
2661
2662                     /**
2663                      * A builder for optionally defining an annotation on a parameter.
2664                      *
2665                      * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2666                      */

2667                     interface Annotatable<V> extends Simple<V> {
2668
2669                         /**
2670                          * Annotates the previously defined parameter with the specified annotations.
2671                          *
2672                          * @param annotation The annotations to declare on the previously defined parameter.
2673                          * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2674                          * the specified annotations.
2675                          */

2676                         Annotatable<V> annotateParameter(Annotation... annotation);
2677
2678                         /**
2679                          * Annotates the previously defined parameter with the specified annotations.
2680                          *
2681                          * @param annotations The annotations to declare on the previously defined parameter.
2682                          * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2683                          * the specified annotations.
2684                          */

2685                         Annotatable<V> annotateParameter(List<? extends Annotation> annotations);
2686
2687                         /**
2688                          * Annotates the previously defined parameter with the specified annotations.
2689                          *
2690                          * @param annotation The annotations to declare on the previously defined parameter.
2691                          * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2692                          * the specified annotations.
2693                          */

2694                         Annotatable<V> annotateParameter(AnnotationDescription... annotation);
2695
2696                         /**
2697                          * Annotates the previously defined parameter with the specified annotations.
2698                          *
2699                          * @param annotations The annotations to declare on the previously defined parameter.
2700                          * @return A new builder that is equal to this builder but with the previously defined parameter annotated with
2701                          * the specified annotations.
2702                          */

2703                         Annotatable<V> annotateParameter(Collection<? extends AnnotationDescription> annotations);
2704
2705                         /**
2706                          * An abstract base implementation of a simple parameter definition.
2707                          *
2708                          * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2709                          */

2710                         abstract class AbstractBase<W> extends Simple.AbstractBase<W> implements Annotatable<W> {
2711
2712                             /**
2713                              * {@inheritDoc}
2714                              */

2715                             public Simple.Annotatable<W> annotateParameter(Annotation... annotation) {
2716                                 return annotateParameter(Arrays.asList(annotation));
2717                             }
2718
2719                             /**
2720                              * {@inheritDoc}
2721                              */

2722                             public Simple.Annotatable<W> annotateParameter(List<? extends Annotation> annotations) {
2723                                 return annotateParameter(new AnnotationList.ForLoadedAnnotations(annotations));
2724                             }
2725
2726                             /**
2727                              * {@inheritDoc}
2728                              */

2729                             public Simple.Annotatable<W> annotateParameter(AnnotationDescription... annotation) {
2730                                 return annotateParameter(Arrays.asList(annotation));
2731                             }
2732
2733                             /**
2734                              * An adapter implementation of a simple parameter definition.
2735                              *
2736                              * @param <X> A loaded type that the built type is guaranteed to be a subclass of.
2737                              */

2738                             protected abstract static class Adapter<X> extends Simple.Annotatable.AbstractBase<X> {
2739
2740                                 /**
2741                                  * {@inheritDoc}
2742                                  */

2743                                 public Simple.Annotatable<X> withParameter(TypeDefinition type) {
2744                                     return materialize().withParameter(type);
2745                                 }
2746
2747                                 /**
2748                                  * {@inheritDoc}
2749                                  */

2750                                 public ExceptionDefinition<X> throwing(Collection<? extends TypeDefinition> types) {
2751                                     return materialize().throwing(types);
2752                                 }
2753
2754                                 /**
2755                                  * {@inheritDoc}
2756                                  */

2757                                 public TypeVariableDefinition.Annotatable<X> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
2758                                     return materialize().typeVariable(symbol, bounds);
2759                                 }
2760
2761                                 /**
2762                                  * {@inheritDoc}
2763                                  */

2764                                 public MethodDefinition.ReceiverTypeDefinition<X> intercept(Implementation implementation) {
2765                                     return materialize().intercept(implementation);
2766                                 }
2767
2768                                 /**
2769                                  * {@inheritDoc}
2770                                  */

2771                                 public MethodDefinition.ReceiverTypeDefinition<X> withoutCode() {
2772                                     return materialize().withoutCode();
2773                                 }
2774
2775                                 /**
2776                                  * {@inheritDoc}
2777                                  */

2778                                 public MethodDefinition.ReceiverTypeDefinition<X> defaultValue(AnnotationValue<?, ?> annotationValue) {
2779                                     return materialize().defaultValue(annotationValue);
2780                                 }
2781
2782                                 /**
2783                                  * {@inheritDoc}
2784                                  */

2785                                 public <V> MethodDefinition.ReceiverTypeDefinition<X> defaultValue(V value, Class<? extends V> type) {
2786                                     return materialize().defaultValue(value, type);
2787                                 }
2788
2789                                 /**
2790                                  * Materializes this instance as a simple parameter definition with the currently defined properties.
2791                                  *
2792                                  * @return A simple parameter definition with the currently defined properties.
2793                                  */

2794                                 protected abstract MethodDefinition.ParameterDefinition.Simple<X> materialize();
2795                             }
2796                         }
2797                     }
2798
2799                     /**
2800                      * An abstract base implementation of an exception definition.
2801                      *
2802                      * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2803                      */

2804                     abstract class AbstractBase<W> extends ExceptionDefinition.AbstractBase<W> implements Simple<W> {
2805
2806                         /**
2807                          * {@inheritDoc}
2808                          */

2809                         public Simple.Annotatable<W> withParameter(Type type) {
2810                             return withParameter(TypeDefinition.Sort.describe(type));
2811                         }
2812                     }
2813                 }
2814
2815                 /**
2816                  * A builder for defining an implementation of a method and optionally defining a type variable, thrown exception or method parameter.
2817                  * Implementations allow for the <i>one-by-one</i> definition of parameters what gives opportunity to annotate parameters in a fluent
2818                  * style. Doing so, it is optionally possible to define parameter names and modifiers. This can be done for either all or no parameters.
2819                  * Alternatively, parameters without annotations, names or modifiers can be defined by a single step.
2820                  *
2821                  * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2822                  */

2823                 interface Initial<V> extends ParameterDefinition<V>, Simple<V> {
2824
2825                     /**
2826                      * Defines the specified parameters for the currently defined method.
2827                      *
2828                      * @param type The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2829                      *             should be equal to the currently instrumented type.
2830                      * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2831                      */

2832                     ExceptionDefinition<V> withParameters(Type... type);
2833
2834                     /**
2835                      * Defines the specified parameters for the currently defined method.
2836                      *
2837                      * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2838                      *              should be equal to the currently instrumented type.
2839                      * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2840                      */

2841                     ExceptionDefinition<V> withParameters(List<? extends Type> types);
2842
2843                     /**
2844                      * Defines the specified parameters for the currently defined method.
2845                      *
2846                      * @param type The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2847                      *             should be equal to the currently instrumented type.
2848                      * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2849                      */

2850                     ExceptionDefinition<V> withParameters(TypeDefinition... type);
2851
2852                     /**
2853                      * Defines the specified parameters for the currently defined method.
2854                      *
2855                      * @param types The parameter types. Any type can also be {@link net.bytebuddy.dynamic.TargetType} if the parameter type
2856                      *              should be equal to the currently instrumented type.
2857                      * @return A new builder that is equal to the current builder but where the currently defined method appends the specified parameters.
2858                      */

2859                     ExceptionDefinition<V> withParameters(Collection<? extends TypeDefinition> types);
2860
2861                     /**
2862                      * An abstract base implementation for an initial parameter definition.
2863                      *
2864                      * @param <W> A loaded type that the built type is guaranteed to be a subclass of.
2865                      */

2866                     abstract class AbstractBase<W> extends ParameterDefinition.AbstractBase<W> implements Initial<W> {
2867
2868                         /**
2869                          * {@inheritDoc}
2870                          */

2871                         public Simple.Annotatable<W> withParameter(Type type) {
2872                             return withParameter(TypeDefinition.Sort.describe(type));
2873                         }
2874
2875                         /**
2876                          * {@inheritDoc}
2877                          */

2878                         public ExceptionDefinition<W> withParameters(Type... type) {
2879                             return withParameters(Arrays.asList(type));
2880                         }
2881
2882                         /**
2883                          * {@inheritDoc}
2884                          */

2885                         public ExceptionDefinition<W> withParameters(List<? extends Type> types) {
2886                             return withParameters(new TypeList.Generic.ForLoadedTypes(types));
2887                         }
2888
2889                         /**
2890                          * {@inheritDoc}
2891                          */

2892                         public ExceptionDefinition<W> withParameters(TypeDefinition... type) {
2893                             return withParameters(Arrays.asList(type));
2894                         }
2895
2896                         /**
2897                          * {@inheritDoc}
2898                          */

2899                         public ExceptionDefinition<W> withParameters(Collection<? extends TypeDefinition> types) {
2900                             ParameterDefinition.Simple<W> parameterDefinition = this;
2901                             for (TypeDefinition type : types) {
2902                                 parameterDefinition = parameterDefinition.withParameter(type);
2903                             }
2904                             return parameterDefinition;
2905                         }
2906                     }
2907                 }
2908
2909                 /**
2910                  * An abstract base implementation for defining an implementation of a method and optionally defining a type variable, thrown exception or parameter type.
2911                  *
2912                  * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
2913                  */

2914                 abstract class AbstractBase<V> extends ExceptionDefinition.AbstractBase<V> implements ParameterDefinition<V> {
2915
2916                     /**
2917                      * {@inheritDoc}
2918                      */

2919                     public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, ModifierContributor.ForParameter... modifierContributor) {
2920                         return withParameter(type, name, Arrays.asList(modifierContributor));
2921                     }
2922
2923                     /**
2924                      * {@inheritDoc}
2925                      */

2926                     public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
2927                         return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
2928                     }
2929
2930                     /**
2931                      * {@inheritDoc}
2932                      */

2933                     public ParameterDefinition.Annotatable<V> withParameter(Type type, String name, int modifiers) {
2934                         return withParameter(TypeDefinition.Sort.describe(type), name, modifiers);
2935                     }
2936
2937                     /**
2938                      * {@inheritDoc}
2939                      */

2940                     public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, ModifierContributor.ForParameter... modifierContributor) {
2941                         return withParameter(type, name, Arrays.asList(modifierContributor));
2942                     }
2943
2944                     /**
2945                      * {@inheritDoc}
2946                      */

2947                     public ParameterDefinition.Annotatable<V> withParameter(TypeDefinition type, String name, Collection<? extends ModifierContributor.ForParameter> modifierContributors) {
2948                         return withParameter(type, name, ModifierContributor.Resolver.of(modifierContributors).resolve());
2949                     }
2950                 }
2951             }
2952
2953             /**
2954              * An abstract base implementation of a method definition.
2955              *
2956              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
2957              */

2958             abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements MethodDefinition<U> {
2959
2960                 /**
2961                  * {@inheritDoc}
2962                  */

2963                 public MethodDefinition<U> annotateMethod(Annotation... annotation) {
2964                     return annotateMethod(Arrays.asList(annotation));
2965                 }
2966
2967                 /**
2968                  * {@inheritDoc}
2969                  */

2970                 public MethodDefinition<U> annotateMethod(List<? extends Annotation> annotations) {
2971                     return annotateMethod(new AnnotationList.ForLoadedAnnotations(annotations));
2972                 }
2973
2974                 /**
2975                  * {@inheritDoc}
2976                  */

2977                 public MethodDefinition<U> annotateMethod(AnnotationDescription... annotation) {
2978                     return annotateMethod(Arrays.asList(annotation));
2979                 }
2980
2981                 /**
2982                  * {@inheritDoc}
2983                  */

2984                 public MethodDefinition<U> annotateParameter(int index, Annotation... annotation) {
2985                     return annotateParameter(index, Arrays.asList(annotation));
2986                 }
2987
2988                 /**
2989                  * {@inheritDoc}
2990                  */

2991                 public MethodDefinition<U> annotateParameter(int index, List<? extends Annotation> annotations) {
2992                     return annotateParameter(index, new AnnotationList.ForLoadedAnnotations(annotations));
2993                 }
2994
2995                 /**
2996                  * {@inheritDoc}
2997                  */

2998                 public MethodDefinition<U> annotateParameter(int index, AnnotationDescription... annotation) {
2999                     return annotateParameter(index, Arrays.asList(annotation));
3000                 }
3001
3002                 /**
3003                  * An adapter implementation of a method definition.
3004                  *
3005                  * @param <V> A loaded type that the built type is guaranteed to be a subclass of.
3006                  */

3007                 @HashCodeAndEqualsPlugin.Enhance
3008                 protected abstract static class Adapter<V> extends MethodDefinition.ReceiverTypeDefinition.AbstractBase<V> {
3009
3010                     /**
3011                      * The handler that determines how a method is implemented.
3012                      */

3013                     protected final MethodRegistry.Handler handler;
3014
3015                     /**
3016                      * The method attribute appender factory to apply onto the method that is currently being implemented.
3017                      */

3018                     protected final MethodAttributeAppender.Factory methodAttributeAppenderFactory;
3019
3020                     /**
3021                      * The transformer to apply onto the method that is currently being implemented.
3022                      */

3023                     protected final Transformer<MethodDescription> transformer;
3024
3025                     /**
3026                      * Creates a new adapter for a method definition.
3027                      *
3028                      * @param handler                        The handler that determines how a method is implemented.
3029                      * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3030                      * @param transformer                    The transformer to apply onto the method that is currently being implemented.
3031                      */

3032                     protected Adapter(MethodRegistry.Handler handler,
3033                                       MethodAttributeAppender.Factory methodAttributeAppenderFactory,
3034                                       Transformer<MethodDescription> transformer) {
3035                         this.handler = handler;
3036                         this.methodAttributeAppenderFactory = methodAttributeAppenderFactory;
3037                         this.transformer = transformer;
3038                     }
3039
3040                     /**
3041                      * {@inheritDoc}
3042                      */

3043                     public MethodDefinition<V> attribute(MethodAttributeAppender.Factory methodAttributeAppenderFactory) {
3044                         return materialize(handler, new MethodAttributeAppender.Factory.Compound(this.methodAttributeAppenderFactory, methodAttributeAppenderFactory), transformer);
3045                     }
3046
3047                     /**
3048                      * {@inheritDoc}
3049                      */

3050                     @SuppressWarnings("unchecked"// In absence of @SafeVarargs
3051                     public MethodDefinition<V> transform(Transformer<MethodDescription> transformer) {
3052                         return materialize(handler, methodAttributeAppenderFactory, new Transformer.Compound<MethodDescription>(this.transformer, transformer));
3053                     }
3054
3055                     /**
3056                      * Materializes the current builder as a method definition.
3057                      *
3058                      * @param handler                        The handler that determines how a method is implemented.
3059                      * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
3060                      * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
3061                      * @return Returns a method definition for the supplied properties.
3062                      */

3063                     protected abstract MethodDefinition<V> materialize(MethodRegistry.Handler handler,
3064                                                                        MethodAttributeAppender.Factory methodAttributeAppenderFactory,
3065                                                                        Transformer<MethodDescription> transformer);
3066                 }
3067             }
3068         }
3069
3070         /**
3071          * A builder for a record component definition.
3072          *
3073          * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
3074          */

3075         interface RecordComponentDefinition<S> {
3076
3077             /**
3078              * Annotates the record component with the supplied annotations.
3079              *
3080              * @param annotation The annotations to declare.
3081              * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3082              */

3083             Optional<S> annotateRecordComponent(Annotation... annotation);
3084
3085             /**
3086              * Annotates the record component with the supplied annotations.
3087              *
3088              * @param annotations The annotations to declare.
3089              * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3090              */

3091             Optional<S> annotateRecordComponent(List<? extends Annotation> annotations);
3092
3093             /**
3094              * Annotates the record component with the supplied annotations.
3095              *
3096              * @param annotation The annotations to declare.
3097              * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3098              */

3099             Optional<S> annotateRecordComponent(AnnotationDescription... annotation);
3100
3101             /**
3102              * Annotates the record component with the supplied annotations.
3103              *
3104              * @param annotations The annotations to declare.
3105              * @return A new builder that is equal to this builder but where the defined component declares the supplied annotations.
3106              */

3107             Optional<S> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations);
3108
3109             /**
3110              * Applies the supplied record component attribute appender factory onto the previously defined record component.
3111              *
3112              * @param recordComponentAttributeAppenderFactory The record component attribute appender factory that should be applied on the
3113              *                                                previously defined or matched method.
3114              * @return A new builder that is equal to this builder but with the supplied record component attribute appender factory
3115              * applied to the previously defined record component.
3116              */

3117             Optional<S> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory);
3118
3119             /**
3120              * Transforms a record component description before writing.
3121              *
3122              * @param transformer The transformer to apply.
3123              * @return new builder that is equal to this builder but with the supplied transformer being applied.
3124              */

3125             Optional<S> transform(Transformer<RecordComponentDescription> transformer);
3126
3127             /**
3128              * A {@link RecordComponentDefinition} as an optional build step.
3129              *
3130              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3131              */

3132             interface Optional<U> extends RecordComponentDefinition<U>, Builder<U> {
3133
3134                 /**
3135                  * An abstract base implementation of a record definition.
3136                  *
3137                  * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3138                  */

3139                 abstract class AbstractBase<U> extends Builder.AbstractBase.Delegator<U> implements RecordComponentDefinition.Optional<U> {
3140
3141                     /**
3142                      * {@inheritDoc}
3143                      */

3144                     public Optional<U> annotateRecordComponent(Annotation... annotation) {
3145                         return annotateRecordComponent(Arrays.asList(annotation));
3146                     }
3147
3148                     /**
3149                      * {@inheritDoc}
3150                      */

3151                     public Optional<U> annotateRecordComponent(List<? extends Annotation> annotations) {
3152                         return annotateRecordComponent(new AnnotationList.ForLoadedAnnotations(annotations));
3153                     }
3154
3155                     /**
3156                      * {@inheritDoc}
3157                      */

3158                     public Optional<U> annotateRecordComponent(AnnotationDescription... annotation) {
3159                         return annotateRecordComponent(Arrays.asList(annotation));
3160                     }
3161                 }
3162             }
3163         }
3164
3165         /**
3166          * An abstract base implementation of a dynamic type builder.
3167          *
3168          * @param <S> A loaded type that the built type is guaranteed to be a subclass of.
3169          */

3170         abstract class AbstractBase<S> implements Builder<S> {
3171
3172             /**
3173              * {@inheritDoc}
3174              */

3175             public InnerTypeDefinition.ForType<S> innerTypeOf(Class<?> type) {
3176                 return innerTypeOf(TypeDescription.ForLoadedType.of(type));
3177             }
3178
3179             /**
3180              * {@inheritDoc}
3181              */

3182             public InnerTypeDefinition<S> innerTypeOf(Method method) {
3183                 return innerTypeOf(new MethodDescription.ForLoadedMethod(method));
3184             }
3185
3186             /**
3187              * {@inheritDoc}
3188              */

3189             public InnerTypeDefinition<S> innerTypeOf(Constructor<?> constructor) {
3190                 return innerTypeOf(new MethodDescription.ForLoadedConstructor(constructor));
3191             }
3192
3193             /**
3194              * {@inheritDoc}
3195              */

3196             public Builder<S> declaredTypes(Class<?>... type) {
3197                 return declaredTypes(Arrays.asList(type));
3198             }
3199
3200             /**
3201              * {@inheritDoc}
3202              */

3203             public Builder<S> declaredTypes(TypeDescription... type) {
3204                 return declaredTypes(Arrays.asList(type));
3205             }
3206
3207             /**
3208              * {@inheritDoc}
3209              */

3210             public Builder<S> declaredTypes(List<? extends Class<?>> type) {
3211                 return declaredTypes(new TypeList.ForLoadedTypes(type));
3212             }
3213
3214             /**
3215              * {@inheritDoc}
3216              */

3217             public Builder<S> noNestMate() {
3218                 return nestHost(TargetType.DESCRIPTION);
3219             }
3220
3221             /**
3222              * {@inheritDoc}
3223              */

3224             public Builder<S> nestHost(Class<?> type) {
3225                 return nestHost(TypeDescription.ForLoadedType.of(type));
3226             }
3227
3228             /**
3229              * {@inheritDoc}
3230              */

3231             public Builder<S> nestMembers(Class<?>... type) {
3232                 return nestMembers(Arrays.asList(type));
3233             }
3234
3235             /**
3236              * {@inheritDoc}
3237              */

3238             public Builder<S> nestMembers(TypeDescription... type) {
3239                 return nestMembers(Arrays.asList(type));
3240             }
3241
3242             /**
3243              * {@inheritDoc}
3244              */

3245             public Builder<S> nestMembers(List<? extends Class<?>> types) {
3246                 return nestMembers(new TypeList.ForLoadedTypes(types));
3247             }
3248
3249             /**
3250              * {@inheritDoc}
3251              */

3252             public Builder<S> permittedSubclass(Class<?>... type) {
3253                 return permittedSubclass(Arrays.asList(type));
3254             }
3255
3256             /**
3257              * {@inheritDoc}
3258              */

3259             public Builder<S> permittedSubclass(TypeDescription... type) {
3260                 return permittedSubclass(Arrays.asList(type));
3261             }
3262
3263             /**
3264              * {@inheritDoc}
3265              */

3266             public Builder<S> permittedSubclass(List<? extends Class<?>> types) {
3267                 return permittedSubclass(new TypeList.ForLoadedTypes(types));
3268             }
3269
3270             /**
3271              * {@inheritDoc}
3272              */

3273             public Builder<S> annotateType(Annotation... annotation) {
3274                 return annotateType(Arrays.asList(annotation));
3275             }
3276
3277             /**
3278              * {@inheritDoc}
3279              */

3280             public Builder<S> annotateType(List<? extends Annotation> annotations) {
3281                 return annotateType(new AnnotationList.ForLoadedAnnotations(annotations));
3282             }
3283
3284             /**
3285              * {@inheritDoc}
3286              */

3287             public Builder<S> annotateType(AnnotationDescription... annotation) {
3288                 return annotateType(Arrays.asList(annotation));
3289             }
3290
3291             /**
3292              * {@inheritDoc}
3293              */

3294             public Builder<S> modifiers(ModifierContributor.ForType... modifierContributor) {
3295                 return modifiers(Arrays.asList(modifierContributor));
3296             }
3297
3298             /**
3299              * {@inheritDoc}
3300              */

3301             public Builder<S> modifiers(Collection<? extends ModifierContributor.ForType> modifierContributors) {
3302                 return modifiers(ModifierContributor.Resolver.of(modifierContributors).resolve());
3303             }
3304
3305             /**
3306              * {@inheritDoc}
3307              */

3308             public Builder<S> merge(ModifierContributor.ForType... modifierContributor) {
3309                 return merge(Arrays.asList(modifierContributor));
3310             }
3311
3312             /**
3313              * {@inheritDoc}
3314              */

3315             public MethodDefinition.ImplementationDefinition.Optional<S> implement(Type... interfaceType) {
3316                 return implement(Arrays.asList(interfaceType));
3317             }
3318
3319             /**
3320              * {@inheritDoc}
3321              */

3322             public MethodDefinition.ImplementationDefinition.Optional<S> implement(List<? extends Type> interfaceTypes) {
3323                 return implement(new TypeList.Generic.ForLoadedTypes(interfaceTypes));
3324             }
3325
3326             /**
3327              * {@inheritDoc}
3328              */

3329             public MethodDefinition.ImplementationDefinition.Optional<S> implement(TypeDefinition... interfaceType) {
3330                 return implement(Arrays.asList(interfaceType));
3331             }
3332
3333             /**
3334              * {@inheritDoc}
3335              */

3336             public TypeVariableDefinition<S> typeVariable(String symbol) {
3337                 return typeVariable(symbol, TypeDescription.Generic.OBJECT);
3338             }
3339
3340             /**
3341              * {@inheritDoc}
3342              */

3343             public TypeVariableDefinition<S> typeVariable(String symbol, Type... bound) {
3344                 return typeVariable(symbol, Arrays.asList(bound));
3345             }
3346
3347             /**
3348              * {@inheritDoc}
3349              */

3350             public TypeVariableDefinition<S> typeVariable(String symbol, List<? extends Type> bounds) {
3351                 return typeVariable(symbol, new TypeList.Generic.ForLoadedTypes(bounds));
3352             }
3353
3354             /**
3355              * {@inheritDoc}
3356              */

3357             public TypeVariableDefinition<S> typeVariable(String symbol, TypeDefinition... bound) {
3358                 return typeVariable(symbol, Arrays.asList(bound));
3359             }
3360
3361             /**
3362              * {@inheritDoc}
3363              */

3364             public RecordComponentDefinition.Optional<S> defineRecordComponent(String name, Type type) {
3365                 return defineRecordComponent(name, TypeDefinition.Sort.describe(type));
3366             }
3367
3368             /**
3369              * {@inheritDoc}
3370              */

3371             public RecordComponentDefinition.Optional<S> define(RecordComponentDescription recordComponentDescription) {
3372                 return defineRecordComponent(recordComponentDescription.getActualName(), recordComponentDescription.getType());
3373             }
3374
3375             /**
3376              * {@inheritDoc}
3377              */

3378             public RecordComponentDefinition<S> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
3379                 return recordComponent(new LatentMatcher.Resolved<RecordComponentDescription>(matcher));
3380             }
3381
3382             /**
3383              * {@inheritDoc}
3384              */

3385             public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, ModifierContributor.ForField... modifierContributor) {
3386                 return defineField(name, type, Arrays.asList(modifierContributor));
3387             }
3388
3389             /**
3390              * {@inheritDoc}
3391              */

3392             public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
3393                 return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
3394             }
3395
3396             /**
3397              * {@inheritDoc}
3398              */

3399             public FieldDefinition.Optional.Valuable<S> defineField(String name, Type type, int modifiers) {
3400                 return defineField(name, TypeDefinition.Sort.describe(type), modifiers);
3401             }
3402
3403             /**
3404              * {@inheritDoc}
3405              */

3406             public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, ModifierContributor.ForField... modifierContributor) {
3407                 return defineField(name, type, Arrays.asList(modifierContributor));
3408             }
3409
3410             /**
3411              * {@inheritDoc}
3412              */

3413             public FieldDefinition.Optional.Valuable<S> defineField(String name, TypeDefinition type, Collection<? extends ModifierContributor.ForField> modifierContributors) {
3414                 return defineField(name, type, ModifierContributor.Resolver.of(modifierContributors).resolve());
3415             }
3416
3417             /**
3418              * {@inheritDoc}
3419              */

3420             public FieldDefinition.Optional.Valuable<S> define(Field field) {
3421                 return define(new FieldDescription.ForLoadedField(field));
3422             }
3423
3424             /**
3425              * {@inheritDoc}
3426              */

3427             public FieldDefinition.Optional.Valuable<S> define(FieldDescription field) {
3428                 return defineField(field.getName(), field.getType(), field.getModifiers());
3429             }
3430
3431             /**
3432              * {@inheritDoc}
3433              */

3434             public FieldDefinition.Optional<S> serialVersionUid(long serialVersionUid) {
3435                 return defineField("serialVersionUID"long.class, Visibility.PRIVATE, FieldManifestation.FINAL, Ownership.STATIC).value(serialVersionUid);
3436             }
3437
3438             /**
3439              * {@inheritDoc}
3440              */

3441             public FieldDefinition.Valuable<S> field(ElementMatcher<? super FieldDescription> matcher) {
3442                 return field(new LatentMatcher.Resolved<FieldDescription>(matcher));
3443             }
3444
3445             /**
3446              * {@inheritDoc}
3447              */

3448             public Builder<S> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
3449                 return ignoreAlso(new LatentMatcher.Resolved<MethodDescription>(ignoredMethods));
3450             }
3451
3452             /**
3453              * {@inheritDoc}
3454              */

3455             public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, ModifierContributor.ForMethod... modifierContributor) {
3456                 return defineMethod(name, returnType, Arrays.asList(modifierContributor));
3457             }
3458
3459             /**
3460              * {@inheritDoc}
3461              */

3462             public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
3463                 return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
3464             }
3465
3466             /**
3467              * {@inheritDoc}
3468              */

3469             public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, Type returnType, int modifiers) {
3470                 return defineMethod(name, TypeDefinition.Sort.describe(returnType), modifiers);
3471             }
3472
3473             /**
3474              * {@inheritDoc}
3475              */

3476             public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, ModifierContributor.ForMethod... modifierContributor) {
3477                 return defineMethod(name, returnType, Arrays.asList(modifierContributor));
3478             }
3479
3480             /**
3481              * {@inheritDoc}
3482              */

3483             public MethodDefinition.ParameterDefinition.Initial<S> defineMethod(String name, TypeDefinition returnType, Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
3484                 return defineMethod(name, returnType, ModifierContributor.Resolver.of(modifierContributors).resolve());
3485             }
3486
3487             /**
3488              * {@inheritDoc}
3489              */

3490             public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(ModifierContributor.ForMethod... modifierContributor) {
3491                 return defineConstructor(Arrays.asList(modifierContributor));
3492             }
3493
3494             /**
3495              * {@inheritDoc}
3496              */

3497             public MethodDefinition.ParameterDefinition.Initial<S> defineConstructor(Collection<? extends ModifierContributor.ForMethod> modifierContributors) {
3498                 return defineConstructor(ModifierContributor.Resolver.of(modifierContributors).resolve());
3499             }
3500
3501             /**
3502              * {@inheritDoc}
3503              */

3504             public MethodDefinition.ImplementationDefinition<S> define(Method method) {
3505                 return define(new MethodDescription.ForLoadedMethod(method));
3506             }
3507
3508             /**
3509              * {@inheritDoc}
3510              */

3511             public MethodDefinition.ImplementationDefinition<S> define(Constructor<?> constructor) {
3512                 return define(new MethodDescription.ForLoadedConstructor(constructor));
3513             }
3514
3515             /**
3516              * {@inheritDoc}
3517              */

3518             public MethodDefinition.ImplementationDefinition<S> define(MethodDescription methodDescription) {
3519                 MethodDefinition.ParameterDefinition.Initial<S> initialParameterDefinition = methodDescription.isConstructor()
3520                         ? defineConstructor(methodDescription.getModifiers())
3521                         : defineMethod(methodDescription.getInternalName(), methodDescription.getReturnType(), methodDescription.getModifiers());
3522                 ParameterList<?> parameterList = methodDescription.getParameters();
3523                 MethodDefinition.ExceptionDefinition<S> exceptionDefinition;
3524                 if (parameterList.hasExplicitMetaData()) {
3525                     MethodDefinition.ParameterDefinition<S> parameterDefinition = initialParameterDefinition;
3526                     for (ParameterDescription parameter : parameterList) {
3527                         parameterDefinition = parameterDefinition.withParameter(parameter.getType(), parameter.getName(), parameter.getModifiers());
3528                     }
3529                     exceptionDefinition = parameterDefinition;
3530                 } else {
3531                     exceptionDefinition = initialParameterDefinition.withParameters(parameterList.asTypeList());
3532                 }
3533                 MethodDefinition.TypeVariableDefinition<S> typeVariableDefinition = exceptionDefinition.throwing(methodDescription.getExceptionTypes());
3534                 for (TypeDescription.Generic typeVariable : methodDescription.getTypeVariables()) {
3535                     typeVariableDefinition = typeVariableDefinition.typeVariable(typeVariable.getSymbol(), typeVariable.getUpperBounds());
3536                 }
3537                 return typeVariableDefinition;
3538             }
3539
3540             /**
3541              * {@inheritDoc}
3542              */

3543             public FieldDefinition.Optional<S> defineProperty(String name, Type type) {
3544                 return defineProperty(name, TypeDefinition.Sort.describe(type));
3545             }
3546
3547             /**
3548              * {@inheritDoc}
3549              */

3550             public FieldDefinition.Optional<S> defineProperty(String name, Type type, boolean readOnly) {
3551                 return defineProperty(name, TypeDefinition.Sort.describe(type), readOnly);
3552             }
3553
3554             /**
3555              * {@inheritDoc}
3556              */

3557             public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type) {
3558                 return defineProperty(name, type, false);
3559             }
3560
3561             /**
3562              * {@inheritDoc}
3563              */

3564             public FieldDefinition.Optional<S> defineProperty(String name, TypeDefinition type, boolean readOnly) {
3565                 if (name.length() == 0) {
3566                     throw new IllegalArgumentException("A bean property cannot have an empty name");
3567                 } else if (type.represents(void.class)) {
3568                     throw new IllegalArgumentException("A bean property cannot have a void type");
3569                 }
3570                 DynamicType.Builder<S> builder = this;
3571                 FieldManifestation fieldManifestation;
3572                 if (!readOnly) {
3573                     builder = builder
3574                             .defineMethod("set" + Character.toUpperCase(name.charAt(0)) + name.substring(1), void.class, Visibility.PUBLIC)
3575                             .withParameters(type)
3576                             .intercept(FieldAccessor.ofField(name));
3577                     fieldManifestation = FieldManifestation.PLAIN;
3578                 } else {
3579                     fieldManifestation = FieldManifestation.FINAL;
3580                 }
3581                 return builder
3582                         .defineMethod((type.represents(boolean.class) || type.represents(Boolean.class)
3583                                 ? "is"
3584                                 : "get") + Character.toUpperCase(name.charAt(0)) + name.substring(1), type, Visibility.PUBLIC)
3585                         .intercept(FieldAccessor.ofField(name))
3586                         .defineField(name, type, Visibility.PRIVATE, fieldManifestation);
3587             }
3588
3589             /**
3590              * {@inheritDoc}
3591              */

3592             public MethodDefinition.ImplementationDefinition<S> method(ElementMatcher<? super MethodDescription> matcher) {
3593                 return invokable(isMethod().and(matcher));
3594             }
3595
3596             /**
3597              * {@inheritDoc}
3598              */

3599             public MethodDefinition.ImplementationDefinition<S> constructor(ElementMatcher<? super MethodDescription> matcher) {
3600                 return invokable(isConstructor().and(matcher));
3601             }
3602
3603             /**
3604              * {@inheritDoc}
3605              */

3606             public MethodDefinition.ImplementationDefinition<S> invokable(ElementMatcher<? super MethodDescription> matcher) {
3607                 return invokable(new LatentMatcher.Resolved<MethodDescription>(matcher));
3608             }
3609
3610             /**
3611              * {@inheritDoc}
3612              */

3613             public Builder<S> withHashCodeEquals() {
3614                 return method(isHashCode())
3615                         .intercept(HashCodeMethod.usingDefaultOffset().withIgnoredFields(isSynthetic()))
3616                         .method(isEquals())
3617                         .intercept(EqualsMethod.isolated().withIgnoredFields(isSynthetic()));
3618             }
3619
3620             /**
3621              * {@inheritDoc}
3622              */

3623             public Builder<S> withToString() {
3624                 return method(isToString()).intercept(ToStringMethod.prefixedBySimpleClassName());
3625             }
3626
3627             /**
3628              * {@inheritDoc}
3629              */

3630             public Builder<S> require(TypeDescription type, byte[] binaryRepresentation) {
3631                 return require(type, binaryRepresentation, LoadedTypeInitializer.NoOp.INSTANCE);
3632             }
3633
3634             /**
3635              * {@inheritDoc}
3636              */

3637             public Builder<S> require(TypeDescription type, byte[] binaryRepresentation, LoadedTypeInitializer typeInitializer) {
3638                 return require(new Default(type, binaryRepresentation, typeInitializer, Collections.<DynamicType>emptyList()));
3639             }
3640
3641             /**
3642              * {@inheritDoc}
3643              */

3644             public Builder<S> require(DynamicType... auxiliaryType) {
3645                 return require(Arrays.asList(auxiliaryType));
3646             }
3647
3648             /**
3649              * {@inheritDoc}
3650              */

3651             public Unloaded<S> make(TypePool typePool) {
3652                 return make(TypeResolutionStrategy.Passive.INSTANCE, typePool);
3653             }
3654
3655             /**
3656              * {@inheritDoc}
3657              */

3658             public Unloaded<S> make() {
3659                 return make(TypeResolutionStrategy.Passive.INSTANCE);
3660             }
3661
3662             /**
3663              * A delegator for a dynamic type builder delegating all invocations to another dynamic type builder.
3664              *
3665              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3666              */

3667             public abstract static class Delegator<U> extends AbstractBase<U> {
3668
3669                 /**
3670                  * {@inheritDoc}
3671                  */

3672                 public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
3673                     return materialize().visit(asmVisitorWrapper);
3674                 }
3675
3676                 /**
3677                  * {@inheritDoc}
3678                  */

3679                 public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
3680                     return materialize().initializer(loadedTypeInitializer);
3681                 }
3682
3683                 /**
3684                  * {@inheritDoc}
3685                  */

3686                 public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
3687                     return materialize().annotateType(annotations);
3688                 }
3689
3690                 /**
3691                  * {@inheritDoc}
3692                  */

3693                 public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
3694                     return materialize().attribute(typeAttributeAppender);
3695                 }
3696
3697                 /**
3698                  * {@inheritDoc}
3699                  */

3700                 public Builder<U> modifiers(int modifiers) {
3701                     return materialize().modifiers(modifiers);
3702                 }
3703
3704                 /**
3705                  * {@inheritDoc}
3706                  */

3707                 public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
3708                     return materialize().merge(modifierContributors);
3709                 }
3710
3711                 /**
3712                  * {@inheritDoc}
3713                  */

3714                 public Builder<U> suffix(String suffix) {
3715                     return materialize().suffix(suffix);
3716                 }
3717
3718                 /**
3719                  * {@inheritDoc}
3720                  */

3721                 public Builder<U> name(String name) {
3722                     return materialize().name(name);
3723                 }
3724
3725                 /**
3726                  * {@inheritDoc}
3727                  */

3728                 public Builder<U> topLevelType() {
3729                     return materialize().topLevelType();
3730                 }
3731
3732                 /**
3733                  * {@inheritDoc}
3734                  */

3735                 public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
3736                     return materialize().innerTypeOf(type);
3737                 }
3738
3739                 /**
3740                  * {@inheritDoc}
3741                  */

3742                 public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
3743                     return materialize().innerTypeOf(methodDescription);
3744                 }
3745
3746                 /**
3747                  * {@inheritDoc}
3748                  */

3749                 public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
3750                     return materialize().declaredTypes(types);
3751                 }
3752
3753                 /**
3754                  * {@inheritDoc}
3755                  */

3756                 public Builder<U> nestHost(TypeDescription type) {
3757                     return materialize().nestHost(type);
3758                 }
3759
3760                 /**
3761                  * {@inheritDoc}
3762                  */

3763                 public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
3764                     return materialize().nestMembers(types);
3765                 }
3766
3767                 /**
3768                  * {@inheritDoc}
3769                  */

3770                 public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
3771                     return materialize().permittedSubclass(types);
3772                 }
3773
3774                 /**
3775                  * {@inheritDoc}
3776                  */

3777                 public Builder<U> unsealed() {
3778                     return materialize().unsealed();
3779                 }
3780
3781                 /**
3782                  * {@inheritDoc}
3783                  */

3784                 public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
3785                     return materialize().implement(interfaceTypes);
3786                 }
3787
3788                 /**
3789                  * {@inheritDoc}
3790                  */

3791                 public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
3792                     return materialize().initializer(byteCodeAppender);
3793                 }
3794
3795                 /**
3796                  * {@inheritDoc}
3797                  */

3798                 public Builder<U> ignoreAlso(ElementMatcher<? super MethodDescription> ignoredMethods) {
3799                     return materialize().ignoreAlso(ignoredMethods);
3800                 }
3801
3802                 /**
3803                  * {@inheritDoc}
3804                  */

3805                 public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
3806                     return materialize().ignoreAlso(ignoredMethods);
3807                 }
3808
3809                 /**
3810                  * {@inheritDoc}
3811                  */

3812                 public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
3813                     return materialize().typeVariable(symbol, bounds);
3814                 }
3815
3816                 /**
3817                  * {@inheritDoc}
3818                  */

3819                 public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
3820                     return materialize().transform(matcher, transformer);
3821                 }
3822
3823                 /**
3824                  * {@inheritDoc}
3825                  */

3826                 public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
3827                     return materialize().defineField(name, type, modifiers);
3828                 }
3829
3830                 /**
3831                  * {@inheritDoc}
3832                  */

3833                 public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
3834                     return materialize().field(matcher);
3835                 }
3836
3837                 /**
3838                  * {@inheritDoc}
3839                  */

3840                 public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
3841                     return materialize().defineMethod(name, returnType, modifiers);
3842                 }
3843
3844                 /**
3845                  * {@inheritDoc}
3846                  */

3847                 public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
3848                     return materialize().defineConstructor(modifiers);
3849                 }
3850
3851                 /**
3852                  * {@inheritDoc}
3853                  */

3854                 public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
3855                     return materialize().invokable(matcher);
3856                 }
3857
3858                 /**
3859                  * {@inheritDoc}
3860                  */

3861                 public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
3862                     return materialize().require(auxiliaryTypes);
3863                 }
3864
3865                 /**
3866                  * {@inheritDoc}
3867                  */

3868                 public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
3869                     return materialize().defineRecordComponent(name, type);
3870                 }
3871
3872                 /**
3873                  * {@inheritDoc}
3874                  */

3875                 public RecordComponentDefinition.Optional<U> define(RecordComponentDescription recordComponentDescription) {
3876                     return materialize().define(recordComponentDescription);
3877                 }
3878
3879                 /**
3880                  * {@inheritDoc}
3881                  */

3882                 public RecordComponentDefinition<U> recordComponent(ElementMatcher<? super RecordComponentDescription> matcher) {
3883                     return materialize().recordComponent(matcher);
3884                 }
3885
3886                 /**
3887                  * {@inheritDoc}
3888                  */

3889                 public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
3890                     return materialize().recordComponent(matcher);
3891                 }
3892
3893                 /**
3894                  * {@inheritDoc}
3895                  */

3896                 public DynamicType.Unloaded<U> make() {
3897                     return materialize().make();
3898                 }
3899
3900                 /**
3901                  * {@inheritDoc}
3902                  */

3903                 public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy) {
3904                     return materialize().make(typeResolutionStrategy);
3905                 }
3906
3907                 /**
3908                  * {@inheritDoc}
3909                  */

3910                 public Unloaded<U> make(TypePool typePool) {
3911                     return materialize().make(typePool);
3912                 }
3913
3914                 /**
3915                  * {@inheritDoc}
3916                  */

3917                 public Unloaded<U> make(TypeResolutionStrategy typeResolutionStrategy, TypePool typePool) {
3918                     return materialize().make(typeResolutionStrategy, typePool);
3919                 }
3920
3921                 /**
3922                  * {@inheritDoc}
3923                  */

3924                 public TypeDescription toTypeDescription() {
3925                     return materialize().toTypeDescription();
3926                 }
3927
3928                 /**
3929                  * Creates a new builder that realizes the current state of the builder.
3930                  *
3931                  * @return A new builder that realizes the current state of the builder.
3932                  */

3933                 protected abstract Builder<U> materialize();
3934             }
3935
3936             /**
3937              * An adapter implementation of a dynamic type builder.
3938              *
3939              * @param <U> A loaded type that the built type is guaranteed to be a subclass of.
3940              */

3941             @HashCodeAndEqualsPlugin.Enhance
3942             public abstract static class Adapter<U> extends AbstractBase<U> {
3943
3944                 /**
3945                  * The instrumented type to be created.
3946                  */

3947                 protected final InstrumentedType.WithFlexibleName instrumentedType;
3948
3949                 /**
3950                  * The current field registry.
3951                  */

3952                 protected final FieldRegistry fieldRegistry;
3953
3954                 /**
3955                  * The current method registry.
3956                  */

3957                 protected final MethodRegistry methodRegistry;
3958
3959                 /**
3960                  * The current record component registry.
3961                  */

3962                 protected final RecordComponentRegistry recordComponentRegistry;
3963
3964                 /**
3965                  * The type attribute appender to apply onto the instrumented type.
3966                  */

3967                 protected final TypeAttributeAppender typeAttributeAppender;
3968
3969                 /**
3970                  * The ASM visitor wrapper to apply onto the class writer.
3971                  */

3972                 protected final AsmVisitorWrapper asmVisitorWrapper;
3973
3974                 /**
3975                  * The class file version to define auxiliary types in.
3976                  */

3977                 protected final ClassFileVersion classFileVersion;
3978
3979                 /**
3980                  * The naming strategy for auxiliary types to apply.
3981                  */

3982                 protected final AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy;
3983
3984                 /**
3985                  * The annotation value filter factory to apply.
3986                  */

3987                 protected final AnnotationValueFilter.Factory annotationValueFilterFactory;
3988
3989                 /**
3990                  * The annotation retention to apply.
3991                  */

3992                 protected final AnnotationRetention annotationRetention;
3993
3994                 /**
3995                  * The implementation context factory to apply.
3996                  */

3997                 protected final Implementation.Context.Factory implementationContextFactory;
3998
3999                 /**
4000                  * The method graph compiler to use.
4001                  */

4002                 protected final MethodGraph.Compiler methodGraphCompiler;
4003
4004                 /**
4005                  * Determines if a type should be explicitly validated.
4006                  */

4007                 protected final TypeValidation typeValidation;
4008
4009                 /**
4010                  * The visibility bridge strategy to apply.
4011                  */

4012                 protected final VisibilityBridgeStrategy visibilityBridgeStrategy;
4013
4014                 /**
4015                  * The class writer strategy to use.
4016                  */

4017                 protected final ClassWriterStrategy classWriterStrategy;
4018
4019                 /**
4020                  * A matcher for identifying methods that should be excluded from instrumentation.
4021                  */

4022                 protected final LatentMatcher<? super MethodDescription> ignoredMethods;
4023
4024                 /**
4025                  * A list of explicitly defined auxiliary types.
4026                  */

4027                 protected final List<? extends DynamicType> auxiliaryTypes;
4028
4029                 /**
4030                  * Creates a new default type writer for creating a new type that is not based on an existing class file.
4031                  *
4032                  * @param instrumentedType             The instrumented type to be created.
4033                  * @param fieldRegistry                The current field registry.
4034                  * @param methodRegistry               The current method registry.
4035                  * @param recordComponentRegistry      The record component pool to use.
4036                  * @param typeAttributeAppender        The type attribute appender to apply onto the instrumented type.
4037                  * @param asmVisitorWrapper            The ASM visitor wrapper to apply onto the class writer.
4038                  * @param classFileVersion             The class file version to define auxiliary types in.
4039                  * @param auxiliaryTypeNamingStrategy  The naming strategy for auxiliary types to apply.
4040                  * @param annotationValueFilterFactory The annotation value filter factory to apply.
4041                  * @param annotationRetention          The annotation retention to apply.
4042                  * @param implementationContextFactory The implementation context factory to apply.
4043                  * @param methodGraphCompiler          The method graph compiler to use.
4044                  * @param typeValidation               Determines if a type should be explicitly validated.
4045                  * @param visibilityBridgeStrategy     The visibility bridge strategy to apply.
4046                  * @param classWriterStrategy          The class writer strategy to use.
4047                  * @param ignoredMethods               A matcher for identifying methods that should be excluded from instrumentation.
4048                  * @param auxiliaryTypes               A list of explicitly defined auxiliary types.
4049                  */

4050                 protected Adapter(InstrumentedType.WithFlexibleName instrumentedType,
4051                                   FieldRegistry fieldRegistry,
4052                                   MethodRegistry methodRegistry,
4053                                   RecordComponentRegistry recordComponentRegistry,
4054                                   TypeAttributeAppender typeAttributeAppender,
4055                                   AsmVisitorWrapper asmVisitorWrapper,
4056                                   ClassFileVersion classFileVersion,
4057                                   AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
4058                                   AnnotationValueFilter.Factory annotationValueFilterFactory,
4059                                   AnnotationRetention annotationRetention,
4060                                   Implementation.Context.Factory implementationContextFactory,
4061                                   MethodGraph.Compiler methodGraphCompiler,
4062                                   TypeValidation typeValidation,
4063                                   VisibilityBridgeStrategy visibilityBridgeStrategy,
4064                                   ClassWriterStrategy classWriterStrategy,
4065                                   LatentMatcher<? super MethodDescription> ignoredMethods,
4066                                   List<? extends DynamicType> auxiliaryTypes) {
4067                     this.instrumentedType = instrumentedType;
4068                     this.fieldRegistry = fieldRegistry;
4069                     this.methodRegistry = methodRegistry;
4070                     this.recordComponentRegistry = recordComponentRegistry;
4071                     this.typeAttributeAppender = typeAttributeAppender;
4072                     this.asmVisitorWrapper = asmVisitorWrapper;
4073                     this.classFileVersion = classFileVersion;
4074                     this.auxiliaryTypeNamingStrategy = auxiliaryTypeNamingStrategy;
4075                     this.annotationValueFilterFactory = annotationValueFilterFactory;
4076                     this.annotationRetention = annotationRetention;
4077                     this.implementationContextFactory = implementationContextFactory;
4078                     this.methodGraphCompiler = methodGraphCompiler;
4079                     this.typeValidation = typeValidation;
4080                     this.visibilityBridgeStrategy = visibilityBridgeStrategy;
4081                     this.classWriterStrategy = classWriterStrategy;
4082                     this.ignoredMethods = ignoredMethods;
4083                     this.auxiliaryTypes = auxiliaryTypes;
4084                 }
4085
4086                 /**
4087                  * {@inheritDoc}
4088                  */

4089                 public FieldDefinition.Optional.Valuable<U> defineField(String name, TypeDefinition type, int modifiers) {
4090                     return new FieldDefinitionAdapter(new FieldDescription.Token(name, modifiers, type.asGenericType()));
4091                 }
4092
4093                 /**
4094                  * {@inheritDoc}
4095                  */

4096                 public FieldDefinition.Valuable<U> field(LatentMatcher<? super FieldDescription> matcher) {
4097                     return new FieldMatchAdapter(matcher);
4098                 }
4099
4100                 /**
4101                  * {@inheritDoc}
4102                  */

4103                 public MethodDefinition.ParameterDefinition.Initial<U> defineMethod(String name, TypeDefinition returnType, int modifiers) {
4104                     return new MethodDefinitionAdapter(new MethodDescription.Token(name, modifiers, returnType.asGenericType()));
4105                 }
4106
4107                 /**
4108                  * {@inheritDoc}
4109                  */

4110                 public MethodDefinition.ParameterDefinition.Initial<U> defineConstructor(int modifiers) {
4111                     return new MethodDefinitionAdapter(new MethodDescription.Token(modifiers));
4112                 }
4113
4114                 /**
4115                  * {@inheritDoc}
4116                  */

4117                 public MethodDefinition.ImplementationDefinition<U> invokable(LatentMatcher<? super MethodDescription> matcher) {
4118                     return new MethodMatchAdapter(matcher);
4119                 }
4120
4121                 /**
4122                  * {@inheritDoc}
4123                  */

4124                 public MethodDefinition.ImplementationDefinition.Optional<U> implement(Collection<? extends TypeDefinition> interfaceTypes) {
4125                     return new OptionalMethodMatchAdapter(new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(interfaceTypes)));
4126                 }
4127
4128                 /**
4129                  * {@inheritDoc}
4130                  */

4131                 @SuppressWarnings("unchecked"// In absence of @SafeVarargs
4132                 public Builder<U> ignoreAlso(LatentMatcher<? super MethodDescription> ignoredMethods) {
4133                     return materialize(instrumentedType,
4134                             fieldRegistry,
4135                             methodRegistry,
4136                             recordComponentRegistry,
4137                             typeAttributeAppender,
4138                             asmVisitorWrapper,
4139                             classFileVersion,
4140                             auxiliaryTypeNamingStrategy,
4141                             annotationValueFilterFactory,
4142                             annotationRetention,
4143                             implementationContextFactory,
4144                             methodGraphCompiler,
4145                             typeValidation,
4146                             visibilityBridgeStrategy,
4147                             classWriterStrategy,
4148                             new LatentMatcher.Disjunction<MethodDescription>(this.ignoredMethods, ignoredMethods),
4149                             auxiliaryTypes);
4150                 }
4151
4152                 /**
4153                  * {@inheritDoc}
4154                  */

4155                 public RecordComponentDefinition.Optional<U> defineRecordComponent(String name, TypeDefinition type) {
4156                     return new RecordComponentDefinitionAdapter(new RecordComponentDescription.Token(name, type.asGenericType()));
4157                 }
4158
4159                 /**
4160                  * {@inheritDoc}
4161                  */

4162                 public RecordComponentDefinition<U> recordComponent(LatentMatcher<? super RecordComponentDescription> matcher) {
4163                     return new RecordComponentMatchAdapter(matcher);
4164                 }
4165
4166                 /**
4167                  * {@inheritDoc}
4168                  */

4169                 public Builder<U> initializer(ByteCodeAppender byteCodeAppender) {
4170                     return materialize(instrumentedType.withInitializer(byteCodeAppender),
4171                             fieldRegistry,
4172                             methodRegistry,
4173                             recordComponentRegistry,
4174                             typeAttributeAppender,
4175                             asmVisitorWrapper,
4176                             classFileVersion,
4177                             auxiliaryTypeNamingStrategy,
4178                             annotationValueFilterFactory,
4179                             annotationRetention,
4180                             implementationContextFactory,
4181                             methodGraphCompiler,
4182                             typeValidation,
4183                             visibilityBridgeStrategy,
4184                             classWriterStrategy,
4185                             ignoredMethods,
4186                             auxiliaryTypes);
4187                 }
4188
4189                 /**
4190                  * {@inheritDoc}
4191                  */

4192                 public Builder<U> initializer(LoadedTypeInitializer loadedTypeInitializer) {
4193                     return materialize(instrumentedType.withInitializer(loadedTypeInitializer),
4194                             fieldRegistry,
4195                             methodRegistry,
4196                             recordComponentRegistry,
4197                             typeAttributeAppender,
4198                             asmVisitorWrapper,
4199                             classFileVersion,
4200                             auxiliaryTypeNamingStrategy,
4201                             annotationValueFilterFactory,
4202                             annotationRetention,
4203                             implementationContextFactory,
4204                             methodGraphCompiler,
4205                             typeValidation,
4206                             visibilityBridgeStrategy,
4207                             classWriterStrategy,
4208                             ignoredMethods,
4209                             auxiliaryTypes);
4210                 }
4211
4212                 /**
4213                  * {@inheritDoc}
4214                  */

4215                 public Builder<U> name(String name) {
4216                     return materialize(instrumentedType.withName(name),
4217                             fieldRegistry,
4218                             methodRegistry,
4219                             recordComponentRegistry,
4220                             typeAttributeAppender,
4221                             asmVisitorWrapper,
4222                             classFileVersion,
4223                             auxiliaryTypeNamingStrategy,
4224                             annotationValueFilterFactory,
4225                             annotationRetention,
4226                             implementationContextFactory,
4227                             methodGraphCompiler,
4228                             typeValidation,
4229                             visibilityBridgeStrategy,
4230                             classWriterStrategy,
4231                             ignoredMethods,
4232                             auxiliaryTypes);
4233                 }
4234
4235                 /**
4236                  * {@inheritDoc}
4237                  */

4238                 public Builder<U> suffix(String suffix) {
4239                     return name(instrumentedType.getName() + "$" + suffix);
4240                 }
4241
4242                 /**
4243                  * {@inheritDoc}
4244                  */

4245                 public Builder<U> modifiers(int modifiers) {
4246                     return materialize(instrumentedType.withModifiers(modifiers),
4247                             fieldRegistry,
4248                             methodRegistry,
4249                             recordComponentRegistry,
4250                             typeAttributeAppender,
4251                             asmVisitorWrapper,
4252                             classFileVersion,
4253                             auxiliaryTypeNamingStrategy,
4254                             annotationValueFilterFactory,
4255                             annotationRetention,
4256                             implementationContextFactory,
4257                             methodGraphCompiler,
4258                             typeValidation,
4259                             visibilityBridgeStrategy,
4260                             classWriterStrategy,
4261                             ignoredMethods,
4262                             auxiliaryTypes);
4263                 }
4264
4265                 /**
4266                  * {@inheritDoc}
4267                  */

4268                 public Builder<U> merge(Collection<? extends ModifierContributor.ForType> modifierContributors) {
4269                     return materialize(instrumentedType.withModifiers(ModifierContributor.Resolver.of(modifierContributors).resolve(instrumentedType.getModifiers())),
4270                             fieldRegistry,
4271                             methodRegistry,
4272                             recordComponentRegistry,
4273                             typeAttributeAppender,
4274                             asmVisitorWrapper,
4275                             classFileVersion,
4276                             auxiliaryTypeNamingStrategy,
4277                             annotationValueFilterFactory,
4278                             annotationRetention,
4279                             implementationContextFactory,
4280                             methodGraphCompiler,
4281                             typeValidation,
4282                             visibilityBridgeStrategy,
4283                             classWriterStrategy,
4284                             ignoredMethods,
4285                             auxiliaryTypes);
4286                 }
4287
4288                 /**
4289                  * {@inheritDoc}
4290                  */

4291                 public Builder<U> topLevelType() {
4292                     return Adapter.this.materialize(instrumentedType
4293                                     .withDeclaringType(TypeDescription.UNDEFINED)
4294                                     .withEnclosingType(TypeDescription.UNDEFINED)
4295                                     .withLocalClass(false),
4296                             fieldRegistry,
4297                             methodRegistry,
4298                             recordComponentRegistry,
4299                             typeAttributeAppender,
4300                             asmVisitorWrapper,
4301                             classFileVersion,
4302                             auxiliaryTypeNamingStrategy,
4303                             annotationValueFilterFactory,
4304                             annotationRetention,
4305                             implementationContextFactory,
4306                             methodGraphCompiler,
4307                             typeValidation,
4308                             visibilityBridgeStrategy,
4309                             classWriterStrategy,
4310                             ignoredMethods,
4311                             auxiliaryTypes);
4312                 }
4313
4314                 /**
4315                  * {@inheritDoc}
4316                  */

4317                 public InnerTypeDefinition.ForType<U> innerTypeOf(TypeDescription type) {
4318                     return new InnerTypeDefinitionForTypeAdapter(type);
4319                 }
4320
4321                 /**
4322                  * {@inheritDoc}
4323                  */

4324                 public InnerTypeDefinition<U> innerTypeOf(MethodDescription.InDefinedShape methodDescription) {
4325                     return methodDescription.isTypeInitializer()
4326                             ? new InnerTypeDefinitionForTypeAdapter(methodDescription.getDeclaringType())
4327                             : new InnerTypeDefinitionForMethodAdapter(methodDescription);
4328                 }
4329
4330                 /**
4331                  * {@inheritDoc}
4332                  */

4333                 public Builder<U> declaredTypes(Collection<? extends TypeDescription> types) {
4334                     return materialize(instrumentedType.withDeclaredTypes(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
4335                             fieldRegistry,
4336                             methodRegistry,
4337                             recordComponentRegistry,
4338                             typeAttributeAppender,
4339                             asmVisitorWrapper,
4340                             classFileVersion,
4341                             auxiliaryTypeNamingStrategy,
4342                             annotationValueFilterFactory,
4343                             annotationRetention,
4344                             implementationContextFactory,
4345                             methodGraphCompiler,
4346                             typeValidation,
4347                             visibilityBridgeStrategy,
4348                             classWriterStrategy,
4349                             ignoredMethods,
4350                             auxiliaryTypes);
4351                 }
4352
4353                 /**
4354                  * {@inheritDoc}
4355                  */

4356                 public Builder<U> nestHost(TypeDescription type) {
4357                     return materialize(instrumentedType.withNestHost(type),
4358                             fieldRegistry,
4359                             methodRegistry,
4360                             recordComponentRegistry,
4361                             typeAttributeAppender,
4362                             asmVisitorWrapper,
4363                             classFileVersion,
4364                             auxiliaryTypeNamingStrategy,
4365                             annotationValueFilterFactory,
4366                             annotationRetention,
4367                             implementationContextFactory,
4368                             methodGraphCompiler,
4369                             typeValidation,
4370                             visibilityBridgeStrategy,
4371                             classWriterStrategy,
4372                             ignoredMethods,
4373                             auxiliaryTypes);
4374                 }
4375
4376                 /**
4377                  * {@inheritDoc}
4378                  */

4379                 public Builder<U> nestMembers(Collection<? extends TypeDescription> types) {
4380                     return materialize(instrumentedType.withNestMembers(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
4381                             fieldRegistry,
4382                             methodRegistry,
4383                             recordComponentRegistry,
4384                             typeAttributeAppender,
4385                             asmVisitorWrapper,
4386                             classFileVersion,
4387                             auxiliaryTypeNamingStrategy,
4388                             annotationValueFilterFactory,
4389                             annotationRetention,
4390                             implementationContextFactory,
4391                             methodGraphCompiler,
4392                             typeValidation,
4393                             visibilityBridgeStrategy,
4394                             classWriterStrategy,
4395                             ignoredMethods,
4396                             auxiliaryTypes);
4397                 }
4398
4399                 /**
4400                  * {@inheritDoc}
4401                  */

4402                 public Builder<U> permittedSubclass(Collection<? extends TypeDescription> types) {
4403                     return materialize(instrumentedType.withPermittedSubclasses(new TypeList.Explicit(new ArrayList<TypeDescription>(types))),
4404                             fieldRegistry,
4405                             methodRegistry,
4406                             recordComponentRegistry,
4407                             typeAttributeAppender,
4408                             asmVisitorWrapper,
4409                             classFileVersion,
4410                             auxiliaryTypeNamingStrategy,
4411                             annotationValueFilterFactory,
4412                             annotationRetention,
4413                             implementationContextFactory,
4414                             methodGraphCompiler,
4415                             typeValidation,
4416                             visibilityBridgeStrategy,
4417                             classWriterStrategy,
4418                             ignoredMethods,
4419                             auxiliaryTypes);
4420                 }
4421
4422                 /**
4423                  * {@inheritDoc}
4424                  */

4425                 public Builder<U> unsealed() {
4426                     return materialize(instrumentedType.withSealed(false),
4427                             fieldRegistry,
4428                             methodRegistry,
4429                             recordComponentRegistry,
4430                             typeAttributeAppender,
4431                             asmVisitorWrapper,
4432                             classFileVersion,
4433                             auxiliaryTypeNamingStrategy,
4434                             annotationValueFilterFactory,
4435                             annotationRetention,
4436                             implementationContextFactory,
4437                             methodGraphCompiler,
4438                             typeValidation,
4439                             visibilityBridgeStrategy,
4440                             classWriterStrategy,
4441                             ignoredMethods,
4442                             auxiliaryTypes);
4443                 }
4444
4445                 /**
4446                  * {@inheritDoc}
4447                  */

4448                 public TypeVariableDefinition<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
4449                     return new TypeVariableDefinitionAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
4450                 }
4451
4452                 /**
4453                  * {@inheritDoc}
4454                  */

4455                 public Builder<U> transform(ElementMatcher<? super TypeDescription.Generic> matcher, Transformer<TypeVariableToken> transformer) {
4456                     return materialize(instrumentedType.withTypeVariables(matcher, transformer),
4457                             fieldRegistry,
4458                             methodRegistry,
4459                             recordComponentRegistry,
4460                             typeAttributeAppender,
4461                             asmVisitorWrapper,
4462                             classFileVersion,
4463                             auxiliaryTypeNamingStrategy,
4464                             annotationValueFilterFactory,
4465                             annotationRetention,
4466                             implementationContextFactory,
4467                             methodGraphCompiler,
4468                             typeValidation,
4469                             visibilityBridgeStrategy,
4470                             classWriterStrategy,
4471                             ignoredMethods,
4472                             auxiliaryTypes);
4473                 }
4474
4475                 /**
4476                  * {@inheritDoc}
4477                  */

4478                 public Builder<U> attribute(TypeAttributeAppender typeAttributeAppender) {
4479                     return materialize(instrumentedType,
4480                             fieldRegistry,
4481                             methodRegistry,
4482                             recordComponentRegistry,
4483                             new TypeAttributeAppender.Compound(this.typeAttributeAppender, typeAttributeAppender),
4484                             asmVisitorWrapper,
4485                             classFileVersion,
4486                             auxiliaryTypeNamingStrategy,
4487                             annotationValueFilterFactory,
4488                             annotationRetention,
4489                             implementationContextFactory,
4490                             methodGraphCompiler,
4491                             typeValidation,
4492                             visibilityBridgeStrategy,
4493                             classWriterStrategy,
4494                             ignoredMethods,
4495                             auxiliaryTypes);
4496                 }
4497
4498                 /**
4499                  * {@inheritDoc}
4500                  */

4501                 public Builder<U> annotateType(Collection<? extends AnnotationDescription> annotations) {
4502                     return materialize(instrumentedType.withAnnotations(new ArrayList<AnnotationDescription>(annotations)),
4503                             fieldRegistry,
4504                             methodRegistry,
4505                             recordComponentRegistry,
4506                             typeAttributeAppender,
4507                             asmVisitorWrapper,
4508                             classFileVersion,
4509                             auxiliaryTypeNamingStrategy,
4510                             annotationValueFilterFactory,
4511                             annotationRetention,
4512                             implementationContextFactory,
4513                             methodGraphCompiler,
4514                             typeValidation,
4515                             visibilityBridgeStrategy,
4516                             classWriterStrategy,
4517                             ignoredMethods,
4518                             auxiliaryTypes);
4519                 }
4520
4521                 /**
4522                  * {@inheritDoc}
4523                  */

4524                 public Builder<U> visit(AsmVisitorWrapper asmVisitorWrapper) {
4525                     return materialize(instrumentedType,
4526                             fieldRegistry,
4527                             methodRegistry,
4528                             recordComponentRegistry,
4529                             typeAttributeAppender,
4530                             new AsmVisitorWrapper.Compound(this.asmVisitorWrapper, asmVisitorWrapper),
4531                             classFileVersion,
4532                             auxiliaryTypeNamingStrategy,
4533                             annotationValueFilterFactory,
4534                             annotationRetention,
4535                             implementationContextFactory,
4536                             methodGraphCompiler,
4537                             typeValidation,
4538                             visibilityBridgeStrategy,
4539                             classWriterStrategy,
4540                             ignoredMethods,
4541                             auxiliaryTypes);
4542                 }
4543
4544                 /**
4545                  * {@inheritDoc}
4546                  */

4547                 public Builder<U> require(Collection<DynamicType> auxiliaryTypes) {
4548                     return materialize(instrumentedType,
4549                             fieldRegistry,
4550                             methodRegistry,
4551                             recordComponentRegistry,
4552                             typeAttributeAppender,
4553                             asmVisitorWrapper,
4554                             classFileVersion,
4555                             auxiliaryTypeNamingStrategy,
4556                             annotationValueFilterFactory,
4557                             annotationRetention,
4558                             implementationContextFactory,
4559                             methodGraphCompiler,
4560                             typeValidation,
4561                             visibilityBridgeStrategy,
4562                             classWriterStrategy,
4563                             ignoredMethods,
4564                             CompoundList.of(this.auxiliaryTypes, new ArrayList<DynamicType>(auxiliaryTypes)));
4565                 }
4566
4567                 /**
4568                  * {@inheritDoc}
4569                  */

4570                 public TypeDescription toTypeDescription() {
4571                     return instrumentedType;
4572                 }
4573
4574                 /**
4575                  * Materializes the supplied state of a dynamic type builder.
4576                  *
4577                  * @param instrumentedType             The instrumented type.
4578                  * @param fieldRegistry                The current field registry.
4579                  * @param methodRegistry               The current method registry.
4580                  * @param recordComponentRegistry      The record component pool to use.
4581                  * @param typeAttributeAppender        The type attribute appender to apply onto the instrumented type.
4582                  * @param asmVisitorWrapper            The ASM visitor wrapper to apply onto the class writer.
4583                  * @param classFileVersion             The class file version to define auxiliary types in.
4584                  * @param auxiliaryTypeNamingStrategy  The naming strategy for auxiliary types to apply.
4585                  * @param annotationValueFilterFactory The annotation value filter factory to apply.
4586                  * @param annotationRetention          The annotation retention to apply.
4587                  * @param implementationContextFactory The implementation context factory to apply.
4588                  * @param methodGraphCompiler          The method graph compiler to use.
4589                  * @param typeValidation               The type validation state.
4590                  * @param visibilityBridgeStrategy     The visibility bridge strategy to apply.
4591                  * @param classWriterStrategy          The class writer strategy to use.
4592                  * @param ignoredMethods               A matcher for identifying methods that should be excluded from instrumentation.
4593                  * @param auxiliaryTypes               A list of explicitly required auxiliary types.
4594                  * @return A type builder that represents the supplied arguments.
4595                  */

4596                 protected abstract Builder<U> materialize(InstrumentedType.WithFlexibleName instrumentedType,
4597                                                           FieldRegistry fieldRegistry,
4598                                                           MethodRegistry methodRegistry,
4599                                                           RecordComponentRegistry recordComponentRegistry,
4600                                                           TypeAttributeAppender typeAttributeAppender,
4601                                                           AsmVisitorWrapper asmVisitorWrapper,
4602                                                           ClassFileVersion classFileVersion,
4603                                                           AuxiliaryType.NamingStrategy auxiliaryTypeNamingStrategy,
4604                                                           AnnotationValueFilter.Factory annotationValueFilterFactory,
4605                                                           AnnotationRetention annotationRetention,
4606                                                           Implementation.Context.Factory implementationContextFactory,
4607                                                           MethodGraph.Compiler methodGraphCompiler,
4608                                                           TypeValidation typeValidation,
4609                                                           VisibilityBridgeStrategy visibilityBridgeStrategy,
4610                                                           ClassWriterStrategy classWriterStrategy,
4611                                                           LatentMatcher<? super MethodDescription> ignoredMethods,
4612                                                           List<? extends DynamicType> auxiliaryTypes);
4613
4614                 /**
4615                  * An adapter for applying an inner type definition for an outer type.
4616                  */

4617                 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4618                 protected class InnerTypeDefinitionForTypeAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition.ForType<U> {
4619
4620                     /**
4621                      * A description of the type that is the defined outer type.
4622                      */

4623                     private final TypeDescription typeDescription;
4624
4625                     /**
4626                      * Creates a new adapter for an inner type definition for an outer type.
4627                      *
4628                      * @param typeDescription A description of the type that is the defined outer type.
4629                      */

4630                     protected InnerTypeDefinitionForTypeAdapter(TypeDescription typeDescription) {
4631                         this.typeDescription = typeDescription;
4632                     }
4633
4634                     /**
4635                      * {@inheritDoc}
4636                      */

4637                     public Builder<U> asAnonymousType() {
4638                         return Adapter.this.materialize(instrumentedType
4639                                         .withDeclaringType(TypeDescription.UNDEFINED)
4640                                         .withEnclosingType(typeDescription)
4641                                         .withAnonymousClass(true),
4642                                 fieldRegistry,
4643                                 methodRegistry,
4644                                 recordComponentRegistry,
4645                                 typeAttributeAppender,
4646                                 asmVisitorWrapper,
4647                                 classFileVersion,
4648                                 auxiliaryTypeNamingStrategy,
4649                                 annotationValueFilterFactory,
4650                                 annotationRetention,
4651                                 implementationContextFactory,
4652                                 methodGraphCompiler,
4653                                 typeValidation,
4654                                 visibilityBridgeStrategy,
4655                                 classWriterStrategy,
4656                                 ignoredMethods,
4657                                 auxiliaryTypes);
4658                     }
4659
4660                     /**
4661                      * {@inheritDoc}
4662                      */

4663                     public Builder<U> asMemberType() {
4664                         return Adapter.this.materialize(instrumentedType
4665                                         .withDeclaringType(typeDescription)
4666                                         .withEnclosingType(typeDescription)
4667                                         .withAnonymousClass(false)
4668                                         .withLocalClass(false),
4669                                 fieldRegistry,
4670                                 methodRegistry,
4671                                 recordComponentRegistry,
4672                                 typeAttributeAppender,
4673                                 asmVisitorWrapper,
4674                                 classFileVersion,
4675                                 auxiliaryTypeNamingStrategy,
4676                                 annotationValueFilterFactory,
4677                                 annotationRetention,
4678                                 implementationContextFactory,
4679                                 methodGraphCompiler,
4680                                 typeValidation,
4681                                 visibilityBridgeStrategy,
4682                                 classWriterStrategy,
4683                                 ignoredMethods,
4684                                 auxiliaryTypes);
4685                     }
4686
4687                     @Override
4688                     protected Builder<U> materialize() {
4689                         return Adapter.this.materialize(instrumentedType
4690                                         .withDeclaringType(TypeDescription.UNDEFINED)
4691                                         .withEnclosingType(typeDescription)
4692                                         .withLocalClass(true),
4693                                 fieldRegistry,
4694                                 methodRegistry,
4695                                 recordComponentRegistry,
4696                                 typeAttributeAppender,
4697                                 asmVisitorWrapper,
4698                                 classFileVersion,
4699                                 auxiliaryTypeNamingStrategy,
4700                                 annotationValueFilterFactory,
4701                                 annotationRetention,
4702                                 implementationContextFactory,
4703                                 methodGraphCompiler,
4704                                 typeValidation,
4705                                 visibilityBridgeStrategy,
4706                                 classWriterStrategy,
4707                                 ignoredMethods,
4708                                 auxiliaryTypes);
4709                     }
4710                 }
4711
4712                 /**
4713                  * An adapter for applying an inner type definition for an outer method or constructor.
4714                  */

4715                 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4716                 protected class InnerTypeDefinitionForMethodAdapter extends Builder.AbstractBase.Delegator<U> implements InnerTypeDefinition<U> {
4717
4718                     /**
4719                      * A description of the declaring method or constructor.
4720                      */

4721                     private final MethodDescription.InDefinedShape methodDescription;
4722
4723                     /**
4724                      * Creates a new adapter for defining a type that is declared within a method or constructor.
4725                      *
4726                      * @param methodDescription A description of the declaring method or constructor.
4727                      */

4728                     protected InnerTypeDefinitionForMethodAdapter(MethodDescription.InDefinedShape methodDescription) {
4729                         this.methodDescription = methodDescription;
4730                     }
4731
4732                     /**
4733                      * {@inheritDoc}
4734                      */

4735                     public Builder<U> asAnonymousType() {
4736                         return Adapter.this.materialize(instrumentedType
4737                                         .withDeclaringType(TypeDescription.UNDEFINED)
4738                                         .withEnclosingMethod(methodDescription)
4739                                         .withAnonymousClass(true),
4740                                 fieldRegistry,
4741                                 methodRegistry,
4742                                 recordComponentRegistry,
4743                                 typeAttributeAppender,
4744                                 asmVisitorWrapper,
4745                                 classFileVersion,
4746                                 auxiliaryTypeNamingStrategy,
4747                                 annotationValueFilterFactory,
4748                                 annotationRetention,
4749                                 implementationContextFactory,
4750                                 methodGraphCompiler,
4751                                 typeValidation,
4752                                 visibilityBridgeStrategy,
4753                                 classWriterStrategy,
4754                                 ignoredMethods,
4755                                 auxiliaryTypes);
4756                     }
4757
4758                     @Override
4759                     protected Builder<U> materialize() {
4760                         return Adapter.this.materialize(instrumentedType
4761                                         .withDeclaringType(TypeDescription.UNDEFINED)
4762                                         .withEnclosingMethod(methodDescription)
4763                                         .withLocalClass(true),
4764                                 fieldRegistry,
4765                                 methodRegistry,
4766                                 recordComponentRegistry,
4767                                 typeAttributeAppender,
4768                                 asmVisitorWrapper,
4769                                 classFileVersion,
4770                                 auxiliaryTypeNamingStrategy,
4771                                 annotationValueFilterFactory,
4772                                 annotationRetention,
4773                                 implementationContextFactory,
4774                                 methodGraphCompiler,
4775                                 typeValidation,
4776                                 visibilityBridgeStrategy,
4777                                 classWriterStrategy,
4778                                 ignoredMethods,
4779                                 auxiliaryTypes);
4780                     }
4781                 }
4782
4783                 /**
4784                  * An adapter for defining a new type variable for the instrumented type.
4785                  */

4786                 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4787                 protected class TypeVariableDefinitionAdapter extends TypeVariableDefinition.AbstractBase<U> {
4788
4789                     /**
4790                      * The current definition of the type variable.
4791                      */

4792                     private final TypeVariableToken token;
4793
4794                     /**
4795                      * Creates a new type variable definition adapter.
4796                      *
4797                      * @param token The current definition of the type variable.
4798                      */

4799                     protected TypeVariableDefinitionAdapter(TypeVariableToken token) {
4800                         this.token = token;
4801                     }
4802
4803                     /**
4804                      * {@inheritDoc}
4805                      */

4806                     public TypeVariableDefinition<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
4807                         return new TypeVariableDefinitionAdapter(new TypeVariableToken(token.getSymbol(),
4808                                 token.getBounds(),
4809                                 CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
4810                     }
4811
4812                     @Override
4813                     protected Builder<U> materialize() {
4814                         return Adapter.this.materialize(instrumentedType.withTypeVariable(token),
4815                                 fieldRegistry,
4816                                 methodRegistry,
4817                                 recordComponentRegistry,
4818                                 typeAttributeAppender,
4819                                 asmVisitorWrapper,
4820                                 classFileVersion,
4821                                 auxiliaryTypeNamingStrategy,
4822                                 annotationValueFilterFactory,
4823                                 annotationRetention,
4824                                 implementationContextFactory,
4825                                 methodGraphCompiler,
4826                                 typeValidation,
4827                                 visibilityBridgeStrategy,
4828                                 classWriterStrategy,
4829                                 ignoredMethods,
4830                                 auxiliaryTypes);
4831                     }
4832                 }
4833
4834                 /**
4835                  * An adapter for defining a new field.
4836                  */

4837                 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4838                 protected class FieldDefinitionAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
4839
4840                     /**
4841                      * The token representing the current field definition.
4842                      */

4843                     private final FieldDescription.Token token;
4844
4845                     /**
4846                      * Creates a new field definition adapter.
4847                      *
4848                      * @param token The token representing the current field definition.
4849                      */

4850                     protected FieldDefinitionAdapter(FieldDescription.Token token) {
4851                         this(FieldAttributeAppender.ForInstrumentedField.INSTANCE,
4852                                 Transformer.NoOp.<FieldDescription>make(),
4853                                 FieldDescription.NO_DEFAULT_VALUE,
4854                                 token);
4855                     }
4856
4857                     /**
4858                      * Creates a new field definition adapter.
4859                      *
4860                      * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
4861                      * @param transformer                   The field transformer to apply.
4862                      * @param defaultValue                  The field's default value or {@code nullif no value is to be defined.
4863                      * @param token                         The token representing the current field definition.
4864                      */

4865                     protected FieldDefinitionAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
4866                                                      Transformer<FieldDescription> transformer,
4867                                                      Object defaultValue,
4868                                                      FieldDescription.Token token) {
4869                         super(fieldAttributeAppenderFactory, transformer, defaultValue);
4870                         this.token = token;
4871                     }
4872
4873                     /**
4874                      * {@inheritDoc}
4875                      */

4876                     public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
4877                         return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, new FieldDescription.Token(token.getName(),
4878                                 token.getModifiers(),
4879                                 token.getType(),
4880                                 CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
4881                     }
4882
4883                     @Override
4884                     protected Builder<U> materialize() {
4885                         return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withField(token),
4886                                 fieldRegistry.prepend(new LatentMatcher.ForFieldToken(token), fieldAttributeAppenderFactory, defaultValue, transformer),
4887                                 methodRegistry,
4888                                 recordComponentRegistry,
4889                                 typeAttributeAppender,
4890                                 asmVisitorWrapper,
4891                                 classFileVersion,
4892                                 auxiliaryTypeNamingStrategy,
4893                                 annotationValueFilterFactory,
4894                                 annotationRetention,
4895                                 implementationContextFactory,
4896                                 methodGraphCompiler,
4897                                 typeValidation,
4898                                 visibilityBridgeStrategy,
4899                                 classWriterStrategy,
4900                                 ignoredMethods,
4901                                 auxiliaryTypes);
4902                     }
4903
4904                     @Override
4905                     protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
4906                                                       Transformer<FieldDescription> transformer,
4907                                                       Object defaultValue) {
4908                         return new FieldDefinitionAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, token);
4909                     }
4910                 }
4911
4912                 /**
4913                  * An adapter for matching an existing field.
4914                  */

4915                 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4916                 protected class FieldMatchAdapter extends FieldDefinition.Optional.Valuable.AbstractBase.Adapter<U> {
4917
4918                     /**
4919                      * The matcher for any fields to apply this matcher to.
4920                      */

4921                     private final LatentMatcher<? super FieldDescription> matcher;
4922
4923                     /**
4924                      * Creates a new field match adapter.
4925                      *
4926                      * @param matcher The matcher for any fields to apply this matcher to.
4927                      */

4928                     protected FieldMatchAdapter(LatentMatcher<? super FieldDescription> matcher) {
4929                         this(FieldAttributeAppender.NoOp.INSTANCE,
4930                                 Transformer.NoOp.<FieldDescription>make(),
4931                                 FieldDescription.NO_DEFAULT_VALUE,
4932                                 matcher);
4933                     }
4934
4935                     /**
4936                      * Creates a new field match adapter.
4937                      *
4938                      * @param fieldAttributeAppenderFactory The field attribute appender factory to apply.
4939                      * @param transformer                   The field transformer to apply.
4940                      * @param defaultValue                  The field's default value or {@code nullif no value is to be defined.
4941                      * @param matcher                       The matcher for any fields to apply this matcher to.
4942                      */

4943                     protected FieldMatchAdapter(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
4944                                                 Transformer<FieldDescription> transformer,
4945                                                 Object defaultValue,
4946                                                 LatentMatcher<? super FieldDescription> matcher) {
4947                         super(fieldAttributeAppenderFactory, transformer, defaultValue);
4948                         this.matcher = matcher;
4949                     }
4950
4951                     /**
4952                      * {@inheritDoc}
4953                      */

4954                     public Optional<U> annotateField(Collection<? extends AnnotationDescription> annotations) {
4955                         return attribute(new FieldAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
4956                     }
4957
4958                     @Override
4959                     protected Builder<U> materialize() {
4960                         return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
4961                                 fieldRegistry.prepend(matcher, fieldAttributeAppenderFactory, defaultValue, transformer),
4962                                 methodRegistry,
4963                                 recordComponentRegistry,
4964                                 typeAttributeAppender,
4965                                 asmVisitorWrapper,
4966                                 classFileVersion,
4967                                 auxiliaryTypeNamingStrategy,
4968                                 annotationValueFilterFactory,
4969                                 annotationRetention,
4970                                 implementationContextFactory,
4971                                 methodGraphCompiler,
4972                                 typeValidation,
4973                                 visibilityBridgeStrategy,
4974                                 classWriterStrategy,
4975                                 ignoredMethods,
4976                                 auxiliaryTypes);
4977                     }
4978
4979                     @Override
4980                     protected Optional<U> materialize(FieldAttributeAppender.Factory fieldAttributeAppenderFactory,
4981                                                       Transformer<FieldDescription> transformer,
4982                                                       Object defaultValue) {
4983                         return new FieldMatchAdapter(fieldAttributeAppenderFactory, transformer, defaultValue, matcher);
4984                     }
4985                 }
4986
4987                 /**
4988                  * An adapter for defining a new method.
4989                  */

4990                 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
4991                 protected class MethodDefinitionAdapter extends MethodDefinition.ParameterDefinition.Initial.AbstractBase<U> {
4992
4993                     /**
4994                      * A token representing the currently defined method.
4995                      */

4996                     private final MethodDescription.Token token;
4997
4998                     /**
4999                      * Creates a new method definition adapter.
5000                      *
5001                      * @param token A token representing the currently defined method.
5002                      */

5003                     protected MethodDefinitionAdapter(MethodDescription.Token token) {
5004                         this.token = token;
5005                     }
5006
5007                     /**
5008                      * {@inheritDoc}
5009                      */

5010                     public MethodDefinition.ParameterDefinition.Annotatable<U> withParameter(TypeDefinition type, String name, int modifiers) {
5011                         return new ParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType(), name, modifiers));
5012                     }
5013
5014                     /**
5015                      * {@inheritDoc}
5016                      */

5017                     public Simple.Annotatable<U> withParameter(TypeDefinition type) {
5018                         return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(type.asGenericType()));
5019                     }
5020
5021                     /**
5022                      * {@inheritDoc}
5023                      */

5024                     public MethodDefinition.ExceptionDefinition<U> throwing(Collection<? extends TypeDefinition> types) {
5025                         return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
5026                                 token.getModifiers(),
5027                                 token.getTypeVariableTokens(),
5028                                 token.getReturnType(),
5029                                 token.getParameterTokens(),
5030                                 CompoundList.of(token.getExceptionTypes(), new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(types))),
5031                                 token.getAnnotations(),
5032                                 token.getDefaultValue(),
5033                                 token.getReceiverType()));
5034                     }
5035
5036                     /**
5037                      * {@inheritDoc}
5038                      */

5039                     public MethodDefinition.TypeVariableDefinition.Annotatable<U> typeVariable(String symbol, Collection<? extends TypeDefinition> bounds) {
5040                         return new TypeVariableAnnotationAdapter(new TypeVariableToken(symbol, new TypeList.Generic.Explicit(new ArrayList<TypeDefinition>(bounds))));
5041                     }
5042
5043                     /**
5044                      * {@inheritDoc}
5045                      */

5046                     public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
5047                         return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
5048                     }
5049
5050                     /**
5051                      * {@inheritDoc}
5052                      */

5053                     public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
5054                         return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
5055                                 (token.getModifiers() & Opcodes.ACC_NATIVE) == 0
5056                                         ? ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers())
5057                                         : token.getModifiers(),
5058                                 token.getTypeVariableTokens(),
5059                                 token.getReturnType(),
5060                                 token.getParameterTokens(),
5061                                 token.getExceptionTypes(),
5062                                 token.getAnnotations(),
5063                                 token.getDefaultValue(),
5064                                 token.getReceiverType())).materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
5065                     }
5066
5067                     /**
5068                      * {@inheritDoc}
5069                      */

5070                     public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
5071                         return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
5072                                 ModifierContributor.Resolver.of(MethodManifestation.ABSTRACT).resolve(token.getModifiers()),
5073                                 token.getTypeVariableTokens(),
5074                                 token.getReturnType(),
5075                                 token.getParameterTokens(),
5076                                 token.getExceptionTypes(),
5077                                 token.getAnnotations(),
5078                                 annotationValue,
5079                                 token.getReceiverType())).materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
5080                     }
5081
5082                     /**
5083                      * Materializes the given handler as the implementation.
5084                      *
5085                      * @param handler The handler for implementing the method.
5086                      * @return A method definition for the given handler.
5087                      */

5088                     private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
5089                         return new AnnotationAdapter(handler);
5090                     }
5091
5092                     /**
5093                      * An adapter for defining a new type variable for the currently defined method.
5094                      */

5095                     @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5096                     protected class TypeVariableAnnotationAdapter extends MethodDefinition.TypeVariableDefinition.Annotatable.AbstractBase.Adapter<U> {
5097
5098                         /**
5099                          * The currently defined type variable.
5100                          */

5101                         private final TypeVariableToken token;
5102
5103                         /**
5104                          * Creates a new type variable annotation adapter.
5105                          *
5106                          * @param token The currently defined type variable.
5107                          */

5108                         protected TypeVariableAnnotationAdapter(TypeVariableToken token) {
5109                             this.token = token;
5110                         }
5111
5112                         @Override
5113                         protected MethodDefinition.ParameterDefinition<U> materialize() {
5114                             return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
5115                                     MethodDefinitionAdapter.this.token.getModifiers(),
5116                                     CompoundList.of(MethodDefinitionAdapter.this.token.getTypeVariableTokens(), token),
5117                                     MethodDefinitionAdapter.this.token.getReturnType(),
5118                                     MethodDefinitionAdapter.this.token.getParameterTokens(),
5119                                     MethodDefinitionAdapter.this.token.getExceptionTypes(),
5120                                     MethodDefinitionAdapter.this.token.getAnnotations(),
5121                                     MethodDefinitionAdapter.this.token.getDefaultValue(),
5122                                     MethodDefinitionAdapter.this.token.getReceiverType()));
5123                         }
5124
5125                         /**
5126                          * {@inheritDoc}
5127                          */

5128                         public Annotatable<U> annotateTypeVariable(Collection<? extends AnnotationDescription> annotations) {
5129                             return new TypeVariableAnnotationAdapter(new TypeVariableToken(token.getSymbol(),
5130                                     token.getBounds(),
5131                                     CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
5132                         }
5133                     }
5134
5135                     /**
5136                      * An annotation adapter for a parameter definition.
5137                      */

5138                     @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5139                     protected class ParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Annotatable.AbstractBase.Adapter<U> {
5140
5141                         /**
5142                          * The token of the currently defined parameter.
5143                          */

5144                         private final ParameterDescription.Token token;
5145
5146                         /**
5147                          * Creates a new parameter annotation adapter.
5148                          *
5149                          * @param token The token of the currently defined parameter.
5150                          */

5151                         protected ParameterAnnotationAdapter(ParameterDescription.Token token) {
5152                             this.token = token;
5153                         }
5154
5155                         /**
5156                          * {@inheritDoc}
5157                          */

5158                         public MethodDefinition.ParameterDefinition.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
5159                             return new ParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
5160                                     CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
5161                                     token.getName(),
5162                                     token.getModifiers()));
5163                         }
5164
5165                         @Override
5166                         protected MethodDefinition.ParameterDefinition<U> materialize() {
5167                             return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
5168                                     MethodDefinitionAdapter.this.token.getModifiers(),
5169                                     MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
5170                                     MethodDefinitionAdapter.this.token.getReturnType(),
5171                                     CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
5172                                     MethodDefinitionAdapter.this.token.getExceptionTypes(),
5173                                     MethodDefinitionAdapter.this.token.getAnnotations(),
5174                                     MethodDefinitionAdapter.this.token.getDefaultValue(),
5175                                     MethodDefinitionAdapter.this.token.getReceiverType()));
5176                         }
5177                     }
5178
5179                     /**
5180                      * An annotation adapter for a simple parameter definition.
5181                      */

5182                     @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5183                     protected class SimpleParameterAnnotationAdapter extends MethodDefinition.ParameterDefinition.Simple.Annotatable.AbstractBase.Adapter<U> {
5184
5185                         /**
5186                          * The token of the currently defined parameter.
5187                          */

5188                         private final ParameterDescription.Token token;
5189
5190                         /**
5191                          * Creates a new simple parameter annotation adapter.
5192                          *
5193                          * @param token The token of the currently defined parameter.
5194                          */

5195                         protected SimpleParameterAnnotationAdapter(ParameterDescription.Token token) {
5196                             this.token = token;
5197                         }
5198
5199                         /**
5200                          * {@inheritDoc}
5201                          */

5202                         public MethodDefinition.ParameterDefinition.Simple.Annotatable<U> annotateParameter(Collection<? extends AnnotationDescription> annotations) {
5203                             return new SimpleParameterAnnotationAdapter(new ParameterDescription.Token(token.getType(),
5204                                     CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
5205                                     token.getName(),
5206                                     token.getModifiers()));
5207                         }
5208
5209                         @Override
5210                         protected MethodDefinition.ParameterDefinition.Simple<U> materialize() {
5211                             return new MethodDefinitionAdapter(new MethodDescription.Token(MethodDefinitionAdapter.this.token.getName(),
5212                                     MethodDefinitionAdapter.this.token.getModifiers(),
5213                                     MethodDefinitionAdapter.this.token.getTypeVariableTokens(),
5214                                     MethodDefinitionAdapter.this.token.getReturnType(),
5215                                     CompoundList.of(MethodDefinitionAdapter.this.token.getParameterTokens(), token),
5216                                     MethodDefinitionAdapter.this.token.getExceptionTypes(),
5217                                     MethodDefinitionAdapter.this.token.getAnnotations(),
5218                                     MethodDefinitionAdapter.this.token.getDefaultValue(),
5219                                     MethodDefinitionAdapter.this.token.getReceiverType()));
5220                         }
5221                     }
5222
5223                     /**
5224                      * An annotation adapter for a method definition.
5225                      */

5226                     @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5227                     protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
5228
5229                         /**
5230                          * Creates a new annotation adapter.
5231                          *
5232                          * @param handler The handler that determines how a method is implemented.
5233                          */

5234                         protected AnnotationAdapter(MethodRegistry.Handler handler) {
5235                             this(handler,
5236                                     MethodAttributeAppender.ForInstrumentedMethod.INCLUDING_RECEIVER,
5237                                     Transformer.NoOp.<MethodDescription>make());
5238                         }
5239
5240                         /**
5241                          * Creates a new annotation adapter.
5242                          *
5243                          * @param handler                        The handler that determines how a method is implemented.
5244                          * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
5245                          * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
5246                          */

5247                         protected AnnotationAdapter(MethodRegistry.Handler handler,
5248                                                     MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5249                                                     Transformer<MethodDescription> transformer) {
5250                             super(handler, methodAttributeAppenderFactory, transformer);
5251                         }
5252
5253                         /**
5254                          * {@inheritDoc}
5255                          */

5256                         public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
5257                             return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
5258                                     token.getModifiers(),
5259                                     token.getTypeVariableTokens(),
5260                                     token.getReturnType(),
5261                                     token.getParameterTokens(),
5262                                     token.getExceptionTypes(),
5263                                     token.getAnnotations(),
5264                                     token.getDefaultValue(),
5265                                     receiverType)).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
5266                         }
5267
5268                         /**
5269                          * {@inheritDoc}
5270                          */

5271                         public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
5272                             return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
5273                                     token.getModifiers(),
5274                                     token.getTypeVariableTokens(),
5275                                     token.getReturnType(),
5276                                     token.getParameterTokens(),
5277                                     token.getExceptionTypes(),
5278                                     CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
5279                                     token.getDefaultValue(),
5280                                     token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
5281                         }
5282
5283                         /**
5284                          * {@inheritDoc}
5285                          */

5286                         public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
5287                             List<ParameterDescription.Token> parameterTokens = new ArrayList<ParameterDescription.Token>(token.getParameterTokens());
5288                             parameterTokens.set(index, new ParameterDescription.Token(token.getParameterTokens().get(index).getType(),
5289                                     CompoundList.of(token.getParameterTokens().get(index).getAnnotations(), new ArrayList<AnnotationDescription>(annotations)),
5290                                     token.getParameterTokens().get(index).getName(),
5291                                     token.getParameterTokens().get(index).getModifiers()));
5292                             return new MethodDefinitionAdapter(new MethodDescription.Token(token.getName(),
5293                                     token.getModifiers(),
5294                                     token.getTypeVariableTokens(),
5295                                     token.getReturnType(),
5296                                     parameterTokens,
5297                                     token.getExceptionTypes(),
5298                                     token.getAnnotations(),
5299                                     token.getDefaultValue(),
5300                                     token.getReceiverType())).new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
5301                         }
5302
5303                         @Override
5304                         protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
5305                                                                   MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5306                                                                   Transformer<MethodDescription> transformer) {
5307                             return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
5308                         }
5309
5310                         @Override
5311                         protected Builder<U> materialize() {
5312                             return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withMethod(token),
5313                                     fieldRegistry,
5314                                     methodRegistry.prepend(new LatentMatcher.ForMethodToken(token),
5315                                             handler,
5316                                             methodAttributeAppenderFactory,
5317                                             transformer),
5318                                     recordComponentRegistry,
5319                                     typeAttributeAppender,
5320                                     asmVisitorWrapper,
5321                                     classFileVersion,
5322                                     auxiliaryTypeNamingStrategy,
5323                                     annotationValueFilterFactory,
5324                                     annotationRetention,
5325                                     implementationContextFactory,
5326                                     methodGraphCompiler,
5327                                     typeValidation,
5328                                     visibilityBridgeStrategy,
5329                                     classWriterStrategy,
5330                                     ignoredMethods,
5331                                     auxiliaryTypes);
5332                         }
5333                     }
5334                 }
5335
5336                 /**
5337                  * An adapter for matching an existing method.
5338                  */

5339                 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5340                 protected class MethodMatchAdapter extends MethodDefinition.ImplementationDefinition.AbstractBase<U> {
5341
5342                     /**
5343                      * The method matcher of this adapter.
5344                      */

5345                     private final LatentMatcher<? super MethodDescription> matcher;
5346
5347                     /**
5348                      * Creates a new method match adapter.
5349                      *
5350                      * @param matcher The method matcher of this adapter.
5351                      */

5352                     protected MethodMatchAdapter(LatentMatcher<? super MethodDescription> matcher) {
5353                         this.matcher = matcher;
5354                     }
5355
5356                     /**
5357                      * {@inheritDoc}
5358                      */

5359                     public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
5360                         return materialize(new MethodRegistry.Handler.ForImplementation(implementation));
5361                     }
5362
5363                     /**
5364                      * {@inheritDoc}
5365                      */

5366                     public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
5367                         return materialize(MethodRegistry.Handler.ForAbstractMethod.INSTANCE);
5368                     }
5369
5370                     /**
5371                      * {@inheritDoc}
5372                      */

5373                     public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
5374                         return materialize(new MethodRegistry.Handler.ForAnnotationValue(annotationValue));
5375                     }
5376
5377                     /**
5378                      * Materializes the method definition with the supplied handler.
5379                      *
5380                      * @param handler The handler that implements any method matched by this instances matcher.
5381                      * @return A method definition where any matched method is implemented by the supplied handler.
5382                      */

5383                     private MethodDefinition.ReceiverTypeDefinition<U> materialize(MethodRegistry.Handler handler) {
5384                         return new AnnotationAdapter(handler);
5385                     }
5386
5387                     /**
5388                      * An annotation adapter for implementing annotations during a method definition.
5389                      */

5390                     @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5391                     protected class AnnotationAdapter extends MethodDefinition.AbstractBase.Adapter<U> {
5392
5393                         /**
5394                          * Creates a new annotation adapter.
5395                          *
5396                          * @param handler The handler that determines how a method is implemented.
5397                          */

5398                         protected AnnotationAdapter(MethodRegistry.Handler handler) {
5399                             this(handler, MethodAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<MethodDescription>make());
5400                         }
5401
5402                         /**
5403                          * Creates a new annotation adapter.
5404                          *
5405                          * @param handler                        The handler that determines how a method is implemented.
5406                          * @param methodAttributeAppenderFactory The method attribute appender factory to apply onto the method that is currently being implemented.
5407                          * @param transformer                    The method transformer to apply onto the method that is currently being implemented.
5408                          */

5409                         protected AnnotationAdapter(MethodRegistry.Handler handler,
5410                                                     MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5411                                                     Transformer<MethodDescription> transformer) {
5412                             super(handler, methodAttributeAppenderFactory, transformer);
5413                         }
5414
5415                         /**
5416                          * {@inheritDoc}
5417                          */

5418                         public MethodDefinition<U> receiverType(TypeDescription.Generic receiverType) {
5419                             return new AnnotationAdapter(handler,
5420                                     new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.ForReceiverType(receiverType)),
5421                                     transformer);
5422                         }
5423
5424                         /**
5425                          * {@inheritDoc}
5426                          */

5427                         public MethodDefinition<U> annotateMethod(Collection<? extends AnnotationDescription> annotations) {
5428                             return new AnnotationAdapter(handler,
5429                                     new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations))),
5430                                     transformer);
5431                         }
5432
5433                         /**
5434                          * {@inheritDoc}
5435                          */

5436                         public MethodDefinition<U> annotateParameter(int index, Collection<? extends AnnotationDescription> annotations) {
5437                             return new AnnotationAdapter(handler,
5438                                     new MethodAttributeAppender.Factory.Compound(methodAttributeAppenderFactory, new MethodAttributeAppender.Explicit(index, new ArrayList<AnnotationDescription>(annotations))),
5439                                     transformer);
5440                         }
5441
5442                         @Override
5443                         protected MethodDefinition<U> materialize(MethodRegistry.Handler handler,
5444                                                                   MethodAttributeAppender.Factory methodAttributeAppenderFactory,
5445                                                                   Transformer<MethodDescription> transformer) {
5446                             return new AnnotationAdapter(handler, methodAttributeAppenderFactory, transformer);
5447                         }
5448
5449                         @Override
5450                         protected Builder<U> materialize() {
5451                             return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
5452                                     fieldRegistry,
5453                                     methodRegistry.prepend(matcher, handler, methodAttributeAppenderFactory, transformer),
5454                                     recordComponentRegistry,
5455                                     typeAttributeAppender,
5456                                     asmVisitorWrapper,
5457                                     classFileVersion,
5458                                     auxiliaryTypeNamingStrategy,
5459                                     annotationValueFilterFactory,
5460                                     annotationRetention,
5461                                     implementationContextFactory,
5462                                     methodGraphCompiler,
5463                                     typeValidation,
5464                                     visibilityBridgeStrategy,
5465                                     classWriterStrategy,
5466                                     ignoredMethods,
5467                                     auxiliaryTypes);
5468                         }
5469                     }
5470                 }
5471
5472                 /**
5473                  * An adapter for optionally matching methods defined by declared interfaces.
5474                  */

5475                 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5476                 protected class OptionalMethodMatchAdapter extends Builder.AbstractBase.Delegator<U> implements MethodDefinition.ImplementationDefinition.Optional<U> {
5477
5478                     /**
5479                      * The interfaces whose methods are optionally matched.
5480                      */

5481                     private final TypeList.Generic interfaces;
5482
5483                     /**
5484                      * Creates a new optional method match adapter.
5485                      *
5486                      * @param interfaces The interfaces whose methods are optionally matched.
5487                      */

5488                     protected OptionalMethodMatchAdapter(TypeList.Generic interfaces) {
5489                         this.interfaces = interfaces;
5490                     }
5491
5492                     @Override
5493                     protected Builder<U> materialize() {
5494                         return Adapter.this.materialize(instrumentedType.withInterfaces(interfaces),
5495                                 fieldRegistry,
5496                                 methodRegistry,
5497                                 recordComponentRegistry,
5498                                 typeAttributeAppender,
5499                                 asmVisitorWrapper,
5500                                 classFileVersion,
5501                                 auxiliaryTypeNamingStrategy,
5502                                 annotationValueFilterFactory,
5503                                 annotationRetention,
5504                                 implementationContextFactory,
5505                                 methodGraphCompiler,
5506                                 typeValidation,
5507                                 visibilityBridgeStrategy,
5508                                 classWriterStrategy,
5509                                 ignoredMethods,
5510                                 auxiliaryTypes);
5511                     }
5512
5513                     /**
5514                      * {@inheritDoc}
5515                      */

5516                     public MethodDefinition.ReceiverTypeDefinition<U> intercept(Implementation implementation) {
5517                         return interfaceType().intercept(implementation);
5518                     }
5519
5520                     /**
5521                      * {@inheritDoc}
5522                      */

5523                     public MethodDefinition.ReceiverTypeDefinition<U> withoutCode() {
5524                         return interfaceType().withoutCode();
5525                     }
5526
5527                     /**
5528                      * {@inheritDoc}
5529                      */

5530                     public MethodDefinition.ReceiverTypeDefinition<U> defaultValue(AnnotationValue<?, ?> annotationValue) {
5531                         return interfaceType().defaultValue(annotationValue);
5532                     }
5533
5534                     /**
5535                      * {@inheritDoc}
5536                      */

5537                     public <V> MethodDefinition.ReceiverTypeDefinition<U> defaultValue(V value, Class<? extends V> type) {
5538                         return interfaceType().defaultValue(value, type);
5539                     }
5540
5541                     /**
5542                      * Returns a matcher for the interfaces' methods.
5543                      *
5544                      * @return A matcher for the interfaces' methods.
5545                      */

5546                     private MethodDefinition.ImplementationDefinition<U> interfaceType() {
5547                         ElementMatcher.Junction<TypeDescription> elementMatcher = none();
5548                         for (TypeDescription typeDescription : interfaces.asErasures()) {
5549                             elementMatcher = elementMatcher.or(isSuperTypeOf(typeDescription));
5550                         }
5551                         return materialize().invokable(isDeclaredBy(isInterface().and(elementMatcher)));
5552                     }
5553                 }
5554
5555                 /**
5556                  * An adapter for defining a record component.
5557                  */

5558                 @HashCodeAndEqualsPlugin.Enhance(includeSyntheticFields = true)
5559                 protected class RecordComponentDefinitionAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
5560
5561                     /**
5562                      * The record component attribute appender factory to apply.
5563                      */

5564                     private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
5565
5566                     /**
5567                      * A token representing the defined record component.
5568                      */

5569                     private final RecordComponentDescription.Token token;
5570
5571                     /**
5572                      * A transformer to apply on matched record component descriptions.
5573                      */

5574                     private final Transformer<RecordComponentDescription> transformer;
5575
5576                     /**
5577                      * Creates a new record component definition adapter.
5578                      *
5579                      * @param token A token representing the defined record component.
5580                      */

5581                     protected RecordComponentDefinitionAdapter(RecordComponentDescription.Token token) {
5582                         this(RecordComponentAttributeAppender.ForInstrumentedRecordComponent.INSTANCE,
5583                                 Transformer.NoOp.<RecordComponentDescription>make(),
5584                                 token);
5585                     }
5586
5587                     /**
5588                      * Creates a new record component definition adapter.
5589                      *
5590                      * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
5591                      * @param transformer                             A transformer to apply on matched record component descriptions.
5592                      * @param token                                   A token representing the defined record component.
5593                      */

5594                     protected RecordComponentDefinitionAdapter(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
5595                                                                Transformer<RecordComponentDescription> transformer,
5596                                                                RecordComponentDescription.Token token) {
5597                         this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
5598                         this.transformer = transformer;
5599                         this.token = token;
5600                     }
5601
5602                     /**
5603                      * {@inheritDoc}
5604                      */

5605                     public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
5606                         return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory, transformer, new RecordComponentDescription.Token(token.getName(),
5607                                 token.getType(),
5608                                 CompoundList.of(token.getAnnotations(), new ArrayList<AnnotationDescription>(annotations))));
5609                     }
5610
5611                     /**
5612                      * {@inheritDoc}
5613                      */

5614                     public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
5615                         return new RecordComponentDefinitionAdapter(new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
5616                                 recordComponentAttributeAppenderFactory), transformer, token);
5617                     }
5618
5619                     /**
5620                      * {@inheritDoc}
5621                      */

5622                     @SuppressWarnings("unchecked"// In absence of @SafeVarargs
5623                     public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
5624                         return new RecordComponentDefinitionAdapter(recordComponentAttributeAppenderFactory,
5625                                 new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer),
5626                                 token);
5627                     }
5628
5629                     @Override
5630                     protected Builder<U> materialize() {
5631                         return Builder.AbstractBase.Adapter.this.materialize(instrumentedType.withRecordComponent(token),
5632                                 fieldRegistry,
5633                                 methodRegistry,
5634                                 recordComponentRegistry.prepend(new LatentMatcher.ForRecordComponentToken(token),
5635                                         recordComponentAttributeAppenderFactory,
5636                                         transformer),
5637                                 typeAttributeAppender,
5638                                 asmVisitorWrapper,
5639                                 classFileVersion,
5640                                 auxiliaryTypeNamingStrategy,
5641                                 annotationValueFilterFactory,
5642                                 annotationRetention,
5643                                 implementationContextFactory,
5644                                 methodGraphCompiler,
5645                                 typeValidation,
5646                                 visibilityBridgeStrategy,
5647                                 classWriterStrategy,
5648                                 ignoredMethods,
5649                                 auxiliaryTypes);
5650                     }
5651                 }
5652
5653                 /**
5654                  * An adapter for matching record components.
5655                  */

5656                 protected class RecordComponentMatchAdapter extends RecordComponentDefinition.Optional.AbstractBase<U> {
5657
5658                     /**
5659                      * The matcher for identifying record components to match.
5660                      */

5661                     private final LatentMatcher<? super RecordComponentDescription> matcher;
5662
5663                     /**
5664                      * The record component attribute appender factory to apply.
5665                      */

5666                     private final RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory;
5667
5668                     /**
5669                      * A transformer to apply on matched record component descriptions.
5670                      */

5671                     private final Transformer<RecordComponentDescription> transformer;
5672
5673                     /**
5674                      * Creates a new record component match adapter.
5675                      *
5676                      * @param matcher The matcher for identifying record components to match.
5677                      */

5678                     protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher) {
5679                         this(matcher, RecordComponentAttributeAppender.NoOp.INSTANCE, Transformer.NoOp.<RecordComponentDescription>make());
5680                     }
5681
5682                     /**
5683                      * Creates a new record component match adapter.
5684                      *
5685                      * @param matcher                                 The matcher for identifying record components to match.
5686                      * @param recordComponentAttributeAppenderFactory The record component attribute appender factory to apply.
5687                      * @param transformer                             A transformer to apply on matched record component descriptions.
5688                      */

5689                     protected RecordComponentMatchAdapter(LatentMatcher<? super RecordComponentDescription> matcher,
5690                                                           RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory,
5691                                                           Transformer<RecordComponentDescription> transformer) {
5692                         this.matcher = matcher;
5693                         this.recordComponentAttributeAppenderFactory = recordComponentAttributeAppenderFactory;
5694                         this.transformer = transformer;
5695                     }
5696
5697                     /**
5698                      * {@inheritDoc}
5699                      */

5700                     public Optional<U> annotateRecordComponent(Collection<? extends AnnotationDescription> annotations) {
5701                         return attribute(new RecordComponentAttributeAppender.Explicit(new ArrayList<AnnotationDescription>(annotations)));
5702                     }
5703
5704                     /**
5705                      * {@inheritDoc}
5706                      */

5707                     public Optional<U> attribute(RecordComponentAttributeAppender.Factory recordComponentAttributeAppenderFactory) {
5708                         return new RecordComponentMatchAdapter(matcher, new RecordComponentAttributeAppender.Factory.Compound(this.recordComponentAttributeAppenderFactory,
5709                                 recordComponentAttributeAppenderFactory), transformer);
5710                     }
5711
5712                     /**
5713                      * {@inheritDoc}
5714                      */

5715                     @SuppressWarnings("unchecked")  // In absence of @SafeVarargs
5716                     public Optional<U> transform(Transformer<RecordComponentDescription> transformer) {
5717                         return new RecordComponentMatchAdapter(matcher,
5718                                 recordComponentAttributeAppenderFactory,
5719                                 new Transformer.Compound<RecordComponentDescription>(this.transformer, transformer));
5720                     }
5721
5722                     @Override
5723                     protected Builder<U> materialize() {
5724                         return Builder.AbstractBase.Adapter.this.materialize(instrumentedType,
5725                                 fieldRegistry,
5726                                 methodRegistry,
5727                                 recordComponentRegistry.prepend(matcher, recordComponentAttributeAppenderFactory, transformer),
5728                                 typeAttributeAppender,
5729                                 asmVisitorWrapper,
5730                                 classFileVersion,
5731                                 auxiliaryTypeNamingStrategy,
5732                                 annotationValueFilterFactory,
5733                                 annotationRetention,
5734                                 implementationContextFactory,
5735                                 methodGraphCompiler,
5736                                 typeValidation,
5737                                 visibilityBridgeStrategy,
5738                                 classWriterStrategy,
5739                                 ignoredMethods,
5740                                 auxiliaryTypes);
5741                     }
5742                 }
5743             }
5744         }
5745     }
5746
5747     /**
5748      * A dynamic type that has not yet been loaded by a given {@link java.lang.ClassLoader}.
5749      *
5750      * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
5751      *            type itself, an interface or the direct super class.
5752      */

5753     interface Unloaded<T> extends DynamicType {
5754
5755         /**
5756          * <p>
5757          * Attempts to load this dynamic type including all of its auxiliary types, if any. If the class loader is an
5758          * unsealed instance of {@link InjectionClassLoader}, the classes are injected directy into the class loader, otherwise,
5759          * a new class loader is created where the supplied class loader is set as parent.
5760          * </p>
5761          * <p>
5762          * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
5763          * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
5764          * </p>
5765          *
5766          * @param classLoader The class loader to use for this class loading.
5767          * @return This dynamic type in its loaded state.
5768          */

5769         Loaded<T> load(ClassLoader classLoader);
5770
5771         /**
5772          * <p>
5773          * Attempts to load this dynamic type including all of its auxiliary types, if any.
5774          * </p>
5775          * <p>
5776          * <b>Note</b>: A new class is attempted to be loaded each time this method is invoked, even if a compatible class was
5777          * created previously. Consider using a {@link net.bytebuddy.TypeCache}.
5778          * </p>
5779          *
5780          * @param classLoader          The class loader to use for this class loading.
5781          * @param classLoadingStrategy The class loader strategy which should be used for this class loading.
5782          * @param <S>                  The least specific type of class loader this strategy can apply to.
5783          * @return This dynamic type in its loaded state.
5784          * @see net.bytebuddy.dynamic.loading.ClassLoadingStrategy.Default
5785          */

5786         <S extends ClassLoader> Loaded<T> load(S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy);
5787
5788         /**
5789          * Includes the provided dynamic types as auxiliary types of this instance.
5790          *
5791          * @param dynamicType The dynamic types to include.
5792          * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
5793          */

5794         Unloaded<T> include(DynamicType... dynamicType);
5795
5796         /**
5797          * Includes the provided dynamic types as auxiliary types of this instance.
5798          *
5799          * @param dynamicTypes The dynamic types to include.
5800          * @return A copy of this unloaded dynamic type which includes the provided dynamic types.
5801          */

5802         Unloaded<T> include(List<? extends DynamicType> dynamicTypes);
5803     }
5804
5805     /**
5806      * A dynamic type that has been loaded into the running instance of the Java virtual machine.
5807      *
5808      * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
5809      *            type itself, an interface or the direct super class.
5810      */

5811     interface Loaded<T> extends DynamicType {
5812
5813         /**
5814          * Returns the loaded main class.
5815          *
5816          * @return A loaded class representation of this dynamic type.
5817          */

5818         Class<? extends T> getLoaded();
5819
5820         /**
5821          * <p>
5822          * Returns a map of all loaded auxiliary types to this dynamic type.
5823          * </p>
5824          * <p>
5825          * <b>Note</b>: The type descriptions will most likely differ from the binary representation of this type.
5826          * Normally, annotations and intercepted methods are not added to the type descriptions of auxiliary types.
5827          * </p>
5828          *
5829          * @return A mapping from the fully qualified names of all auxiliary types to their loaded class representations.
5830          */

5831         Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes();
5832     }
5833
5834     /**
5835      * A default implementation of a dynamic type.
5836      */

5837     @HashCodeAndEqualsPlugin.Enhance
5838     class Default implements DynamicType {
5839
5840         /**
5841          * The file name extension for Java class files.
5842          */

5843         private static final String CLASS_FILE_EXTENSION = ".class";
5844
5845         /**
5846          * The default version of a jar file manifest.
5847          */

5848         private static final String MANIFEST_VERSION = "1.0";
5849
5850         /**
5851          * The size of a writing buffer.
5852          */

5853         private static final int BUFFER_SIZE = 1024;
5854
5855         /**
5856          * A convenience index for the beginning of an array to improve the readability of the code.
5857          */

5858         private static final int FROM_BEGINNING = 0;
5859
5860         /**
5861          * A convenience representative of an {@link java.io.InputStream}'s end to improve the readability of the code.
5862          */

5863         private static final int END_OF_FILE = -1;
5864
5865         /**
5866          * A suffix for temporary files.
5867          */

5868         private static final String TEMP_SUFFIX = "tmp";
5869
5870         /**
5871          * A dispacher for applying a file copy.
5872          */

5873         protected static final Dispatcher DISPATCHER = AccessController.doPrivileged(Dispatcher.CreationAction.INSTANCE);
5874
5875         /**
5876          * A type description of this dynamic type.
5877          */

5878         protected final TypeDescription typeDescription;
5879
5880         /**
5881          * The byte array representing this dynamic type.
5882          */

5883         protected final byte[] binaryRepresentation;
5884
5885         /**
5886          * The loaded type initializer for this dynamic type.
5887          */

5888         protected final LoadedTypeInitializer loadedTypeInitializer;
5889
5890         /**
5891          * A list of auxiliary types for this dynamic type.
5892          */

5893         protected final List<? extends DynamicType> auxiliaryTypes;
5894
5895         /**
5896          * Creates a new dynamic type.
5897          *
5898          * @param typeDescription       A description of this dynamic type.
5899          * @param binaryRepresentation  A byte array containing the binary representation of this dynamic type. The array must not be modified.
5900          * @param loadedTypeInitializer The loaded type initializer of this dynamic type.
5901          * @param auxiliaryTypes        The auxiliary type required for this dynamic type.
5902          */

5903         @SuppressFBWarnings(value = "EI_EXPOSE_REP2", justification = "The array is not to be modified by contract")
5904         public Default(TypeDescription typeDescription,
5905                        byte[] binaryRepresentation,
5906                        LoadedTypeInitializer loadedTypeInitializer,
5907                        List<? extends DynamicType> auxiliaryTypes) {
5908             this.typeDescription = typeDescription;
5909             this.binaryRepresentation = binaryRepresentation;
5910             this.loadedTypeInitializer = loadedTypeInitializer;
5911             this.auxiliaryTypes = auxiliaryTypes;
5912         }
5913
5914         /**
5915          * {@inheritDoc}
5916          */

5917         public TypeDescription getTypeDescription() {
5918             return typeDescription;
5919         }
5920
5921         /**
5922          * {@inheritDoc}
5923          */

5924         public Map<TypeDescription, byte[]> getAllTypes() {
5925             Map<TypeDescription, byte[]> allTypes = new LinkedHashMap<TypeDescription, byte[]>();
5926             allTypes.put(typeDescription, binaryRepresentation);
5927             for (DynamicType auxiliaryType : auxiliaryTypes) {
5928                 allTypes.putAll(auxiliaryType.getAllTypes());
5929             }
5930             return allTypes;
5931         }
5932
5933         /**
5934          * {@inheritDoc}
5935          */

5936         public Map<TypeDescription, LoadedTypeInitializer> getLoadedTypeInitializers() {
5937             Map<TypeDescription, LoadedTypeInitializer> classLoadingCallbacks = new HashMap<TypeDescription, LoadedTypeInitializer>();
5938             for (DynamicType auxiliaryType : auxiliaryTypes) {
5939                 classLoadingCallbacks.putAll(auxiliaryType.getLoadedTypeInitializers());
5940             }
5941             classLoadingCallbacks.put(typeDescription, loadedTypeInitializer);
5942             return classLoadingCallbacks;
5943         }
5944
5945         /**
5946          * {@inheritDoc}
5947          */

5948         public boolean hasAliveLoadedTypeInitializers() {
5949             for (LoadedTypeInitializer loadedTypeInitializer : getLoadedTypeInitializers().values()) {
5950                 if (loadedTypeInitializer.isAlive()) {
5951                     return true;
5952                 }
5953             }
5954             return false;
5955         }
5956
5957         /**
5958          * {@inheritDoc}
5959          */

5960         @SuppressFBWarnings(value = "EI_EXPOSE_REP", justification = "The array is not to be modified by contract")
5961         public byte[] getBytes() {
5962             return binaryRepresentation;
5963         }
5964
5965         /**
5966          * {@inheritDoc}
5967          */

5968         public Map<TypeDescription, byte[]> getAuxiliaryTypes() {
5969             Map<TypeDescription, byte[]> auxiliaryTypes = new HashMap<TypeDescription, byte[]>();
5970             for (DynamicType auxiliaryType : this.auxiliaryTypes) {
5971                 auxiliaryTypes.put(auxiliaryType.getTypeDescription(), auxiliaryType.getBytes());
5972                 auxiliaryTypes.putAll(auxiliaryType.getAuxiliaryTypes());
5973             }
5974             return auxiliaryTypes;
5975         }
5976
5977         /**
5978          * {@inheritDoc}
5979          */

5980         public Map<TypeDescription, File> saveIn(File folder) throws IOException {
5981             Map<TypeDescription, File> files = new HashMap<TypeDescription, File>();
5982             File target = new File(folder, typeDescription.getName().replace('.', File.separatorChar) + CLASS_FILE_EXTENSION);
5983             if (target.getParentFile() != null && !target.getParentFile().isDirectory() && !target.getParentFile().mkdirs()) {
5984                 throw new IllegalArgumentException("Could not create directory: " + target.getParentFile());
5985             }
5986             OutputStream outputStream = new FileOutputStream(target);
5987             try {
5988                 outputStream.write(binaryRepresentation);
5989             } finally {
5990                 outputStream.close();
5991             }
5992             files.put(typeDescription, target);
5993             for (DynamicType auxiliaryType : auxiliaryTypes) {
5994                 files.putAll(auxiliaryType.saveIn(folder));
5995             }
5996             return files;
5997         }
5998
5999         /**
6000          * {@inheritDoc}
6001          */

6002         public File inject(File sourceJar, File targetJar) throws IOException {
6003             return sourceJar.equals(targetJar)
6004                     ? inject(sourceJar)
6005                     : doInject(sourceJar, targetJar);
6006         }
6007
6008         /**
6009          * {@inheritDoc}
6010          */

6011         public File inject(File jar) throws IOException {
6012             File temporary = doInject(jar, File.createTempFile(jar.getName(), TEMP_SUFFIX));
6013             boolean delete = true;
6014             try {
6015                 delete = DISPATCHER.copy(temporary, jar);
6016             } finally {
6017                 if (delete && !temporary.delete()) {
6018                     temporary.deleteOnExit();
6019                 }
6020             }
6021             return jar;
6022         }
6023
6024         /**
6025          * Injects this dynamic type into a source jar and writes the result to the target jar.
6026          *
6027          * @param sourceJar The source jar.
6028          * @param targetJar The target jar.
6029          * @return The jar file that was written to.
6030          * @throws IOException If an I/O error occurs.
6031          */

6032         private File doInject(File sourceJar, File targetJar) throws IOException {
6033             JarInputStream inputStream = new JarInputStream(new FileInputStream(sourceJar));
6034             try {
6035                 if (!targetJar.isFile() && !targetJar.createNewFile()) {
6036                     throw new IllegalArgumentException("Could not create file: " + targetJar);
6037                 }
6038                 Manifest manifest = inputStream.getManifest();
6039                 JarOutputStream outputStream = manifest == null
6040                         ? new JarOutputStream(new FileOutputStream(targetJar))
6041                         : new JarOutputStream(new FileOutputStream(targetJar), manifest);
6042                 try {
6043                     Map<TypeDescription, byte[]> rawAuxiliaryTypes = getAuxiliaryTypes();
6044                     Map<String, byte[]> files = new HashMap<String, byte[]>();
6045                     for (Map.Entry<TypeDescription, byte[]> entry : rawAuxiliaryTypes.entrySet()) {
6046                         files.put(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION, entry.getValue());
6047                     }
6048                     files.put(typeDescription.getInternalName() + CLASS_FILE_EXTENSION, binaryRepresentation);
6049                     JarEntry jarEntry;
6050                     while ((jarEntry = inputStream.getNextJarEntry()) != null) {
6051                         byte[] replacement = files.remove(jarEntry.getName());
6052                         if (replacement == null) {
6053                             outputStream.putNextEntry(jarEntry);
6054                             byte[] buffer = new byte[BUFFER_SIZE];
6055                             int index;
6056                             while ((index = inputStream.read(buffer)) != END_OF_FILE) {
6057                                 outputStream.write(buffer, FROM_BEGINNING, index);
6058                             }
6059                         } else {
6060                             outputStream.putNextEntry(new JarEntry(jarEntry.getName()));
6061                             outputStream.write(replacement);
6062                         }
6063                         inputStream.closeEntry();
6064                         outputStream.closeEntry();
6065                     }
6066                     for (Map.Entry<String, byte[]> entry : files.entrySet()) {
6067                         outputStream.putNextEntry(new JarEntry(entry.getKey()));
6068                         outputStream.write(entry.getValue());
6069                         outputStream.closeEntry();
6070                     }
6071                 } finally {
6072                     outputStream.close();
6073                 }
6074             } finally {
6075                 inputStream.close();
6076             }
6077             return targetJar;
6078         }
6079
6080         /**
6081          * {@inheritDoc}
6082          */

6083         public File toJar(File file) throws IOException {
6084             Manifest manifest = new Manifest();
6085             manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, MANIFEST_VERSION);
6086             return toJar(file, manifest);
6087         }
6088
6089         /**
6090          * {@inheritDoc}
6091          */

6092         public File toJar(File file, Manifest manifest) throws IOException {
6093             if (!file.isFile() && !file.createNewFile()) {
6094                 throw new IllegalArgumentException("Could not create file: " + file);
6095             }
6096             JarOutputStream outputStream = new JarOutputStream(new FileOutputStream(file), manifest);
6097             try {
6098                 for (Map.Entry<TypeDescription, byte[]> entry : getAuxiliaryTypes().entrySet()) {
6099                     outputStream.putNextEntry(new JarEntry(entry.getKey().getInternalName() + CLASS_FILE_EXTENSION));
6100                     outputStream.write(entry.getValue());
6101                     outputStream.closeEntry();
6102                 }
6103                 outputStream.putNextEntry(new JarEntry(typeDescription.getInternalName() + CLASS_FILE_EXTENSION));
6104                 outputStream.write(binaryRepresentation);
6105                 outputStream.closeEntry();
6106             } finally {
6107                 outputStream.close();
6108             }
6109             return file;
6110         }
6111
6112         /**
6113          * A dispatcher that allows for file copy operations based on NIO2 if available.
6114          */

6115         protected interface Dispatcher {
6116
6117             /**
6118              * Copies the source file to the target location.
6119              *
6120              * @param source The source file.
6121              * @param target The target file.
6122              * @return {@code trueif the source file needs to be deleted.
6123              * @throws IOException If an I/O error occurs.
6124              */

6125             boolean copy(File source, File target) throws IOException;
6126
6127             /**
6128              * An action for creating a dispatcher.
6129              */

6130             enum CreationAction implements PrivilegedAction<Dispatcher> {
6131
6132                 /**
6133                  * The singleton instance.
6134                  */

6135                 INSTANCE;
6136
6137                 /**
6138                  * {@inheritDoc}
6139                  */

6140                 @SuppressWarnings("unchecked")
6141                 public Dispatcher run() {
6142                     try {
6143                         Class<?> path = Class.forName("java.nio.file.Path");
6144                         Object[] arguments = (Object[]) Array.newInstance(Class.forName("java.nio.file.CopyOption"), 1);
6145                         arguments[0] = Enum.valueOf((Class) Class.forName("java.nio.file.StandardCopyOption"), "REPLACE_EXISTING");
6146                         return new ForJava7CapableVm(File.class.getMethod("toPath"),
6147                                 Class.forName("java.nio.file.Files").getMethod("move", path, path, arguments.getClass()),
6148                                 arguments);
6149                     } catch (Throwable ignored) {
6150                         return ForLegacyVm.INSTANCE;
6151                     }
6152                 }
6153             }
6154
6155             /**
6156              * A legacy dispatcher that is not capable of NIO.
6157              */

6158             enum ForLegacyVm implements Dispatcher {
6159
6160                 /**
6161                  * The singleton instance.
6162                  */

6163                 INSTANCE;
6164
6165                 /**
6166                  * {@inheritDoc}
6167                  */

6168                 public boolean copy(File source, File target) throws IOException {
6169                     InputStream inputStream = new FileInputStream(source);
6170                     try {
6171                         OutputStream outputStream = new FileOutputStream(target);
6172                         try {
6173                             byte[] buffer = new byte[BUFFER_SIZE];
6174                             int index;
6175                             while ((index = inputStream.read(buffer)) != END_OF_FILE) {
6176                                 outputStream.write(buffer, FROM_BEGINNING, index);
6177                             }
6178                         } finally {
6179                             outputStream.close();
6180                         }
6181                     } finally {
6182                         inputStream.close();
6183                     }
6184                     return true;
6185                 }
6186             }
6187
6188             /**
6189              * A dispatcher for VMs that are capable of NIO2.
6190              */

6191             @HashCodeAndEqualsPlugin.Enhance
6192             class ForJava7CapableVm implements Dispatcher {
6193
6194                 /**
6195                  * The {@code java.io.File#toPath()} method.
6196                  */

6197                 private final Method toPath;
6198
6199                 /**
6200                  * The {@code java.nio.Files#copy(Path,Path,CopyOption[])} method.
6201                  */

6202                 private final Method move;
6203
6204                 /**
6205                  * The copy options to apply.
6206                  */

6207                 private final Object[] copyOptions;
6208
6209                 /**
6210                  * Creates a new NIO2 capable dispatcher.
6211                  *
6212                  * @param toPath      The {@code java.io.File#toPath()} method.
6213                  * @param move        The {@code java.nio.Files#move(Path,Path,CopyOption[])} method.
6214                  * @param copyOptions The copy options to apply.
6215                  */

6216                 protected ForJava7CapableVm(Method toPath, Method move, Object[] copyOptions) {
6217                     this.toPath = toPath;
6218                     this.move = move;
6219                     this.copyOptions = copyOptions;
6220                 }
6221
6222                 /**
6223                  * {@inheritDoc}
6224                  */

6225                 public boolean copy(File source, File target) throws IOException {
6226                     try {
6227                         move.invoke(null, toPath.invoke(source), toPath.invoke(target), copyOptions);
6228                         return false;
6229                     } catch (IllegalAccessException exception) {
6230                         throw new IllegalStateException("Cannot access NIO file copy", exception);
6231                     } catch (InvocationTargetException exception) {
6232                         Throwable cause = exception.getCause();
6233                         if (cause instanceof IOException) {
6234                             throw (IOException) cause;
6235                         } else {
6236                             throw new IllegalStateException("Cannot execute NIO file copy", cause);
6237                         }
6238                     }
6239                 }
6240             }
6241         }
6242
6243         /**
6244          * A default implementation of an unloaded dynamic type.
6245          *
6246          * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
6247          *            type itself, an interface or the direct super class.
6248          */

6249         @HashCodeAndEqualsPlugin.Enhance
6250         public static class Unloaded<T> extends Default implements DynamicType.Unloaded<T> {
6251
6252             /**
6253              * The type resolution strategy to use for initializing the dynamic type.
6254              */

6255             private final TypeResolutionStrategy.Resolved typeResolutionStrategy;
6256
6257             /**
6258              * Creates a new unloaded representation of a dynamic type.
6259              *
6260              * @param typeDescription        A description of this dynamic type.
6261              * @param binaryRepresentation   An array of byte of the binary representation of this dynamic type.
6262              * @param loadedTypeInitializer  The type initializer of this dynamic type.
6263              * @param auxiliaryTypes         The auxiliary types that are required for this dynamic type.
6264              * @param typeResolutionStrategy The type resolution strategy to use for initializing the dynamic type.
6265              */

6266             public Unloaded(TypeDescription typeDescription,
6267                             byte[] binaryRepresentation,
6268                             LoadedTypeInitializer loadedTypeInitializer,
6269                             List<? extends DynamicType> auxiliaryTypes,
6270                             TypeResolutionStrategy.Resolved typeResolutionStrategy) {
6271                 super(typeDescription, binaryRepresentation, loadedTypeInitializer, auxiliaryTypes);
6272                 this.typeResolutionStrategy = typeResolutionStrategy;
6273             }
6274
6275             /**
6276              * {@inheritDoc}
6277              */

6278             public DynamicType.Loaded<T> load(ClassLoader classLoader) {
6279                 return classLoader instanceof InjectionClassLoader && !((InjectionClassLoader) classLoader).isSealed()
6280                         ? load((InjectionClassLoader) classLoader, InjectionClassLoader.Strategy.INSTANCE)
6281                         : load(classLoader, ClassLoadingStrategy.Default.WRAPPER);
6282             }
6283
6284             /**
6285              * {@inheritDoc}
6286              */

6287             public <S extends ClassLoader> DynamicType.Loaded<T> load(S classLoader, ClassLoadingStrategy<? super S> classLoadingStrategy) {
6288                 return new Default.Loaded<T>(typeDescription,
6289                         binaryRepresentation,
6290                         loadedTypeInitializer,
6291                         auxiliaryTypes,
6292                         typeResolutionStrategy.initialize(this, classLoader, classLoadingStrategy));
6293             }
6294
6295             /**
6296              * {@inheritDoc}
6297              */

6298             public DynamicType.Unloaded<T> include(DynamicType... dynamicType) {
6299                 return include(Arrays.asList(dynamicType));
6300             }
6301
6302             /**
6303              * {@inheritDoc}
6304              */

6305             public DynamicType.Unloaded<T> include(List<? extends DynamicType> dynamicType) {
6306                 return new Default.Unloaded<T>(typeDescription,
6307                         binaryRepresentation,
6308                         loadedTypeInitializer,
6309                         CompoundList.of(auxiliaryTypes, dynamicType),
6310                         typeResolutionStrategy);
6311             }
6312         }
6313
6314         /**
6315          * A default implementation of a loaded dynamic type.
6316          *
6317          * @param <T> The most specific known loaded type that is implemented by this dynamic type, usually the
6318          *            type itself, an interface or the direct super class.
6319          */

6320         @HashCodeAndEqualsPlugin.Enhance
6321         protected static class Loaded<T> extends Default implements DynamicType.Loaded<T> {
6322
6323             /**
6324              * The loaded types for the given loaded dynamic type.
6325              */

6326             private final Map<TypeDescription, Class<?>> loadedTypes;
6327
6328             /**
6329              * Creates a new representation of a loaded dynamic type.
6330              *
6331              * @param typeDescription       A description of this dynamic type.
6332              * @param typeByte              An array of byte of the binary representation of this dynamic type.
6333              * @param loadedTypeInitializer The type initializer of this dynamic type.
6334              * @param auxiliaryTypes        The auxiliary types that are required for this dynamic type.
6335              * @param loadedTypes           A map of loaded types for this dynamic type and all its auxiliary types.
6336              */

6337             protected Loaded(TypeDescription typeDescription,
6338                              byte[] typeByte,
6339                              LoadedTypeInitializer loadedTypeInitializer,
6340                              List<? extends DynamicType> auxiliaryTypes,
6341                              Map<TypeDescription, Class<?>> loadedTypes) {
6342                 super(typeDescription, typeByte, loadedTypeInitializer, auxiliaryTypes);
6343                 this.loadedTypes = loadedTypes;
6344             }
6345
6346             /**
6347              * {@inheritDoc}
6348              */

6349             @SuppressWarnings("unchecked")
6350             public Class<? extends T> getLoaded() {
6351                 return (Class<? extends T>) loadedTypes.get(typeDescription);
6352             }
6353
6354             /**
6355              * {@inheritDoc}
6356              */

6357             public Map<TypeDescription, Class<?>> getLoadedAuxiliaryTypes() {
6358                 Map<TypeDescription, Class<?>> loadedAuxiliaryTypes = new HashMap<TypeDescription, Class<?>>(
6359                         loadedTypes);
6360                 loadedAuxiliaryTypes.remove(typeDescription);
6361                 return loadedAuxiliaryTypes;
6362             }
6363         }
6364     }
6365 }
6366