CommentProcessorFactory.java

1
package pro.verron.officestamper.preset;
2
3
import jakarta.xml.bind.JAXBElement;
4
import org.docx4j.XmlUtils;
5
import org.docx4j.jaxb.Context;
6
import org.docx4j.openpackaging.exceptions.Docx4JException;
7
import org.docx4j.openpackaging.packages.WordprocessingMLPackage;
8
import org.docx4j.wml.*;
9
import org.jvnet.jaxb2_commons.ppp.Child;
10
import org.slf4j.Logger;
11
import org.slf4j.LoggerFactory;
12
import org.springframework.lang.Nullable;
13
import pro.verron.officestamper.api.*;
14
import pro.verron.officestamper.core.*;
15
16
import java.io.IOException;
17
import java.io.OutputStream;
18
import java.io.PipedInputStream;
19
import java.io.PipedOutputStream;
20
import java.math.BigInteger;
21
import java.util.*;
22
import java.util.concurrent.CopyOnWriteArrayList;
23
import java.util.concurrent.Executors;
24
import java.util.concurrent.ThreadFactory;
25
import java.util.concurrent.atomic.AtomicReference;
26
import java.util.function.BiFunction;
27
import java.util.function.Consumer;
28
import java.util.function.Function;
29
import java.util.function.Supplier;
30
31
import static java.lang.String.format;
32
import static java.util.Collections.emptyList;
33
import static java.util.Objects.requireNonNull;
34
import static java.util.stream.Collectors.toMap;
35
import static org.docx4j.TextUtils.getText;
36
import static pro.verron.officestamper.core.DocumentUtil.walkObjectsAndImportImages;
37
38
/**
39
 * Factory class to create the correct comment processor for a given comment.
40
 *
41
 * @author Joseph Verron
42
 * @version ${version}
43
 * @since 1.6.4
44
 */
