社団法人 電子情報通信学会
THE INSTITUTE OF ELECTRONICS,
INFORMATION AND COMMUNICATION ENGINEERS

信学技報
TECHNICAL REPORT OF IEICE.

Token Comparison Approach to Detect Code Clone-related Bugs
YongLee YII† , Yasuhiro HAYASE† , Makoto MATSUSHITA† , and Katsuro INOUE†† Graduate School of Information Science and Technology, Osaka University
1-3 Machikaneyama-cho, Toyonaka, Osaka 560-8531, Japan
E-mail: †{yii,y-hayase,matusita,inoue}@ist.osaka-u.ac.jp
Abstract Large software tends to have a signiﬁcant amount of similar code, commonly known as code clones.
Often the code clones are introduced through copy-and-paste process for code reuse purpose where the pasted code
usually will go through some modiﬁcations such as renaming of identiﬁers and changing of parameters. In this paper,
we propose a method using token comparison approach to detect bugs caused by abovementioned modiﬁcations.
Our method tokenizes detected clones and performs a comparison to ﬁnd out inconsistencies between them. The
inconsistencies are then ranked based on predeﬁned metrics to produce a bug candidate list. We implemented our
method and tested on open source software. Our tool has found real bugs from the test subject. We believe ourtool is suitable to serve the purpose of detecting code clone-related bugs in large software.
Key words Software Maintenance, Inconsistent Change, Code Clone-related Bug
scope, thus produce no warning or syntax error.

1. Introduction

According to [2] [3], unintended inconsistencies similar to

Recent studies [8] [9] show that large software systems con-abovementioned example are actually happened in produc-

tain a signiﬁcant amount of similar code, commonly known

tion systems. In fact, the inconsistency shown in Figure 1 isas code clones or simply clones (hereafter we use them in-detected by our proposed method (which will be describedterchangeably). A pair of similar code fragments is called ain detail later in this paper) in Linux version 2.6.6. This in-clone pair. An equivalence set of a clone relation is called aconsistency was rectiﬁed in later version of Linux; therefore

clone set.

we can conﬁrm that it is a genuine bug.

In many cases, code clones are introduced to the program

Although manual inspection is an eﬀective method to ﬁnd

While this practice canout bugs in programs, it would be too time-consuming andgreatly reduce programming eﬀort by reusing code in fast

impractical for large software system. Jablonski et al. [4] pro-and easy way, it is prone to create bugs.

posed a tool called CReN, which is implemented as a plug-in

through copy-and-paste process.

During code cloning, developer often modiﬁes the pasted

to the integrated development environment (IDE) to trackcode in order to implement the desired functionality, but

copy-and-paste activities and to ensure consistent renaming

sometimes bugs are introduced. One of such modiﬁcationsof identiﬁers. However, CReN is only applicable when coding

is to rename all instances of an identiﬁer in pasted code.

a new program or to add new code to an existing program.

When this modiﬁcation is done manually, there is possibility

In this paper, we propose a method to detect bugs caused

that the renaming is not completely applied to all relevant

by inconsistent change of identiﬁers that exist in production

instances by mistake, therefore introducing unintended in-systems. Our method ﬁrst ﬁnds out inconsistencies between

consistency which is considered as bug to the system.

a pair of code clones based on token comparison. The incon-

Figure 1 shows an example of bug caused by inconsistentsistencies are then going through some metric calculations

renaming of identiﬁer. Code fragments consist of line 1486-

to produce a list of potential bugs. In order to evaluate the1503 and line 1563-1579 are detected as a pair of code clones.

eﬀectiveness of our method, we implemented a tool based on

This clone pair could be the result of copy-and-paste process.

proposed method and ran it on well-known large open source

All variables named rc in pasted code fragment (line 1563-

software.

1579) have to be changed to retval but the one in line 1575

The rest of this paper is organized as follows. Section 2

was left out. In consequence, the system displays wrong er-

describes the proposed method in detail, and Section 3 gives

ror code. This bug cannot be detected by compiler since thethe implementation details of our method. Section 4 ex-variable rc in pasted code fragment is still within the valid

plains the experiments that we performed and their results.
—1—

