DoubleChromosome.java

1
package net.bmahe.genetics4j.core.chromosomes;
2
3
import java.util.Arrays;
4
import java.util.Objects;
5
6
import org.apache.commons.lang3.Validate;
7
8
/**
9
 * A chromosome implementation that represents genetic information as an array of double-precision floating-point values.
10
 * 
11
 * <p>DoubleChromosome is ideal for continuous optimization problems where solutions can be encoded as
12
 * real-valued vectors. This chromosome type provides high precision for numerical optimization tasks
13
 * and is commonly used in function optimization, neural network weight evolution, and parameter tuning.
14
 * 
15
 * <p>This chromosome type is particularly suitable for:
16
 * <ul>
17
 * <li><strong>Continuous optimization</strong>: Function minimization/maximization with real-valued parameters</li>
18
 * <li><strong>Neural network evolution</strong>: Evolving connection weights and biases</li>
19
 * <li><strong>Engineering optimization</strong>: Design parameters with continuous constraints</li>
20
 * <li><strong>Scientific computing</strong>: Model parameter estimation and calibration</li>
21
 * <li><strong>Financial modeling</strong>: Portfolio optimization and risk parameter tuning</li>
22
 * <li><strong>Machine learning</strong>: Hyperparameter optimization for continuous parameters</li>
23
 * </ul>
24
 * 
25
 * <p>Key characteristics:
26
 * <ul>
27
 * <li><strong>High precision</strong>: 64-bit floating-point representation for accurate computations</li>
28
 * <li><strong>Bounded values</strong>: All doubles are constrained to [minValue, maxValue]</li>
29
 * <li><strong>Fixed length</strong>: Chromosome size is determined at creation time</li>
30
 * <li><strong>Immutable</strong>: Values cannot be changed after construction</li>
31
 * <li><strong>IEEE 754 compliant</strong>: Standard floating-point arithmetic and comparisons</li>
32
 * </ul>
33
 * 
34
 * <p>The chromosome maintains bounds information which is used by genetic operators such as:
35
 * <ul>
36
 * <li><strong>Arithmetic crossover</strong>: Weighted averaging of parent values</li>
37
 * <li><strong>Gaussian mutation</strong>: Adding normally distributed noise</li>
38
 * <li><strong>Uniform mutation</strong>: Random replacement within bounds</li>
39
 * <li><strong>Creep mutation</strong>: Small incremental changes</li>
40
 * </ul>
41
 * 
42
 * <p>Special considerations for floating-point chromosomes:
43
 * <ul>
44
 * <li><strong>Precision handling</strong>: Be aware of floating-point precision limits</li>
45
 * <li><strong>Boundary conditions</strong>: Handle edge cases at min/max values</li>
46
 * <li><strong>Convergence</strong>: May require epsilon-based convergence criteria</li>
47
 * <li><strong>Scaling</strong>: Consider normalizing parameters for better performance</li>
48
 * </ul>
49
 * 
50
 * @see Chromosome
51
 * @see net.bmahe.genetics4j.core.spec.chromosome.DoubleChromosomeSpec
52
 * @see net.bmahe.genetics4j.core.chromosomes.factory.DoubleChromosomeFactory
53
 * @see FloatChromosome
54
 */