45
public class CommentProcessorFactory {
46
    private static final Logger log = LoggerFactory.getLogger(CommentProcessorFactory.class);
47
    private final OfficeStamperConfiguration configuration;
48
49
    /**
50
     * Creates a new CommentProcessorFactory.
51
     *
52
     * @param configuration the configuration to use for the created processors.
53
     */
54
    public CommentProcessorFactory(OfficeStamperConfiguration configuration) {
55
        this.configuration = configuration;
56
    }
57
58
    private static Tbl parentTable(P p) {
59 1 1. parentTable : negated conditional → KILLED
        if (parentRow(p).getParent() instanceof Tbl table)
60 1 1. parentTable : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::parentTable → KILLED
            return table;
61
        throw new OfficeStamperException(format("Paragraph is not within a table! : %s", getText(p)));
62
    }
63
64
    private static Tr parentRow(P p) {
65 1 1. parentRow : negated conditional → KILLED
        if (parentCell(p).getParent() instanceof Tr row)
66 1 1. parentRow : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::parentRow → KILLED
            return row;
67
        throw new OfficeStamperException(format("Paragraph is not within a row! : %s", getText(p)));
68
    }
69
70
    private static Tc parentCell(P p) {
71 1 1. parentCell : negated conditional → KILLED
        if (p.getParent() instanceof Tc cell)
72 1 1. parentCell : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::parentCell → KILLED
            return cell;
73
        throw new OfficeStamperException(format("Paragraph is not within a cell! : %s", getText(p)));
74
    }
75
76
    /**
77
     * Creates a new CommentProcessorFactory with default configuration.
78
     *
79
     * @param pr a {@link PlaceholderReplacer} object
80
     *
81
     * @return a {@link CommentProcessor} object
82
     */
83
    public CommentProcessor repeatParagraph(ParagraphPlaceholderReplacer pr) {
84 1 1. repeatParagraph : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::repeatParagraph → KILLED
        return ParagraphRepeatProcessor.newInstance(pr);
85
    }
86
87
    /**
88
     * Creates a new CommentProcessorFactory with default configuration.
89
     *
90
     * @param pr a {@link PlaceholderReplacer} object
91
     *
92
     * @return a {@link CommentProcessor} object
93
     */
94
    public CommentProcessor repeatDocPart(ParagraphPlaceholderReplacer pr) {
95 1 1. repeatDocPart : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::repeatDocPart → KILLED
        return RepeatDocPartProcessor.newInstance(pr, getStamper());
96
    }
97
98
    private OfficeStamper<WordprocessingMLPackage> getStamper() {
99 2 1. lambda$getStamper$0 : removed call to pro/verron/officestamper/core/DocxStamper::stamp → TIMED_OUT
2. getStamper : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::getStamper → KILLED
        return (template, context, output) -> new DocxStamper(configuration).stamp(template, context, output);
100
    }
101
102
    /**
103
     * Creates a new CommentProcessorFactory with default configuration.
104
     *
105
     * @param pr a {@link PlaceholderReplacer} object
106
     *
107
     * @return a {@link CommentProcessor} object
108
     */
109
    public CommentProcessor repeat(ParagraphPlaceholderReplacer pr) {
110 1 1. repeat : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::repeat → KILLED
        return RepeatProcessor.newInstance(pr);
111
    }
112
113
    /**
114
     * Creates a new CommentProcessorFactory with default configuration.
115
     *
116
     * @param pr a {@link PlaceholderReplacer} object
117
     *
118
     * @return a {@link CommentProcessor} object
119
     */
120
    public CommentProcessor tableResolver(ParagraphPlaceholderReplacer pr) {
121 1 1. tableResolver : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::tableResolver → KILLED
        return TableResolver.newInstance(pr);
122
    }
123
124
    /**
125
     * Creates a new CommentProcessorFactory with default configuration.
126
     *
127
     * @param pr a {@link PlaceholderReplacer} object
128
     *
129
     * @return a {@link CommentProcessor} object
130
     */
131
    public CommentProcessor displayIf(ParagraphPlaceholderReplacer pr) {
132 1 1. displayIf : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::displayIf → KILLED
        return DisplayIfProcessor.newInstance(pr);
133
    }
134
135
    /**
136
     * Creates a new CommentProcessorFactory with default configuration.
137
     *
138
     * @param pr a {@link PlaceholderReplacer} object
139
     *
140
     * @return a {@link CommentProcessor} object
141
     */
142
    public CommentProcessor replaceWith(ParagraphPlaceholderReplacer pr) {
143 1 1. replaceWith : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::replaceWith → KILLED
        return ReplaceWithProcessor.newInstance(pr);
144
    }
145
146
    /**
147
     * This interface is used to resolve a table in the template document.
148
     * The table is passed to the resolveTable method and will be used to fill an existing Tbl object in the document.
149
     *
150
     * @author Joseph Verron
151
     * @version ${version}
152
     * @since 1.6.2
153
     */
154
    public interface ITableResolver {
155
        /**
156
         * Resolves the given table by manipulating the given table in the template
157
         *
158
         * @param table the table to resolve.
159
         */
160
        void resolveTable(StampTable table);
161
    }
162
163
    /**
164
     * Interface for processors that replace a single word with an expression defined
165
     * in a comment.
166
     *
167
     * @author Joseph Verron
168
     * @author Tom Hombergs
169
     * @version ${version}
170
     * @since 1.0.8
171
     */
172
    public interface IReplaceWithProcessor {
173
174
        /**
175
         * May be called to replace a single word inside a paragraph with an expression
176
         * defined in a comment. The comment must be applied to a single word for the
177
         * replacement to take effect!
178
         *
179
         * @param expression the expression to replace the text with
180
         */
181
        void replaceWordWith(@Nullable String expression);
182
    }
183
184
    /**
185
     * Implementations of this interface are responsible for processing the repeat paragraph instruction.
186
     * The repeat paragraph instruction is a comment that contains the following text:
187
     * <p>
188
     * <code>
189
     * repeatParagraph(...)
190
     * </code>
191
     * <p>
192
     * Where the three dots represent an expression that evaluates to a list of objects.
193
     * The processor then copies the paragraph once for each object in the list and evaluates all expressions
194
     * within each copy against the respective object.
195
     *
196
     * @author Joseph Verron
197
     * @author Romain Lamarche
198
     * @version ${version}
199
     * @since 1.0.0
200
     */
201
    public interface IParagraphRepeatProcessor {
202
203
        /**
204
         * May be called to mark a paragraph to be copied once for each element in the passed-in list.
205
         * Within each copy of the row, all expressions are evaluated against one of the objects in the list.
206
         *
207
         * @param objects the objects which serve as context root for expressions found in the template table row.
208
         */
209
        void repeatParagraph(List<Object> objects);
210
    }
211
212
    /**
213
     * Interface for processors which may be called to mark a document part to be copied once for each element in the
214
     * passed-in list.
215
     * Within each copy of the row, all expressions are evaluated against one of the objects in the list.
216
     *
217
     * @author Joseph Verron
218
     * @author Artem Medvedev
219
     * @version ${version}
220
     * @since 1.0.0
221
     */
222
    public interface IRepeatDocPartProcessor {
223
224
        /**
225
         * May be called to mark a document part to be copied once for each element in the passed-in list.
226
         * Within each copy of the row, all expressions are evaluated against one of the objects in the list.
227
         *
228
         * @param objects the objects which serve as context root for expressions found in the template table row.
229
         *
230
         * @throws Exception if the processing fails.
231
         */
232
        void repeatDocPart(@Nullable List<Object> objects)
233
                throws Exception;
234
    }
235
236
    /**
237
     * Interface for processors that can repeat a table row.
238
     *
239
     * @author Joseph Verron
240
     * @author Tom Hombergs
241
     * @version ${version}
242
     * @since 1.0.0
243
     */
244
    public interface IRepeatProcessor {
245
246
        /**
247
         * May be called to mark a table row to be copied once for each element in the passed-in list.
248
         * Within each copy of the row, all expressions are evaluated against one of the objects in the list.
249
         *
250
         * @param objects the objects which serve as context root for expressions found in the template table row.
251
         */
252
        void repeatTableRow(List<Object> objects);
253
254
    }
255
256
    /**
257
     * Interface for processors that may be used to delete commented paragraphs or tables from the document, depending
258
     * on a given condition.
259
     *
260
     * @author Joseph Verron
261
     * @author Tom Hombergs
262
     * @version ${version}
263
     * @since 1.0.0
264
     */
265
    public interface IDisplayIfProcessor {
266
267
        /**
268
         * May be called to delete the commented paragraph or not, depending on the given boolean condition.
269
         *
270
         * @param condition if true, the commented paragraph will remain in the document. If false, the commented
271
         *                  paragraph
272
         *                  will be deleted at stamping.
273
         */
274
        void displayParagraphIf(Boolean condition);
275
276
        /**
277
         * May be called to delete the commented paragraph or not, depending on the presence of the given data.
278
         *
279
         * @param condition if non-null, the commented paragraph will remain in
280
         *                  the document. If null, the commented paragraph
281
         *                  will be deleted at stamping.
282
         */
283
        void displayParagraphIfPresent(@Nullable Object condition);
284
285
        /**
286
         * May be called to delete the table surrounding the commented paragraph, depending on the given boolean
287
         * condition.
288
         *
289
         * @param condition if true, the table row surrounding the commented paragraph will remain in the document. If
290
         *                  false, the table row
291
         *                  will be deleted at stamping.
292
         */
293
        void displayTableRowIf(Boolean condition);
294
295
        /**
296
         * May be called to delete the table surrounding the commented paragraph, depending on the given boolean
297
         * condition.
298
         *
299
         * @param condition if true, the table surrounding the commented paragraph will remain in the document. If
300
         *                  false, the table
301
         *                  will be deleted at stamping.
302
         */
303
        void displayTableIf(Boolean condition);
304
305
    }
306
307
    /**
308
     * TableResolver class.
309
     *
310
     * @author Joseph Verron
311
     * @version ${version}
312
     * @since 1.6.2
313
     */
314
    private static class TableResolver
315
            extends AbstractCommentProcessor
316
            implements ITableResolver {
317
        private final Map<Tbl, StampTable> cols = new HashMap<>();
318
        private final Function<Tbl, List<Object>> nullSupplier;
319
320
        private TableResolver(
321
                ParagraphPlaceholderReplacer placeholderReplacer,
322
                Function<Tbl, List<Object>> nullSupplier
323
        ) {
324
            super(placeholderReplacer);
325
            this.nullSupplier = nullSupplier;
326
        }
327
328
        /**
329
         * Generate a new {@link TableResolver} instance where value is replaced by an empty list when <code>null</code>
330
         *
331
         * @param pr a {@link PlaceholderReplacer} instance
332
         *
333
         * @return a new {@link TableResolver} instance
334
         */
335
        public static CommentProcessor newInstance(ParagraphPlaceholderReplacer pr) {
336 1 1. newInstance : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::newInstance → KILLED
            return new TableResolver(pr, table -> Collections.emptyList());
337
        }
338
339
        /**
340
         * {@inheritDoc}
341
         */
342
        @Override public void resolveTable(StampTable givenTable) {
343
            cols.put(parentTable(getParagraph()), givenTable);
344
        }
345
346
        /**
347
         * {@inheritDoc}
348
         */
349
        @Override
350
        public void commitChanges(DocxPart document) {
351
            for (Map.Entry<Tbl, StampTable> entry : cols.entrySet()) {
352
                Tbl wordTable = entry.getKey();
353
354
                StampTable stampedTable = entry.getValue();
355
356 1 1. commitChanges : negated conditional → KILLED
                if (stampedTable != null) {
357 1 1. commitChanges : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::replaceTableInplace → KILLED
                    replaceTableInplace(wordTable, stampedTable);
358
                }
359
                else {
360
                    List<Object> tableParentContent = ((ContentAccessor) wordTable.getParent()).getContent();
361
                    int tablePosition = tableParentContent.indexOf(wordTable);
362
                    List<Object> toInsert = nullSupplier.apply(wordTable);
363
                    tableParentContent.set(tablePosition, toInsert);
364
                }
365
            }
366
        }
367
368
        @Override public void commitChanges(WordprocessingMLPackage document) {
369
            throw new OfficeStamperException("Should not be called, since deprecation");
370
        }
371
372
        /**
373
         * {@inheritDoc}
374
         */
375
        @Override public void reset() {
376 1 1. reset : removed call to java/util/Map::clear → SURVIVED
            cols.clear();
377
        }
378
379
        private void replaceTableInplace(Tbl wordTable, StampTable stampedTable) {
380
            var headers = stampedTable.headers();
381
382
            var rows = wordTable.getContent();
383
            var headerRow = (Tr) rows.get(0);
384
            var firstDataRow = (Tr) rows.get(1);
385
386 1 1. replaceTableInplace : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::growAndFillRow → KILLED
            growAndFillRow(headerRow, headers);
387
388 1 1. replaceTableInplace : negated conditional → KILLED
            if (stampedTable.isEmpty()) rows.remove(firstDataRow);
389
            else {
390 1 1. replaceTableInplace : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::growAndFillRow → KILLED
                growAndFillRow(firstDataRow, stampedTable.get(0));
391
                for (var rowContent : stampedTable.subList(1, stampedTable.size()))
392
                    rows.add(copyRowFromTemplate(firstDataRow, rowContent));
393
            }
394
        }
395
396
        private void growAndFillRow(Tr row, List<String> values) {
397
            List<Object> cellRowContent = row.getContent();
398
399
            //Replace text in first cell
400
            JAXBElement<Tc> cell0 = (JAXBElement<Tc>) cellRowContent.get(0);
401
            Tc cell0tc = cell0.getValue();
402 2 1. growAndFillRow : negated conditional → KILLED
2. growAndFillRow : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::setCellText → KILLED
            setCellText(cell0tc, values.isEmpty() ? "" : values.get(0));
403
404 2 1. growAndFillRow : changed conditional boundary → SURVIVED
2. growAndFillRow : negated conditional → KILLED
            if (values.size() > 1) {
405
                //Copy the first cell and replace content for each remaining value
406
                for (String cellContent : values.subList(1, values.size())) {
407
                    JAXBElement<Tc> xmlCell = XmlUtils.deepCopy(cell0);
408 1 1. growAndFillRow : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::setCellText → KILLED
                    setCellText(xmlCell.getValue(), cellContent);
409
                    cellRowContent.add(xmlCell);
410
                }
411
            }
412
        }
413
414
        private Tr copyRowFromTemplate(Tr firstDataRow, List<String> rowContent) {
415
            Tr newXmlRow = XmlUtils.deepCopy(firstDataRow);
416
            List<Object> xmlRow = newXmlRow.getContent();
417 2 1. copyRowFromTemplate : negated conditional → KILLED
2. copyRowFromTemplate : changed conditional boundary → KILLED
            for (int i = 0; i < rowContent.size(); i++) {
418
                String cellContent = rowContent.get(i);
419
                Tc xmlCell = ((JAXBElement<Tc>) xmlRow.get(i)).getValue();
420 1 1. copyRowFromTemplate : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::setCellText → KILLED
                setCellText(xmlCell, cellContent);
421
            }
422 1 1. copyRowFromTemplate : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::copyRowFromTemplate → KILLED
            return newXmlRow;
423
        }
424
425
        private void setCellText(Tc tableCell, String content) {
426
            var tableCellContent = tableCell.getContent();
427 1 1. setCellText : removed call to java/util/List::clear → KILLED
            tableCellContent.clear();
428
            tableCellContent.add(ParagraphUtil.create(content));
429
        }
430
    }
431
432
    /**
433
     * Processor that replaces the current run with the provided expression.
434
     * This is useful for replacing an expression in a comment with the result of the expression.
435
     *
436
     * @author Joseph Verron
437
     * @author Tom Hombergs
438
     * @version ${version}
439
     * @since 1.0.7
440
     */
441
    private static class ReplaceWithProcessor
442
            extends AbstractCommentProcessor
443
            implements IReplaceWithProcessor {
444
445
        private final Function<R, List<Object>> nullSupplier;
446
447
        private ReplaceWithProcessor(
448
                ParagraphPlaceholderReplacer placeholderReplacer, Function<R, List<Object>> nullSupplier
449
        ) {
450
            super(placeholderReplacer);
451
            this.nullSupplier = nullSupplier;
452
        }
453
454
        /**
455
         * Creates a new processor that replaces the current run with the result of the expression.
456
         *
457
         * @param pr the placeholder replacer to use
458
         *
459
         * @return the processor
460
         */
461
        public static CommentProcessor newInstance(ParagraphPlaceholderReplacer pr) {
462 1 1. newInstance : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$ReplaceWithProcessor::newInstance → KILLED
            return new ReplaceWithProcessor(pr, R::getContent);
463
        }
464
465
        /**
466
         * {@inheritDoc}
467
         */
468
        @Override
469
        public void commitChanges(DocxPart document) {
470
            // nothing to commit
471
        }
472
473
        /**
474
         * {@inheritDoc}
475
         */
476
        @Override public void reset() {
477
            // nothing to reset
478
        }
479
480
        /**
481
         * {@inheritDoc}
482
         */
483
        @Override public void replaceWordWith(@Nullable String expression) {
484
            R run = this.getCurrentRun();
485 1 1. replaceWordWith : negated conditional → KILLED
            if (run == null) {
486
                log.info(format("Impossible to put expression %s in a null run", expression));
487
                return;
488
            }
489
490
            List<Object> target;
491 1 1. replaceWordWith : negated conditional → KILLED
            if (expression != null) {
492
                target = List.of(RunUtil.createText(expression));
493
            }
494
            else {
495
                target = nullSupplier.apply(run);
496
            }
497
            run.getContent()
498 1 1. replaceWordWith : removed call to java/util/List::clear → KILLED
               .clear();
499
            run.getContent()
500
               .addAll(target);
501
        }
502
    }
503
504
    /**
505
     * This class is used to repeat paragraphs and tables.
506
     * <p>
507
     * It is used internally by the DocxStamper and should not be instantiated by
508
     * clients.
509
     *
510
     * @author Joseph Verron
511
     * @author Youssouf Naciri
512
     * @version ${version}
513
     * @since 1.2.2
514
     */
515
    private static class ParagraphRepeatProcessor
516
            extends AbstractCommentProcessor
517
            implements IParagraphRepeatProcessor {
518
        private final Supplier<? extends List<? extends P>> nullSupplier;
519
        private Map<P, Paragraphs> pToRepeat = new HashMap<>();
520
521
        /**
522
         * @param placeholderReplacer replaces placeholders with values
523
         * @param nullSupplier        supplies a list of paragraphs if the list of objects to repeat is null
524
         */
525
        private ParagraphRepeatProcessor(
526
                ParagraphPlaceholderReplacer placeholderReplacer,
527
                Supplier<? extends List<? extends P>> nullSupplier
528
        ) {
529
            super(placeholderReplacer);
530
            this.nullSupplier = nullSupplier;
531
        }
532
533
        /**
534
         * <p>newInstance.</p>
535
         *
536
         * @param placeholderReplacer replaces expressions with values
537
         *
538
         * @return a new instance of ParagraphRepeatProcessor
539
         */
540
        public static CommentProcessor newInstance(ParagraphPlaceholderReplacer placeholderReplacer) {
541 1 1. newInstance : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$ParagraphRepeatProcessor::newInstance → KILLED
            return new ParagraphRepeatProcessor(placeholderReplacer, Collections::emptyList);
542
        }
543
544
        /**
545
         * {@inheritDoc}
546
         */
547
        @Override public void repeatParagraph(List<Object> objects) {
548
            P paragraph = getParagraph();
549
550
            Deque<P> paragraphs = getParagraphsInsideComment(paragraph);
551
552
            Paragraphs toRepeat = new Paragraphs();
553
            toRepeat.comment = getCurrentCommentWrapper();
554
            toRepeat.data = new ArrayDeque<>(objects);
555
            toRepeat.paragraphs = paragraphs;
556
            toRepeat.sectionBreakBefore = SectionUtil.getPreviousSectionBreakIfPresent(paragraph,
557
                    (ContentAccessor) paragraph.getParent());
558
            toRepeat.firstParagraphSectionBreak = SectionUtil.getParagraphSectionBreak(paragraph);
559
            toRepeat.hasOddSectionBreaks = SectionUtil.isOddNumberOfSectionBreaks(new ArrayList<>(toRepeat.paragraphs));
560
561
            var paragraphPPr = paragraph.getPPr();
562 2 1. repeatParagraph : negated conditional → SURVIVED
2. repeatParagraph : negated conditional → KILLED
            if (paragraphPPr != null && paragraphPPr.getSectPr() != null) {
563
                // we need to clear the first paragraph's section break to be able to control how to repeat it
564 1 1. repeatParagraph : removed call to org/docx4j/wml/PPr::setSectPr → NO_COVERAGE
                paragraphPPr.setSectPr(null);
565
            }
566
            pToRepeat.put(paragraph, toRepeat);
567
        }
568
569
        /**
570
         * Returns all paragraphs inside the comment of the given paragraph.
571
         * <p>
572
         * If the paragraph is not inside a comment, the given paragraph is returned.
573
         *
574
         * @param paragraph the paragraph to analyze
575
         *
576
         * @return all paragraphs inside the comment of the given paragraph
577
         */
578
        public static Deque<P> getParagraphsInsideComment(P paragraph) {
579
            BigInteger commentId = null;
580
            boolean foundEnd = false;
581
582
            Deque<P> paragraphs = new ArrayDeque<>();
583
            paragraphs.add(paragraph);
584
585
            for (Object object : paragraph.getContent()) {
586 1 1. getParagraphsInsideComment : negated conditional → KILLED
                if (object instanceof CommentRangeStart crs) commentId = crs.getId();
587 2 1. getParagraphsInsideComment : negated conditional → KILLED
2. getParagraphsInsideComment : negated conditional → KILLED
                if (object instanceof CommentRangeEnd cre && Objects.equals(commentId, cre.getId())) foundEnd = true;
588
            }
589 3 1. getParagraphsInsideComment : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$ParagraphRepeatProcessor::getParagraphsInsideComment → KILLED
2. getParagraphsInsideComment : negated conditional → KILLED
3. getParagraphsInsideComment : negated conditional → KILLED
            if (foundEnd || commentId == null) return paragraphs;
590
591
            Object parent = paragraph.getParent();
592 1 1. getParagraphsInsideComment : negated conditional → KILLED
            if (parent instanceof ContentAccessor contentAccessor) {
593
                var accessorContent = contentAccessor.getContent();
594
                int index = accessorContent.indexOf(paragraph);
595 4 1. getParagraphsInsideComment : changed conditional boundary → SURVIVED
2. getParagraphsInsideComment : negated conditional → KILLED
3. getParagraphsInsideComment : negated conditional → KILLED
4. getParagraphsInsideComment : Replaced integer addition with subtraction → KILLED
                for (int i = index + 1; i < accessorContent.size() && !foundEnd; i++) {
596
                    var next = accessorContent.get(i);
597 2 1. getParagraphsInsideComment : negated conditional → NO_COVERAGE
2. getParagraphsInsideComment : negated conditional → KILLED
                    if (next instanceof CommentRangeEnd cre && Objects.equals(commentId, cre.getId())) foundEnd = true;
598
                    else {
599 1 1. getParagraphsInsideComment : negated conditional → KILLED
                        if (next instanceof P p) {
600
                            paragraphs.add(p);
601
                        }
602 1 1. getParagraphsInsideComment : negated conditional → KILLED
                        if (next instanceof ContentAccessor childContent) {
603
                            for (Object child : childContent.getContent()) {
604 2 1. getParagraphsInsideComment : negated conditional → KILLED
2. getParagraphsInsideComment : negated conditional → KILLED
                                if (child instanceof CommentRangeEnd cre && Objects.equals(commentId, cre.getId())) {
605
                                    foundEnd = true;
606
                                    break;
607
                                }
608
                            }
609
                        }
610
                    }
611
                }
612
            }
613 1 1. getParagraphsInsideComment : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$ParagraphRepeatProcessor::getParagraphsInsideComment → KILLED
            return paragraphs;
614
        }
615
616
        /**
617
         * {@inheritDoc}
618
         */
619
        @Override
620
        public void commitChanges(DocxPart document) {
621
            for (Map.Entry<P, Paragraphs> entry : pToRepeat.entrySet()) {
622
                P currentP = entry.getKey();
623
                ContentAccessor parent = (ContentAccessor) currentP.getParent();
624
                List<Object> parentContent = parent.getContent();
625
                int index = parentContent.indexOf(currentP);
626 2 1. commitChanges : changed conditional boundary → SURVIVED
2. commitChanges : negated conditional → KILLED
                if (index < 0) throw new OfficeStamperException("Impossible");
627
628
                Paragraphs paragraphsToRepeat = entry.getValue();
629
                Deque<Object> expressionContexts = Objects.requireNonNull(paragraphsToRepeat).data;
630
631 1 1. commitChanges : negated conditional → KILLED
                Deque<P> collection = expressionContexts == null
632
                        ? new ArrayDeque<>(nullSupplier.get())
633
                        : generateParagraphsToAdd(document, paragraphsToRepeat, expressionContexts);
634 1 1. commitChanges : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$ParagraphRepeatProcessor::restoreFirstSectionBreakIfNeeded → SURVIVED
                restoreFirstSectionBreakIfNeeded(paragraphsToRepeat, collection);
635
                parentContent.addAll(index, collection);
636
                parentContent.removeAll(paragraphsToRepeat.paragraphs);
637
            }
638
        }
639
640
        private Deque<P> generateParagraphsToAdd(
641
                DocxPart document,
642
                Paragraphs paragraphs,
643
                Deque<Object> expressionContexts
644
        ) {
645
            Deque<P> paragraphsToAdd = new ArrayDeque<>();
646
647
            Object lastExpressionContext = expressionContexts.peekLast();
648
            P lastParagraph = paragraphs.paragraphs.peekLast();
649
650
            for (Object expressionContext : expressionContexts) {
651
                for (P paragraphToClone : paragraphs.paragraphs) {
652
                    P pClone = XmlUtils.deepCopy(paragraphToClone);
653
654 4 1. generateParagraphsToAdd : negated conditional → KILLED
2. generateParagraphsToAdd : negated conditional → KILLED
3. generateParagraphsToAdd : negated conditional → KILLED
4. generateParagraphsToAdd : negated conditional → KILLED
                    if (paragraphs.sectionBreakBefore != null && paragraphs.hasOddSectionBreaks
655
                        && expressionContext != lastExpressionContext
656
                        && paragraphToClone == lastParagraph) {
657 1 1. generateParagraphsToAdd : removed call to pro/verron/officestamper/core/SectionUtil::applySectionBreakToParagraph → KILLED
                        SectionUtil.applySectionBreakToParagraph(paragraphs.sectionBreakBefore, pClone);
658
                    }
659
660
                    var pCloneContent = pClone.getContent();
661
                    var commentId = paragraphs.comment
662
                            .getComment()
663
                            .getId();
664 1 1. generateParagraphsToAdd : removed call to pro/verron/officestamper/core/CommentUtil::deleteCommentFromElements → KILLED
                    CommentUtil.deleteCommentFromElements(pCloneContent, commentId);
665
                    var paragraph = new StandardParagraph(pClone);
666 1 1. generateParagraphsToAdd : removed call to pro/verron/officestamper/api/ParagraphPlaceholderReplacer::resolveExpressionsForParagraph → KILLED
                    placeholderReplacer.resolveExpressionsForParagraph(document, paragraph, expressionContext);
667
                    paragraphsToAdd.add(pClone);
668
                }
669
            }
670 1 1. generateParagraphsToAdd : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$ParagraphRepeatProcessor::generateParagraphsToAdd → KILLED
            return paragraphsToAdd;
671
        }
672
673
        private static void restoreFirstSectionBreakIfNeeded(
674
                Paragraphs paragraphs, Deque<P> paragraphsToAdd
675
        ) {
676 1 1. restoreFirstSectionBreakIfNeeded : negated conditional → KILLED
            if (paragraphs.firstParagraphSectionBreak != null) {
677
                P breakP = paragraphsToAdd.getLast();
678 1 1. restoreFirstSectionBreakIfNeeded : removed call to pro/verron/officestamper/core/SectionUtil::applySectionBreakToParagraph → NO_COVERAGE
                SectionUtil.applySectionBreakToParagraph(paragraphs.firstParagraphSectionBreak, breakP);
679
            }
680
        }
681
682
        /**
683
         * {@inheritDoc}
684
         */
685
        @Override public void reset() {
686
            pToRepeat = new HashMap<>();
687
        }
688
689
        private static class Paragraphs {
690
            Comment comment;
691
            Deque<Object> data;
692
            Deque<P> paragraphs;
693
            // hasOddSectionBreaks is true if the paragraphs to repeat contain an odd number of section breaks
694
            // changing the layout, false otherwise
695
            boolean hasOddSectionBreaks;
696
            // section break right before the first paragraph to repeat if present, or null
697
            SectPr sectionBreakBefore;
698
            // section break on the first paragraph to repeat if present, or null
699
            SectPr firstParagraphSectionBreak;
700
        }
701
    }
702
703
    /**
704
     * Walks through a document and replaces expressions with values from the given
705
     * expression context.
706
     * This walker only replaces expressions in paragraphs, not in tables.
707
     *
708
     * @author Joseph Verron
709
     * @version ${version}
710
     * @since 1.4.7
711
     */
712
    private static class ParagraphResolverDocumentWalker
713
            extends BaseDocumentWalker {
714
        private final Object expressionContext;
715
        private final DocxPart docxPart;
716
        private final ParagraphPlaceholderReplacer placeholderReplacer;
717
718
        /**
719
         * <p>Constructor for ParagraphResolverDocumentWalker.</p>
720
         *
721
         * @param rowClone          The row to start with
722
         * @param expressionContext The context of the expressions to resolve
723
         * @param replacer          The placeholderReplacer to use for resolving
724
         */
725
        public ParagraphResolverDocumentWalker(
726
                DocxPart docxPart,
727
                Tr rowClone,
728
                Object expressionContext,
729
                ParagraphPlaceholderReplacer replacer
730
        ) {
731
            super(docxPart.from(rowClone));
732
            this.expressionContext = expressionContext;
733
            this.docxPart = docxPart;
734
            this.placeholderReplacer = replacer;
735
        }
736
737
        /**
738
         * {@inheritDoc}
739
         */
740
        @Override protected void onParagraph(P paragraph) {
741
            var standardParagraph = new StandardParagraph(paragraph);
742 1 1. onParagraph : removed call to pro/verron/officestamper/api/ParagraphPlaceholderReplacer::resolveExpressionsForParagraph → KILLED
            placeholderReplacer.resolveExpressionsForParagraph(docxPart, standardParagraph, expressionContext);
743
        }
744
    }
745
746
    /**
747
     * This class is responsible for processing the &lt;ds: repeat&gt; tag.
748
     * It uses the {@link OfficeStamper} to stamp the sub document and then
749
     * copies the resulting sub document to the correct position in the
750
     * main document.
751
     *
752
     * @author Joseph Verron
753
     * @author Youssouf Naciri
754
     * @version ${version}
755
     * @since 1.3.0
756
     */
757
    private static class RepeatDocPartProcessor
758
            extends AbstractCommentProcessor
759
            implements IRepeatDocPartProcessor {
760
        private static final ThreadFactory threadFactory = Executors.defaultThreadFactory();
761
        private static final ObjectFactory objectFactory = Context.getWmlObjectFactory();
762
763
        private final OfficeStamper<WordprocessingMLPackage> stamper;
764
        private final Map<Comment, List<Object>> contexts = new HashMap<>();
765
        private final Supplier<? extends List<?>> nullSupplier;
766
767
        private RepeatDocPartProcessor(
768
                ParagraphPlaceholderReplacer placeholderReplacer,
769
                OfficeStamper<WordprocessingMLPackage> stamper,
770
                Supplier<? extends List<?>> nullSupplier
771
        ) {
772
            super(placeholderReplacer);
773
            this.stamper = stamper;
774
            this.nullSupplier = nullSupplier;
775
        }
776
777
        /**
778
         * <p>newInstance.</p>
779
         *
780
         * @param pr      the placeholderReplacer
781
         * @param stamper the stamper
782
         *
783
         * @return a new instance of this processor
784
         */
785
        public static CommentProcessor newInstance(
786
                ParagraphPlaceholderReplacer pr, OfficeStamper<WordprocessingMLPackage> stamper
787
        ) {
788 1 1. newInstance : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::newInstance → KILLED
            return new RepeatDocPartProcessor(pr, stamper, Collections::emptyList);
789
        }
790
791
        /**
792
         * {@inheritDoc}
793
         */
794
        @Override public void repeatDocPart(@Nullable List<Object> contexts) {
795 1 1. repeatDocPart : negated conditional → KILLED
            if (contexts == null) contexts = Collections.emptyList();
796
797
            Comment currentComment = getCurrentCommentWrapper();
798
            List<Object> elements = currentComment.getElements();
799
800 1 1. repeatDocPart : negated conditional → KILLED
            if (!elements.isEmpty()) {
801
                this.contexts.put(currentComment, contexts);
802
            }
803
        }
804
805
        /**
806
         * {@inheritDoc}
807
         */
808
        @Override public void commitChanges(DocxPart source) {
809
            for (Map.Entry<Comment, List<Object>> entry : this.contexts.entrySet()) {
810
                var comment = entry.getKey();
811
                var expressionContexts = entry.getValue();
812
                var gcp = requireNonNull(comment.getParent());
813
                var repeatElements = comment.getElements();
814
                var subTemplate = CommentUtil.createSubWordDocument(comment);
815
                var previousSectionBreak = SectionUtil.getPreviousSectionBreakIfPresent(repeatElements.get(0), gcp);
816
                var oddNumberOfBreaks = SectionUtil.isOddNumberOfSectionBreaks(repeatElements);
817 1 1. commitChanges : negated conditional → KILLED
                var changes = expressionContexts == null
818
                        ? nullSupplier.get()
819
                        : stampSubDocuments(source.document(),
820
                                expressionContexts,
821
                                gcp,
822
                                subTemplate,
823
                                previousSectionBreak,
824
                                oddNumberOfBreaks);
825
                var gcpContent = gcp.getContent();
826
                var index = gcpContent.indexOf(repeatElements.get(0));
827
                gcpContent.addAll(index, changes);
828
                gcpContent.removeAll(repeatElements);
829
            }
830
831
        }
832
833
        private List<Object> stampSubDocuments(
834
                WordprocessingMLPackage document,
835
                List<Object> expressionContexts,
836
                ContentAccessor gcp,
837
                WordprocessingMLPackage subTemplate,
838
                @Nullable SectPr previousSectionBreak,
839
                boolean oddNumberOfBreaks
840
        ) {
841
            var subDocuments = stampSubDocuments(expressionContexts, subTemplate);
842
            var replacements = subDocuments.stream()
843
                                           //TODO_LATER: move side effect somewhere else
844 1 1. lambda$stampSubDocuments$0 : replaced return value with Collections.emptyMap for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::lambda$stampSubDocuments$0 → KILLED
                                           .map(p -> walkObjectsAndImportImages(p, document))
845
                                           .map(Map::entrySet)
846
                                           .flatMap(Set::stream)
847
                                           .collect(toMap(Map.Entry::getKey, Map.Entry::getValue));
848
849
            var changes = new ArrayList<>();
850
            for (WordprocessingMLPackage subDocument : subDocuments) {
851
                var os = documentAsInsertableElements(subDocument, oddNumberOfBreaks, previousSectionBreak);
852
                os.stream()
853
                  .filter(ContentAccessor.class::isInstance)
854
                  .map(ContentAccessor.class::cast)
855 2 1. lambda$stampSubDocuments$1 : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::recursivelyReplaceImages → KILLED
2. stampSubDocuments : removed call to java/util/stream/Stream::forEach → KILLED
                  .forEach(o -> recursivelyReplaceImages(o, replacements));
856 2 1. stampSubDocuments : removed call to java/util/List::forEach → SURVIVED
2. lambda$stampSubDocuments$2 : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::setParentIfPossible → SURVIVED
                os.forEach(c -> setParentIfPossible(c, gcp));
857
                changes.addAll(os);
858
            }
859 1 1. stampSubDocuments : replaced return value with Collections.emptyList for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::stampSubDocuments → KILLED
            return changes;
860
        }
861
862
        private List<WordprocessingMLPackage> stampSubDocuments(
863
                List<Object> subContexts, WordprocessingMLPackage subTemplate
864
        ) {
865
            var subDocuments = new ArrayList<WordprocessingMLPackage>();
866
            for (Object subContext : subContexts) {
867 1 1. lambda$stampSubDocuments$3 : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::copy → TIMED_OUT
                var templateCopy = outputWord(os -> copy(subTemplate, os));
868 1 1. lambda$stampSubDocuments$4 : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::stamp → TIMED_OUT
                var subDocument = outputWord(os -> stamp(subContext, templateCopy, os));
869
                subDocuments.add(subDocument);
870
            }
871 1 1. stampSubDocuments : replaced return value with Collections.emptyList for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::stampSubDocuments → KILLED
            return subDocuments;
872
        }
873
874
        private static List<Object> documentAsInsertableElements(
875
                WordprocessingMLPackage subDocument, boolean oddNumberOfBreaks, @Nullable SectPr previousSectionBreak
876
        ) {
877
            List<Object> inserts = new ArrayList<>(DocumentUtil.allElements(subDocument));
878
            // make sure we replicate the previous section break before each repeated doc part
879 2 1. documentAsInsertableElements : negated conditional → KILLED
2. documentAsInsertableElements : negated conditional → KILLED
            if (oddNumberOfBreaks && previousSectionBreak != null) {
880 1 1. documentAsInsertableElements : negated conditional → KILLED
                if (DocumentUtil.lastElement(subDocument) instanceof P p) {
881 1 1. documentAsInsertableElements : removed call to pro/verron/officestamper/core/SectionUtil::applySectionBreakToParagraph → KILLED
                    SectionUtil.applySectionBreakToParagraph(previousSectionBreak, p);
882
                }
883
                else {
884
                    // when the last element to be repeated is not a paragraph, we need to add a new
885
                    // one right after to carry the section break to have a valid xml
886
                    P p = objectFactory.createP();
887 1 1. documentAsInsertableElements : removed call to pro/verron/officestamper/core/SectionUtil::applySectionBreakToParagraph → KILLED
                    SectionUtil.applySectionBreakToParagraph(previousSectionBreak, p);
888
                    inserts.add(p);
889
                }
890
            }
891 1 1. documentAsInsertableElements : replaced return value with Collections.emptyList for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::documentAsInsertableElements → KILLED
            return inserts;
892
        }
893
894
        private static void recursivelyReplaceImages(
895
                ContentAccessor r, Map<R, R> replacements
896
        ) {
897
            Queue<ContentAccessor> q = new ArrayDeque<>();
898
            q.add(r);
899 1 1. recursivelyReplaceImages : negated conditional → KILLED
            while (!q.isEmpty()) {
900
                ContentAccessor run = q.remove();
901 2 1. recursivelyReplaceImages : negated conditional → KILLED
2. recursivelyReplaceImages : negated conditional → KILLED
                if (replacements.containsKey(run) && run instanceof Child child
902 1 1. recursivelyReplaceImages : negated conditional → KILLED
                    && child.getParent() instanceof ContentAccessor parent) {
903
                    List<Object> parentContent = parent.getContent();
904 1 1. recursivelyReplaceImages : removed call to java/util/List::add → KILLED
                    parentContent.add(parentContent.indexOf(run), replacements.get(run));
905
                    parentContent.remove(run);
906
                }
907
                else {
908
                    q.addAll(run.getContent()
909
                                .stream()
910
                                .filter(ContentAccessor.class::isInstance)
911
                                .map(ContentAccessor.class::cast)
912
                                .toList());
913
                }
914
            }
915
        }
916
917
        private static void setParentIfPossible(
918
                Object object, ContentAccessor parent
919
        ) {
920 2 1. setParentIfPossible : removed call to org/jvnet/jaxb2_commons/ppp/Child::setParent → SURVIVED
2. setParentIfPossible : negated conditional → KILLED
            if (object instanceof Child child) child.setParent(parent);
921
        }
922
923
        private WordprocessingMLPackage outputWord(Consumer<OutputStream> outputter) {
924
            var exceptionHandler = new ProcessorExceptionHandler();
925
            try (
926
                    PipedOutputStream os = new PipedOutputStream(); PipedInputStream is = new PipedInputStream(os)
927
            ) {
928
                // closing on exception to not block the pipe infinitely
929
                // TODO_LATER: model both PipedxxxStream as 1 class for only 1 close()
930 1 1. outputWord : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor$ProcessorExceptionHandler::onException → SURVIVED
                exceptionHandler.onException(is::close); // I know it's redundant,
931 1 1. outputWord : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor$ProcessorExceptionHandler::onException → TIMED_OUT
                exceptionHandler.onException(os::close); // but symmetry
932
933 1 1. lambda$outputWord$5 : removed call to java/util/function/Consumer::accept → TIMED_OUT
                var thread = threadFactory.newThread(() -> outputter.accept(os));
934 1 1. outputWord : removed call to java/lang/Thread::setUncaughtExceptionHandler → TIMED_OUT
                thread.setUncaughtExceptionHandler(exceptionHandler);
935 1 1. outputWord : removed call to java/lang/Thread::start → TIMED_OUT
                thread.start();
936
                var wordprocessingMLPackage = WordprocessingMLPackage.load(is);
937 1 1. outputWord : removed call to java/lang/Thread::join → SURVIVED
                thread.join();
938
                return wordprocessingMLPackage;
939
            } catch (Docx4JException | IOException e) {
940
                OfficeStamperException exception = new OfficeStamperException(e);
941
                exceptionHandler.exception()
942 1 1. outputWord : removed call to java/util/Optional::ifPresent → KILLED
                                .ifPresent(exception::addSuppressed);
943
                throw exception;
944
            } catch (InterruptedException e) {
945
                OfficeStamperException exception = new OfficeStamperException(e);
946
                exceptionHandler.exception()
947 1 1. outputWord : removed call to java/util/Optional::ifPresent → NO_COVERAGE
                                .ifPresent(e::addSuppressed);
948
                Thread.currentThread()
949 1 1. outputWord : removed call to java/lang/Thread::interrupt → NO_COVERAGE
                      .interrupt();
950
                throw exception;
951
            }
952
        }
953
954
        private void copy(
955
                WordprocessingMLPackage aPackage, OutputStream outputStream
956
        ) {
957
            try {
958 1 1. copy : removed call to org/docx4j/openpackaging/packages/WordprocessingMLPackage::save → TIMED_OUT
                aPackage.save(outputStream);
959
            } catch (Docx4JException e) {
960
                throw new OfficeStamperException(e);
961
            }
962
        }
963
964
        private void stamp(
965
                Object context, WordprocessingMLPackage template, OutputStream outputStream
966
        ) {
967 1 1. stamp : removed call to pro/verron/officestamper/api/OfficeStamper::stamp → TIMED_OUT
            stamper.stamp(template, context, outputStream);
968
        }
969
970
        /**
971
         * {@inheritDoc}
972
         */
973
        @Override public void reset() {
974 1 1. reset : removed call to java/util/Map::clear → SURVIVED
            contexts.clear();
975
        }
976
977
        /**
978
         * A functional interface representing runnable task able to throw an exception.
979
         * It extends the {@link Runnable} interface and provides default implementation
980
         * of the {@link Runnable#run()} method handling the exception by rethrowing it
981
         * wrapped inside a {@link OfficeStamperException}.
982
         *
983
         * @author Joseph Verron
984
         * @version ${version}
985
         * @since 1.6.6
986
         */
987
        interface ThrowingRunnable
988
                extends Runnable {
989
990
            /**
991
             * Executes the runnable task, handling any exception by throwing it wrapped
992
             * inside a {@link OfficeStamperException}.
993
             */
994
            default void run() {
995
                try {
996 1 1. run : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor$ThrowingRunnable::throwingRun → TIMED_OUT
                    throwingRun();
997
                } catch (Exception e) {
998
                    throw new OfficeStamperException(e);
999
                }
1000
            }
1001
1002
            /**
1003
             * Executes the runnable task
1004
             *
1005
             * @throws Exception if an exception occurs executing the task
1006
             */
1007
            void throwingRun()
1008
                    throws Exception;
1009
        }
1010
1011
        /**
1012
         * This class is responsible for capturing and handling uncaught exceptions
1013
         * that occur in a thread.
1014
         * It implements the {@link Thread.UncaughtExceptionHandler} interface and can
1015
         * be assigned to a thread using the
1016
         * {@link Thread#setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler)} method.
1017
         * When an exception occurs in the thread,
1018
         * the {@link ProcessorExceptionHandler#uncaughtException(Thread, Throwable)}
1019
         * method will be called.
1020
         * This class provides the following features:
1021
         * 1. Capturing and storing the uncaught exception.
1022
         * 2. Executing a list of routines when an exception occurs.
1023
         * 3. Providing access to the captured exception, if any.
1024
         * Example usage:
1025
         * <code>
1026
         * ProcessorExceptionHandler exceptionHandler = new
1027
         * ProcessorExceptionHandler(){};
1028
         * thread.setUncaughtExceptionHandler(exceptionHandler);
1029
         * </code>
1030
         *
1031
         * @author Joseph Verron
1032
         * @version ${version}
1033
         * @see Thread.UncaughtExceptionHandler
1034
         * @since 1.6.6
1035
         */
1036
        static class ProcessorExceptionHandler
1037
                implements Thread.UncaughtExceptionHandler {
1038
            private final AtomicReference<Throwable> exception;
1039
            private final List<Runnable> onException;
1040
1041
            /**
1042
             * Constructs a new instance for managing thread's uncaught exceptions.
1043
             * Once set to a thread, it retains the exception information and performs specified routines.
1044
             */
1045
            public ProcessorExceptionHandler() {
1046
                this.exception = new AtomicReference<>();
1047
                this.onException = new CopyOnWriteArrayList<>();
1048
            }
1049
1050
            /**
1051
             * {@inheritDoc}
1052
             * <p>
1053
             * Captures and stores an uncaught exception from a thread run
1054
             * and executes all defined routines on occurrence of the exception.
1055
             */
1056
            @Override public void uncaughtException(Thread t, Throwable e) {
1057 1 1. uncaughtException : removed call to java/util/concurrent/atomic/AtomicReference::set → KILLED
                exception.set(e);
1058 1 1. uncaughtException : removed call to java/util/List::forEach → TIMED_OUT
                onException.forEach(Runnable::run);
1059
            }
1060
1061
            /**
1062
             * Adds a routine to the list of routines that should be run
1063
             * when an exception occurs.
1064
             *
1065
             * @param runnable The runnable routine to be added
1066
             */
1067
            public void onException(ThrowingRunnable runnable) {
1068
                onException.add(runnable);
1069
            }
1070
1071
            /**
1072
             * Returns the captured exception if present.
1073
             *
1074
             * @return an {@link Optional} containing the captured exception,
1075
             * or an {@link Optional#empty()} if no exception was captured
1076
             */
1077
            public Optional<Throwable> exception() {
1078 1 1. exception : replaced return value with Optional.empty for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor$ProcessorExceptionHandler::exception → KILLED
                return Optional.ofNullable(exception.get());
1079
            }
1080
        }
1081
    }
1082
1083
    /**
1084
     * Repeats a table row for each element in a list.
1085
     *
1086
     * @author Joseph Verron
1087
     * @author Tom Hombergs
1088
     * @version ${version}
1089
     * @since 1.0.0
1090
     */
1091
    private static class RepeatProcessor
1092
            extends AbstractCommentProcessor
1093
            implements IRepeatProcessor {
1094
1095
        private final BiFunction<WordprocessingMLPackage, Tr, List<Tr>> nullSupplier;
1096
        private Map<Tr, List<Object>> tableRowsToRepeat = new HashMap<>();
1097
        private Map<Tr, Comment> tableRowsCommentsToRemove = new HashMap<>();
1098
1099
        private RepeatProcessor(
1100
                ParagraphPlaceholderReplacer placeholderReplacer,
1101
                BiFunction<WordprocessingMLPackage, Tr, List<Tr>> nullSupplier1
1102
        ) {
1103
            super(placeholderReplacer);
1104
            nullSupplier = nullSupplier1;
1105
        }
1106
1107
        /**
1108
         * Creates a new RepeatProcessor.
1109
         *
1110
         * @param pr The PlaceholderReplacer to use.
1111
         *
1112
         * @return A new RepeatProcessor.
1113
         */
1114
        public static CommentProcessor newInstance(ParagraphPlaceholderReplacer pr) {
1115 1 1. newInstance : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatProcessor::newInstance → KILLED
            return new RepeatProcessor(pr, (document, row) -> emptyList());
1116
        }
1117
1118
        /** {@inheritDoc} */
1119
        @Override public void commitChanges(DocxPart source) {
1120 1 1. commitChanges : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatProcessor::repeatRows → KILLED
            repeatRows(source);
1121
        }
1122
1123
        private void repeatRows(DocxPart source) {
1124
            for (Map.Entry<Tr, List<Object>> entry : tableRowsToRepeat.entrySet()) {
1125
                Tr row = entry.getKey();
1126
                List<Object> expressionContexts = entry.getValue();
1127
1128
                Tbl table = (Tbl) XmlUtils.unwrap(row.getParent());
1129
                var content = table.getContent();
1130
                int index = content.indexOf(row);
1131
                content.remove(row);
1132
1133
                List<Tr> changes;
1134 1 1. repeatRows : negated conditional → KILLED
                if (expressionContexts == null) {
1135
                    changes = nullSupplier.apply(source.document(), row);
1136
                }
1137
                else {
1138
                    changes = new ArrayList<>();
1139
                    for (Object expressionContext : expressionContexts) {
1140
                        Tr rowClone = XmlUtils.deepCopy(row);
1141
                        Comment commentWrapper = requireNonNull(tableRowsCommentsToRemove.get(row));
1142
                        Comments.Comment comment = requireNonNull(commentWrapper.getComment());
1143
                        BigInteger commentId = comment.getId();
1144 1 1. repeatRows : removed call to pro/verron/officestamper/core/CommentUtil::deleteCommentFromElements → KILLED
                        CommentUtil.deleteCommentFromElements(rowClone.getContent(), commentId);
1145
                        new ParagraphResolverDocumentWalker(source,
1146
                                rowClone,
1147
                                expressionContext,
1148 1 1. repeatRows : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$ParagraphResolverDocumentWalker::walk → KILLED
                                this.placeholderReplacer).walk();
1149
                        changes.add(rowClone);
1150
                    }
1151
                }
1152
                content.addAll(index, changes);
1153
            }
1154
        }
1155
1156
        /** {@inheritDoc} */
1157
        @Override public void reset() {
1158
            this.tableRowsToRepeat = new HashMap<>();
1159
            this.tableRowsCommentsToRemove = new HashMap<>();
1160
        }
1161
1162
        /** {@inheritDoc} */
1163
        @Override public void repeatTableRow(List<Object> objects) {
1164
            var row = parentRow(getParagraph());
1165
            tableRowsToRepeat.put(row, objects);
1166
            tableRowsCommentsToRemove.put(row, getCurrentCommentWrapper());
1167
        }
1168
    }
1169
1170
    /**
1171
     * Processor for the {@link IDisplayIfProcessor} comment.
1172
     *
1173
     * @author Joseph Verron
1174
     * @author Tom Hombergs
1175
     * @version ${version}
1176
     * @since 1.0.0
1177
     */
1178
    private static class DisplayIfProcessor
1179
            extends AbstractCommentProcessor
1180
            implements IDisplayIfProcessor {
1181
1182
        private List<P> paragraphsToBeRemoved = new ArrayList<>();
1183
        private List<Tbl> tablesToBeRemoved = new ArrayList<>();
1184
        private List<Tr> tableRowsToBeRemoved = new ArrayList<>();
1185
1186
        private DisplayIfProcessor(ParagraphPlaceholderReplacer placeholderReplacer) {
1187
            super(placeholderReplacer);
1188
        }
1189
1190
        /**
1191
         * Creates a new DisplayIfProcessor instance.
1192
         *
1193
         * @param pr the {@link PlaceholderReplacer} used for replacing expressions.
1194
         *
1195
         * @return a new DisplayIfProcessor instance.
1196
         */
1197
        public static CommentProcessor newInstance(ParagraphPlaceholderReplacer pr) {
1198 1 1. newInstance : replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$DisplayIfProcessor::newInstance → KILLED
            return new DisplayIfProcessor(pr);
1199
        }
1200
1201
        /** {@inheritDoc} */
1202
        @Override public void commitChanges(DocxPart source) {
1203 1 1. commitChanges : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$DisplayIfProcessor::removeParagraphs → KILLED
            removeParagraphs();
1204 1 1. commitChanges : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$DisplayIfProcessor::removeTables → KILLED
            removeTables();
1205 1 1. commitChanges : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$DisplayIfProcessor::removeTableRows → KILLED
            removeTableRows();
1206
        }
1207
1208
        private void removeParagraphs() {
1209
            for (P p : paragraphsToBeRemoved) {
1210 1 1. removeParagraphs : removed call to pro/verron/officestamper/core/ObjectDeleter::deleteParagraph → KILLED
                ObjectDeleter.deleteParagraph(p);
1211
            }
1212
        }
1213
1214
        private void removeTables() {
1215
            for (Tbl table : tablesToBeRemoved) {
1216 1 1. removeTables : removed call to pro/verron/officestamper/core/ObjectDeleter::deleteTable → KILLED
                ObjectDeleter.deleteTable(table);
1217
            }
1218
        }
1219
1220
        private void removeTableRows() {
1221
            for (Tr row : tableRowsToBeRemoved) {
1222 1 1. removeTableRows : removed call to pro/verron/officestamper/core/ObjectDeleter::deleteTableRow → KILLED
                ObjectDeleter.deleteTableRow(row);
1223
            }
1224
        }
1225
1226
        /** {@inheritDoc} */
1227
        @Override public void reset() {
1228
            paragraphsToBeRemoved = new ArrayList<>();
1229
            tablesToBeRemoved = new ArrayList<>();
1230
            tableRowsToBeRemoved = new ArrayList<>();
1231
        }
1232
1233
        /** {@inheritDoc} */
1234
        @Override public void displayParagraphIf(Boolean condition) {
1235 1 1. displayParagraphIf : negated conditional → KILLED
            if (Boolean.TRUE.equals(condition)) return;
1236
            paragraphsToBeRemoved.add(getParagraph());
1237
        }
1238
1239
        /** {@inheritDoc} */
1240
        @Override public void displayParagraphIfPresent(@Nullable Object condition) {
1241 2 1. displayParagraphIfPresent : removed call to pro/verron/officestamper/preset/CommentProcessorFactory$DisplayIfProcessor::displayParagraphIf → SURVIVED
2. displayParagraphIfPresent : negated conditional → KILLED
            displayParagraphIf(condition != null);
1242
        }
1243
1244
        /** {@inheritDoc} */
1245
        @Override public void displayTableRowIf(Boolean condition) {
1246 1 1. displayTableRowIf : negated conditional → KILLED
            if (Boolean.TRUE.equals(condition)) return;
1247
            P p = getParagraph();
1248
            var tr = parentRow(p);
1249
            tableRowsToBeRemoved.add(tr);
1250
        }
1251
1252
        /** {@inheritDoc} */
1253
        @Override public void displayTableIf(Boolean condition) {
1254 1 1. displayTableIf : negated conditional → KILLED
            if (Boolean.TRUE.equals(condition)) return;
1255
            tablesToBeRemoved.add(parentTable(getParagraph()));
1256
        }
1257
    }
1258
}

