<!DOCTYPE article PUBLIC "-//NLM//DTD JATS (Z39.96) Journal Archiving and Interchange DTD v1.0 20120330//EN" "JATS-archivearticle1.dtd">
<article xmlns:xlink="http://www.w3.org/1999/xlink">
  <front>
    <journal-meta>
      <journal-title-group>
        <journal-title>Program-
ming Journal 3 (2019) 15. doi:10.22152/programming-journal.org/2019/3/15.
[17] D. Piatov</journal-title>
      </journal-title-group>
    </journal-meta>
    <article-meta>
      <article-id pub-id-type="doi">10.1109/MTD.2012.6225994</article-id>
      <title-group>
        <article-title>Developing and Applying Custom Static Analysis Tools for Industrial Multi-Language Code Bases</article-title>
      </title-group>
      <contrib-group>
        <contrib contrib-type="author">
          <string-name>Dennis R. Dams</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Jeroen Ketema</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Pepijn Kramer</string-name>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Arjan J. Mooij</string-name>
          <xref ref-type="aff" rid="aff0">0</xref>
        </contrib>
        <contrib contrib-type="author">
          <string-name>Andrei Rădulescu</string-name>
          <xref ref-type="aff" rid="aff1">1</xref>
        </contrib>
        <aff id="aff0">
          <label>0</label>
          <institution>ESI (TNO)</institution>
          ,
          <addr-line>Eindhoven</addr-line>
          ,
          <country country="NL">The Netherlands</country>
        </aff>
        <aff id="aff1">
          <label>1</label>
          <institution>Thermo Fisher Scientific</institution>
          ,
          <addr-line>Eindhoven</addr-line>
          ,
          <country country="NL">The Netherlands</country>
        </aff>
      </contrib-group>
      <pub-date>
        <year>2012</year>
      </pub-date>
      <volume>4006</volume>
      <fpage>1</fpage>
      <lpage>6</lpage>
      <abstract>
        <p>Maintaining large, multi-language code bases is challenging because of their size and complexity. Hence, tool support is desirable. Unfortunately, of-the-shelf tools fall short by aiming for genericity instead of exploiting characteristics of the specific code bases and maintenance tasks. Our objective is to support software maintenance by facilitating the development of custom tools for static code analysis. We report on a case study in which we developed and applied a custom static analysis tool to verify 2441 build dependencies between Visual Studio projects with C++ and IDL code.</p>
      </abstract>
    </article-meta>
  </front>
  <body>
    <sec id="sec-1">
      <title>1. Introduction</title>
      <p>Embedded software of advanced industrial products often consists of large, multi-language
code bases that reflect not only the complexity of the product but also the accumulated efect of
decades of development. Maintaining the software is challenging due to its size and complexity.
Empirical evidence [1] also indicates that multi-language software development is problematic
for program understanding.</p>
      <p>Of-the-shelf analysis tools often fall short by aiming for genericity instead of exploiting
characteristics of specific code bases and maintenance tasks. In our experience, customization
is key to getting useful results (cf. [2, 3]). Even general software maintenance tasks may require
custom analysis tools due to the use of technologies that are either developed in-house or do not
come with good tool support. Our objective is to support software maintenance by facilitating
the development of custom tools for static code analysis.</p>
      <p>We present an exploratory case study [4] in which we developed and applied custom static
analysis tools to analyze build dependencies between Visual Studio projects with C++ and IDL
code (see Sect. 3). Initially, we developed the custom tools for a specific code base. Later on, we
investigated the reusability on another code base (see Sect. 6).</p>
      <p>Our analysis is split in a model extraction phase and a model analysis phase (cf. [5]). Our model
(or knowledge base) is represented as a directed graph (cf. [6]), and contains information on
high-level concepts that developers use to reason about their code; lower-level concepts used
by compilers are omitted. Our main contribution is a compositional approach to multi-language
and multi-archive model extraction (see Sects. 4 and 5). The results obtained by applying the
developed custom static analysis tools are presented in Sect. 7.</p>
    </sec>
    <sec id="sec-2">
      <title>2. Preliminaries</title>
      <p>We discuss Visual Studio projects and Microsoft’s Interface Definition Language (IDL), as far as
relevant to our case study.</p>
      <p>Visual Studio Projects Visual Studio projects form the basis of the Visual Studio build system
and contain information on dependencies on other projects, files to compile, libraries to link
against, files that will be generated (source files and binaries), and compiler flags.</p>
      <p>A build dependency occurs when building one project results in the generation of a source
