From 55be4998cb59a2f71519abf8b1877c908f0eacd3 Mon Sep 17 00:00:00 2001
From: Luc Maisonobe <luc@orekit.org>
Date: Tue, 19 May 2015 11:30:48 +0200
Subject: [PATCH] Revert "Use exceptions rather than null for inverse location
 errors."

This reverts commit b61d7eadbf497dc6ac40a0e6c51774dcfbeb232a.
---
 .../java/org/orekit/rugged/api/Rugged.java    | 138 +++++++++---------
 .../java/org/orekit/rugged/errors/Dump.java   |  13 --
 .../org/orekit/rugged/errors/DumpManager.java |   9 --
 .../orekit/rugged/errors/DumpReplayer.java    |  46 +-----
 .../InverseLocOutOfColumnRangeException.java  |  45 ------
 .../InverseLocOutOfLineRangeException.java    |  45 ------
 .../orekit/rugged/errors/RuggedMessages.java  |   2 -
 .../linesensor/SensorMeanPlaneCrossing.java   |  57 ++++----
 .../linesensor/SensorPixelCrossing.java       |  43 +++---
 .../org/orekit/rugged/RuggedMessages_de.utf8  |   6 -
 .../org/orekit/rugged/RuggedMessages_en.utf8  |   6 -
 .../org/orekit/rugged/RuggedMessages_es.utf8  |   6 -
 .../org/orekit/rugged/RuggedMessages_fr.utf8  |   6 -
 .../org/orekit/rugged/RuggedMessages_gl.utf8  |   6 -
 .../org/orekit/rugged/RuggedMessages_it.utf8  |   6 -
 .../org/orekit/rugged/RuggedMessages_no.utf8  |   6 -
 .../org/orekit/rugged/RuggedMessages_ro.utf8  |   6 -
 src/site/xdoc/changes.xml                     |   5 -
 .../org/orekit/rugged/api/RuggedTest.java     |  76 +++-------
 .../rugged/errors/DumpReplayerTest.java       |  25 ----
 .../rugged/errors/RuggedMessagesTest.java     |   2 +-
 .../replay/replay-inverse-loc-03.txt          |  15 --
 22 files changed, 137 insertions(+), 432 deletions(-)
 delete mode 100644 src/main/java/org/orekit/rugged/errors/InverseLocOutOfColumnRangeException.java
 delete mode 100644 src/main/java/org/orekit/rugged/errors/InverseLocOutOfLineRangeException.java
 delete mode 100644 src/test/resources/replay/replay-inverse-loc-03.txt

diff --git a/src/main/java/org/orekit/rugged/api/Rugged.java b/src/main/java/org/orekit/rugged/api/Rugged.java
index b0d8c876..fe9b8dcf 100644
--- a/src/main/java/org/orekit/rugged/api/Rugged.java
+++ b/src/main/java/org/orekit/rugged/api/Rugged.java
@@ -27,8 +27,6 @@ import org.apache.commons.math3.util.FastMath;
 import org.orekit.bodies.GeodeticPoint;
 import org.orekit.frames.Transform;
 import org.orekit.rugged.errors.DumpManager;
-import org.orekit.rugged.errors.InverseLocOutOfColumnRangeException;
-import org.orekit.rugged.errors.InverseLocOutOfLineRangeException;
 import org.orekit.rugged.errors.RuggedException;
 import org.orekit.rugged.errors.RuggedMessages;
 import org.orekit.rugged.intersection.IntersectionAlgorithm;