55
public class DoubleChromosome implements Chromosome {
56
57
	private final int size;
58
	private final double minValue;
59
	private final double maxValue;
60
	private final double[] values;
61
62
	/**
63
	 * Creates a new double chromosome with the specified parameters and values.
64
	 * 
65
	 * @param _size the number of double values in this chromosome
66
	 * @param _minValue the minimum allowed value for any double in this chromosome
67
	 * @param _maxValue the maximum allowed value for any double in this chromosome
68
	 * @param _values the array of double values for this chromosome
69
	 * @throws IllegalArgumentException if size is not positive, if minValue > maxValue,
70
	 *                                  if values array is null, or if the array length
71
	 *                                  doesn't match the specified size
72
	 */
73
	public DoubleChromosome(final int _size, final double _minValue, final double _maxValue, final double[] _values) {
74
		Validate.isTrue(_size > 0);
75
		Validate.isTrue(_minValue <= _maxValue);
76
		Validate.notNull(_values);
77
		Validate.isTrue(_size == _values.length, "Provided size does not match the size of the content");
78
79 1 1. <init> : Removed assignment to member variable size → KILLED
		this.size = _size;
80 1 1. <init> : Removed assignment to member variable minValue → KILLED
		this.minValue = _minValue;
81 1 1. <init> : Removed assignment to member variable maxValue → KILLED
		this.maxValue = _maxValue;
82 3 1. <init> : Removed assignment to member variable values → KILLED
2. <init> : removed call to java/util/Arrays::copyOf → KILLED
3. <init> : replaced call to java/util/Arrays::copyOf with argument → KILLED
		this.values = Arrays.copyOf(_values, _size);
83
	}
84
85
	@Override
86
	public int getNumAlleles() {
87 1 1. getNumAlleles : replaced int return with 0 for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::getNumAlleles → KILLED
		return size;
88
	}
89
90
	/**
91
	 * Returns the double value at the specified index.
92
	 * 
93
	 * @param index the index of the allele to retrieve (0-based)
94
	 * @return the double value at the specified position
95
	 * @throws IllegalArgumentException if index is negative or greater than or equal to the chromosome size
96
	 */
97
	public double getAllele(final int index) {
98
		Validate.inclusiveBetween(0, size - 1, index);
99
100 1 1. getAllele : replaced double return with 0.0d for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::getAllele → KILLED
		return values[index];
101
	}
102
103
	/**
104
	 * Returns the number of double values in this chromosome.
105
	 * 
106
	 * @return the chromosome size
107
	 */
108
	public int getSize() {
109 1 1. getSize : replaced int return with 0 for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::getSize → KILLED
		return size;
110
	}
111
112
	/**
113
	 * Returns the minimum allowed value for doubles in this chromosome.
114
	 * 
115
	 * @return the minimum value constraint
116
	 */
117
	public double getMinValue() {
118 1 1. getMinValue : replaced double return with 0.0d for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::getMinValue → KILLED
		return minValue;
119
	}
120
121
	/**
122
	 * Returns the maximum allowed value for doubles in this chromosome.
123
	 * 
124
	 * @return the maximum value constraint
125
	 */
126
	public double getMaxValue() {
127 1 1. getMaxValue : replaced double return with 0.0d for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::getMaxValue → KILLED
		return maxValue;
128
	}
129
130
	/**
131
	 * Returns a copy of the double values in this chromosome.
132
	 * 
133
	 * <p>The returned array is a defensive copy; modifications to it will not
134
	 * affect this chromosome.
135
	 * 
136
	 * @return a copy of the double values array
137
	 */
138
	public double[] getValues() {
139 1 1. getValues : replaced return value with null for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::getValues → KILLED
		return values;
140
	}
141
142
	@Override
143
	public int hashCode() {
144 1 1. hashCode : Substituted 31 with 32 → NO_COVERAGE
		final int prime = 31;
145 1 1. hashCode : Substituted 1 with 0 → NO_COVERAGE
		int result = 1;
146 4 1. hashCode : removed call to java/util/Arrays::hashCode → NO_COVERAGE
2. hashCode : Substituted 31 with 32 → NO_COVERAGE
3. hashCode : Replaced integer addition with subtraction → NO_COVERAGE
4. hashCode : Replaced integer multiplication with division → NO_COVERAGE
		result = prime * result + Arrays.hashCode(values);
147
		result = prime * result + Objects.hash(maxValue, minValue, size);
148 1 1. hashCode : replaced int return with 0 for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::hashCode → NO_COVERAGE
		return result;
149
	}
150
151
	@Override
152
	public boolean equals(Object obj) {
153 2 1. equals : negated conditional → SURVIVED
2. equals : removed conditional - replaced equality check with true → SURVIVED
		if (this == obj)
154 2 1. equals : replaced boolean return with false for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::equals → NO_COVERAGE
2. equals : Substituted 1 with 0 → NO_COVERAGE
			return true;
155 3 1. equals : removed conditional - replaced equality check with false → SURVIVED
2. equals : removed conditional - replaced equality check with true → KILLED
3. equals : negated conditional → KILLED
		if (obj == null)
156 2 1. equals : Substituted 0 with 1 → NO_COVERAGE
2. equals : replaced boolean return with true for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::equals → NO_COVERAGE
			return false;
157 5 1. equals : removed conditional - replaced equality check with false → SURVIVED
2. equals : removed call to java/lang/Object::getClass → KILLED
3. equals : removed conditional - replaced equality check with true → KILLED
4. equals : negated conditional → KILLED
5. equals : removed call to java/lang/Object::getClass → KILLED
		if (getClass() != obj.getClass())
158 2 1. equals : Substituted 0 with 1 → NO_COVERAGE
2. equals : replaced boolean return with true for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::equals → NO_COVERAGE
			return false;
159
		DoubleChromosome other = (DoubleChromosome) obj;
160 6 1. equals : removed conditional - replaced equality check with true → SURVIVED
2. equals : replaced boolean return with true for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::equals → SURVIVED
3. equals : removed call to java/lang/Double::doubleToLongBits → KILLED
4. equals : negated conditional → KILLED
5. equals : removed call to java/lang/Double::doubleToLongBits → KILLED
6. equals : removed conditional - replaced equality check with false → KILLED
		return Double.doubleToLongBits(maxValue) == Double.doubleToLongBits(other.maxValue)
161 8 1. equals : removed conditional - replaced equality check with true → SURVIVED
2. equals : removed conditional - replaced equality check with true → SURVIVED
3. equals : removed conditional - replaced equality check with false → KILLED
4. equals : removed conditional - replaced equality check with false → KILLED
5. equals : negated conditional → KILLED
6. equals : removed call to java/lang/Double::doubleToLongBits → KILLED
7. equals : removed call to java/lang/Double::doubleToLongBits → KILLED
8. equals : negated conditional → KILLED
				&& Double.doubleToLongBits(minValue) == Double.doubleToLongBits(other.minValue) && size == other.size
162 6 1. equals : removed conditional - replaced equality check with true → SURVIVED
2. equals : Substituted 0 with 1 → NO_COVERAGE
3. equals : removed conditional - replaced equality check with false → KILLED
4. equals : removed call to java/util/Arrays::equals → KILLED
5. equals : negated conditional → KILLED
6. equals : Substituted 1 with 0 → KILLED
				&& Arrays.equals(values, other.values);
163
	}
164
165
	@Override
166
	public String toString() {
167 1 1. toString : replaced return value with "" for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::toString → NO_COVERAGE
		return "DoubleChromosome [size=" + size + ", minValue=" + minValue + ", maxValue=" + maxValue + ", values="
168 1 1. toString : removed call to java/util/Arrays::toString → NO_COVERAGE
				+ Arrays.toString(values) + "]";
169
	}
170
}