File: Linux−2.6.6/drivers/pci/hotplug/shpchp_ctrl.c1486: rc = p_slot−>hpc_ops−>slot_enable(p_slot);1487:
1488: if (rc) {1489: err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
1490: /* Done with exclusive hardware access */1491: up(&ctrl−>crit_sect);1492: return rc;
1493: }
1494: /* Wait for the command to complete */1495: wait_for_ctrl_irq (ctrl);
1496:
1497: rc = p_slot−>hpc_ops−>check_cmd_status(ctrl);
1498: if (rc) {1499: err("%s: Failed to enable slot, error code(%d)\n", __FUNCTION__, rc);
1500: /* Done with exclusive hardware access */1501: up(&ctrl−>crit_sect);1502: return rc;
1503: }......
1563: retval = p_slot−>hpc_ops−>slot_disable(p_slot);
1564: if (retval) {1565: err("%s: Issue of Slot Enable command failed\n", __FUNCTION__);
1566: /* Done with exclusive hardware access */1567: up(&ctrl−>crit_sect);1568: return retval;
should be changed to1569: }
retval1570: /* Wait for the command to complete */1571: wait_for_ctrl_irq (ctrl);
1572:
1573: retval = p_slot−>hpc_ops−>check_cmd_status(ctrl);
1574: if (retval) {1575: err("%s: Failed to disable slot, error code(%d)\n", __FUNCTION__, rc);
1576: /* Done with exclusive hardware access */1577: up(&ctrl−>crit_sect);1578: return retval;
1579: }

Figure 1 Bug Caused by Inconsistent Renaming of Identiﬁer

127: o_count = v_count;
128: o_var = varse;
129: o_names = v_names;
130:
131: v_count += STORE_INCR;
132: varse = (char **) malloc (v_count*sizeof(char *));
133: v_names = (char **) malloc (v_count*sizeof(char *));
134:
135: for (indx = 3; indx < o_count; indx++)
135: varse[indx] = o_var[indx];
137:
138: for (; indx < v_count; indx++)
139: varse[indx] = NULL;......
161: o_count = a_count;
162: o_ary = arrays;
163: o_names = a_names;
164:
165: a_count += STORE_INCR;
166: arrays = (char **) malloc (a_count*sizeof(char *));
167: a_names = (char **) malloc (a_count*sizeof(char *));
168:
169: for (indx = 1; indx < o_count; indx++)
170: varse[indx] = o_ary[indx];
171:
172: for (; indx < v_count; indx++)
173: lists[indx] = NULL;

Figure 2 Example of Code Clones

step. Code clones that exist in target software are divided
into tokens according to lexical rules of the programming

Section 5 discusses issues related to our method and somelanguage and each of these code clones will form a token se-

related work. Finally in Section 6, we oﬀer our conclusions

quence. While lexical analyzer scans through the code clones,

and recommendations for future work.

it tokenizes them and identiﬁes tokens made up by identiﬁer.
Comments and white spaces are eliminated, giving a normal-

2. Methodology

ized token sequence.

In this section, we will describe our approach aimed to

In a clone pair, if one code fragment is an exact copy with-

detect bugs caused by inconsistent change of identiﬁers inout modiﬁcation of another, or only variable, type or func-

detail.

tion identiﬁers were changed, the resulting normalized token

Figure 3 gives an overview of our approach. The initial

sequences will have the same number of tokens with identi-

input to the approach is source ﬁles and the ﬁnal output willﬁer at the same position (i.e. same token index). Tokenized

be a bug candidate list which gives the details such as lo-

clone pairs that fulﬁll this criteria will be selected for further

cation of potential bugs. The approach is generally divided

processing in next step.

into clone detection phase and inconsistency detection phase.

2. 2 Mapping Analysis

The inconsistency detection phase can be further divided into

In this step, mapping of identiﬁers in each clone pair is

3 steps, namely lexical analysis, mapping analysis and result

carried out. The clone pairs are in the form of token se-ﬁltering.

quences which are the output of lexical analysis step. Each

We use a token-based clone detection tool, CCFinder [1]identiﬁer in a code fragment is mapped to the identiﬁer at

in clone detection phase. The reasons of choosing CCFinder

the same position in another code fragment within a pair ofand other details of clone detection phase will be given incode clones.

section 3. We explain the 3 steps in inconsistency detection
phase below.

If the instances of an identiﬁer in one code fragment arerenamed to more than one identiﬁer names, or not all in-

2. 1 Lexical Analysis

