diff --git a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
index 7c1337651ce98baa1acb667749916ba2f5b69864..ad6bfa6bcf9ad6c8199cb78390818f7ff3e58d19 100644
--- a/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
+++ b/Modules/Wrappers/ApplicationEngine/include/otbWrapperApplication.h
@@ -284,8 +284,21 @@ public:
 
   void SetParameterEmpty(std::string parameter, bool value, bool hasUserValueFlag = true);
 
+  /** Checks if the application is ready to be executed. It checks that there
+   *  is no parameter missing
+   */
   bool IsApplicationReady();
 
+  /** Checks if a parameter 'key' is missing.
+   *
+   * A parameter is missing when all the following conditions are true :
+   *   - the parameter is mandatory
+   *   - the parameter has Role_Input
+   *   - the parameter is not a group
+   *   - the parameter has no value
+   *   - the parameter ancestors are mandatory or enabled.
+   */
+  bool IsParameterMissing(const std::string &key) const;
 
   /* Set an default integer value, must used in the
    * DoInit when setting a value by default
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
index 3a04bad27075d99caa0ff696b601b8f8512f6556..c2282f7f9c3c048b9bae9713837a7c0d497f8b29 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperApplication.cxx
@@ -36,6 +36,7 @@
 #include "otbWrapperInputProcessXMLParameter.h"
 #include "otbWrapperRAMParameter.h"
 #include "otbWrapperProxyParameter.h"
+#include "otbWrapperParameterKey.h"
 
 
 #include "otbWrapperAddProcessToWatchEvent.h"
@@ -1599,57 +1600,50 @@ Application::IsApplicationReady()
        it != paramList.end();
        ++it)
     {
-    // Check all Input Parameters with Input Role
-    if (GetParameterByKey(*it)->GetRole() == Role_Input)
+    // Check all parameters
+    if (IsParameterMissing(*it))
       {
-      // When a parameter is mandatory :
-      // return false when does not have value and:
-      //  - The param is root
-      //  - The param is not root and belonging to a Mandatory Group
-      //    which is activated
-      if ( !this->HasValue(*it)  && IsMandatory(*it) )
-        {
-        if( GetParameterByKey(*it)->IsRoot() )
-          {
-          otbDebugMacro("MISSING : "<< (*it).c_str() << " ( Is Root)");
-          return false;
-          }
-        else
-          {
-          // check if the parameter is linked to a root parameter with a chain of active parameters
-          Parameter* currentParam = GetParameterByKey(*it)->GetRoot();
-          if (currentParam->IsRoot())
-            {
-            otbDebugMacro("MISSING : "<< (*it).c_str() << " ( Is Level 1)");
-            return false;
-            }
-
-          int level = 1;
-
-          while (!currentParam->IsRoot())
-            {
-            if (!currentParam->GetActive())
-              {
-              // the missing parameter is not on an active branch : we can ignore it
-              break;
-              }
-            currentParam = currentParam->GetRoot();
-
-            level++;
+      ready = false;
+      break;
+      }
+    }
+  return ready;
+}
 
-            if (currentParam->IsRoot())
-              {
-              // the missing parameter is on an active branch : we need it
-              otbDebugMacro("MISSING : "<< (*it).c_str() << " ( Is Level "<< level<<")");
-              return false;
-              }
-            }
-          }
+bool
+Application::IsParameterMissing(const std::string &key) const
+{
+  bool ret(false);
+  const Parameter* param = GetParameterByKey(key);
+  if (param->GetRole() == Role_Input &&
+      GetParameterType(key) != ParameterType_Group &&
+      param->GetMandatory() &&
+      !param->HasValue())
+    {
+    ret = true;
+    ParameterKey paramKey(key);
+    std::vector<std::string> split = paramKey.Split();
+    std::string currentRoot(key);
+    unsigned int level = 1;
+    while (level < split.size())
+      {
+      currentRoot.resize(currentRoot.find_last_of("."));
+      param = GetParameterByKey(currentRoot);
+      if (!param->GetActive() && !param->GetMandatory())
+        {
+        // the missing parameter is not on an active branch : we can ignore it
+        ret = false;
+        break;
         }
+      level++;
+      }
+    if (ret)
+      {
+      // the missing parameter is on an active branch : we need it
+      otbDebugMacro("MISSING : "<< key << " (Level "<< split.size()<<")");
       }
     }
-
-  return ready;
+  return ret;
 }
 
 void
diff --git a/Modules/Wrappers/ApplicationEngine/src/otbWrapperChoiceParameter.cxx b/Modules/Wrappers/ApplicationEngine/src/otbWrapperChoiceParameter.cxx
index 1ebb88d529cb5648416a466f98dc4a1dec8ec527..2f64625f58a08987b4db3c4940c8d1b978d2e3f6 100644
--- a/Modules/Wrappers/ApplicationEngine/src/otbWrapperChoiceParameter.cxx
+++ b/Modules/Wrappers/ApplicationEngine/src/otbWrapperChoiceParameter.cxx
@@ -44,7 +44,7 @@ ChoiceParameter::AddChoice( std::string choicekey, std::string choiceName )
   choice.m_AssociatedParameter->SetName(choiceName);
   choice.m_AssociatedParameter->SetRoot(this);
   choice.m_AssociatedParameter->SetKey(choicekey);
-  
+  choice.m_AssociatedParameter->SetMandatory(false);
   m_ChoiceList.push_back(choice);
 
   // check if the new choice matches the m_CurrentChoice : if so the group should be active.