Mutations

59

1.1
Location : parentTable
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#23]
negated conditional → KILLED

60

1.1
Location : parentTable
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#23]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::parentTable → KILLED

65

1.1
Location : parentRow
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#22]
negated conditional → KILLED

66

1.1
Location : parentRow
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#22]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::parentRow → KILLED

71

1.1
Location : parentCell
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#22]
negated conditional → KILLED

72

1.1
Location : parentCell
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#22]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::parentCell → KILLED

84

1.1
Location : repeatParagraph
Killed by : pro.verron.officestamper.test.SpelInjectionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.SpelInjectionTest]/[method:spelInjectionTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::repeatParagraph → KILLED

95

1.1
Location : repeatDocPart
Killed by : pro.verron.officestamper.test.SpelInjectionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.SpelInjectionTest]/[method:spelInjectionTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::repeatDocPart → KILLED

99

1.1
Location : lambda$getStamper$0
Killed by : none
removed call to pro/verron/officestamper/core/DocxStamper::stamp → TIMED_OUT

2.2
Location : getStamper
Killed by : pro.verron.officestamper.test.RepeatDocPartBadPlaceholderTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RepeatDocPartBadPlaceholderTest]/[method:testBadExpressionShouldNotBlockCallerThread()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::getStamper → KILLED

110

1.1
Location : repeat
Killed by : pro.verron.officestamper.test.SpelInjectionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.SpelInjectionTest]/[method:spelInjectionTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::repeat → KILLED

121

1.1
Location : tableResolver
Killed by : pro.verron.officestamper.test.SpelInjectionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.SpelInjectionTest]/[method:spelInjectionTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::tableResolver → KILLED

132

1.1
Location : displayIf
Killed by : pro.verron.officestamper.test.SpelInjectionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.SpelInjectionTest]/[method:spelInjectionTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::displayIf → KILLED

143

1.1
Location : replaceWith
Killed by : pro.verron.officestamper.test.SpelInjectionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.SpelInjectionTest]/[method:spelInjectionTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory::replaceWith → KILLED

336

1.1
Location : newInstance
Killed by : pro.verron.officestamper.test.SpelInjectionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.SpelInjectionTest]/[method:spelInjectionTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::newInstance → KILLED

356

1.1
Location : commitChanges
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
negated conditional → KILLED

357

1.1
Location : commitChanges
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::replaceTableInplace → KILLED

376

1.1
Location : reset
Killed by : none
removed call to java/util/Map::clear → SURVIVED
Covering tests

386

1.1
Location : replaceTableInplace
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::growAndFillRow → KILLED

388

1.1
Location : replaceTableInplace
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
negated conditional → KILLED

390

1.1
Location : replaceTableInplace
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::growAndFillRow → KILLED

402

1.1
Location : growAndFillRow
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
negated conditional → KILLED

2.2
Location : growAndFillRow
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::setCellText → KILLED

404

1.1
Location : growAndFillRow
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

2.2
Location : growAndFillRow
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
negated conditional → KILLED

408

1.1
Location : growAndFillRow
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::setCellText → KILLED

417

1.1
Location : copyRowFromTemplate
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
negated conditional → KILLED

2.2
Location : copyRowFromTemplate
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
changed conditional boundary → KILLED

420

1.1
Location : copyRowFromTemplate
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::setCellText → KILLED

422

1.1
Location : copyRowFromTemplate
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$TableResolver::copyRowFromTemplate → KILLED

427

1.1
Location : setCellText
Killed by : pro.verron.officestamper.test.StampTableTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.StampTableTest]/[method:stampTableTest()]
removed call to java/util/List::clear → KILLED