or binary file needed to build another project. When one project has a build dependency on
another, the developer should declare this.</p>
      <p>IDL The Component Object Model (COM) is an interface technology for software
components [7]. To define interfaces, IDL is used. IDL language elements include libraries, which
contain other (non-library) elements, interfaces, which are collections of method signatures,
and coclasses, which are objects implementing interfaces. Libraries, interfaces, and coclasses are
identified by UUIDs (Universally Unique IDentifiers). IDL also has a cpp_quote construct that
allows for inserting C++ code fragments into the C++ files generated from the IDL files.</p>
      <p>Given an IDL file, the Microsoft IDL compiler (MIDL) generates both C++ files and a type
library binary (TLB). TLBs can be imported in C++ and IDL files via, respectively, the #import
and importlib statements. When the C++ compiler encounters a #import, it generates a type
library header (TLH) based on the imported TLB and #includes that header for further processing.
Fig. 1 depicts the interplay.</p>
    </sec>
    <sec id="sec-3">
      <title>3. Industrial Application: Motivation</title>
      <p>Our use case was driven by a desire for software architectural improvements and removing
technical debt. Architectural improvements are an enabler for incremental and distributed
builds, assuming correctly specified dependencies. Dependencies can be incorrectly specified in
one of two ways [8]:
• under-declared dependencies are needed but undeclared dependencies, and may lead to
builds that fail occasionally due to missing files (depending on the build order);
• over-declared dependencies are unneeded but declared dependencies, and may restrict
the build order unnecessarily, reducing build performance, or may prohibit the build
altogether (due to dependency cycles).</p>
      <p>Verification of dependencies can be time-consuming [ 9]. Several tools exist that visualize
dependencies between Visual Studio projects [10, 11, 12, 13], but these do not verify correctness.
Analysis To verify correctness, we need to compare declared and actual build dependencies.
To identify actual dependencies, we look for evidence. A build dependency between two projects
is evidenced by a file that is generated by one project, and used by another project. In turn, the
need for a file is induced by another kind of dependency, which can also be over- or
underdeclared. This latter dependency is evidenced by element usage: a dependency on a file is only
needed when an element defined in the file is used. Thus, we desire checking the consistency
between declared build dependencies, used files, and used elements.</p>
      <p>Knowledge Base To perform the analysis, our knowledge base will need to contain several
types of relations. Some of these can be extracted from project files, e.g., build dependency
declarations, or files needed, compiled, and generated. Other relations can be extracted from
C++ and IDL files, e.g., #include/#import relations, or the definition and use of elements. Hence,
we need to handle multiple languages and combine information from various build stages.</p>
    </sec>
    <sec id="sec-4">
      <title>4. Compositional Model Extraction</title>
      <p>We next describe our compositional approach to multi-language and multi-archive model
– or knowledge base – extraction, as summarized in Fig. 2. Each extraction block in the
ifgure represents an extraction for a single language applied to a single archive. Merge Graphs
and Semantic Linking integrate the results step-wise into a knowledge base. Finally, Finalize
represents a finalization step that removes information that is used during integration, but is
unneeded otherwise.</p>
      <p>Single Languages and Archives At the single language and single archive level, we extract
information from each individual file. As seen in Fig. 2, some of the extraction blocks also yield
information that is fed into other extraction blocks, e.g., Extract Project yields a list of C++ and
IDL files that is used to drive the extraction in Extract C++ and Extract IDL.</p>
      <p>Multiple Languages and Archives Merge Graphs takes the (non-disjoint) union of the
graphs extracted during the earlier stages, while Semantic Linking adds cross-language edges
(cf. [14]). The cross-language edges represent the higher-level relations that developers use
to reason about their code. For example, relations between uses in C++ files – via TLBs or
generated C++ files – of elements whose definitions find their origin in IDL files (see Fig. 1).
Finalization Extraction also yields information that is used for integration but not needed
for our maintenance task. When integration has been completed, finalization removes the
additional information, which ensures we do not have to deal with it during analysis. For
example, some links to C++ files generated from IDL files are removed, which are no longer
needed, as links to the IDL files have been added.</p>
      <p>As mentioned, we remove information from the knowledge base that is not needed for our
