Buggy code:
public abstract class RungeKuttaIntegrator extends AbstractIntegrator { protected RungeKuttaIntegrator ( final String name , final double [ ] c , final double [ ] [ ] a , final double [ ] b , final RungeKuttaStepInterpolator prototype , final double step ) { } public double integrate ( final FirstOrderDifferentialEquations equations , final double t0 , final double [ ] y0 , final double t , final double [ ] y ) throws DerivativeException , IntegratorException { sanityChecks ( equations , t0 , y0 , t , y ) ; final boolean forward = t > t0 ; final int stages = ( c . length ) + 1 ; if ( y != y0 ) { System . arraycopy ( y0 , 0 , y , 0 , y0 . length ) ; } final double [ ] [ ] yDotK = new double [ stages ] [ ] ; for ( int i = 0 ; i < stages ; ++ i ) { yDotK [ i ] = new double [ y0 . length ] ; } final double [ ] yTmp = new double [ y0 . length ] ; AbstractStepInterpolator interpolator ; if ( ( requiresDenseOutput ( ) ) || ( ! ( eventsHandlersManager . isEmpty ( ) ) ) ) { final RungeKuttaStepInterpolator rki = ( ( RungeKuttaStepInterpolator ) ( prototype . copy ( ) ) ) ; rki . reinitialize ( equations , yTmp , yDotK , forward ) ; interpolator = rki ; } else { interpolator = new DummyStepInterpolator ( yTmp , forward ) ; } interpolator . storeTime ( t0 ) ; stepStart = t0 ; stepSize = step ; for ( StepHandler handler : stepHandlers ) { handler . reset ( ) ; } <START_BUG> CombinedEventsManager manager = addEndTimeChecker ( t , eventsHandlersManager ) ; <END_BUG> boolean lastStep = false ; while ( ! lastStep ) { interpolator . shift ( ) ; for ( boolean loop = true ; loop ; ) { equations . computeDerivatives ( stepStart , y , yDotK [ 0 ] ) ; 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 ) ; } interpolator . storeTime ( ( ( stepStart ) + ( stepSize ) ) ) ; if ( manager . evaluateStep ( interpolator ) ) { stepSize = ( manager . getEventTime ( ) ) - ( stepStart ) ; } else { loop = false ; } } final double nextStep = ( stepStart ) + ( stepSize ) ; System . arraycopy ( yTmp , 0 , y , 0 , y0 . length ) ; manager . stepAccepted ( nextStep , y ) ; lastStep = manager . stop ( ) ; interpolator . storeTime ( nextStep ) ; for ( StepHandler handler : stepHandlers ) { handler . handleStep ( interpolator , lastStep ) ; } stepStart = nextStep ; if ( ( manager . reset ( stepStart , y ) ) && ( ! lastStep ) ) { equations . computeDerivatives ( stepStart , y , yDotK [ 0 ] ) ; } stepSize = step ; } final double stopTime = stepStart ; stepStart = Double . NaN ; stepSize = Double . NaN ; return stopTime ; } private double [ ] c ; private double [ ] [ ] a ; private double [ ] b ; private RungeKuttaStepInterpolator prototype ; private double step ; }

Fix:
CombinedEventsManager manager = addEndTimeChecker ( t0 , t , eventsHandlersManager ) ;