462

1.1
Location : newInstance
Killed by : pro.verron.officestamper.test.SpelInjectionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.SpelInjectionTest]/[method:spelInjectionTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$ReplaceWithProcessor::newInstance → KILLED

485

1.1
Location : replaceWordWith
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#30]
negated conditional → KILLED

491

1.1
Location : replaceWordWith
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#30]
negated conditional → KILLED

498

1.1
Location : replaceWordWith
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#30]
removed call to java/util/List::clear → KILLED

541

1.1
Location : newInstance
Killed by : pro.verron.officestamper.test.SpelInjectionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.SpelInjectionTest]/[method:spelInjectionTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$ParagraphRepeatProcessor::newInstance → KILLED

562

1.1
Location : repeatParagraph
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

2.2
Location : repeatParagraph
Killed by : none
negated conditional → SURVIVED
Covering tests

564

1.1
Location : repeatParagraph
Killed by : none
removed call to org/docx4j/wml/PPr::setSectPr → NO_COVERAGE

586

1.1
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

587

1.1
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#7]
negated conditional → KILLED

2.2
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

589

1.1
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#7]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$ParagraphRepeatProcessor::getParagraphsInsideComment → KILLED

2.2
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

3.3
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

592

1.1
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

595

1.1
Location : getParagraphsInsideComment
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

2.2
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

3.3
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

4.4
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
Replaced integer addition with subtraction → KILLED

597

1.1
Location : getParagraphsInsideComment
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

599

1.1
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

602

1.1
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

604

1.1
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

2.2
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

613

1.1
Location : getParagraphsInsideComment
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$ParagraphRepeatProcessor::getParagraphsInsideComment → KILLED

626

1.1
Location : commitChanges
Killed by : none
changed conditional boundary → SURVIVED
Covering tests

2.2
Location : commitChanges
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

631

1.1
Location : commitChanges
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

634

1.1
Location : commitChanges
Killed by : none
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$ParagraphRepeatProcessor::restoreFirstSectionBreakIfNeeded → SURVIVED
Covering tests

654

1.1
Location : generateParagraphsToAdd
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

2.2
Location : generateParagraphsToAdd
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

3.3
Location : generateParagraphsToAdd
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

4.4
Location : generateParagraphsToAdd
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

657

1.1
Location : generateParagraphsToAdd
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
removed call to pro/verron/officestamper/core/SectionUtil::applySectionBreakToParagraph → KILLED

664

1.1
Location : generateParagraphsToAdd
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
removed call to pro/verron/officestamper/core/CommentUtil::deleteCommentFromElements → KILLED

666

1.1
Location : generateParagraphsToAdd
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
removed call to pro/verron/officestamper/api/ParagraphPlaceholderReplacer::resolveExpressionsForParagraph → KILLED

670

1.1
Location : generateParagraphsToAdd
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$ParagraphRepeatProcessor::generateParagraphsToAdd → KILLED

676

1.1
Location : restoreFirstSectionBreakIfNeeded
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#14]
negated conditional → KILLED

678

1.1
Location : restoreFirstSectionBreakIfNeeded
Killed by : none
removed call to pro/verron/officestamper/core/SectionUtil::applySectionBreakToParagraph → NO_COVERAGE

742

1.1
Location : onParagraph
Killed by : pro.verron.officestamper.test.MultiStampTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.MultiStampTest]/[method:expressionsAreResolvedOnMultiStamp()]
removed call to pro/verron/officestamper/api/ParagraphPlaceholderReplacer::resolveExpressionsForParagraph → KILLED