maintenance task. This means, e.g., that we do not include full parse trees in our knowledge
base, as they contain a lot of information that we generally do not need. We also take an iterative
approach with regard to deciding what information to include in the knowledge base, as we
generally do not know beforehand what information is needed for our maintenance task.</p>
    </sec>
    <sec id="sec-5">
      <title>5. Model Extraction Challenges</title>
      <p>Our main observation is that it is non-trivial to get the extraction details right, mostly due
to information originating from diferent sources. However, we did notice that imperfect
approximations can already provide useful information that is not easily available otherwise.</p>
      <p>Developing custom tools is both a challenge and relief. It is a challenge when trying to cover
everything in full generality. It is a relief, as the customized context does not always require
full generality, and provides opportunities to exploit specific knowledge of the considered code.</p>
      <sec id="sec-5-1">
        <title>5.1. Finding Appropriate Parsers</title>
        <sec id="sec-5-1-1">
          <title>We discuss some specific concerns regarding parsing.</title>
          <p>C++ Although commercial C++ parsers exists, we cannot readily experiment with them.
Furthermore, open source parsers usually do not handle all C++ dialects we encounter. For this
reason we select a parser with good error recovery, like Eclipse CDT [15]. This parser is also
used by [16, 2, 17], and, additionally, ofers reference resolving [17].</p>
          <p>Visual Studio Projects We initially developed our own parser. As project interpretation
turned out to be dificult, we migrated to the APIs ofered by MSBuild (the tool driving the build
in Visual Studio). Although our custom parser was instrumental in moving forward during the
early stages of our case study, we consider the use of MSBuild to be preferred.
IDL No open source parser exists that can parse IDL. Hence, we wrote our own. What makes
extraction from IDL tricky is the cpp_quote construct (see Sect. 2). In our case, the use of
cpp_quote was limited to constant definitions, where it was desired to link the definitions with
their uses in C++ code.</p>
        </sec>
      </sec>
      <sec id="sec-5-2">
        <title>5.2. Unique Naming Schemes</title>
        <p>As our knowledge base is a flat graph, we have to uniquely name nodes. A proper naming
scheme also simplifies merging multiple graphs. Our scheme is based on the following, where
names are prefixed with a node type to avoid name clashes between elements with identical
names (such as archives and symbols, or C++ definitions and their (forward) declarations):
• file paths relative to the root of the archive (e.g., for files);
• names (e.g., for archives, symbols);
• UUIDs (e.g., for IDL interfaces, coclasses, libraries);
• hierarchical names relative to files (e.g., for C++ elements, IDL data types);
• hierarchical names relative to UUIDs (e.g., for IDL data types);
The scheme is stable under small changes of the code base, which is convenient when continuing
or rerunning an analysis after updating the extracted models. Stability is also useful for assessing
code changes by comparing the graphs extracted before and after changes.</p>
      </sec>
      <sec id="sec-5-3">
        <title>5.3. Binary File Formats</title>
        <p>
          To extract information from (generated) binary files (such as TLBs), we can either (
          <xref ref-type="bibr" rid="ref1">1</xref>
          ) decompile
the binary, (
          <xref ref-type="bibr" rid="ref2">2</xref>
          ) use available APIs to read the binary, (
          <xref ref-type="bibr" rid="ref3">3</xref>
          ) use textual artifacts derived from the
binary during compilation, or (
          <xref ref-type="bibr" rid="ref4">4</xref>
          ) use the source code from which the binary was constructed.
        </p>
        <p>We use the third approach for TLBs imported in C++. To this end, we first build the considered
archive, generating all TLHs (see Fig. 1), and then run our extraction on the TLHs.</p>
        <p>We use the fourth approach for TLBs imported in IDL files, as no textual artifact are generated.
The sources of the TLBs may become available when extracting other archives. Hence, we store
extra information on IDL files and element uses, which is removed during finalization.</p>
      </sec>
      <sec id="sec-5-4">
        <title>5.4. Dealing with the Preprocessor</title>
        <p>
          To be able to properly parse C++ and IDL files, the C/C++ preprocessor needs to process the
ifles. The result of preprocessing may depend on compiler settings. Even for a simple analysis
question such as showing the #include relations between files, we can either (
          <xref ref-type="bibr" rid="ref1">1</xref>
          ) analyze the
code for a specific build configuration, or (
          <xref ref-type="bibr" rid="ref2">2</xref>
          ) analyze the code for all build configurations. We
use the first option, as it provides enough information for our maintenance task.
        </p>
        <p>Applying the preprocessor may expand simple, well-recognizable macros into complicated
