An Annotations-Based API For Supporting Runtime Code Annotation Reading
An Annotations-Based API For Supporting Runtime Code Annotation Reading
6
Meta’17, October 22, 2017, Vancouver, Canada P. Lima et al.
7
An Annotation-Based API for Supporting Runtime Code... Meta’17, October 22, 2017, Vancouver, Canada
API for individual metadata retrieval, and a Mapping API the API implementation should verify if it is present
to retrieve metadata into a Metadata Container [11], follow- in its class;
ing the pattern presented in section 2. Also, the annotation • @SearchOnAbstractions - This annotation configures
schema from the API itself can be extended. If the framework when an annotation can be defined in abstractions,
needs to retrieve a metadata from the class that is not sup- such as superclasses and interfaces3 . When an annota-
ported by the native API annotations, new metadata reading tion with this configuration is searched in types, the
APIs might be defined. API implementation should verify its superclasses and
The Simple API has methods that are equivalent to the interfaces. When it is searched on a method, it should
Java current API, which retrieves annotations from single search on a method that it overrides from the super-
elements. The difference is that it takes in consideration class or that it implements in interfaces.
configurations that can indicate that the target annotation Those configurations can be freely combined. For instance,
might be defined in other elements. These configurations are for an annotation with @SearchOnAbstractions and @Sea-
detailed in subsection 3.1. The Mapping API retrieves infor- rchInsideAnnotations, it can be defined in an abstraction
mation from an annotation schema and populates a metadata and inside other annotations. That means that for a given
container instance with them. The class AnnotationReader class, this annotation could be found inside another annota-
has a method called readingAnnotationsTo() that receives tion which is defined in its superclass.
as parameters the class with the annotations that should be The API defines an extension point that allows the in-
read and the class that represents the metadata container. troduction of new strategies to locate metadata. That could
Fig. 2 presents examples from both approaches. be used, for instance, to define code conventions that can
be an alternative to annotations for metadata representa-
//Simple API usage tion. In order to define a new metadata search annotation, it
List<Annotation> annotList = AnnotationFinder.findAnnotation should receive the annotation @Locator with the class that
(codeElement, MyAnnotation.class); implements the interface MetadataLocator.
//Mapping API usage
AnnotationReader annotationReader = new AnnotationReader();
MetadataContainer container = annotationReader 3.2 Mapping Simple Metadata
.readingAnnotationsTo(AnnotatedClass.class, The class that represents a metadata container should have
MetadataContainer.class);
annotations to map the class metadata to its attributes. This
subsection presents the fundamental annotations of the API,
Figure 2. Simple and Mapping API usage. that maps information that can be directly retrieved from
the target element. It is important to highlight that all anno-
To use the mapping API the metadata container class tations for metadata search presented in subsection 3.1 are
should contain annotations that maps each of its attributes considered for the mapping.
to meta-information that should be retrieved from the target The initial configuration that a metadata container needs
class. The subsections 3.2, 3.3 and 3.4 detail the mapping to have is the @ContainerFor annotation. It defines the kind
annotations. of code element that this container is for. The allowed values
are TYPE (for classes, interfaces, enums and annotations),
3.1 Metadata Search METHOD, FIELD or ALL (if all kinds of elements are allowed).
Fig. 3 presents the example of a class with a simple mapping.
There are several patterns where annotations can be defined
outside the target element, like on the enclosing code element @ContainerFor(ContainerTarget.TYPE)
or inside other annotations. Because of that, the API provides public class ContainerClass {
a way to configure an annotation about the places where it @ElementName private String elementName;
@ContainsAnnotation(Element.class) private boolean element;
can be defined. The following are the annotations provided @ReflectionReference private Class<?> clazz;
by the API that can be added in the annotation definition to @AnnotationProperty(annotation = Table.class,
enable its search in other places: property ="value")
private String tableName;
• @SearchInsideAnnotations - This annotation con- }
figures when an annotation can be defined inside an-
other one. When an annotation with this configuration Figure 3. Example of an annotated metadata container.
is searched, the API implementation should look for it
inside each of the target element annotations; The attributes can receive annotations that maps them
• @SearchOnEnclosingElements - This annotation con- to information on the target class metadata. They can refer
figures when an annotation can be defined in the scope 3 Theannotation @Inherited from the regular Java API configures that an
of its enclosing element. When an annotation with this annotation defined in a class is inherited by its subclasses. However, it does
configuration is searched in a method, if not found, not work on methods and for implemented interfaces.
8
Meta’17, October 22, 2017, Vancouver, Canada P. Lima et al.
to intrinsic reflective metadata, such as element name, or that previously needed to be manually implemented by the
to custom metadata on annotations. Table 1 presents the framework. Each new annotation introduced should be asso-
descriptions of the annotations used on the code example in ciated with a class responsible for its interpretation. What
Fig. 3. should be added in the metadata container is the metadata
processor that results from the execution of the annotation
Table 1. Simple API Annotations reading method for the custom annotation.
Fig. 5 presents an example of a mapping of metadata
Annotation Description processors. The attribute from the @CustomReader anno-
@ElementName Receives the name of the target code element. tation receives the class from the annotation used to con-
Maps to a boolean value that states if the figure the delegate metadata reader. In another words, in
@ContainsAnnotation
annotation is present or not. the given example, the API implementation should search in
Receives the instance from the Reflection the target element for annotations that are annotated with
@ReflectionReference
API that represents the target code element. @ReaderConfigAnnotation. The presence of this annota-
@AnnotationProperty Receives the value of an annotation property. tion is used to configure that it is a custom annotation from
the framework.
9
An Annotation-Based API for Supporting Runtime Code... Meta’17, October 22, 2017, Vancouver, Canada
10
Meta’17, October 22, 2017, Vancouver, Canada P. Lima et al.
according to the defined constraints. It is important to high- of an existing software, the proposed API also aims to be
light that Esfinge Metadata uses itself to read its own an- introduced in the beginning of the framework development.
notations and create its own container. In other words, the
same classes that use Esfinge Metadata to create and store 5.1 Study Design
the metadata containers from other frameworks are used The case study focuses on answering the following research
to do the same for the framework itself. Due to this fact, question: How does the refactoring performed with the
MetadataExecute invokes MetadataRepository to retrieve proposed API impact the internal structure of the target
the metadata reading container. framework?
The class MetadataContainer is the Esfinge Metadata After the refactoring process, the automated unit tests
container and is composed by instances of AnnotationRead were executed to guarantee that Esfinge Comparison main-
ingProcessor. All Esfinge annotations that map attributes tained its expected behavior. Different techniques were used
to metadata are associated to a processor. Each processor to assess distinct characteristics from the source code of both
implementation uses the class AnnotationFinder, which versions.
uses the metadata locator chain to retrieve the annotations. The following are the approaches that were used in the
Despite the usage of Esfinge Metadata in the case study study: (a) Object-oriented (OO) and annotation metrics: Ex-
presented in section 5, it was also applied in the development traction of metrics from the source code, including size, com-
of a gamification framework [14]. It was also used internally plexity and coupling metrics; (b) Bad smell detection: Ana-
to read the Esfinge Metadata annotations, in other words, it lyze if bad smell instances appeared or were removed from
uses itself to read its own annotations. the source code.
Since both versions of the framework implements the
5 Case Study - Refactoring an Existing same functionalities, we can perform a direct comparison
Framework between them. This allows, for example, to analyze whether
This section discusses the case study used to validate the the code complexity increased or decreased in the refactored
metadata reading API, implemented by Esfinge Metadata. system, without the need for defining thresholds indicating
The framework used for the case study was the Esfinge Com- high/low complexity levels.
parison6 . The initial version of the framework was released 5.2 Framework Refactoring
on 2012 on Sourceforge platform7 , and it is already used in
some real applications currently in production. The refactoring focused on changing the annotation reading
The Esfinge Comparison framework compares two in- class to use EsfingeMetadata for annotation reading. Both
stances of the same class and returns a list with the differ- the original8 and the refactored9 versions are available in
ences between them. It is heavily based on code annotations, GitHub. Table 2 presents a summary of the changes in the
since it allows applications using the framework to config- refactoring. These changes were extracted from the GitHub
ure the comparison algorithm for each class property. For website using the feature to compare versions. Changes in
instance, the framework provides annotations to configure configuration and project files were excluded.
numeric tolerance or a property to be ignored.
Table 2. Changes for refactoring
Esfinge Comparison was chosen for this case study as it is
using patterns for the internal structure of metadata-based
Changes Added Removed Changed
frameworks [11]. It has features to enable the annotation
schema extension, which is specially interesting to evaluate if Classes 4 3 13
the proposed solution supports this appropriately. Its internal Lines of code 317 214 -
design was evaluated as good in a previous study [9] that
focused on the reference architecture it is based on. These The test coverage of the original version measured with
facts support the claim that comparing the refactored version Intellij IDE10 was 83%, and for the refactored version was
of Esfinge Comparison with its previous version can provide 80%. A code inspection was performed in the parts of the
a case study in which it is possible to focus on the impact code not covered by the tests. It was found that most of them
generated by the usage of the proposed API, without the involved default constructors and access methods.
interference of a poor previous design. The greatest difficulty in the mapping of the metadata
The goal of this evaluation is to compare two metadata- container happened when it was necessary to retrieve an in-
based frameworks in which the unique difference is the usage formation from the field type that was not supported by the
of the proposed API. Despite the case study is a refactoring 8 https://github.com/EsfingeFramework/comparison/releases/tag/1.1.
0-SNAPSHOT
6 http://esfinge.sourceforge.net/Comparasion.html - available in portuguese. 9 https://github.com/EsfingeFramework/comparison/releases/tag/1.2.
7 https://sourceforge.net/projects/esfinge/files/Esfinge2/Comparison%201.
0-SNAPSHOT
0/ 10 https://www.jetbrains.com/idea/
11
An Annotation-Based API for Supporting Runtime Code... Meta’17, October 22, 2017, Vancouver, Canada
Table 3. Metrics changes Java Reflection API. The added lines are annotations pro-
vided by the Esfinge Metadata and the imports associated to
Metrics {Original} {Refactored} it.
LOC 703 729 The reduction in CYCLO is explained by the fact that
CYCLO 189 182 several of the new lines of codes are annotations, which are
NOM 104 106 not considered by this metric. The new classes introduced
NOC 35 36 have small methods and their invocation are orchestrated
NOP 8 9 by the proposed API, which eliminates much of the need for
CALL 295 266 conditional expressions. The complexity removed were in
FOUT 36 30 the metadata reading classes, before the refactoring.
Looking at the coupling metrics, both Number of Opera-
tion Calls (CALL) (295 -> 266) and Number of Called Classes
framework. For list comparison, it was necessary to retrieve (FOUT) (36 -> 30) reduced. Annotation reading logic usually
the generic type from the collection, and the framework did is coupled with several other types, specially the ones related
not provide an annotation to map this. The feature for meta- to the annotations that are being retrieved. Inspecting the
data extension was used to create a new custom metadata code searching were there was a reduction in coupling, we
reading annotation called @Associate. Following this ap- confirmed that it happened in the metadata reading classes.
proach it was possible to map the desired information to the The great responsible for this decrease were the removed
metadata container. classes.
The class responsible for metadata reading was removed Despite most of the changes observed in the analysed
from the project, as well as the class Repository, which quality metrics might look minor (e.g., CYCLO going from
cached the metadata container instances relative to classes 189 to 182), it is worth highlighting that the number of classes
in which the annotations were already processed. In the impacted by the refactoring is quite limited (see Table 2).
compare() method, which orchestrates the framework func- Thus, we cannot expect strong changes in the value of the
tionality, a call to the removed classes was replaced to a call considered metrics.
to the AnnotationReader class from Esfinge Metadata. The
framework, based on the annotations added in the metadata 5.4 Bad Smells Elimination
container classes, was able to retrieve the meta-information A bad smell detection analysis was carried out to verify if
from the classes. some bad smell was removed or added by the refactoring.
In conclusion, the API was enough to fulfill the metadata It is important to highlight that bad smells are not neces-
reading requirements for the Esfinge Comparison framework. sarily code bugs, but rather design flaws that might become
The feature for having an extensible metadata schema was troublesome in the long term. The bad smell detection tool
supported by the API standard features. For the retrieve used to perform the anaysis was JSpirit [27]. A total of 16
of a generic type parameter that was not implemented by bad smells were found in the original version and 14 in the
Esfinge Metadata, a new reading annotation was created. refactored version.
That fact presents evidence that the API is flexible enough The refactoring removed two bad smells, one Intensive
for metadata reading requirements that were not directly Coupling and one Dispersed Coupling. This follows what
supported by the implementation. was already observed in the OO metrics, where we found ev-
idence that the coupling has been reduced by the refactoring.
5.3 Object-Oriented This results reinforces what was described in the previous
The analysis was performed based on a suite of object ori- subsection, demonstrating that the cyclomatic complexity is
ented (OO) metrics proposed by [21]. The tool Infusion11 associated to the metadata reading previously performed in
was used to extract the OO metrics. Table 3 presents the the Esfinge Comparison.
modifications.
A first change is an increase on the Lines of Code (LOC) 5.5 Case Study Conclusions
(703 -> 729) and a decrease on the Cyclomatic Complexity This section presents an evaluation of the results facing the
(CYCLO) (189 -> 182). It was expected a reduction in LOC research question How does the refactoring performed
value, since some code regarding metadata reading was re- with the proposed API impact the internal structure of
moved. However, the addition of the API and the need for the target framework?
the framework extension compensated the lines of code re- The proposed API removed the need for the major part of
moved. The removed lines are primarily concerned with the metadata reading logic from the original version. There-
metadata reading, previously done by code relying on the fore we expected a decrease in the LOC value. However, the
lines eliminated in that part were compensated by implemen-
11 currently discontinued tation of a framework extension and to the API annotations
12
Meta’17, October 22, 2017, Vancouver, Canada P. Lima et al.
added in the container class. Also, the API caused a reduction be used by compiler plugins and not by metadata-based
in code coupling. Evidences of this are seen by the decrease frameworks.
of CALL and FOUT metrics, and by the removal of two cou-
pling bad smells.
Metadata reading logic usually needs to be coupled to the 7 Conclusion
annotation types and to the metadata container classes. That This paper presented the proposal of a new API for reading
fact makes this logic sensible to changes on both. The use code annotations. This API is based on documented patterns
of the proposed API exchanged the imperative code that and aims to provide a better support for frameworks to adopt
perform the metadata reading for a declarative mapping and implement such practices. The proposed API is based on
using annotations. metadata mapping, where a class receives annotations that
provide information about what meta-information should be
5.6 Threats to Validity retrieved from the target class and attributed to each field.
The main threat to validity of the results come from the fact The proposed API provides innovative features, such as: (a)
that the case study was conducted based on a single frame- support to search annotations in other code elements related
work. It shows a possible impact that the usage of the pro- to the target code element; (b) mapping for class metadata
posed API, but it cannot be generalized that all frameworks and annotation attributes; (c) chain processing of methods
that adopt the API would have a similar impact. However, and field metadata; (d) support for implementation of an
we can affirm that the reduction in the internal dependencies extensible metadata schema; (e) extension point that allows
found in the results is possible to be achieved. the creation of new metadata reading annotations. Esfinge
To mitigate the impact of using the refactoring of a single Metadata is a framework that implemented the proposed
framework as the case study, a qualitative analysis based API as a way to show the viability of its implementation.
on code inspection was performed. This qualitative analysis A case study was conducted by refactoring an existing
aimed to investigate more deeply the causes of the differ- framework aiming to evaluate the impact in source code
ences between the two versions, understanding in terms of of using the proposed API. The most evident conclusion
software design what happened to impact the metrics. was the reduction in the number of dependencies in compo-
nents that perform metadata reading. This was confirmed
by the reduction in coupling metrics and the elimination of
6 Related Work two coupling bad smells. The new version of the refactored
The metadata-based frameworks widely used by industry framework also has an increase on its number of annotations
still use the standard Java reflection API to retrieve annota- as expected. However, an expected reduction in the number
tions. Despite there are several works that explore the use of of lines of code does not happened, mainly because of an
annotations, we found none that aims to focus on a general extension of the framework that was needed to retrieve a
purpose API for reading annotations in runtime. metadata that was not originally supported by it.
There are some alternative APIs for reflection in Java based As a future work, there are some points in the API that
on the concept of fluent APIs [5]. An example of such im- could be improved in a further version. One of them is the
plementation is Mirror 12 . Despite it gives some support for support for reading metadata defined by other means, such
annotation reading, it still retrieve each annotation individu- as external files and code conventions. Another possibility is
ally. the mapping between equivalent annotations from different
There are some implementations that instead of searching frameworks. Another point to be improved is to investi-
annotations based on the target element, search for classes gate the current structure of existing frameworks to search
with a given annotation. Scannotation 13 and Extensible Com- for additional possibilities on mapping for features that the
ponent Scanner 14 are examples of such solutions. Despite framework currently implements. Another future work will
these solutions can be considered for general purpose, they aim to evaluate the usage of the current API by developers.
focus on searching classes and not on retrieving those classes Some points to be investigated are: (a) How is the impact of
metadata. the API learning curve in development?; (b) Are developers
Checker Framework [3, 22] is a framework for compile more productive by using the API? To investigate this points
time annotation processing. It aims to extend the Java’s type a study involving a controlled experiment might be applied
system using type annotations to enable verifications that or its usage in the development of a new framework could
can detect bugs and bad practices in source code. Despite be investigated.
it can be used for more general purposes, it is designed to
Acknowledgements
12 http://projetos.vidageek.net/mirror/mirror/
13 http://scannotation.sourceforge.net This work is supported by CNPq (grant 445562/2014-5) and
14 http://extcos.sourceforge.net FAPESP (grant 2014/16236-6)
13
An Annotation-Based API for Supporting Runtime Code... Meta’17, October 22, 2017, Vancouver, Canada
References http://dx.doi.org/10.1145/2493288.2493292
[1] J.A. Cassoli. 2016. Web Application with Spring Annotation-Driven [14] Eduardo M. Guerra, Gabriel Fornari, Wanderson S. Costa, Sandy M.
Configuration: Rapidly Develop Lightweight Java Web Applications Us- Porto, Marcos P. L. Candia, and Tiago Silva da Silva. 2017. An
ing Spring with Annotations. CreateSpace Independent Publishing Approach for Modularizing Gamification Concerns. Springer Inter-
Platform. https://books.google.ch/books?id=QsUdvgAACAAJ national Publishing, Cham, 635–651. DOI:http://dx.doi.org/10.1007/
[2] José Lázaro de Siqueira, Fábio Fagundes Silveira, and Eduardo Martins 978-3-319-62404-4_47
Guerra. 2016. An Approach for Code Annotation Validation with Meta- [15] JSR. 2003. JSR 153: Enterprise JavaBeans 2.1. (Aug. 2003). http:
data Location Transparency. Springer International Publishing, Cham, //www.jcp.org/en/jsr/detail?id=153
422–438. DOI:http://dx.doi.org/10.1007/978-3-319-42089-9_30 [16] JSR. 2004. JSR 175: A Metadata Facility for the Java Programming
[3] Werner Dietl, Stephanie Dietzel, Michael D Ernst, Kivanç Muşlu, and Language. (Aug. 2004). http://www.jcp.org/en/jsr/detail?id=175
Todd W Schiller. 2011. Building and using pluggable type-checkers. In [17] JSR. 2013. JSR 338: JavaTM Persistence 2.1. (May 2013). http://www.
Proceedings of the 33rd International Conference on Software Engineering. jcp.org/en/jsr/detail?id=338
ACM, 681–690. [18] JSR. 2013. JSR 344: JavaServerTM Faces 2.2. (May 2013). http://www.
[4] Erick Doernenburg. 2008. Domain annotations. The Thought-Works jcp.org/en/jsr/detail?id=344
[19] JSR. 2017. JSR 365: Contexts and Dependency Injection for JavaTM
Anthology: Essays on Software Technology and Innovation (2008).
2.0. (Jan. 2017). http://www.jcp.org/en/jsr/detail?id=365
[5] Steve Freeman and Nat Pryce. 2006. Evolving an embedded domain-
[20] Jeff Langr, Andy Hunt, and Dave Thomas. 2015. Pragmatic Unit Testing
specific language in Java. In Companion to the 21st ACM SIGPLAN
in Java 8 with JUnit (1st ed.). Pragmatic Bookshelf.
symposium on Object-oriented programming systems, languages, and
[21] Michele Lanza and Radu Marinescu. 2006. Object-oriented metrics in
applications. ACM, 855–865.
practice: using software metrics to characterize, evaluate, and improve
[6] Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides. 1995.
the design of object-oriented systems. Springer.
Design Patterns: Elements of Reusable Object-oriented Software. Addison-
[22] Matthew M Papi, Mahmood Ali, Telmo Luis Correa Jr, Jeff H Perkins,
Wesley Longman Publishing Co., Inc., Boston, MA, USA.
and Michael D Ernst. 2008. Practical pluggable types for Java. In
[7] Eduardo Guerra. 2016. Design Patterns for Annotation-based APIs. In
Proceedings of the 2008 international symposium on Software testing
Proceedings of the 11th Latin American Conference on Pattern Languages
and analysis. ACM, 201–212.
of Programs (SugarLoafPLoP ’16). ACM, New York, NY, USA.
[23] José Perillo, Eduardo Guerra, Jefferson Silva, Fábio Silveira, and Clovis
[8] Eduardo Guerra and Ademar Aguiar. 2014. Support for Refactor-
Fernandes. 2009. Metadata modularization using domain annotations.
ing an Application towards an Adaptive Object Model. Springer In-
In Workshop On Assessment Of Contemporary Modularization Tech-
ternational Publishing, Cham, 73–89. DOI:http://dx.doi.org/10.1007/
niques (ACoM. 09) at OOPSLA, Vol. 3.
978-3-319-09156-3_6
[24] Romain Rouvoy and Philippe Merle. 2006. Leveraging Component-
[9] Eduardo Guerra, Felipe Alves, Uirá Kulesza, and Clovis Fernandes.
Oriented Programming with Attribute-Oriented Programming. In 11th
2013. A Reference Architecture for Organizing the Internal Structure
International ECOOP Workshop on Component-Oriented Programming
of Metadata-based Frameworks. J. Syst. Softw. 86, 5 (May 2013), 1239–
(WCOP’06). 10–18.
1256. DOI:http://dx.doi.org/10.1016/j.jss.2012.12.024
[25] Romain Rouvoy, Nicolas Pessemier, Renaud Pawlak, and Philippe
[10] Eduardo Guerra, Menanes Cardoso, Jefferson Silva, and Clovis Fer-
Merle. 2006. Using Attribute-Oriented Programming to Leverage
nandes. 2010. Idioms for Code Annotations in the Java Language. In
Fractal-Based Developments. In 5th International ECOOP Workshop on
Proceedings of the 8th Latin American Conference on Pattern Languages
the Fractal Component Model (Fractal’06), Nantes, France.
of Programs (SugarLoafPLoP ’10). ACM, New York, NY, USA, Article 7,
[26] Jefferson O. Silva, Eduardo M. Guerra, and Clovis T. Fernandes. 2013.
14 pages. DOI:http://dx.doi.org/10.1145/2581507.2581514
An Extensible and Decoupled Architectural Model for Authorization
[11] Eduardo Guerra, Jerffeson de Souza, and Clovis Fernandes. 2013. Pat-
Frameworks. Springer Berlin Heidelberg, Berlin, Heidelberg, 614–628.
tern Language for the Internal Structure of Metadata-Based Frame-
DOI:http://dx.doi.org/10.1007/978-3-642-39649-6_44
works. Springer Berlin Heidelberg, Berlin, Heidelberg, 55–110. DOI:
[27] S. Vidal, H. Vazquez, J. A. Diaz-Pace, C. Marcos, A. Garcia, and W.
http://dx.doi.org/10.1007/978-3-642-38676-3_3
Oizumi. 2015. JSpIRIT: a flexible tool for the analysis of code smells. In
[12] Eduardo Guerra and Clovis Fernandes. 2013. A Qualitative and Quanti-
2015 34th International Conference of the Chilean Computer Science So-
tative Analysis on Metadata-Based Frameworks Usage. Springer Berlin
ciety (SCCC). 1–6. DOI:http://dx.doi.org/10.1109/SCCC.2015.7416572
Heidelberg, Berlin, Heidelberg, 375–390. DOI:http://dx.doi.org/10.
[28] Hiroshi Wada and Junichi Suzuki. 2005. Modeling turnpike fron-
1007/978-3-642-39643-4_28
tend system: A model-driven development framework leveraging
[13] Eduardo Guerra, Clovis Fernandes, and Fábio Fagundes Silveira. 2010.
UML metamodeling and attribute-oriented programming. Model
Architectural Patterns for Metadata-based Frameworks Usage. In Pro-
Driven Engineering Languages and Systems (2005), 584–600. http:
ceedings of the 17th Conference on Pattern Languages of Programs
//www.springerlink.com/index/l166363337837142.pdf
(PLOP ’10). ACM, New York, NY, USA, Article 4, 25 pages. DOI:
14