stances of an identiﬁer is renamed, inconsistencies are said

The general goal of lexical analysis in our approach is toto be occurred. For each unique identiﬁer in a code fragment,

transform the code clones detected in clone detection phase
into structure that afterward fed into the mapping analysis

the mapping is performed and its result is stored.
Table 1 shows one of such mapping results using the example shown in Figure 2. All identiﬁers exist in code fragment—2—Figure 3 Overview of Proposed Bug Detection Method

1 (line 127-139) are renamed consistently or remained thesame in code fragment 2 (line 161-173) except v count andvarse. There is one of the instances of v count (underlinedin Figure 2) is left unchanged in fragment 2. On the other
hand, instances of varse (italicized in Figure 2) are changed

Table 1 Identiﬁer Mapping Result for Clone Pair in Figure 2
Identiﬁers in

Identiﬁers in

Code Fragment 1 Code Fragment 2 Occurrence(line 127-139)(line 161-173)

indx

indx

8

mallocmalloc2

to 2 diﬀerent identiﬁer names, arrays and lists, while one iso counto count2

left unchanged. Inconsistencies are said to be occurred ino nameo name1

this 2 cases.

o var

o ary

2

v count

a count

4v count

1v namev name2

varse

arrays

2

lists

1

varse

1

STORE INCR

1

2. 3 Result Filtering
Inconsistencies detected from the identiﬁer mapping result are not necessary the case of unintended inconsistency
resulted from developer’s careless mistakes. In other words,
these inconsistencies are not always bugs. Therefore, theyneed to go through some ﬁltering algorithm in order to pro-STORE INCR

duce a list of potential bugs with less false positives. In our
approach, we use 2 metrics to serve the ﬁltering purpose.
The ﬁrst metric is UnchangedRatio as proposed in [2]. It
is deﬁned as
UnchangedRatio(v) =will be ﬁltered out from bug candidate list. Since the original code fragment in a clone pair cannot be determined,
UnchangedRatio has to be calculated in both directions.

NumOfUnchangedID(v)TotalNumOfID(v)Referring to Table 1, 4 instances of v count are changed toa count in Fragment 2 while one instance is remained in the

For identiﬁer v, NumOfUnchangedID is the number of oc-

same name, result in UnchangedRatio(v count) = 0.2. Sim-currences of v in code fragment f2 where its name is remain

ilarly, 3 instances of varse are changed to arrays and lists

unchanged as compared to identiﬁer at the same position

while one instance is left unchanged, result in Unchange-

in code fragment f1 . TotalNumOfID is the total number ofdRatio(varse) = 0.25.

occurrences of v in f1 . f1 and f2 form a clone pair.

We propose another metric called Conﬂict to complement

When UnchangedRatio equals to 0, it means all instances

UnchangedRatio since UnchangedRatio does not provide anyof an identiﬁer are being renamed. In contrast, when Un-

information if the instances of an identiﬁer is changed to mul-changedRatio equals to 1, it means all instances of an identi-

tiple names. When the instances of an identiﬁer is changed

ﬁer are remained in the same name. It is believed that if an

to multiple names, Conﬂict is set to true. In Table 1, varse

identiﬁer is renamed in most of its instances and only a few

is one of such examples. In this case, the possibility that theof its instances are not renamed, there is high possibility that

instances of an identiﬁer are changed to multiple names in-developer forgets to change them. Therefore, the smaller thetentionally to implement the functionality is high. We ﬁlter

value of UnchangedRatio (except zero), the higher the possi-

out this kind of inconsistencies even though their Unchange-

bility of the not renamed identiﬁer to be a bug. Inconsisten-dRatio are below threshold value.

cies with the value of UnchangedRatio above the threshold—3—

3. Implementation
We have implemented a tool based on the proposed
method. The system takes raw source ﬁles as input andproduces a bug candidate list displayed on a graphical userinterface as output. This section gives the details related toour implementation.
3. 1 Code Clone Detection and Filtering
Code clone detection is an important step since code clone
is the input to our approach. Therefore, the eﬀectiveness ofclone detection aﬀects the result. There are plenty of toolsthat available for clone detection [1] [8] [10]. Among them, we

Figure 4 Snapshot of System’s Graphical Interface

have chosen CCFinder to perform the clone detection task
in our approach. CCFinder is a token-based clone detection