code fragments. This may confuse developers, as they often reason about macros as they do
about functions. Hence, we include macro definitions and all references to them in our model.</p>
      </sec>
    </sec>
    <sec id="sec-6">
      <title>6. Model Extraction Reusability</title>
      <p>As mentioned in Sect. 5, customized model extraction provides opportunities to avoid hard
problems. However, this may complicate reuse. To evaluate this, we applied our model extraction
tool to a Visual Studio code base from a diferent company. We discuss the observed diferences.
Insight in these helps to separate generic and specific aspects of the extraction.
Build Infrastructure Both code bases have their own custom build infrastructure on top of
Visual Studio projects. The configuration files from these infrastructures are easy to parse, but
specific to the code base.</p>
      <p>File Locations The code bases use diferent conventions for the folders containing files shared
between projects and archives. However, in the case of sharing between archives we do observe
that the shared files always live in the same folder relative to the root of the archive, which
means that multi-archive merging can be kept generic.</p>
      <p>Code Patterns The code bases use COM diferently in relation to the two paths through the
middle layer of Fig. 1, which we both support:
• each IDL file is compiled by one project, which generates a TLB that can be imported by
other projects;
• each project that wants to use a IDL element from a given IDL file compiles that IDL file.</p>
      <p>In the case of cpp_quote, the code bases use slightly diferent patterns to define constants.
These are typically generic, but occasionally depend on code base-specific macros.</p>
    </sec>
    <sec id="sec-7">
      <title>7. Industrial Application: Results</title>
      <p>We describe the model analysis phase and the results obtained for the case from Sect. 3. We
illustrate the general line of the analysis and do not aim to be complete. We focus on the part of
the knowledge base represented by the schema of Fig. 3, where projects  are related by:
• ProjectDependsOn(, ):  declares a build dependency on project ;
• MidlGenerates(,  ):  invokes the MIDL compiler generating a TLB or C++ file  ;
• Compiles(,  ):  compiles file  .</p>
      <sec id="sec-7-1">
        <title>The other relations relate to IDL and C++ files  : • Includes(, ):  #includes an IDL or C++ file ; • Imports(, ):  #imports a TLB ;</title>
        <p>• Defines (, ):  defines an IDL element ;
• Uses(, ):  uses an IDL element .</p>
        <p>The relations can be combined via composition (;), inversion (− 1), reflexive closure ( ?), and
reflexive, transitive closure ( * ).</p>
        <sec id="sec-7-1-1">
          <title>7.1. Verification Rules for Dependencies</title>
          <p>Like [8], we first consider under-declared dependencies. Unlike [ 8], we distinguish file- and
element-level analyses.</p>
        </sec>
        <sec id="sec-7-1-2">
          <title>Declared Dependencies vs. File References Declared build dependencies should be con</title>
          <p>sistent with file references, which requires relating projects  with generated files  :</p>
          <p>MidlReferences(,  ) = ∃.MidlGenerates(,  ) ∧ (Compiles; Includes* ; Imports?)(,  )</p>
        </sec>
      </sec>
      <sec id="sec-7-2">
        <title>Consistency can now be expressed as an inference rule:</title>
      </sec>
      <sec id="sec-7-3">
        <title>MidlReferences(,  ) MidlGenerates(,  )</title>
        <p>ProjectDependsOn(, )
To detect under-declared dependencies we read the rule top-down, i.e., if we find a MidlReferences
and MidlGenerates pair, we expect a ProjectDependsOn. To detect over-declared dependencies
we read the rule bottom-up. This latter reading is also used to establish evidence for a declared
dependency.</p>
        <p>File References vs. Element References File references should be consistent with element
references. This requires relating IDL elements  to projects  and files  :</p>
        <p>ProjectUses(, ) = (Compiles; Includes* ; Uses)(, )</p>
        <p>MidlDefines (, ) = (MidlGenerates− 1; Compiles; Includes* ; Defines )(, )
When a project declares a dependency on a MIDL-generated file, it is expected that some file
from the project uses an IDL element from the generated file. This is captured by:</p>
      </sec>
      <sec id="sec-7-4">
        <title>ProjectUses(, ) MidlDefines (, ) MidlReferences(,  )</title>
      </sec>
      <sec id="sec-7-5">
        <title>We can relate declared build dependencies and element references as</title>
        <p>An under-declared dependency evidenced by this rule is shown in Fig. 4, where  and  are
