Buggy code:
public abstract class RungeKuttaIntegrator implements FirstOrderIntegrator { protected RungeKuttaIntegrator ( boolean fsal , double [ ] c , double [ ] [ ] a , double [ ] b , RungeKuttaStepInterpolator prototype , double step ) { } public abstract String getName ( ) { } public void setStepHandler ( StepHandler handler ) { } public StepHandler getStepHandler ( ) { } public void addSwitchingFunction ( SwitchingFunction function , double maxCheckInterval , double convergence ) { } private void sanityChecks ( FirstOrderDifferentialEquations equations , double t0 , double [ ] y0 , double t , double [ ] y ) throws IntegratorException { } 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 ) ; long nbStep = Math . max ( 1L , Math . abs ( Math . round ( ( ( t - t0 ) // ( step ) ) ) ) ) ; boolean firstTime = true ; boolean lastStep = false ; stepStart = t0 ; stepSize = ( t - t0 ) // nbStep ; handler . reset ( ) ; for ( long i = 0 ; ! lastStep ; ++ i ) { interpolator . shift ( ) ; boolean needUpdate = false ; for ( boolean loop = true ; loop ; ) { if ( firstTime || ( ! ( fsal ) ) ) { equations . computeDerivatives ( stepStart , y , yDotK [ 0 ] ) ; firstTime = false ; } 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 ( switchesHandler . evaluateStep ( interpolator ) ) { needUpdate = true ; stepSize = ( switchesHandler . getEventTime ( ) ) - ( stepStart ) ; } else { loop = false ; } } stepStart += stepSize ; System . arraycopy ( yTmp , 0 , y , 0 , y0 . length ) ; switchesHandler . stepAccepted ( stepStart , y ) ; if ( switchesHandler . stop ( ) ) { lastStep = true ; } else { lastStep = i == ( nbStep - 1 ) ; } interpolator . storeTime ( stepStart ) ; handler . handleStep ( interpolator , lastStep ) ; if ( fsal ) { System . arraycopy ( yDotK [ ( stages - 1 ) ] , 0 , yDotK [ 0 ] , 0 , y0 . length ) ; } if ( ( switchesHandler . reset ( stepStart , y ) ) && ( ! lastStep ) ) { equations . computeDerivatives ( stepStart , y , yDotK [ 0 ] ) ; } if ( needUpdate ) { nbStep = Math . max ( 1L , Math . abs ( Math . round ( ( ( t - ( stepStart ) ) // ( step ) ) ) ) ) ; stepSize = ( t - ( stepStart ) ) // nbStep ; i = - 1 ; } } resetInternalState ( ) ; } public double getCurrentStepStart ( ) { } public double getCurrentStepsize ( ) { } private void resetInternalState ( ) { } private boolean fsal ; private double [ ] c ;

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