788

1.1
Location : newInstance
Killed by : pro.verron.officestamper.test.SpelInjectionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.SpelInjectionTest]/[method:spelInjectionTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::newInstance → KILLED

795

1.1
Location : repeatDocPart
Killed by : pro.verron.officestamper.test.RepeatDocPartBadPlaceholderTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RepeatDocPartBadPlaceholderTest]/[method:testBadExpressionShouldNotBlockCallerThread()]
negated conditional → KILLED

800

1.1
Location : repeatDocPart
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#1]
negated conditional → KILLED

817

1.1
Location : commitChanges
Killed by : pro.verron.officestamper.test.RepeatDocPartBadPlaceholderTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RepeatDocPartBadPlaceholderTest]/[method:testBadExpressionShouldNotBlockCallerThread()]
negated conditional → KILLED

844

1.1
Location : lambda$stampSubDocuments$0
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#9]
replaced return value with Collections.emptyMap for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::lambda$stampSubDocuments$0 → KILLED

855

1.1
Location : lambda$stampSubDocuments$1
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#9]
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::recursivelyReplaceImages → KILLED

2.2
Location : stampSubDocuments
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#9]
removed call to java/util/stream/Stream::forEach → KILLED

856

1.1
Location : stampSubDocuments
Killed by : none
removed call to java/util/List::forEach → SURVIVED
Covering tests

