@Test
  public void testResetAdditionalStateEvent() throws OrekitException {
    propagator.addAdditionalEquations(
        new AdditionalEquations() {

          public String getName() {
            return "linear";
          }

          public double[] computeDerivatives(SpacecraftState s, double[] pDot) {
            pDot[0] = 1.0;
            return null;
          }
        });
    propagator.setInitialState(propagator.getInitialState().addAdditionalState("linear", 1.5));

    CheckingHandler<AdditionalStateLinearDetector> checking =
        new CheckingHandler<AdditionalStateLinearDetector>(Action.RESET_STATE) {
          public SpacecraftState resetState(
              AdditionalStateLinearDetector detector, SpacecraftState oldState)
              throws OrekitException {
            return oldState.addAdditionalState(
                "linear", oldState.getAdditionalState("linear")[0] * 2);
          }
        };

    propagator.addEventDetector(
        new AdditionalStateLinearDetector(10.0, 1.0e-8).withHandler(checking));

    final double dt = 3200;
    checking.assertEvent(false);
    final SpacecraftState finalState = propagator.propagate(initDate.shiftedBy(dt));
    checking.assertEvent(true);
    Assert.assertEquals(dt + 4.5, finalState.getAdditionalState("linear")[0], 1.0e-8);
    Assert.assertEquals(dt, finalState.getDate().durationFrom(initDate), 1.0e-8);
  }
  @Test
  public void testEphemerisAdditionalState() throws OrekitException, IOException {

    // Propagation of the initial at t + dt
    final double dt = -3200;
    final double rate = 2.0;

    propagator.addAdditionalStateProvider(
        new AdditionalStateProvider() {
          public String getName() {
            return "squaredA";
          }

          public double[] getAdditionalState(SpacecraftState state) {
            return new double[] {state.getA() * state.getA()};
          }
        });
    propagator.addAdditionalEquations(
        new AdditionalEquations() {
          public String getName() {
            return "extra";
          }

          public double[] computeDerivatives(SpacecraftState s, double[] pDot) {
            pDot[0] = rate;
            return null;
          }
        });
    propagator.setInitialState(propagator.getInitialState().addAdditionalState("extra", 1.5));

    propagator.setOrbitType(OrbitType.CARTESIAN);
    propagator.setEphemerisMode();
    propagator.propagate(initDate.shiftedBy(dt));
    final BoundedPropagator ephemeris1 = propagator.getGeneratedEphemeris();
    Assert.assertEquals(initDate.shiftedBy(dt), ephemeris1.getMinDate());
    Assert.assertEquals(initDate, ephemeris1.getMaxDate());
    try {
      ephemeris1.propagate(ephemeris1.getMinDate().shiftedBy(-10.0));
      Assert.fail("an exception should have been thrown");
    } catch (PropagationException pe) {
      Assert.assertEquals(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE, pe.getSpecifier());
    }
    try {
      ephemeris1.propagate(ephemeris1.getMaxDate().shiftedBy(+10.0));
      Assert.fail("an exception should have been thrown");
    } catch (PropagationException pe) {
      Assert.assertEquals(OrekitMessages.OUT_OF_RANGE_EPHEMERIDES_DATE, pe.getSpecifier());
    }

    double shift = -60;
    SpacecraftState s = ephemeris1.propagate(initDate.shiftedBy(shift));
    Assert.assertEquals(2, s.getAdditionalStates().size());
    Assert.assertTrue(s.hasAdditionalState("squaredA"));
    Assert.assertTrue(s.hasAdditionalState("extra"));
    Assert.assertEquals(s.getA() * s.getA(), s.getAdditionalState("squaredA")[0], 1.0e-10);
    Assert.assertEquals(1.5 + shift * rate, s.getAdditionalState("extra")[0], 1.0e-10);

    try {
      ephemeris1.resetInitialState(s);
      Assert.fail("an exception should have been thrown");
    } catch (OrekitException oe) {
      Assert.assertEquals(OrekitMessages.NON_RESETABLE_STATE, oe.getSpecifier());
    }
  }
 public double g(SpacecraftState s) throws OrekitException {
   return s.getAdditionalState("linear")[0] - 3.0;
 }
  @Test
  public void testAdditionalStateEvent() throws OrekitException {
    propagator.addAdditionalEquations(
        new AdditionalEquations() {

          public String getName() {
            return "linear";
          }

          public double[] computeDerivatives(SpacecraftState s, double[] pDot) {
            pDot[0] = 1.0;
            return new double[7];
          }
        });
    try {
      propagator.addAdditionalEquations(
          new AdditionalEquations() {

            public String getName() {
              return "linear";
            }

            public double[] computeDerivatives(SpacecraftState s, double[] pDot) {
              pDot[0] = 1.0;
              return new double[7];
            }
          });
      Assert.fail("an exception should have been thrown");
    } catch (OrekitException oe) {
      Assert.assertEquals(oe.getSpecifier(), OrekitMessages.ADDITIONAL_STATE_NAME_ALREADY_IN_USE);
    }
    try {
      propagator.addAdditionalStateProvider(
          new AdditionalStateProvider() {
            public String getName() {
              return "linear";
            }

            public double[] getAdditionalState(SpacecraftState state) {
              return null;
            }
          });
      Assert.fail("an exception should have been thrown");
    } catch (OrekitException oe) {
      Assert.assertEquals(oe.getSpecifier(), OrekitMessages.ADDITIONAL_STATE_NAME_ALREADY_IN_USE);
    }
    propagator.addAdditionalStateProvider(
        new AdditionalStateProvider() {
          public String getName() {
            return "constant";
          }

          public double[] getAdditionalState(SpacecraftState state) {
            return new double[] {1.0};
          }
        });
    Assert.assertTrue(propagator.isAdditionalStateManaged("linear"));
    Assert.assertTrue(propagator.isAdditionalStateManaged("constant"));
    Assert.assertFalse(propagator.isAdditionalStateManaged("non-managed"));
    Assert.assertEquals(2, propagator.getManagedAdditionalStates().length);
    propagator.setInitialState(propagator.getInitialState().addAdditionalState("linear", 1.5));

    CheckingHandler<AdditionalStateLinearDetector> checking =
        new CheckingHandler<AdditionalStateLinearDetector>(Action.STOP);
    propagator.addEventDetector(
        new AdditionalStateLinearDetector(10.0, 1.0e-8).withHandler(checking));

    final double dt = 3200;
    checking.assertEvent(false);
    final SpacecraftState finalState = propagator.propagate(initDate.shiftedBy(dt));
    checking.assertEvent(true);
    Assert.assertEquals(3.0, finalState.getAdditionalState("linear")[0], 1.0e-8);
    Assert.assertEquals(1.5, finalState.getDate().durationFrom(initDate), 1.0e-8);
  }