linked via  and , but where no ProjectDependsOn edge exists. An over-declared dependency
may, e.g., be the result of a developer not removing a project dependency after having removed
the use of an IDL element.</p>
        <sec id="sec-7-5-1">
          <title>7.2. Implementation and Results</title>
          <p>Based on the above rules and several others, we developed Depanneur, a tool for analyzing build
dependencies. The tool queries the graph created during model extraction, and produces both
textual output and pictures like the one in Fig. 4.</p>
          <p>The code base we considered consists of about 1080 Visual Studio projects with 2441 build
dependency declarations (before any fixes). Depanneur reports 498 under-declared
dependencies via MIDL-generated files. This relatively high number may point to over-declared
MidlReferences, where no elements are actually used. We corrected all under-declared
dependencies by adding them using a custom tool.</p>
          <p>As noted by [8], the removal of over-declarations is best done after fixing under-declarations
to avoid a temporary increase of build failures. Depanneur reports 622 over-declarations. Based
on our discussions with the developers, these indeed seem to be over-declarations.</p>
        </sec>
      </sec>
    </sec>
    <sec id="sec-8">
      <title>8. Related Work</title>
      <p>Overviews of static analysis techniques for multi-language code bases can be found in [14, 18].
A generic approach to cross-language analysis and refactoring is described in [14]; as in our case,
language-specific meta-models are used. Our extraction approach resembles that of [ 19] for
ifnding JNI dependencies between Java and C/C++. First, languages are treated independently;
only later is integration considered.</p>
      <p>An overview of dependency analysis techniques can be found in [9]. Some more recent
approaches are [20, 21, 8, 22].</p>
      <p>The Bauhaus Tool Suite [23] focuses on typical kinds of program analyses and reverse
engineering, with professional services for customer-specific tailoring of the analyses. Our
focus is fully on customizability using open source tools.</p>
    </sec>
    <sec id="sec-9">
      <title>9. Conclusions</title>
      <p>
        We presented a case study around the industrial challenge of build dependencies. As no
of-theshelf analysis tools were available, we proposed to develop and apply custom tools. To facilitate
the development of custom tools, our approach is three-fold: (
        <xref ref-type="bibr" rid="ref1">1</xref>
        ) compositional model extraction
to handle multi-language and multi-archive code bases, (
        <xref ref-type="bibr" rid="ref2">2</xref>
        ) exploiting specific characteristics of
code bases, and (
        <xref ref-type="bibr" rid="ref3">3</xref>
        ) graph-based analysis.
      </p>
    </sec>
    <sec id="sec-10">
      <title>Acknowledgments</title>
      <p>The authors wish to thank Piërre van de Laar from ESI (TNO) for valuable feedback.</p>
      <p>The research was carried out as part of the Renaissance program under the responsibility of ESI