Repeated code sequence is the repetition of its adjacent code

tool which oﬀer good scalability and execution time to copesequence and non-repeated code sequence is the other parts.

with large software. This tool is very eﬀective in ﬁnding ex-

The lower the value of RNR(S ), the more repeated code

actly identical clones and clones with only modiﬁcation insequences in clone set S. In our experiment, we set the RNR

identiﬁers.

value to 0.5, ﬁltering out clone set with the value less than

One of the factors that aﬀects the output of CCFinder isthe minimum length of code clone. The lower the number,the more code clones will be found. In our experiments, we
set the minimum length of a code clone to 30 tokens. This
number was used in numerous previous researches [11] [12] on
CCFinder and gave positive results.
CCFinder identiﬁes a large amount of code clones, whichsome of them are deemed insigniﬁcant to our bug detection
method. Therefore, it is important to ﬁlter the raw output
of CCFinder and select only good candidate clones as the input to our proposed method. We applied the following two
techniques to ﬁlter code clones detected by CCFinder andconducted experiments (details in section 4. 2) to evaluate
their eﬀectiveness.

0.5 from the input to our method. This is the value proposedin [5].
（ 2 ） Removing Overlapping Clones

Among the clones detected by CCFinder, we discovered a
lot of overlapping clones where a portion of code fragments
in a clone pair overlap each other. Overlapping clones do
not represent the nature of copy-and-paste process and mostprobably created coincidently. Since our method is basedon the assumption of copy-paste-modify mechanism, overlapping clones are deemed insigniﬁcant to our method andneed to be ﬁltered out.
3. 2 Graphical User Interface
Since our proposed method will produce a list of potential bugs for inspection, it is important to provides necessary（ 1 ） Removing Highly Repeated Code Sequence

Clonesinformation presented in decent way to ease the developers
carry out this job. We built a graphical user interface to

There is a large portion of code clones detected by
CCFinder consists of consecutive variable declarations andconsecutive method invocations. These kinds of clones aremainly due to the structure of programming language andmany of them are stereotyped code which is very stable. We
ﬁlter out these kinds of clones using a metric called RNR(S )that represent the ratio of non-repeated code sequence inclone set S [5].

browse bug candidate list. A screen shot of the interface isshown in Figure 4.
The top left frame of the interface is a bug candidate list
which can be sorted by the value of UnchangedRatio. One
can start the inspection by looking at the most suspicious
case (i.e identiﬁers with small value of UnchangedRatio).
When clicking on an item in bug candidate list, the mapping
result of selected identiﬁer will be displayed on the bottom

Let clone set S consists of n fragments, f1 , f2 , …, fn .
LOSwhole (fi ) represents the Length Of whole Sequence offragment fi , and LOSrepeated (fi ) represents the Length Of

left frame. At the same time, the 2 frames on the right will
display the related source ﬁles. Code clones where the selected identiﬁer resided in are highlighted in the source ﬁles.

repeated Sequence of fragment fi , RNR(S ) is deﬁned asn∑

RNR(S) = 1 −4. Experiments
LOSrepeated (fi )In this section, we will describe the details of experiments

i=1
n

∑

LOSwhole (fi )that we have carried out with the tool implemented based

i=1

—4—

Table 2 Number of Code Clones in Linux 2.6.6# Without # Filtered
ModuleFilteringwith RNR
linux-2.6.6/arch

102,539

17,085linux-2.6.6/drivers

159,764

44,881on the proposed method. The main purpose of experiments

Table 4 Number of Bug Candidates in Linux 2.6.6
Module# FileTotal# Bug Total LOC

LOC

Candi- Suspicous
date

linux-2.6.6/arch

2,355

724,858

87

1,615

linux-2.6.6/drivers

2,323 2,344,594

120

3,637

Table 5 Genuine Bugs Found in Linux 2.6.6

is to evaluate the eﬀectiveness of our tool to detect real bugs
in software systems.
We have chosen Linux version 2.6.6, which consist of 6,491

ClonesFile Path

File
Line

Identiﬁer../arch/m68k/mac/iop.c

264

IOP NUM SCC

ﬁles and 4,364,540 lines of code as our experiment subject.

../arch/sparc/prom/memory.c

159prom phys total

We chose Linux because it is a well-known large scale pro-../arch/sparc64/prom/memory.c

