Buggy code:
public abstract class RungeKuttaFehlbergIntegrator extends AdaptiveStepsizeIntegrator { protected RungeKuttaFehlbergIntegrator ( boolean fsal , double [ ] c , double [ ] [ ] a , double [ ] b , RungeKuttaStepInterpolator prototype , double minStep , double maxStep , double scalAbsoluteTolerance , double scalRelativeTolerance ) { } protected RungeKuttaFehlbergIntegrator ( boolean fsal , double [ ] c , double [ ] [ ] a , double [ ] b , RungeKuttaStepInterpolator prototype , double minStep , double maxStep , double [ ] vecAbsoluteTolerance , double [ ] vecRelativeTolerance ) { } public abstract String getName ( ) { } public abstract int getOrder ( ) { } public double getSafety ( ) { } public void setSafety ( double safety ) { } public void integrate ( FirstOrderDifferentialEquations equations , double t0 , double [ ] y0 , double t , double [ ] y ) throws DerivativeException , IntegratorException { sanityChecks ( equations , t0 , y0 , t , y ) ; boolean forward = t > t0 ; int stages = ( c . length ) + 1 ; if ( y != y0 ) { System . arraycopy ( y0 , 0 , y , 0 , y0 . length ) ; } double [ ] [ ] yDotK = new double [ stages ] [ ] ; for ( int i = 0 ; i < stages ; ++ i ) { yDotK [ i ] = new double [ y0 . length ] ; } double [ ] yTmp = new double [ y0 . length ] ; AbstractStepInterpolator interpolator ; if ( ( handler . requiresDenseOutput ( ) ) || ( ! ( switchesHandler . isEmpty ( ) ) ) ) { <START_BUG> RungeKuttaStepInterpolator rki = ( ( RungeKuttaStepInterpolator ) ( prototype . clone ( ) ) ) ; <END_BUG> rki . reinitialize ( equations , yTmp , yDotK , forward ) ; interpolator = rki ; } else { interpolator = new DummyStepInterpolator ( yTmp , forward ) ; } interpolator . storeTime ( t0 ) ; stepStart = t0 ; double hNew = 0 ; boolean firstTime = true ; boolean lastStep ; handler . reset ( ) ; do { interpolator . shift ( ) ; double error = 0 ; for ( boolean loop = true ; loop ; ) { if ( firstTime || ( ! ( fsal ) ) ) { equations . computeDerivatives ( stepStart , y , yDotK [ 0 ] ) ; } if ( firstTime ) { double [ ] scale ; if ( ( vecAbsoluteTolerance ) != null ) { scale = vecAbsoluteTolerance ; } else { scale = new double [ y0 . length ] ; for ( int i = 0 ; i < ( scale . length ) ; ++ i ) { scale [ i ] = scalAbsoluteTolerance ; } } hNew = initializeStep ( equations , forward , getOrder ( ) , scale , stepStart , y , yDotK [ 0 ] , yTmp , yDotK [ 1 ] ) ; firstTime = false ; } stepSize = hNew ; if ( ( forward && ( ( ( stepStart ) + ( stepSize ) ) > t ) ) || ( ( ! forward ) && ( ( ( stepStart ) + ( stepSize ) ) < t ) ) ) { stepSize = t - ( stepStart ) ; } for ( int k = 1 ; k < stages ; ++ k ) { for ( int j = 0 ; j < ( y0 . length ) ; ++ j ) { double sum = ( a [ ( k - 1 ) ] [ 0 ] ) * ( yDotK [ 0 ] [ j ] ) ; for ( int l = 1 ; l < k ; ++ l ) { sum += ( a [ ( k - 1 ) ] [ l ] ) * ( yDotK [ l ] [ j ] ) ; } yTmp [ j ] = ( y [ j ] ) + ( ( stepSize ) * sum ) ; } equations . computeDerivatives ( ( ( stepStart ) + ( ( c [ ( k - 1 ) ] ) * ( stepSize ) ) ) , yTmp , yDotK [ k ] ) ; } for ( int j = 0 ; j < ( y0 . length ) ; ++ j ) { double sum = ( b [ 0 ] ) * ( yDotK [ 0 ] [ j ] ) ; for ( int l = 1 ; l < stages ; ++ l ) { sum += ( b [ l ] ) * ( yDotK [ l ] [ j ] ) ; } yTmp [ j ] = ( y [ j ] ) + ( ( stepSize ) * sum ) ; } error = estimateError ( yDotK , y , yTmp , stepSize ) ; if ( error <= 1.0 ) { interpolator . storeTime ( ( ( stepStart ) + ( stepSize ) ) ) ; if ( switchesHandler . evaluateStep ( interpolator ) ) { hNew = ( switchesHandler . getEventTime ( ) ) - ( stepStart ) ; } else { loop = false ; } } else { double factor = Math . min ( maxGrowth , Math . max ( minReduction , ( ( safety ) * ( Math . pow ( error , exp ) ) ) ) ) ; hNew = filterStep ( ( ( stepSize ) * factor ) , false ) ; } } stepStart += stepSize ; System . arraycopy ( yTmp , 0 , y , 0 , y0 . length ) ; switchesHandler . stepAccepted ( stepStart , y ) ; if ( switchesHandler . stop ( ) ) { lastStep = true ; }

Fix:
RungeKuttaStepInterpolator rki = ( ( RungeKuttaStepInterpolator ) ( prototype . copy ( ) ) ) ;