diff --git a/src/main/java/org/orekit/rugged/adjustment/measurements/Observables.java b/src/main/java/org/orekit/rugged/adjustment/measurements/Observables.java
index 845a1c2dd87b53454080f5dcfd1863d67d59e6d5..5eca225657ac2c9d44d49540d32981767826ac03 100644
--- a/src/main/java/org/orekit/rugged/adjustment/measurements/Observables.java
+++ b/src/main/java/org/orekit/rugged/adjustment/measurements/Observables.java
@@ -35,10 +35,10 @@ public class Observables {
     /** Separator between sensors. */
     private static final String SENSORS_SEPARATOR = "__";
 
-    /** Sensor to ground mapping structure (example: for GCP points).*/
+    /** Sensor to ground mapping structure (example: for Ground Control Points GCP points).*/
     private final Map<String, SensorToGroundMapping> groundMappings;
 
-    /** Sensor to sensor mappings structure (liaison points). */
+    /** Sensor to sensor mappings structure (Tie points). */
     private final Map<String, SensorToSensorMapping> interMappings;
 
     /** Number of viewing models to map.*/
diff --git a/src/test/java/org/orekit/rugged/adjustment/AdjustmentContextTest.java b/src/test/java/org/orekit/rugged/adjustment/AdjustmentContextTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..3d45d74577081676fae919421df232f931f7888d
--- /dev/null
+++ b/src/test/java/org/orekit/rugged/adjustment/AdjustmentContextTest.java
@@ -0,0 +1,147 @@
+/* Copyright 2013-2018 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.adjustment;
+
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.hipparchus.optim.nonlinear.vector.leastsquares.LeastSquaresOptimizer.Optimum;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.orekit.rugged.adjustment.measurements.Observables;
+import org.orekit.rugged.api.Rugged;
+import org.orekit.rugged.errors.RuggedException;
+import org.orekit.rugged.utils.RefiningTest;
+
+public class AdjustmentContextTest {
+    
+    @Before
+    public void setUp() {
+        
+        try {
+            RefiningTest refiningTest = new RefiningTest();
+            refiningTest.initRefiningTest();
+
+            ruggedList = refiningTest.getRuggedList();
+
+            int lineSampling = 1000;
+            int pixelSampling = 1000;
+
+            measurements = refiningTest.generateNoisyPoints(lineSampling, pixelSampling);
+            numberOfParameters = refiningTest.getParameterToAdjust();
+            
+        }  catch (RuggedException re) {
+            Assert.fail(re.getLocalizedMessage());
+        }
+    }
+
+    @Test
+    public void testAdjustmentContext() throws RuggedException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
+        
+        AdjustmentContext adjustmentContext = new AdjustmentContext(ruggedList, measurements);
+        
+        // Check if the default OptimizerId is the expected one
+        Field optimizerId = adjustmentContext.getClass().getDeclaredField("optimizerID");
+        optimizerId.setAccessible(true);
+        OptimizerId defaultOptimizerId = (OptimizerId) optimizerId.get(adjustmentContext);
+        
+        System.out.println(defaultOptimizerId);
+        assertTrue((defaultOptimizerId == OptimizerId.GAUSS_NEWTON_QR));
+        
+//        // Check if the change of the default OptimizerId is correct
+//        adjustmentContext.setOptimizer(OptimizerId.GAUSS_NEWTON_LU);
+//        OptimizerId modifiedOptimizerId = (OptimizerId) optimizerId.get(adjustmentContext);
+//        System.out.println(modifiedOptimizerId);
+//        assertTrue((modifiedOptimizerId == OptimizerId.GAUSS_NEWTON_LU));
+        
+//        // Check if the change of the default OptimizerId is correct
+//        adjustmentContext.setOptimizer(OptimizerId.GAUSS_NEWTON_LU);
+//        OptimizerId modifiedOptimizerId = (OptimizerId) optimizerId.get(adjustmentContext);
+//        System.out.println(modifiedOptimizerId);
+//        assertTrue((modifiedOptimizerId == OptimizerId.GAUSS_NEWTON_LU));
+
+        
+//        OptimizerId.valueOf(OptimizerId.LEVENBERG_MARQUADT.toString());
+    }
+    
+ 
+
+    @Test
+    public void testEstimateFreeParameters() throws RuggedException, NoSuchFieldException, SecurityException, IllegalArgumentException, IllegalAccessException {
+        
+        AdjustmentContext adjustmentContext = new AdjustmentContext(ruggedList, measurements);
+        
+        List<String> ruggedNameList = new ArrayList<String>();
+        for(Rugged rugged : ruggedList) {
+            ruggedNameList.add(rugged.getName());
+        }
+        final int maxIterations = 120;
+        final double convergenceThreshold = 1.e-7;
+
+        Optimum optimum = adjustmentContext.estimateFreeParameters(ruggedNameList, maxIterations, convergenceThreshold);
+        
+        Assert.assertTrue(optimum.getIterations() < 20);
+        Field optimizerId = adjustmentContext.getClass().getDeclaredField("optimizerID");
+        optimizerId.setAccessible(true);
+        OptimizerId usedOptimizerId = (OptimizerId) optimizerId.get(adjustmentContext);
+        if (usedOptimizerId == OptimizerId.GAUSS_NEWTON_QR || usedOptimizerId == OptimizerId.GAUSS_NEWTON_LU) {
+            // For Gauss Newton, the number of evaluations is equal to the number of iterations
+            Assert.assertTrue(optimum.getEvaluations() == optimum.getIterations());
+        } else if (usedOptimizerId == OptimizerId.LEVENBERG_MARQUADT) {
+            // For Levenberg Marquadt, the number of evaluations is slightly greater than the number of iterations
+            Assert.assertTrue(optimum.getEvaluations() >= optimum.getIterations());
+        }
+
+        final double expectedMaxValue = 3.324585e-03;
+        Assert.assertEquals(expectedMaxValue, optimum.getResiduals().getMaxValue(), 1.0e-6);
+
+        final double expectedRMS = 0.069669;
+        Assert.assertEquals(expectedRMS, optimum.getRMS(), 1.0e-6);
+
+        System.out.format("Chi sqaure %3.8e %n", optimum.getChiSquare());
+        
+        assertTrue(numberOfParameters == optimum.getPoint().getDimension());
+        
+        System.out.format("residuals %d \n", optimum.getResiduals().getDimension());
+//        int measureCount = 0;
+//        while (measurements.getInterMappings().iterator().hasNext()) {
+//            measureCount++; 
+//            System.out.println("measure " + measureCount);
+//        }
+//        System.out.format(" measurements %d \n", measureCount);
+        System.out.format("cost %3.8e \n", optimum.getCost());
+        
+
+        
+    }
+
+    @After
+    public void tearDown() {
+        measurements = null;
+        ruggedList = null;
+    }
+    
+    private Observables measurements;
+    private List<Rugged> ruggedList;
+    private int numberOfParameters;
+
+}
diff --git a/src/test/java/org/orekit/rugged/utils/RefiningTest.java b/src/test/java/org/orekit/rugged/utils/RefiningTest.java
index bf0ff2dad01bef03746e078add0b94f6a8ef8b00..01269840918f7bf72ab8565ba9c56984aaf6e110 100644
--- a/src/test/java/org/orekit/rugged/utils/RefiningTest.java
+++ b/src/test/java/org/orekit/rugged/utils/RefiningTest.java
@@ -83,35 +83,32 @@ import org.orekit.rugged.los.TimeDependentLOS;
 public class RefiningTest {
 
     /** Pleiades viewing model A */
-    PleiadesViewingModel pleiadesViewingModelA;
+    private PleiadesViewingModel pleiadesViewingModelA;
 
     /** Pleiades viewing model B */
-    PleiadesViewingModel pleiadesViewingModelB;
+    private PleiadesViewingModel pleiadesViewingModelB;
     
     /** Line sensor A */
-    LineSensor lineSensorA;
+    private LineSensor lineSensorA;
     
     /** Line sensor B */
-    LineSensor lineSensorB;
+    private LineSensor lineSensorB;
 
     /** RuggedA's instance */
-    Rugged ruggedA;
+    private Rugged ruggedA;
 
     /** RuggedB's instance */
-    Rugged ruggedB;
+    private Rugged ruggedB;
     
+    /** Number of parameters to adjust */
+    private int parameterToAdjust;
     
-    /**
-     * Part of the name of parameter drivers 
-     */
+    // Part of the name of parameter drivers
     static final String rollSuffix = "_roll";
     static final String pitchSuffix = "_pitch";
     static final String factorName = "factor";
 
-    
-    /**
-     * Default values for disruption to apply to roll (deg), pitch (deg) and factor 
-     */
+    // Default values for disruption to apply to roll (deg), pitch (deg) and factor 
     static final double defaultRollDisruptionA =  0.004;
     static final double defaultPitchDisruptionA = 0.0008;
     static final double defaultFactorDisruptionA = 1.000000001;
@@ -242,6 +239,8 @@ public class RefiningTest {
 
             setSelectedRoll(ruggedB, sensorNameB);
             setSelectedPitch(ruggedB, sensorNameB);
+            
+            this.parameterToAdjust = 4;
 
             // Initialize disruptions:
             // -----------------------
@@ -461,11 +460,7 @@ public class RefiningTest {
         // Observables which contains sensor to sensor mapping
         Observables observables = new Observables(2);
         
-        
-        System.out.format("\n**** Generate noisy measurements (sensor to sensor mapping) **** %n");
-
         // Generation noisy measurements
-        
         // distribution: gaussian(0), vector dimension: 2
         final double meanA[] = { 5.0, 5.0 };
         final double stdA[]  = { 0.1, 0.1 };
@@ -541,9 +536,6 @@ public class RefiningTest {
         } // end loop on line of sensorA
 
         observables.addInterMapping(interMapping);
-        
-        System.out.format("Number of tie points generated: %d %n", measurementCount);
-        
         return observables;
     }
     
@@ -565,6 +557,13 @@ public class RefiningTest {
     @After
     public void tearDown() {
     }
+    
+    /** Get the number of parameters to adjust
+     * @return number of parameters to adjust
+     */
+    public int getParameterToAdjust() {
+        return parameterToAdjust;
+    }
 }
 
 
diff --git a/src/test/java/org/orekit/rugged/utils/RefiningTiePointsMetrics.java b/src/test/java/org/orekit/rugged/utils/RefiningTiePointsMetrics.java
index 4e655361f62416b0179112fb9571a00e7dd3deb2..5e3f3038f5da30437d0190e83400a3cd0c568579 100644
--- a/src/test/java/org/orekit/rugged/utils/RefiningTiePointsMetrics.java
+++ b/src/test/java/org/orekit/rugged/utils/RefiningTiePointsMetrics.java
@@ -1,9 +1,9 @@
 package org.orekit.rugged.utils;
 
 /**
- * Contains results from liaison metrics computation
+ * Contains results from tie metrics computation
  */
-public class RefiningLiaisonMetrics {
+public class RefiningTiePointsMetrics {
     
     /** Maximum residual distance. */
     private double resMax;
@@ -18,7 +18,7 @@ public class RefiningLiaisonMetrics {
     /** Earth distance mean.*/
     private double earthDistanceMean;
     
-    public RefiningLiaisonMetrics() {
+    public RefiningTiePointsMetrics() {
         
         this.resMax = 0.0;
         this.resMean = 0.0;