117

prom phys total

duction system, therefore we can test the capability of our../drivers/pci/hotplug/shpchp ctrl.c 1575 rc

tool to cope with large software system.
For the experiment results, we concentrate the discussion
on 2 of the largest modules of Linux, arch and drivers.

4. 3 Bugs Detection
The number of bug candidates found in Linux 2.6.6 is

4. 1 Experiment Parameters

shown in Table 4. We have detected 87 bug candidates in

There are several parameters that will aﬀect the experi-arch module and 120 in drivers module.

ment results. The following describes each of them and the

If a clone pair contains a bug candidate, we call it suspi-

value we set in our experiment.

cious clone pair. Adding up the lines of code (LOC) of all（ 1 ） Threshold Value for UnchangedRatio

suspicious clone pairs gives total LOC of suspicious clones.

As mentioned in Section 2. 3, a non-zero or non-one value

Sometimes a clone pair can contain more than 1 bug candi-

for UnchangedRatio indicates inconsistent change of identi-

date. In that case, we only add once when calculating theﬁers. When using this metric to narrow down the bug candi-

total LOC of suspicious clones. In both arch and drivers

dates, we are based on the idea that the developer intents tomodules, the total LOC of suspicious clones occupies lesschanged all instances of an identiﬁer consistently to anotherthan 0.1% of the total LOC. This gives a rough ﬁgure on

name but left out some of them . As such, smaller value ofthe total number of lines that we need to review. In reality,

UnchangedRatio (except zero) better reveal a potential bug.

we might need to review more code in order to verify a bug

In our experiments, we set the value of UnchangedRatio tocandidate, but it serve as a good start especially to detect

0.4, same to the value used in [2].

bugs in a millions-line-of-code software.

（ 2 ） Conﬂict Setting

One of the major tasks in our result analysis is to verify

We can specify the degree we tolerate inconsistency by

the bug candidates detected by our tool. We have inspected

determine how many diﬀerent names an identiﬁer can be

the bug candidates in arch and drivers modules. Some ofchanged to. In our experiment, if an identiﬁer is changed tothe bug candidates are in high possibility. We checked them

2 diﬀerent names or above, Conﬂict is set to true and it willagainst Linux change log and later version of Linux. As abe ﬁltered out.

result, we were able to verify some of them to be the genuine

4. 2 Code Clones Filtering
Table 2 shows the diﬀerence of the number of code clones
detected by CCFinder from our test subject, Linux 2.6.6 be-bugs. Table 5 gives some instances of veriﬁed bug.

5. Discussion and Related Work

fore and after applying RNR ﬁltering method. On the other5. 1 Limitation of Tool

hand, Table 3 gives the number of clone pairs after we took

Our tool currently cannot handle gapped clone that is cre-out the overlapped clones. The diﬀerence becomes obvious

ated when a copy-and-paste code fragment gone throughafter we applied the RNR ﬁltering.

modiﬁcations such as insertion and deletion of statements.

The ﬁltering can be set to on or oﬀ in the experiment.

Gapped clones should be inspected as well since they also

We have conducted experiments both with and without thehave the possibility of containing inconsistent renaming bugs.

ﬁltering and we found that the ﬁltering techniques greatly re-

The greatest barrier for our current implementation to han-duce our investigation eﬀort by reducing the number of bug

dle gapped clones is on the mapping analysis. Our method

candidates created by insigniﬁcant clones. Therefore, we ap-

still lack of comprehensive algorithm to correctly map theplied these ﬁltering techniques when running our experimentidentiﬁers in gapped clone. This gives a space for our tool towith Linux 2.6.6.

be improved.

—5—

Table 3 Number of Clone Pairs in Linux 2.6.6
Before RNR Filtering

ModuleAfter RNR FilteringWith Overlapping Clone Without Overlapping Clone With Overlapping Clone Without Overlapping Clone
linux-2.6.6/arch

16,740,180

14,977,660

23,59919,273linux-2.6.6/drivers

8,325,367

7,888,115

60,70656,2605. 2 Related Work
Li et al. [2] have developed a tool called CP-Miner to detect copy-and-paste related bugs. CP-Miner uses data min-[3]