Mutations

79

1.1
Location : <init>
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
Removed assignment to member variable size → KILLED

80

1.1
Location : <init>
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
Removed assignment to member variable minValue → KILLED

81

1.1
Location : <init>
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
Removed assignment to member variable maxValue → KILLED

82

1.1
Location : <init>
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
Removed assignment to member variable values → KILLED

2.2
Location : <init>
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed call to java/util/Arrays::copyOf → KILLED

3.3
Location : <init>
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
replaced call to java/util/Arrays::copyOf with argument → KILLED

87

1.1
Location : getNumAlleles
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
replaced int return with 0 for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::getNumAlleles → KILLED

100

1.1
Location : getAllele
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
replaced double return with 0.0d for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::getAllele → KILLED

109

1.1
Location : getSize
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
replaced int return with 0 for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::getSize → KILLED

118

1.1
Location : getMinValue
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
replaced double return with 0.0d for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::getMinValue → KILLED

127

1.1
Location : getMaxValue
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
replaced double return with 0.0d for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::getMaxValue → KILLED

139

1.1
Location : getValues
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
replaced return value with null for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::getValues → KILLED

144

1.1
Location : hashCode
Killed by : none
Substituted 31 with 32 → NO_COVERAGE

145

1.1
Location : hashCode
Killed by : none
Substituted 1 with 0 → NO_COVERAGE