@@ -378,20 +376,25 @@ public class Rugged {
      * @param minLine minimum line number
      * @param maxLine maximum line number
      * @return date at which ground point is seen by line sensor
-     * @exception InverseLocOutOfLineRangeException if the ground point is out of line range
      * @exception RuggedException if line cannot be localized, or sensor is unknown
      * @see #inverseLocation(String, GeodeticPoint, int, int)
      */
     public AbsoluteDate dateLocation(final String sensorName, final GeodeticPoint point,
                                      final int minLine, final int maxLine)
-        throws InverseLocOutOfLineRangeException, RuggedException {
+        throws RuggedException {
 
         final LineSensor sensor = getLineSensor(sensorName);
         final SensorMeanPlaneCrossing planeCrossing = getPlaneCrossing(sensorName, minLine, maxLine);
 
         // find approximately the sensor line at which ground point crosses sensor mean plane
         final Vector3D   target = ellipsoid.transform(point);
-        return sensor.getDate(planeCrossing.find(target).getLine());
+        final SensorMeanPlaneCrossing.CrossingResult crossingResult = planeCrossing.find(target);
+        if (crossingResult == null) {
+            // target is out of search interval
+            return null;
+        } else {
+            return sensor.getDate(crossingResult.getLine());
+        }
 
     }
 
@@ -405,15 +408,14 @@ public class Rugged {
      * @param longitude ground point longitude
      * @param minLine minimum line number
      * @param maxLine maximum line number
-     * @return sensor pixel seeing ground point
-     * @exception InverseLocOutOfLineRangeException if the ground point is out of line range
-     * @exception InverseLocOutOfColumnRangeException if the ground point is out of column range
+     * @return sensor pixel seeing ground point, or null if ground point cannot
+     * be seen between the prescribed line numbers
      * @exception RuggedException if line cannot be localized, or sensor is unknown
      */
     public SensorPixel inverseLocation(final String sensorName,
                                        final double latitude, final double longitude,
                                        final int minLine,  final int maxLine)
-        throws InverseLocOutOfLineRangeException, InverseLocOutOfColumnRangeException, RuggedException {
+        throws RuggedException {
         final GeodeticPoint groundPoint =
                 new GeodeticPoint(latitude, longitude, algorithm.getElevation(latitude, longitude));
         return inverseLocation(sensorName, groundPoint, minLine, maxLine);
@@ -424,74 +426,72 @@ public class Rugged {
      * @param point point to localize
      * @param minLine minimum line number
      * @param maxLine maximum line number
-     * @return sensor pixel seeing point
-     * @exception InverseLocOutOfLineRangeException if the ground point is out of line range
-     * @exception InverseLocOutOfColumnRangeException if the ground point is out of column range
+     * @return sensor pixel seeing point, or null if point cannot be seen between the
+     * prescribed line numbers
      * @exception RuggedException if line cannot be localized, or sensor is unknown
      * @see #dateLocation(String, GeodeticPoint, int, int)
      */
     public SensorPixel inverseLocation(final String sensorName, final GeodeticPoint point,
                                        final int minLine, final int maxLine)
-        throws InverseLocOutOfLineRangeException, InverseLocOutOfColumnRangeException, RuggedException {
-
-        try {
-            final LineSensor sensor = getLineSensor(sensorName);
-            DumpManager.dumpInverseLocation(sensor, point, minLine, maxLine,
-                                            lightTimeCorrection, aberrationOfLightCorrection);
-
-            final SensorMeanPlaneCrossing planeCrossing = getPlaneCrossing(sensorName, minLine, maxLine);
-
-            DumpManager.dumpSensorMeanPlane(planeCrossing);
-
-            // find approximately the sensor line at which ground point crosses sensor mean plane
-            final Vector3D   target = ellipsoid.transform(point);
-            final SensorMeanPlaneCrossing.CrossingResult crossingResult = planeCrossing.find(target);
-
-            // find approximately the pixel along this sensor line
-            final SensorPixelCrossing pixelCrossing =
-                    new SensorPixelCrossing(sensor, planeCrossing.getMeanPlaneNormal(),
-                                            crossingResult.getTargetDirection().toVector3D(),
-                                            MAX_EVAL, COARSE_INVERSE_LOCATION_ACCURACY);
-            final double coarsePixel = pixelCrossing.locatePixel(crossingResult.getDate());
-            if (Double.isNaN(coarsePixel)) {
-                // target is out of search interval
-                return null;
-            }
+        throws RuggedException {
+
+        final LineSensor sensor = getLineSensor(sensorName);
+        DumpManager.dumpInverseLocation(sensor, point, minLine, maxLine,
+                                        lightTimeCorrection, aberrationOfLightCorrection);
 
-            // fix line by considering the closest pixel exact position and line-of-sight
-            // (this pixel might point towards a direction slightly above or below the mean sensor plane)
-            final int      lowIndex        = FastMath.max(0, FastMath.min(sensor.getNbPixels() - 2, (int) FastMath.floor(coarsePixel)));
-            final Vector3D lowLOS          = sensor.getLos(crossingResult.getDate(), lowIndex);
-            final Vector3D highLOS         = sensor.getLos(crossingResult.getDate(), lowIndex + 1);
-            final Vector3D localZ          = Vector3D.crossProduct(lowLOS, highLOS);
-            final DerivativeStructure beta = FieldVector3D.angle(crossingResult.getTargetDirection(), localZ);
-            final double   deltaL          = (0.5 * FastMath.PI - beta.getValue()) / beta.getPartialDerivative(1);
-            final double   fixedLine       = crossingResult.getLine() + deltaL;
-            final Vector3D fixedDirection  = new Vector3D(crossingResult.getTargetDirection().getX().taylor(deltaL),
-                                                          crossingResult.getTargetDirection().getY().taylor(deltaL),
-                                                          crossingResult.getTargetDirection().getZ().taylor(deltaL)).normalize();
-
-            // fix neighbouring pixels
-            final AbsoluteDate fixedDate   = sensor.getDate(fixedLine);
-            final Vector3D fixedX          = sensor.getLos(fixedDate, lowIndex);
-            final Vector3D fixedZ          = Vector3D.crossProduct(fixedX, sensor.getLos(fixedDate, lowIndex + 1));
-            final Vector3D fixedY          = Vector3D.crossProduct(fixedZ, fixedX);
-
-            // fix pixel
-            final double pixelWidth = FastMath.atan2(Vector3D.dotProduct(highLOS,        fixedY),
-                                                     Vector3D.dotProduct(highLOS,        fixedX));
-            final double alpha      = FastMath.atan2(Vector3D.dotProduct(fixedDirection, fixedY),
-                                                     Vector3D.dotProduct(fixedDirection, fixedX));
-            final double fixedPixel = lowIndex + alpha / pixelWidth;
-
-            final SensorPixel result = new SensorPixel(fixedLine, fixedPixel);
-            DumpManager.dumpInverseLocationResult(result);
-            return result;
-        } catch (RuggedException re) {
-            DumpManager.dumpException(re);
-            throw(re);
+        final SensorMeanPlaneCrossing planeCrossing = getPlaneCrossing(sensorName, minLine, maxLine);
+
+        DumpManager.dumpSensorMeanPlane(planeCrossing);
+
+        // find approximately the sensor line at which ground point crosses sensor mean plane
+        final Vector3D   target = ellipsoid.transform(point);
+        final SensorMeanPlaneCrossing.CrossingResult crossingResult = planeCrossing.find(target);
+        if (crossingResult == null) {
+            // target is out of search interval
+            return null;
         }
 
+        // find approximately the pixel along this sensor line
+        final SensorPixelCrossing pixelCrossing =
+                new SensorPixelCrossing(sensor, planeCrossing.getMeanPlaneNormal(),
+                                        crossingResult.getTargetDirection().toVector3D(),
+                                        MAX_EVAL, COARSE_INVERSE_LOCATION_ACCURACY);
+        final double coarsePixel = pixelCrossing.locatePixel(crossingResult.getDate());
+        if (Double.isNaN(coarsePixel)) {
+            // target is out of search interval
+            return null;
+        }
+
+        // fix line by considering the closest pixel exact position and line-of-sight
+        // (this pixel might point towards a direction slightly above or below the mean sensor plane)
+        final int      lowIndex        = FastMath.max(0, FastMath.min(sensor.getNbPixels() - 2, (int) FastMath.floor(coarsePixel)));
+        final Vector3D lowLOS          = sensor.getLos(crossingResult.getDate(), lowIndex);
+        final Vector3D highLOS         = sensor.getLos(crossingResult.getDate(), lowIndex + 1);
+        final Vector3D localZ          = Vector3D.crossProduct(lowLOS, highLOS);
+        final DerivativeStructure beta = FieldVector3D.angle(crossingResult.getTargetDirection(), localZ);
+        final double   deltaL          = (0.5 * FastMath.PI - beta.getValue()) / beta.getPartialDerivative(1);
+        final double   fixedLine       = crossingResult.getLine() + deltaL;
+        final Vector3D fixedDirection  = new Vector3D(crossingResult.getTargetDirection().getX().taylor(deltaL),
+                                                      crossingResult.getTargetDirection().getY().taylor(deltaL),
+                                                      crossingResult.getTargetDirection().getZ().taylor(deltaL)).normalize();
+
+        // fix neighbouring pixels
+        final AbsoluteDate fixedDate   = sensor.getDate(fixedLine);
+        final Vector3D fixedX          = sensor.getLos(fixedDate, lowIndex);
+        final Vector3D fixedZ          = Vector3D.crossProduct(fixedX, sensor.getLos(fixedDate, lowIndex + 1));
+        final Vector3D fixedY          = Vector3D.crossProduct(fixedZ, fixedX);
+
+        // fix pixel
+        final double pixelWidth = FastMath.atan2(Vector3D.dotProduct(highLOS,        fixedY),
+                                                 Vector3D.dotProduct(highLOS,        fixedX));
+        final double alpha      = FastMath.atan2(Vector3D.dotProduct(fixedDirection, fixedY),
+                                                 Vector3D.dotProduct(fixedDirection, fixedX));
+        final double fixedPixel = lowIndex + alpha / pixelWidth;
+
+        final SensorPixel result = new SensorPixel(fixedLine, fixedPixel);
+        DumpManager.dumpInverseLocationResult(result);
+        return result;
+
     }
 
     /** Get the mean plane crossing finder for a sensor.
diff --git a/src/main/java/org/orekit/rugged/errors/Dump.java b/src/main/java/org/orekit/rugged/errors/Dump.java
index c60c7374..3b581aa1 100644
--- a/src/main/java/org/orekit/rugged/errors/Dump.java
+++ b/src/main/java/org/orekit/rugged/errors/Dump.java
@@ -207,19 +207,6 @@ class Dump {
         }
     }
 
-    /** Dump an exception.
-     * @param e exception to dump
-     */
-    public void dumpException(final RuggedException e) {
-        writer.format(Locale.US,
-                      "Rugged exception: specifier %s parts",
-                      e.getSpecifier().toString());
-        for (final Object part : e.getParts()) {
-            writer.format(Locale.US, " %s", part);
-        }
-        writer.format(" %n");
-    }
-
     /** Dump an observation transform transform.
      * @param scToBody provider for observation
      * @param index index of the transform
diff --git a/src/main/java/org/orekit/rugged/errors/DumpManager.java b/src/main/java/org/orekit/rugged/errors/DumpManager.java
index 0dc11e04..713beb5f 100644
--- a/src/main/java/org/orekit/rugged/errors/DumpManager.java
+++ b/src/main/java/org/orekit/rugged/errors/DumpManager.java
@@ -186,15 +186,6 @@ public class DumpManager {
         }
     }
 
-    /** Dump an exception.
-     * @param e exception to dump
-     */
-    public static void dumpException(final RuggedException e) {
-        if (isActive()) {
-            DUMP.get().dumpException(e);
-        }
-    }
-
     /** Dump an observation transform transform.
      * @param scToBody provider for observation
      * @param index index of the transform
diff --git a/src/main/java/org/orekit/rugged/errors/DumpReplayer.java b/src/main/java/org/orekit/rugged/errors/DumpReplayer.java
index 4f5f8c00..6fdec225 100644
--- a/src/main/java/org/orekit/rugged/errors/DumpReplayer.java
+++ b/src/main/java/org/orekit/rugged/errors/DumpReplayer.java
@@ -34,7 +34,6 @@ import java.util.NavigableMap;
 import java.util.TreeMap;
 
 import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
-import org.apache.commons.math3.exception.util.Localizable;
 import org.apache.commons.math3.exception.util.LocalizedFormats;
 import org.apache.commons.math3.geometry.euclidean.threed.FieldVector3D;
 import org.apache.commons.math3.geometry.euclidean.threed.Rotation;
@@ -45,7 +44,6 @@ import org.apache.commons.math3.util.Pair;
 import org.orekit.bodies.GeodeticPoint;
 import org.orekit.bodies.OneAxisEllipsoid;
 import org.orekit.errors.OrekitException;
-import org.orekit.errors.OrekitMessages;
 import org.orekit.frames.Frame;
 import org.orekit.frames.FramesFactory;
 import org.orekit.frames.Predefined;
@@ -213,12 +211,6 @@ public class DumpReplayer {
     /** Keyword for target direction. */
     private static final String TARGET_DIRECTION = "targetDirection";
 
-    /** Keyword for exception specifier. */
-    private static final String SPECIFIER = "specifier";
-
-    /** Keyword for exception parts. */
-    private static final String PARTS = "parts";
-
     /** Constant elevation for constant elevation algorithm. */
     private double constantElevation;
 
@@ -444,13 +436,8 @@ public class DumpReplayer {
     public Result[] execute(final Rugged rugged) throws RuggedException {
         final Result[] results = new Result[calls.size()];
         for (int i = 0; i < calls.size(); ++i) {
-            Object result = null;
-            try {
-                result = calls.get(i).execute(rugged);
-            } catch (RuggedException re) {
-                result = re;
-            }
-            results[i] = new Result(calls.get(i).expected, result);
+            results[i] = new Result(calls.get(i).expected,
+                                    calls.get(i).execute(rugged));
         }
         return results;
     }
@@ -976,35 +963,6 @@ public class DumpReplayer {
 
             }
 
-        },
-
-        /** Parser for exception dump lines. */
-        RUGGED_EXCEPTION() {
-
-            /** {@inheritDoc} */
-            @Override
-            public void parse(final int l, final File file, final String line, final String[] fields, final DumpReplayer global)
-                throws RuggedException {
-                if (fields.length < 3 || !fields[0].equals(SPECIFIER) || !fields[2].equals(PARTS)) {
-                    throw new RuggedException(RuggedMessages.CANNOT_PARSE_LINE, l, file, line);
-                }
-                Localizable specifier = null;
-                try {
-                    specifier = RuggedMessages.valueOf(fields[1]);
-                } catch (IllegalArgumentException e1) {
-                    try {
-                        specifier = OrekitMessages.valueOf(fields[1]);
-                    } catch (IllegalArgumentException e2) {
-                        specifier = LocalizedFormats.valueOf(fields[1]);
-                    }
-                }
-                final Object[] parts = new Object[fields.length -  3];
-                System.arraycopy(fields, 3, parts, 0, parts.length);
-                final RuggedException re = new RuggedException(specifier, parts);
-                final DumpedCall last = global.calls.get(global.calls.size() - 1);
-                last.expected = re;
-            }
-
         };
 
         /** Parse a line.
diff --git a/src/main/java/org/orekit/rugged/errors/InverseLocOutOfColumnRangeException.java b/src/main/java/org/orekit/rugged/errors/InverseLocOutOfColumnRangeException.java
deleted file mode 100644
index a6fad865..00000000
--- a/src/main/java/org/orekit/rugged/errors/InverseLocOutOfColumnRangeException.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright 2013-2015 CS Systèmes d'Information
- * Licensed to CS Systèmes d'Information (CS) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * CS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.orekit.rugged.errors;
-
-
-/** This class is a specialized exception for inverse location errors.
- * @author Luc Maisonobe
- */
-
-public class InverseLocOutOfColumnRangeException extends RuggedException {
-
-    /** Serializable UID. */
-    private static final long serialVersionUID = 20150518L;
-
-    /** Simple constructor.
-     * @param expectedColumn expected column number for the ground point
-     * @param minColumn minimum column number
-     * @param maxColumn maximum column number
-     */
-    public InverseLocOutOfColumnRangeException(final double expectedColumn, final int minColumn, final int maxColumn) {
-        super(RuggedMessages.GROUND_POINT_OUT_OF_COLUMN_RANGE, expectedColumn, minColumn, maxColumn);
-    }
-
-    /** Get the expected column number for the ground point.
-     * @return expected column number for the ground point
-     */
-    public double getExpectedColumn() {
-        return ((Double) getParts()[0]).doubleValue();
-    }
-
-}
diff --git a/src/main/java/org/orekit/rugged/errors/InverseLocOutOfLineRangeException.java b/src/main/java/org/orekit/rugged/errors/InverseLocOutOfLineRangeException.java
deleted file mode 100644
index 833e09a8..00000000
--- a/src/main/java/org/orekit/rugged/errors/InverseLocOutOfLineRangeException.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/* Copyright 2013-2015 CS Systèmes d'Information
- * Licensed to CS Systèmes d'Information (CS) under one or more
- * contributor license agreements.  See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * CS licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.orekit.rugged.errors;
-
-
-/** This class is a specialized exception for inverse location errors.
- * @author Luc Maisonobe
- */
-
-public class InverseLocOutOfLineRangeException extends RuggedException {
-
-    /** Serializable UID. */
-    private static final long serialVersionUID = 20150518L;
-
-    /** Simple constructor.
-     * @param expectedLine expected line number for the ground point
-     * @param minLine minimum line number
-     * @param maxLine maximum line number
-     */
-    public InverseLocOutOfLineRangeException(final double expectedLine, final int minLine, final int maxLine) {
-        super(RuggedMessages.GROUND_POINT_OUT_OF_LINE_RANGE, expectedLine, minLine, maxLine);
-    }
-
-    /** Get the expected line number for the ground point.
-     * @return expected line number for the ground point
-     */
-    public double getExpectedLine() {
-        return ((Double) getParts()[0]).doubleValue();
-    }
-
-}
diff --git a/src/main/java/org/orekit/rugged/errors/RuggedMessages.java b/src/main/java/org/orekit/rugged/errors/RuggedMessages.java
index f3cb9741..e657479f 100644
--- a/src/main/java/org/orekit/rugged/errors/RuggedMessages.java
+++ b/src/main/java/org/orekit/rugged/errors/RuggedMessages.java
@@ -63,8 +63,6 @@ public enum RuggedMessages implements Localizable {
     LINE_OF_SIGHT_NEVER_CROSSES_LATITUDE("line-of-sight never crosses latitude {0}"),
     LINE_OF_SIGHT_NEVER_CROSSES_LONGITUDE("line-of-sight never crosses longitude {0}"),
     LINE_OF_SIGHT_NEVER_CROSSES_ALTITUDE("line-of-sight never crosses altitude {0}"),
-    GROUND_POINT_OUT_OF_LINE_RANGE("ground point is around line {0}, out of the [{1}, {2}] range"),
-    GROUND_POINT_OUT_OF_COLUMN_RANGE("ground point is around column {0}, out of the [{1}, {2}] range"),
     DEM_ENTRY_POINT_IS_BEHIND_SPACECRAFT("line-of-sight enters the Digital Elevation Model behind spacecraft!"),
     FRAMES_MISMATCH_WITH_INTERPOLATOR_DUMP("frame {0} does not match frame {1} from interpolator dump"),
     NOT_INTERPOLATOR_DUMP_DATA("data is not an interpolator dump"),
diff --git a/src/main/java/org/orekit/rugged/linesensor/SensorMeanPlaneCrossing.java b/src/main/java/org/orekit/rugged/linesensor/SensorMeanPlaneCrossing.java
index 5ca1b0cb..4f7bcce0 100644
--- a/src/main/java/org/orekit/rugged/linesensor/SensorMeanPlaneCrossing.java
+++ b/src/main/java/org/orekit/rugged/linesensor/SensorMeanPlaneCrossing.java
@@ -21,7 +21,6 @@ import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
 import org.apache.commons.math3.analysis.solvers.BracketingNthOrderBrentSolver;
 import org.apache.commons.math3.analysis.solvers.UnivariateSolver;
 import org.apache.commons.math3.exception.NoBracketingException;
-import org.apache.commons.math3.exception.util.LocalizedFormats;
 import org.apache.commons.math3.geometry.euclidean.threed.FieldVector3D;
 import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
 import org.apache.commons.math3.linear.Array2DRowRealMatrix;
@@ -36,7 +35,6 @@ import org.apache.commons.math3.linear.SingularValueDecomposition;
 import org.apache.commons.math3.util.FastMath;
 import org.apache.commons.math3.util.Precision;
 import org.orekit.frames.Transform;
-import org.orekit.rugged.errors.InverseLocOutOfLineRangeException;
 import org.orekit.rugged.errors.RuggedException;
 import org.orekit.rugged.errors.RuggedExceptionWrapper;
 import org.orekit.rugged.utils.SpacecraftToObservedBody;
@@ -333,13 +331,13 @@ public class SensorMeanPlaneCrossing {
 
     /** Find mean plane crossing.
      * @param target target ground point
-     * @return line number and target direction at mean plane crossing
-     * @exception InverseLocOutOfLineRangeException if the ground point is out of line range
+     * @return line number and target direction at mean plane crossing,
+     * or null if search interval does not bracket a solution
      * @exception RuggedException if geometry cannot be computed for some line or
      * if the maximum number of evaluations is exceeded
      */
     public CrossingResult find(final Vector3D target)
-        throws InverseLocOutOfLineRangeException, RuggedException {
+        throws RuggedException {
 
         double crossingLine     = midLine;
         Transform bodyToInert   = midBodyToInert;
@@ -412,6 +410,9 @@ public class SensorMeanPlaneCrossing {
                     // rare case: we are stuck in a loop!
                     // switch to a more robust (but slower) algorithm in this case
                     final CrossingResult slowResult = slowFind(targetPV, crossingLine);
+                    if (slowResult == null) {
+                        return null;
+                    }
                     for (int k = cachedResults.length - 1; k > 0; --k) {
                         cachedResults[k] = cachedResults[k - 1];
                     }
@@ -424,7 +425,7 @@ public class SensorMeanPlaneCrossing {
                 if (atMin) {
                     // we were already trying at minLine and we need to go below that
                     // give up as the solution is out of search interval
-                    throw new InverseLocOutOfLineRangeException(crossingLine, minLine, maxLine);
+                    return null;
                 }
                 atMin        = true;
                 crossingLine = minLine;
@@ -432,7 +433,7 @@ public class SensorMeanPlaneCrossing {
                 if (atMax) {
                     // we were already trying at maxLine and we need to go above that
                     // give up as the solution is out of search interval
-                    throw new InverseLocOutOfLineRangeException(crossingLine, minLine, maxLine);
+                    return null;
                 }
                 atMax        = true;
                 crossingLine = maxLine;
@@ -447,7 +448,7 @@ public class SensorMeanPlaneCrossing {
             scToInert   = scToBody.getScToInertial(date);
         }
 
-        throw new RuggedException(LocalizedFormats.MAX_COUNT_EXCEEDED, maxEval);
+        return null;
 
     }
 
@@ -495,24 +496,6 @@ public class SensorMeanPlaneCrossing {
      */
     public CrossingResult slowFind(final PVCoordinates targetPV, final double initialGuess)
         throws RuggedException {
-
-        // set up function evaluating to 0.0 where target matches line
-        final UnivariateFunction f = new UnivariateFunction() {
-            /** {@inheritDoc} */
-            @Override
-            public double value(final double x) throws RuggedExceptionWrapper {
-                try {
-                    final AbsoluteDate date = sensor.getDate(x);
-                    final FieldVector3D<DerivativeStructure> targetDirection =
-                            evaluateLine(x, targetPV, scToBody.getBodyToInertial(date), scToBody.getScToInertial(date));
-                    final DerivativeStructure beta = FieldVector3D.angle(targetDirection, meanPlaneNormal);
-                    return 0.5 * FastMath.PI - beta.getValue();
-                } catch (RuggedException re) {
-                    throw new RuggedExceptionWrapper(re);
-                }
-            }
-        };
-
         try {
 
             // safety check
@@ -524,7 +507,21 @@ public class SensorMeanPlaneCrossing {
             }
 
             final UnivariateSolver solver = new BracketingNthOrderBrentSolver(accuracy, 5);
-            double crossingLine = solver.solve(maxEval, f, minLine, maxLine, startValue);
+            double crossingLine = solver.solve(maxEval, new UnivariateFunction() {
+                /** {@inheritDoc} */
+                @Override
+                public double value(final double x) throws RuggedExceptionWrapper {
+                    try {
+                        final AbsoluteDate date = sensor.getDate(x);
+                        final FieldVector3D<DerivativeStructure> targetDirection =
+                                evaluateLine(x, targetPV, scToBody.getBodyToInertial(date), scToBody.getScToInertial(date));
+                        final DerivativeStructure beta = FieldVector3D.angle(targetDirection, meanPlaneNormal);
+                        return 0.5 * FastMath.PI - beta.getValue();
+                    } catch (RuggedException re) {
+                        throw new RuggedExceptionWrapper(re);
+                    }
+                }
+            }, minLine, maxLine, startValue);
 
             final AbsoluteDate date = sensor.getDate(crossingLine);
             final FieldVector3D<DerivativeStructure> targetDirection =
@@ -532,14 +529,10 @@ public class SensorMeanPlaneCrossing {
             return new CrossingResult(sensor.getDate(crossingLine), crossingLine, targetPV.getPosition(), targetDirection);
 
         } catch (NoBracketingException nbe) {
-            final double fMinLine     = f.value(minLine);
-            final double fMaxLine     = f.value(maxLine);
-            final double expectedLine = (fMaxLine * minLine - fMinLine * maxLine) / (fMaxLine - fMinLine);
-            throw new InverseLocOutOfLineRangeException(expectedLine, minLine, maxLine);
+            return null;
         } catch (RuggedExceptionWrapper rew) {
             throw rew.getException();
         }
-
     }
 
     /** Evaluate geometry for a given line number.
diff --git a/src/main/java/org/orekit/rugged/linesensor/SensorPixelCrossing.java b/src/main/java/org/orekit/rugged/linesensor/SensorPixelCrossing.java
index d3e04c8e..0e972175 100644
--- a/src/main/java/org/orekit/rugged/linesensor/SensorPixelCrossing.java
+++ b/src/main/java/org/orekit/rugged/linesensor/SensorPixelCrossing.java
@@ -23,7 +23,6 @@ import org.apache.commons.math3.exception.NoBracketingException;
 import org.apache.commons.math3.exception.TooManyEvaluationsException;
 import org.apache.commons.math3.geometry.euclidean.threed.Vector3D;
 import org.apache.commons.math3.util.FastMath;
-import org.orekit.rugged.errors.InverseLocOutOfColumnRangeException;
 import org.orekit.rugged.errors.RuggedException;
 import org.orekit.rugged.errors.RuggedExceptionWrapper;
 import org.orekit.time.AbsoluteDate;
@@ -69,40 +68,34 @@ public class SensorPixelCrossing {
 
     /** Locate pixel along sensor line.
      * @param date current date
-     * @return pixel location
-     * @exception InverseLocOutOfColumnRangeException if the ground point is out of column range
+     * @return pixel location ({@code Double.NaN} if the first and last
+     * pixels of the line do not bracket a location)
      * @exception RuggedException if the maximum number of evaluations is exceeded
      */
-    public double locatePixel(final AbsoluteDate date)
-        throws InverseLocOutOfColumnRangeException, RuggedException {
-
-        // set up function evaluating to 0.0 where target matches pixel
-        final UnivariateFunction f = new UnivariateFunction() {
-            /** {@inheritDoc} */
-            @Override
-            public double value(final double x) throws RuggedExceptionWrapper {
-                try {
-                    return Vector3D.angle(cross, getLOS(date, x)) - 0.5 * FastMath.PI;
-                } catch (RuggedException re) {
-                    throw new RuggedExceptionWrapper(re);
-                }
-            }
-        };
-
+    public double locatePixel(final AbsoluteDate date) throws RuggedException {
         try {
 
+            // set up function evaluating to 0.0 where target matches pixel
+            final UnivariateFunction f = new UnivariateFunction() {
+                /** {@inheritDoc} */
+                @Override
+                public double value(final double x) throws RuggedExceptionWrapper {
+                    try {
+                        return Vector3D.angle(cross, getLOS(date, x)) - 0.5 * FastMath.PI;
+                    } catch (RuggedException re) {
+                        throw new RuggedExceptionWrapper(re);
+                    }
+                }
+            };
+
             // find the root
             final UnivariateSolver solver =
                     new BracketingNthOrderBrentSolver(0.0, accuracy, 5);
             return solver.solve(maxEval, f, -MARGIN, sensor.getNbPixels() - 1 + MARGIN);
 
         } catch (NoBracketingException nbe) {
-            final int minPixel         = 0;
-            final int maxPixel         = sensor.getNbPixels() - 1;
-            final double fMinPixel     = f.value(minPixel);
-            final double fMaxPixel     = f.value(maxPixel);
-            final double expectedPixel = (fMaxPixel * minPixel - fMinPixel * maxPixel) / (fMaxPixel - fMinPixel);
-            throw new InverseLocOutOfColumnRangeException(expectedPixel, minPixel, maxPixel);
+            // there are no solutions in the search interval
+            return Double.NaN;
         } catch (TooManyEvaluationsException tmee) {
             throw new RuggedException(tmee);
         } catch (RuggedExceptionWrapper rew) {
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8
index 13a0465a..c65fd1b2 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_de.utf8
@@ -37,12 +37,6 @@ LINE_OF_SIGHT_NEVER_CROSSES_LONGITUDE = die Sichtverbindung kreuzt nie die Läng
 # line never crosses altitude {0}
 LINE_OF_SIGHT_NEVER_CROSSES_ALTITUDE = die Linie kreuzt nie die Höhe {0}
 
-# ground point is around line {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_LINE_RANGE = <MISSING TRANSLATION>
-
-# ground point is around column {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_COLUMN_RANGE = <MISSING TRANSLATION>
-
 # line-of-sight enters the Digital Elevation Model behind spacecraft!
 DEM_ENTRY_POINT_IS_BEHIND_SPACECRAFT = die Sichtverbindung tritt in das digitale Höhenlinienmodell ein, hinter dem Satellite!
 
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8
index 63908662..7d5f68fa 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_en.utf8
@@ -37,12 +37,6 @@ LINE_OF_SIGHT_NEVER_CROSSES_LONGITUDE = line-of-sight never crosses longitude {0
 # line never crosses altitude {0}
 LINE_OF_SIGHT_NEVER_CROSSES_ALTITUDE = line-of-sight never crosses altitude {0}
 
-# ground point is around line {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_LINE_RANGE = ground point is around line {0}, out of the [{1}, {2}] range
-
-# ground point is around column {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_COLUMN_RANGE = ground point is around column {0}, out of the [{1}, {2}] range
-
 # line-of-sight enters the Digital Elevation Model behind spacecraft!
 DEM_ENTRY_POINT_IS_BEHIND_SPACECRAFT = line-of-sight enters the Digital Elevation Model behind spacecraft!
 
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8
index 8490d5b7..44b53843 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_es.utf8
@@ -37,12 +37,6 @@ LINE_OF_SIGHT_NEVER_CROSSES_LONGITUDE = la línea de visión nunca atraviesa la
 # line never crosses altitude {0}
 LINE_OF_SIGHT_NEVER_CROSSES_ALTITUDE = la línea de visión nunca atraviesa la altitud {0}
 
-# ground point is around line {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_LINE_RANGE = <MISSING TRANSLATION>
-
-# ground point is around column {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_COLUMN_RANGE = <MISSING TRANSLATION>
-
 # line-of-sight enters the Digital Elevation Model behind spacecraft!
 DEM_ENTRY_POINT_IS_BEHIND_SPACECRAFT = ¡ la línea de visión entra en el Modelo Digital del Terreno por detrás del satélite !
 
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8
index 94d159f7..b3e5c040 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_fr.utf8
@@ -37,12 +37,6 @@ LINE_OF_SIGHT_NEVER_CROSSES_LONGITUDE = la ligne de visée ne franchit jamais la
 # line never crosses altitude {0}
 LINE_OF_SIGHT_NEVER_CROSSES_ALTITUDE = la ligne de visée ne franchit jamais l''altitude {0}
 
-# ground point is around line {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_LINE_RANGE = le point au sol est aux alentours de la ligne {0}, hors du domaine [{1}, {2}]
-
-# ground point is around column {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_COLUMN_RANGE = le point au sol est aux alentours de la colonne {0}, hors du domaine [{1}, {2}]
-
 # line-of-sight enters the Digital Elevation Model behind spacecraft!
 DEM_ENTRY_POINT_IS_BEHIND_SPACECRAFT = la ligne de visée entre dans le Modèle Numérique de Terrain derrière le satellite !
 
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8
index bb21a777..b927d20a 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_gl.utf8
@@ -37,12 +37,6 @@ LINE_OF_SIGHT_NEVER_CROSSES_LONGITUDE = a liña de visión xamais atravesa a lon
 # line never crosses altitude {0}
 LINE_OF_SIGHT_NEVER_CROSSES_ALTITUDE = a liña de visión xamais atravesa a altitude {0}
 
-# ground point is around line {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_LINE_RANGE = <MISSING TRANSLATION>
-
-# ground point is around column {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_COLUMN_RANGE = <MISSING TRANSLATION>
-
 # line-of-sight enters the Digital Elevation Model behind spacecraft!
 DEM_ENTRY_POINT_IS_BEHIND_SPACECRAFT = ¡ a liña de visión entra no Modelo Dixital do Terren por detrás do satélite !
 
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8
index 12b41ac2..35ae3343 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_it.utf8
@@ -37,12 +37,6 @@ LINE_OF_SIGHT_NEVER_CROSSES_LONGITUDE = la linea di visibilità non attraversa m
 # line never crosses altitude {0}
 LINE_OF_SIGHT_NEVER_CROSSES_ALTITUDE = la linea di visibilità non attraversa mai la altitudine {0}
 
-# ground point is around line {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_LINE_RANGE = <MISSING TRANSLATION>
-
-# ground point is around column {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_COLUMN_RANGE = <MISSING TRANSLATION>
-
 # line-of-sight enters the Digital Elevation Model behind spacecraft!
 DEM_ENTRY_POINT_IS_BEHIND_SPACECRAFT = la linea di visibilità entra nel Modello Digitale di Suolo dietro il satellite!
 
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8
index db88653a..90280718 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_no.utf8
@@ -37,12 +37,6 @@ LINE_OF_SIGHT_NEVER_CROSSES_LONGITUDE = synslinjen krysser aldri lengdegrad {0}
 # line never crosses altitude {0}
 LINE_OF_SIGHT_NEVER_CROSSES_ALTITUDE = linjen krysser aldri høyden {0}
 
-# ground point is around line {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_LINE_RANGE = <MISSING TRANSLATION>
-
-# ground point is around column {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_COLUMN_RANGE = <MISSING TRANSLATION>
-
 # line-of-sight enters the Digital Elevation Model behind spacecraft!
 DEM_ENTRY_POINT_IS_BEHIND_SPACECRAFT = synslinjen går inn i den digital terrengmodellen bak romfartøyet
 
diff --git a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8 b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8
index 0dff443c..900187a7 100644
--- a/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8
+++ b/src/main/resources/assets/org/orekit/rugged/RuggedMessages_ro.utf8
@@ -37,12 +37,6 @@ LINE_OF_SIGHT_NEVER_CROSSES_LONGITUDE = linia de vizare nu intersectează longit
 # line never crosses altitude {0}
 LINE_OF_SIGHT_NEVER_CROSSES_ALTITUDE = linia de vizare nu intersectează altitudinea {0}
 
-# ground point is around line {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_LINE_RANGE = <MISSING TRANSLATION>
-
-# ground point is around column {0}, out of the [{1}, {2}] range
-GROUND_POINT_OUT_OF_COLUMN_RANGE = <MISSING TRANSLATION>
-
 # line-of-sight enters the Digital Elevation Model behind spacecraft!
 DEM_ENTRY_POINT_IS_BEHIND_SPACECRAFT = linia de vizare intră în Modelul Digital de Elevație în spatele navei spațiale!
 
diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml
index 81c2eb35..8f9d7f45 100644
--- a/src/site/xdoc/changes.xml
+++ b/src/site/xdoc/changes.xml
@@ -22,11 +22,6 @@
   <body>
     <release version="1.0" date="TBD"
              description="TBD">
-      <action dev="luc" type="update" >
-        Use specific exceptions rather than returning null when inverse location identifies
-        out of range errors along lines or columns. This helps caller to set fix the
-        min/max lines as we can provide information about where the point is expected.
-      </action>
       <action dev="luc" type="add" >
         Added a CONSTANT_ELEVATION_OVER_ELLIPSOID algorithm, similar in spirit
         to the IGNORE_DEM_USE_ELLIPSOID, but with a user-specified elevation
diff --git a/src/test/java/org/orekit/rugged/api/RuggedTest.java b/src/test/java/org/orekit/rugged/api/RuggedTest.java
index b82e2310..00252890 100644
--- a/src/test/java/org/orekit/rugged/api/RuggedTest.java
+++ b/src/test/java/org/orekit/rugged/api/RuggedTest.java
@@ -48,8 +48,6 @@ import org.orekit.frames.FramesFactory;
 import org.orekit.orbits.Orbit;
 import org.orekit.propagation.Propagator;
 import org.orekit.rugged.TestUtils;
-import org.orekit.rugged.errors.InverseLocOutOfColumnRangeException;
-import org.orekit.rugged.errors.InverseLocOutOfLineRangeException;
 import org.orekit.rugged.errors.RuggedException;
 import org.orekit.rugged.errors.RuggedMessages;
 import org.orekit.rugged.linesensor.LineDatation;
@@ -992,52 +990,32 @@ public class RuggedTest {
         }
 
         // point out of line (20 pixels before first pixel)
-        try {
-            rugged.inverseLocation("line",
+        Assert.assertNull(rugged.inverseLocation("line",
                                                     21 * gp[0].getLatitude()  - 20 * gp[1].getLatitude(),
                                                     21 * gp[0].getLongitude() - 20 * gp[1].getLongitude(),
-                                                    0, dimension);
-            Assert.fail("an exception should have been thrown");
-        } catch (InverseLocOutOfColumnRangeException e) {
-            Assert.assertEquals(-20, e.getExpectedColumn(), 1.0);
-        }
+                                                    0, dimension));
 
         // point out of line (20 pixels after last pixel)
-        try {
-            rugged.inverseLocation("line",
-                                   -20 * gp[gp.length - 2].getLatitude()  + 21 * gp[gp.length - 1].getLatitude(),
-                                   -20 * gp[gp.length - 2].getLongitude() + 21 * gp[gp.length - 1].getLongitude(),
-                                   0, dimension);
-            Assert.fail("an exception should have been thrown");
-        } catch (InverseLocOutOfColumnRangeException e) {
-            Assert.assertEquals(2019.0, e.getExpectedColumn(), 1.0);
-        }
+        Assert.assertNull(rugged.inverseLocation("line",
+                                                    -20 * gp[gp.length - 2].getLatitude()  + 21 * gp[gp.length - 1].getLatitude(),
+                                                    -20 * gp[gp.length - 2].getLongitude() + 21 * gp[gp.length - 1].getLongitude(),
+                                                    0, dimension));
 
         // point out of line (20 lines before first line)
         GeodeticPoint[] gp0 = rugged.directLocation("line", 0);
         GeodeticPoint[] gp1 = rugged.directLocation("line", 1);
-        try {
-            rugged.inverseLocation("line",
-                                   21 * gp0[dimension / 2].getLatitude()  - 20 * gp1[dimension / 2].getLatitude(),
-                                   21 * gp0[dimension / 2].getLongitude() - 20 * gp1[dimension / 2].getLongitude(),
-                                   0, dimension);
-            Assert.fail("an exception should have been thrown");
-        } catch (InverseLocOutOfLineRangeException e) {
-            Assert.assertEquals(-20, e.getExpectedLine(), 1.0);
-        }
+        Assert.assertNull(rugged.inverseLocation("line",
+                                                    21 * gp0[dimension / 2].getLatitude()  - 20 * gp1[dimension / 2].getLatitude(),
+                                                    21 * gp0[dimension / 2].getLongitude() - 20 * gp1[dimension / 2].getLongitude(),
+                                                    0, dimension));
 
         // point out of line (20 lines after last line)
         GeodeticPoint[] gp2 = rugged.directLocation("line", dimension - 2);
         GeodeticPoint[] gp3 = rugged.directLocation("line", dimension - 1);
-        try {
-            rugged.inverseLocation("line",
-                                   -20 * gp2[dimension / 2].getLatitude()  + 21 * gp3[dimension / 2].getLatitude(),
-                                   -20 * gp2[dimension / 2].getLongitude() + 21 * gp3[dimension / 2].getLongitude(),
-                                   0, dimension);
-            Assert.fail("an exception should have been thrown");
-        } catch (InverseLocOutOfLineRangeException e) {
-            Assert.assertEquals(2019.0, e.getExpectedLine(), 1.0);
-        }
+        Assert.assertNull(rugged.inverseLocation("line",
+                                                    -20 * gp2[dimension / 2].getLatitude()  + 21 * gp3[dimension / 2].getLatitude(),
+                                                    -20 * gp2[dimension / 2].getLongitude() + 21 * gp3[dimension / 2].getLongitude(),
+                                                    0, dimension));
 
     }
 
@@ -1104,28 +1082,18 @@ public class RuggedTest {
         // point out of line (20 lines before first line)
         GeodeticPoint[] gp0 = rugged.directLocation("line", 0);
         GeodeticPoint[] gp1 = rugged.directLocation("line", 1);
-        try {
-            rugged.dateLocation("line",
-                                21 * gp0[dimension / 2].getLatitude()  - 20 * gp1[dimension / 2].getLatitude(),
-                                21 * gp0[dimension / 2].getLongitude() - 20 * gp1[dimension / 2].getLongitude(),
-                                0, dimension);
-            Assert.fail("an exception should have been thrown");
-        } catch (InverseLocOutOfLineRangeException e) {
-            Assert.assertEquals(-20.0, e.getExpectedLine(), 1.0);
-        }
+        Assert.assertNull(rugged.dateLocation("line",
+                                                    21 * gp0[dimension / 2].getLatitude()  - 20 * gp1[dimension / 2].getLatitude(),
+                                                    21 * gp0[dimension / 2].getLongitude() - 20 * gp1[dimension / 2].getLongitude(),
+                                                    0, dimension));
 
         // point out of line (20 lines after last line)
         GeodeticPoint[] gp2 = rugged.directLocation("line", dimension - 2);
         GeodeticPoint[] gp3 = rugged.directLocation("line", dimension - 1);
-        try {
-            rugged.dateLocation("line",
-                                -20 * gp2[dimension / 2].getLatitude()  + 21 * gp3[dimension / 2].getLatitude(),
-                                -20 * gp2[dimension / 2].getLongitude() + 21 * gp3[dimension / 2].getLongitude(),
-                                0, dimension);
-            Assert.fail("an exception should have been thrown");
-        } catch (InverseLocOutOfLineRangeException e) {
-            Assert.assertEquals(2019.0, e.getExpectedLine(), 1.0);
-        }
+        Assert.assertNull(rugged.dateLocation("line",
+                                                    -20 * gp2[dimension / 2].getLatitude()  + 21 * gp3[dimension / 2].getLatitude(),
+                                                    -20 * gp2[dimension / 2].getLongitude() + 21 * gp3[dimension / 2].getLongitude(),
+                                                    0, dimension));
 
     }
 
diff --git a/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java b/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java
index b4fa3fa0..572a74f2 100644
--- a/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java
+++ b/src/test/java/org/orekit/rugged/errors/DumpReplayerTest.java
@@ -123,29 +123,4 @@ public class DumpReplayerTest {
 
     }
 
-    @Test
-    public void testInverseLoc03() throws URISyntaxException, IOException, OrekitException, RuggedException {
-
-        String orekitPath = getClass().getClassLoader().getResource("orekit-data").toURI().getPath();
-        DataProvidersManager.getInstance().addProvider(new DirectoryCrawler(new File(orekitPath)));
-
-        String dumpPath = getClass().getClassLoader().getResource("replay/replay-inverse-loc-03.txt").toURI().getPath();
-        DumpReplayer replayer = new DumpReplayer();
-        replayer.parse(new File(dumpPath));
-        Rugged rugged = replayer.createRugged();
-        DumpReplayer.Result[] results = replayer.execute(rugged);
-
-        Assert.assertEquals(1, results.length);
-        for (final DumpReplayer.Result result : results) {
-            RuggedException expectedSP = (RuggedException) result.getExpected();
-            RuggedException replayedSP = (RuggedException) result.getReplayed();
-            Assert.assertEquals(expectedSP.getSpecifier(), replayedSP.getSpecifier());
-            Assert.assertEquals(expectedSP.getParts().length, replayedSP.getParts().length);
-            for (int i = 0; i < expectedSP.getParts().length; ++i) {
-                Assert.assertEquals(expectedSP.getParts()[i].toString(), replayedSP.getParts()[i].toString());
-            }
-        }
-
-    }
-
 }
diff --git a/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java b/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java
index 90afd4c3..fa07bcf5 100644
--- a/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java
+++ b/src/test/java/org/orekit/rugged/errors/RuggedMessagesTest.java
@@ -30,7 +30,7 @@ public class RuggedMessagesTest {
 
     @Test
     public void testMessageNumber() {
-        Assert.assertEquals(27, RuggedMessages.values().length);
+        Assert.assertEquals(25, RuggedMessages.values().length);
     }
 
     @Test
diff --git a/src/test/resources/replay/replay-inverse-loc-03.txt b/src/test/resources/replay/replay-inverse-loc-03.txt
deleted file mode 100644
index d02d1a47..00000000
--- a/src/test/resources/replay/replay-inverse-loc-03.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-# Rugged library dump file, created on 2015-05-13T10:02:15Z
-# all units are SI units (m, m/s, rad ...)
-sensor: sensorName s0 nbPixels 2548 position  0.000000000000000e+00 0.000000000000000e+00  0.000000000000000e+00
-sensor datation: sensorName s0 lineNumber  2.534400000000000e+05 date 2009-12-11T10:56:08.87816069400002Z
-sensor datation: sensorName s0 lineNumber  3.456000000000000e+05 date 2009-12-11T10:58:33.19814021399996Z
-inverse location: sensorName s0 latitude  8.744540902932477e-01 longitude  8.223965816103829e-02 elevation  1.932387539216973e+02 minLine 253440 maxLine 345600 lightTime false aberration false
-sensor mean plane: sensorName s0 minLine 253440 maxLine 345600 maxEval 50 accuracy  1.000000000000000e-02 normal 9.992992685324403e-01  3.581342262283560e-02  1.087982860931817e-02 cachedResults 0
-sensor datation: sensorName s0 lineNumber  2.995200000000000e+05 date 2009-12-11T10:57:21.03815045399999Z
-span: minDate 2009-12-11T10:49:31.00000000000000Z maxDate 2009-12-11T11:03:30.00000000000000Z tStep  1.000000000000000e-01 tolerance  1.000000000000000e+01 inertialFrame EME2000
-transform: index 4700 body r  5.336117270046078e-01 4.251589590898946e-04 -2.597710250850116e-04  8.457294346078028e-01 Ω -7.257892947630780e-08 -1.030887896243645e-09 -7.292111453494791e-05 ΩDot -1.960038458846624e-16 2.118427550826115e-16  1.921009249184302e-19 spacecraft p -2.053168038837612e-01 -4.479465554468334e-01 -7.157555881515884e+06 v -6.899290198987784e-02 -3.025941225892836e-02 -5.079406124814291e+00 a  3.805095952731160e-01 5.497720860602762e-01 -8.918837042129590e-03 r -2.219560290614089e-01 -4.227878241169732e-01 8.530519262360150e-01  2.104480650582249e-01 Ω -8.821450598425838e-04  5.190249503929784e-04  2.032835938889824e-04 ΩDot -4.852855703503804e-08 -1.727683064915104e-07 -5.843961481065110e-09
-ellipsoid: ae  6.378137000000000e+06 f  3.352810664747481e-03 frame ITRF_CIO_CONV_2010_SIMPLE_EOP
-sensor rate: sensorName s0 lineNumber  2.995200000000000e+05 rate 6.385810218828944e+02
-transform: index 5422 body r  5.358362189638148e-01 4.244746734277517e-04 -2.608866680050883e-04  8.443217977797100e-01 Ω -7.257894362971709e-08 -1.030872599745237e-09 -7.292111453507905e-05 ΩDot -1.960533569532405e-16 2.118830189595701e-16  1.921497489163665e-19 spacecraft p -2.077100353781134e-01 -5.937387477606535e-01 -7.157941245109990e+06 v -2.079879880167868e-02  6.790481151207040e-02 -5.590344257542220e+00 a  2.559067822717660e-01 1.523619888721470e+00 -6.690495582427680e-03 r -2.527575739550456e-01 -4.131723819265151e-01 8.446513348497744e-01  2.279612119594559e-01 Ω -8.835025599828953e-04  5.181159787201125e-04  1.981184601497435e-04 ΩDot -4.833822353095120e-08 -2.339809966148790e-08 -3.757527734431237e-07
-sensor rate: sensorName s0 lineNumber  3.456000000000000e+05 rate 6.385810218828944e+02
-Rugged exception: specifier GROUND_POINT_OUT_OF_LINE_RANGE parts 345933.8595532291 253440 345600
-- 
GitLab