ing techniques to identify code clones and the bug detection
is implemented as part of the tool. Before passing to bug detection process, code clones detected gone through a seriesof pruning procedures. CP-Miner has the ability to handle[4]clone that is not exactly the same.
Recently, Jiang et al. [3] developed a tool to detect bugsin code clones and their surrounding code, called context.
The clone detection component of the tool is based on[5]

DECKARD [13], a clone detection tool developed by them.
Bug caused by renaming inconsistency is called a type-3 in-[6]consistency in their work. The tool counts the number of
unique identiﬁers in each code fragment within a pair of[7]clones. Diﬀerent number of unique identiﬁers is deemed as
likely to be a bug.

[8]

6. Conclusion
In this paper, we introduced a method to detect bugs

[9]caused by inconsistent change of identiﬁers. We have also
conducted experiments using Linux kernel in order to eval-[10]uate the eﬀectiveness of our proposed method. As a result,
we were able to discover bugs on this system. Therefore, we
believe that our tool is eﬀective for detecting bugs in large[11]

software systems.
In future, we would like to conduct more experiments on
production software and perform a comprehensive analysis[12]

on the results. Also, we would like to improve our tool tohandle gapped clones.

Acknowledgments
This work has been conducted as a part of EASE Project,
Comprehensive Development of e-Society Foundation Soft-[13]

ing Copy-Paste and Related Bugs in Large-Scale Software
Code, IEEE Transactions on Software Engineering, vol.
32, no. 3, pp. 176-192, March 2006.
L. Jiang, Z. Su, and E.Chiu, Context-Based Detection ofClone-Related Bugs, Proceedings of the 6th joint meetingof the European Software Engineering Conference and the
ACM SIGSOFT Symposium of the Foundations of Software
Engineering, pp. 55-64, September 2007.
P. Jablonski, and D. Hou, CReN: A Tool for Tracking Copy-and-Paste Code Clones and Renaming Identiﬁers Consistently in the IDE, Proceedings of the OOPSLA
Workshop on Eclipse Technology Exchange, pp. 16-20, October 2007.
Y. Higo, T. Kamiya, S. Kusumoto and K. Inoue, Mehtod
and Implementation for Investigating Code Clones in a Software System, Information and Software Technology, vol.
49, pp. 985-998, September 2007.
G. Klein, JFlex User s Manual, November 2004.
Available at http://jflex.de/manual.html.
J. Krinke, A Study of Consistent and Inconsistent Changes
to Code Clones, Proceedings of the 14th Working Conference on Reverse Engineering, 2007.
B.S. Baker, On Finding Duplication and Near-Duplicationin Large Software Systems, Proceedings of the Second
Working Conference on Reverse Engineering, pp. 86-95,
July 1995.
C. Kapser and M.W. Godfrey, Toward a Taxonomy ofClones in Source Code: A Case Study, Evolution of Largescale Industrial Software Applications, September 2003.
S. Ducasse, M. Reiger, and S. Demeyer, A Language Independent Approach for Detecting Duplicated Code, Proceedings of the IEEE International Conference on Software
Maintenance, pp. 109-118, August 1999.
C. Kapser, and M. Godfrey, Supporting the Analysis ofClones in Software Systems: A Case Study, Journal of Software Maintenance and Evolution: Research and Practice,Vol.18, pp. 61-82, 2006.
M. Kim, V. Sazawal, D. Notkin, and G. Murphy, An Empirical Study of Code Clone Genealogies, Proceedings of theEuropean Software Engineering Conference and ACM SIGSOFT Symposium Foundation of Software Engineering, pp.
187-196, Sept. 2005.
L. Jiang, G. Misherghi, Z. Su, and S. Glondu, DECKARD:
Scalable and Accurate Tree-based Detection of CodeClones, Proceedings of 29th International Conference on
Software Engineering, pp. 96-105, May 2007.

ware Program, supported by Ministry of Education, Culture,
Sports, Science and Technology of Japan. The work was also
supported by Japan Society for the Promotion of Science under Grant-in-Aid for Scientiﬁc Research (A)(17200001).
References[1] T. Kamiya, S. Kusumoto, and K. Inoue, CCFinder: A
Multilinguistic Token-Based Code Clone Detection System
for Large Scale Source Code, IEEE Transactions on Software Engineering, vol. 28, no. 7, pp. 654-670, July 2002.
[2] Z. Li, S. Lu, S. Myagmar, and Y. Zhou, CP-Miner: Find-—6—