2.2
Location : lambda$stampSubDocuments$2
Killed by : none
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::setParentIfPossible → SURVIVED Covering tests

859

1.1
Location : stampSubDocuments
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#3]
replaced return value with Collections.emptyList for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::stampSubDocuments → KILLED

867

1.1
Location : lambda$stampSubDocuments$3
Killed by : none
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::copy → TIMED_OUT

868

1.1
Location : lambda$stampSubDocuments$4
Killed by : none
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::stamp → TIMED_OUT

871

1.1
Location : stampSubDocuments
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#3]
replaced return value with Collections.emptyList for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::stampSubDocuments → KILLED

879

1.1
Location : documentAsInsertableElements
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#15]
negated conditional → KILLED

2.2
Location : documentAsInsertableElements
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#18]
negated conditional → KILLED

880

1.1
Location : documentAsInsertableElements
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#15]
negated conditional → KILLED

881

1.1
Location : documentAsInsertableElements
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#15]
removed call to pro/verron/officestamper/core/SectionUtil::applySectionBreakToParagraph → KILLED

887

1.1
Location : documentAsInsertableElements
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#17]
removed call to pro/verron/officestamper/core/SectionUtil::applySectionBreakToParagraph → KILLED

891

1.1
Location : documentAsInsertableElements
Killed by : pro.verron.officestamper.test.RegressionTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RegressionTests]/[test-template:test52(pro.verron.officestamper.test.RegressionTests$Conditions, java.lang.String)]/[test-template-invocation:#3]
replaced return value with Collections.emptyList for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor::documentAsInsertableElements → KILLED

899

1.1
Location : recursivelyReplaceImages
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#9]
negated conditional → KILLED

901

1.1
Location : recursivelyReplaceImages
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#9]
negated conditional → KILLED

2.2
Location : recursivelyReplaceImages
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#9]
negated conditional → KILLED

902

1.1
Location : recursivelyReplaceImages
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#9]
negated conditional → KILLED

904

1.1
Location : recursivelyReplaceImages
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#9]
removed call to java/util/List::add → KILLED

920

1.1
Location : setParentIfPossible
Killed by : none
removed call to org/jvnet/jaxb2_commons/ppp/Child::setParent → SURVIVED
Covering tests

2.2
Location : setParentIfPossible
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#17]
negated conditional → KILLED

930

1.1
Location : outputWord
Killed by : none
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor$ProcessorExceptionHandler::onException → SURVIVED
Covering tests

931

1.1
Location : outputWord
Killed by : none
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor$ProcessorExceptionHandler::onException → TIMED_OUT

933

1.1
Location : lambda$outputWord$5
Killed by : none
removed call to java/util/function/Consumer::accept → TIMED_OUT

934

1.1
Location : outputWord
Killed by : none
removed call to java/lang/Thread::setUncaughtExceptionHandler → TIMED_OUT

935

1.1
Location : outputWord
Killed by : none
removed call to java/lang/Thread::start → TIMED_OUT

937

1.1
Location : outputWord
Killed by : none
removed call to java/lang/Thread::join → SURVIVED
Covering tests

942

1.1
Location : outputWord
Killed by : pro.verron.officestamper.test.RepeatDocPartBadPlaceholderTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RepeatDocPartBadPlaceholderTest]/[method:testBadExpressionShouldNotBlockCallerThread()]
removed call to java/util/Optional::ifPresent → KILLED