(TNO) with Thermo Fisher Scientific as the carrying industrial partner. The Renaissance program
was supported by the Netherlands Ministry of Economic Afairs (Toeslag voor Topconsortia
voor Kennis en Innovatie).</p>
    </sec>
  </body>
  <back>
    <ref-list>
      <ref id="ref1">
        <mixed-citation>
          [1]
          <string-name>
            <given-names>P.</given-names>
            <surname>Mayer</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Kirsch</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M. A.</given-names>
            <surname>Le</surname>
          </string-name>
          ,
          <article-title>On multi-language software development, cross-language links and accompanying tools: a survey of professional software developers</article-title>
          ,
          <source>J. Software Eng. R&amp;D</source>
          <volume>5</volume>
          (
          <year>2017</year>
          )
          <article-title>1</article-title>
          . doi:
          <volume>10</volume>
          .1186/s40411-017-0035-z.
        </mixed-citation>
      </ref>
      <ref id="ref2">
        <mixed-citation>
          [2]
          <string-name>
            <given-names>D.</given-names>
            <surname>Dams</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A. J.</given-names>
            <surname>Mooij</surname>
          </string-name>
          ,
          <string-name>
            <given-names>P.</given-names>
            <surname>Kramer</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Radulescu</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Vanhara</surname>
          </string-name>
          ,
          <article-title>Model-based software restructuring: Lessons from cleaning up COM interfaces in industrial legacy code</article-title>
          ,
          <source>in: 25th International Conference on Software Analysis, Evolution and Reengineering</source>
          ,
          <string-name>
            <surname>SANER</surname>
          </string-name>
          <year>2018</year>
          ,
          <year>2018</year>
          , pp.
          <fpage>552</fpage>
          -
          <lpage>556</lpage>
          . doi:
          <volume>10</volume>
          .1109/SANER.
          <year>2018</year>
          .
          <volume>8330258</volume>
          .
        </mixed-citation>
      </ref>
      <ref id="ref3">
        <mixed-citation>
          [3]
          <string-name>
            <given-names>E.</given-names>
            <surname>Hajiyev</surname>
          </string-name>
          ,
          <string-name>
            <given-names>M.</given-names>
            <surname>Verbaere</surname>
          </string-name>
          , O. de Moor, codeQuest:
          <article-title>Scalable source code queries with datalog</article-title>
          ,
          <source>in: 20th European Conference on Object-Oriented Programming, ECOOP</source>
          <year>2006</year>
          , volume
          <volume>4067</volume>
          <source>of LNCS</source>
          ,
          <year>2006</year>
          , pp.
          <fpage>2</fpage>
          -
          <lpage>27</lpage>
          . doi:
          <volume>10</volume>
          .1007/11785477_2.
        </mixed-citation>
      </ref>
      <ref id="ref4">
        <mixed-citation>
          [4]
          <string-name>
            <given-names>S.</given-names>
            <surname>Easterbrook</surname>
          </string-name>
          ,
          <string-name>
            <given-names>J.</given-names>
            <surname>Singer</surname>
          </string-name>
          , M.
          <article-title>-</article-title>
          <string-name>
            <surname>A. Storey</surname>
            ,
            <given-names>D.</given-names>
          </string-name>
          <string-name>
            <surname>Damian</surname>
          </string-name>
          ,
          <article-title>Selecting empirical methods for software engineering research</article-title>
          , in: Guide to Advanced Empirical Software Engineering, Springer,
          <year>2008</year>
          , pp.
          <fpage>285</fpage>
          -
          <lpage>311</lpage>
          .
        </mixed-citation>
      </ref>
      <ref id="ref5">
        <mixed-citation>
          [5]
          <string-name>
            <given-names>Y.</given-names>
            <surname>Zhao</surname>
          </string-name>
          ,
          <string-name>
            <given-names>G.</given-names>
            <surname>Chen</surname>
          </string-name>
          ,
          <string-name>
            <given-names>C.</given-names>
            <surname>Liao</surname>
          </string-name>
          ,
          <string-name>
            <given-names>X.</given-names>
            <surname>Shen</surname>
          </string-name>
          ,
          <article-title>Towards ontology-based program analysis</article-title>
          ,
          <source>in: 30th European Conference on Object-Oriented Programming, ECOOP</source>
          <year>2016</year>
          , volume
          <volume>56</volume>
          of LIPIcs,
          <year>2016</year>
          , pp.
          <volume>26</volume>
          :
          <fpage>1</fpage>
          -
          <lpage>26</lpage>
          :
          <fpage>25</fpage>
          . doi:
          <volume>10</volume>
          .4230/LIPIcs.ECOOP.
          <year>2016</year>
          .
          <volume>26</volume>
          .
        </mixed-citation>
      </ref>
      <ref id="ref6">
        <mixed-citation>
          [6]
          <string-name>
            <given-names>J.</given-names>
            <surname>Ebert</surname>
          </string-name>
          ,
          <string-name>
            <given-names>V.</given-names>
            <surname>Riediger</surname>
          </string-name>
          ,
          <string-name>
            <given-names>A.</given-names>
            <surname>Winter</surname>
          </string-name>
          ,
          <article-title>Graph technology in reverse engineering: The TGraph approach</article-title>
          , in: 10th Workshop Software Reengineering,
          <string-name>
            <surname>WSR</surname>
          </string-name>
          <year>2008</year>
          , volume
          <volume>126</volume>
          <source>of LNI</source>
          ,
          <year>2008</year>
          , pp.
          <fpage>67</fpage>
          -
          <lpage>81</lpage>
          . URL: http://subs.emis.de/LNI/Proceedings/Proceedings126/article2088.html.
        </mixed-citation>
      </ref>
      <ref id="ref7">
        <mixed-citation>
          [7]
          <string-name>
            <given-names>D.</given-names>
            <surname>Box</surname>
          </string-name>
          ,
          <string-name>
            <surname>Essential</surname>
            <given-names>COM</given-names>
          </string-name>
          ,
          <string-name>
            <surname>Addison-Wesley Professional</surname>
          </string-name>
          ,
          <year>1998</year>
          .
        </mixed-citation>
      </ref>
    </ref-list>
  </back>
</article>