146

1.1
Location : hashCode
Killed by : none
removed call to java/util/Arrays::hashCode → NO_COVERAGE

2.2
Location : hashCode
Killed by : none
Substituted 31 with 32 → NO_COVERAGE

3.3
Location : hashCode
Killed by : none
Replaced integer addition with subtraction → NO_COVERAGE

4.4
Location : hashCode
Killed by : none
Replaced integer multiplication with division → NO_COVERAGE

148

1.1
Location : hashCode
Killed by : none
replaced int return with 0 for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::hashCode → NO_COVERAGE

153

1.1
Location : equals
Killed by : none
negated conditional → SURVIVED
Covering tests

2.2
Location : equals
Killed by : none
removed conditional - replaced equality check with true → SURVIVED Covering tests

154

1.1
Location : equals
Killed by : none
replaced boolean return with false for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::equals → NO_COVERAGE

2.2
Location : equals
Killed by : none
Substituted 1 with 0 → NO_COVERAGE

155

1.1
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed conditional - replaced equality check with true → KILLED

2.2
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
negated conditional → KILLED

3.3
Location : equals
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

156

1.1
Location : equals
Killed by : none
Substituted 0 with 1 → NO_COVERAGE

2.2
Location : equals
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::equals → NO_COVERAGE

157

1.1
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed call to java/lang/Object::getClass → KILLED

2.2
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed conditional - replaced equality check with true → KILLED

3.3
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
negated conditional → KILLED

4.4
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed call to java/lang/Object::getClass → KILLED

5.5
Location : equals
Killed by : none
removed conditional - replaced equality check with false → SURVIVED
Covering tests

158

1.1
Location : equals
Killed by : none
Substituted 0 with 1 → NO_COVERAGE

2.2
Location : equals
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::equals → NO_COVERAGE

160

1.1
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed call to java/lang/Double::doubleToLongBits → KILLED

2.2
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
negated conditional → KILLED

3.3
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed call to java/lang/Double::doubleToLongBits → KILLED

4.4
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed conditional - replaced equality check with false → KILLED

5.5
Location : equals
Killed by : none
removed conditional - replaced equality check with true → SURVIVED
Covering tests

6.6
Location : equals
Killed by : none
replaced boolean return with true for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::equals → SURVIVED Covering tests

161

1.1
Location : equals
Killed by : none
removed conditional - replaced equality check with true → SURVIVED
Covering tests

2.2
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed conditional - replaced equality check with false → KILLED

3.3
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed conditional - replaced equality check with false → KILLED

4.4
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
negated conditional → KILLED

5.5
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed call to java/lang/Double::doubleToLongBits → KILLED

6.6
Location : equals
Killed by : none
removed conditional - replaced equality check with true → SURVIVED Covering tests

7.7
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed call to java/lang/Double::doubleToLongBits → KILLED

8.8
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
negated conditional → KILLED

162

1.1
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed conditional - replaced equality check with false → KILLED

2.2
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
removed call to java/util/Arrays::equals → KILLED

3.3
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
negated conditional → KILLED

4.4
Location : equals
Killed by : none
removed conditional - replaced equality check with true → SURVIVED
Covering tests

5.5
Location : equals
Killed by : net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest.[engine:junit-jupiter]/[class:net.bmahe.genetics4j.core.chromosomes.DoubleChromosomeTest]/[method:simple()]
Substituted 1 with 0 → KILLED

6.6
Location : equals
Killed by : none
Substituted 0 with 1 → NO_COVERAGE

167

1.1
Location : toString
Killed by : none
replaced return value with "" for net/bmahe/genetics4j/core/chromosomes/DoubleChromosome::toString → NO_COVERAGE

168

1.1
Location : toString
Killed by : none
removed call to java/util/Arrays::toString → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.19.6