947

1.1
Location : outputWord
Killed by : none
removed call to java/util/Optional::ifPresent → NO_COVERAGE

949

1.1
Location : outputWord
Killed by : none
removed call to java/lang/Thread::interrupt → NO_COVERAGE

958

1.1
Location : copy
Killed by : none
removed call to org/docx4j/openpackaging/packages/WordprocessingMLPackage::save → TIMED_OUT

967

1.1
Location : stamp
Killed by : none
removed call to pro/verron/officestamper/api/OfficeStamper::stamp → TIMED_OUT

974

1.1
Location : reset
Killed by : none
removed call to java/util/Map::clear → SURVIVED
Covering tests

996

1.1
Location : run
Killed by : none
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor$ThrowingRunnable::throwingRun → TIMED_OUT

1057

1.1
Location : uncaughtException
Killed by : pro.verron.officestamper.test.RepeatDocPartBadPlaceholderTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RepeatDocPartBadPlaceholderTest]/[method:testBadExpressionShouldNotBlockCallerThread()]
removed call to java/util/concurrent/atomic/AtomicReference::set → KILLED

1058

1.1
Location : uncaughtException
Killed by : none
removed call to java/util/List::forEach → TIMED_OUT

1078

1.1
Location : exception
Killed by : pro.verron.officestamper.test.RepeatDocPartBadPlaceholderTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.RepeatDocPartBadPlaceholderTest]/[method:testBadExpressionShouldNotBlockCallerThread()]
replaced return value with Optional.empty for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatDocPartProcessor$ProcessorExceptionHandler::exception → KILLED

1115

1.1
Location : newInstance
Killed by : pro.verron.officestamper.test.SpelInjectionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.SpelInjectionTest]/[method:spelInjectionTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$RepeatProcessor::newInstance → KILLED

1120

1.1
Location : commitChanges
Killed by : pro.verron.officestamper.test.MultiStampTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.MultiStampTest]/[method:expressionsAreResolvedOnMultiStamp()]
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$RepeatProcessor::repeatRows → KILLED

1134

1.1
Location : repeatRows
Killed by : pro.verron.officestamper.test.MultiStampTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.MultiStampTest]/[method:expressionsAreResolvedOnMultiStamp()]
negated conditional → KILLED

1144

1.1
Location : repeatRows
Killed by : pro.verron.officestamper.test.MultiStampTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.MultiStampTest]/[method:expressionsAreResolvedOnMultiStamp()]
removed call to pro/verron/officestamper/core/CommentUtil::deleteCommentFromElements → KILLED

1148

1.1
Location : repeatRows
Killed by : pro.verron.officestamper.test.MultiStampTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.MultiStampTest]/[method:expressionsAreResolvedOnMultiStamp()]
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$ParagraphResolverDocumentWalker::walk → KILLED

1198

1.1
Location : newInstance
Killed by : pro.verron.officestamper.test.SpelInjectionTest.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.SpelInjectionTest]/[method:spelInjectionTest()]
replaced return value with null for pro/verron/officestamper/preset/CommentProcessorFactory$DisplayIfProcessor::newInstance → KILLED

1203

1.1
Location : commitChanges
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#20]
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$DisplayIfProcessor::removeParagraphs → KILLED

1204

1.1
Location : commitChanges
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#23]
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$DisplayIfProcessor::removeTables → KILLED

1205

1.1
Location : commitChanges
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#22]
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$DisplayIfProcessor::removeTableRows → KILLED

1210

1.1
Location : removeParagraphs
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#20]
removed call to pro/verron/officestamper/core/ObjectDeleter::deleteParagraph → KILLED

1216

1.1
Location : removeTables
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#23]
removed call to pro/verron/officestamper/core/ObjectDeleter::deleteTable → KILLED

1222

1.1
Location : removeTableRows
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#22]
removed call to pro/verron/officestamper/core/ObjectDeleter::deleteTableRow → KILLED

1235

1.1
Location : displayParagraphIf
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#21]
negated conditional → KILLED

1241

1.1
Location : displayParagraphIfPresent
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#35]
negated conditional → KILLED

2.2
Location : displayParagraphIfPresent
Killed by : none
removed call to pro/verron/officestamper/preset/CommentProcessorFactory$DisplayIfProcessor::displayParagraphIf → SURVIVED
Covering tests

1246

1.1
Location : displayTableRowIf
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#22]
negated conditional → KILLED

1254

1.1
Location : displayTableIf
Killed by : pro.verron.officestamper.test.DefaultTests.[engine:junit-jupiter]/[class:pro.verron.officestamper.test.DefaultTests]/[test-template:features(java.lang.String, pro.verron.officestamper.api.OfficeStamperConfiguration, java.lang.Object, java.io.InputStream, java.lang.String)]/[test-template-invocation:#23]
negated conditional → KILLED

Active mutators

Tests examined


Report generated by PIT 1.17.0