Index: CMT/v1r19/source/cmt.h
===================================================================
--- CMT/v1r19/source/cmt.h	(revision 11)
+++ CMT/v1r19/source/cmt.h	(revision 15)
@@ -32,7 +32,4 @@
   cmt_string m_cmt_site;
   cmt_string m_cmt_version;
-  
-  int m_current_build_strategy;
-  int m_current_setup_strategy;
   
   cmt_string m_current_dir;
@@ -204,6 +201,4 @@
   static const cmt_string& get_current_offset ();
   static AccessMode get_current_access ();
-  static int get_current_build_strategy ();
-  static int get_current_setup_strategy ();
   static CmtStructuringStyle get_current_structuring_style ();
   static CmtDirStyle get_current_style ();
@@ -240,6 +235,4 @@
   static void restore_all_tags (Use* use);
   static void set_current_access (AccessMode mode);
-  static void set_current_build_strategy (int strategy);
-  static void set_current_setup_strategy (int strategy);
   static void set_scope_filtering_mode (CmtScopeFilteringMode mode);
   static void set_standard_macros ();
Index: CMT/v1r19/source/cmt_commands.cxx
===================================================================
--- CMT/v1r19/source/cmt_commands.cxx	(revision 11)
+++ CMT/v1r19/source/cmt_commands.cxx	(revision 15)
@@ -1897,5 +1897,5 @@
 void ArgParser::option_no_cleanup ()
 {
-  cmt.m_current_setup_strategy |= SetupNoCleanup;
+  //cmt.m_current_setup_strategy |= SetupNoCleanup;
 }
 
Index: CMT/v1r19/source/cmt_parser.cxx
===================================================================
--- CMT/v1r19/source/cmt_parser.cxx	(revision 11)
+++ CMT/v1r19/source/cmt_parser.cxx	(revision 15)
@@ -62,6 +62,4 @@
   m_cmt_root       = "";
   m_cmt_version    = "";
-  m_current_build_strategy = DefaultBuildStrategy;
-  m_current_setup_strategy = DefaultSetupStrategy;
   m_current_dir     = "";
   m_current_package = "";
@@ -155,5 +153,5 @@
 
 //----------------------------------------------------------
-static int get_build_strategy (Use& use = Use::current())
+static bool get_strategy (const cmt_string& name, Use& use = Use::current())
 {
   static cmt_string cmtpath;
@@ -164,26 +162,8 @@
   Project* p = Project::find_by_cmtpath (cmtpath);
 
-  int strategy = 0;
-
-  if (p == 0) strategy = Cmt::get_current_build_strategy ();
-  else strategy = p->get_build_strategy ();
-
-  return (strategy);
-}
-
-//----------------------------------------------------------
-static int get_setup_strategy (Use& use = Use::current())
-{
-  static cmt_string cmtpath;
-  static cmt_string offset;
-
-  use.get_cmtpath_and_offset (cmtpath, offset);
-
-  Project* p = Project::find_by_cmtpath (cmtpath);
-
-  int strategy = 0;
-
-  if (p == 0) strategy = Cmt::get_current_setup_strategy ();
-  else strategy = p->get_setup_strategy ();
+  bool strategy;
+
+  if (p == 0) strategy = StrategyMgr::get_default_strategy (name);
+  else strategy = p->get_strategy (name);
 
   return (strategy);
@@ -1737,5 +1717,5 @@
   }
 
-  if ((get_build_strategy () & InstallAreaMask) == WithInstallArea)
+  if (get_strategy ("InstallArea"))
     {
       const CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
@@ -2159,5 +2139,5 @@
     //  Try a cleanup of the installation area
     //
-  if ((get_build_strategy () & InstallAreaMask) == WithInstallArea)
+  if (get_strategy ("InstallArea"))
     {
       CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
@@ -2165,5 +2145,5 @@
       //cout << "#IA3>" << endl;
 
-      if ((get_setup_strategy () & SetupCleanupMask) == SetupCleanup)
+      if (get_strategy ("SetupCleanup"))
 	{
 	  ia_mgr.config ();
@@ -2833,5 +2813,5 @@
               Symbol::expand (libname);
 
-              if ((get_build_strategy () & InstallAreaMask) == WithInstallArea)
+              if (get_strategy ("InstallArea"))
                 {
                   const CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
@@ -3032,5 +3012,5 @@
     //  Try a cleanup of the installation area
     //
-  if ((get_build_strategy () & InstallAreaMask) == WithInstallArea)
+  if (get_strategy ("InstallArea"))
     {
       CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
@@ -3041,5 +3021,5 @@
 
       /*
-      if ((get_setup_strategy () & SetupCleanupMask) == SetupCleanup)
+      if (get_strategy ("SetupCleanup"))
         {
 	  const cmt_string& installarea = ia_mgr.get_installarea ();
@@ -3581,10 +3561,10 @@
   Project* p = Project::get_current ();
 
-  if (p != 0) p->show ();
-  else cout << "No current project" << endl;
+  /*
+    if (p != 0) p->show ();
+    else cout << "No current project" << endl;
+  */
 
   cout << "Structuring style : ";
-
-  int strategy = 0;
 
   switch (Me.m_current_structuring_style)
@@ -3602,17 +3582,14 @@
   cout << "Build strategy    : ";
 
-  if (p == 0) strategy = Me.m_current_build_strategy;
-  else strategy = p->get_build_strategy ();
+  if (get_strategy ("BuildPrototypes"))
+    {
+      cout << "prototypes";
+    }
+  else
+    {
+      cout << "no_prototypes";
+    }
   
-  if ((strategy & PrototypesMask) == Prototypes)
-    {
-      cout << "prototypes";
-    }
-  else
-    {
-      cout << "no_prototypes";
-    }
-  
-  if ((strategy & InstallAreaMask) == WithInstallArea)
+  if (get_strategy ("InstallArea"))
     {
       cout << " with_installarea";
@@ -3627,7 +3604,5 @@
   cout << "Setup strategy    : ";
   
-  strategy = get_setup_strategy ();
-
-  if ((strategy & SetupConfigMask) == SetupConfig)
+  if (get_strategy ("SetupConfig"))
     {
       cout << "config";
@@ -3638,5 +3613,5 @@
     }
   
-  if ((strategy & SetupRootMask) == SetupRoot)
+  if (get_strategy ("SetupRoot"))
     {
       cout << " root";
@@ -3647,5 +3622,5 @@
     }
   
-  if ((strategy & SetupCleanupMask) == SetupCleanup)
+  if (get_strategy ("SetupCleanup"))
     {
       cout << " cleanup";
@@ -3802,14 +3777,4 @@
 {
   return (Me.m_current_access);
-}
-
-int Cmt::get_current_build_strategy ()
-{
-  return (Me.m_current_build_strategy);
-}
-
-int Cmt::get_current_setup_strategy ()
-{
-  return (Me.m_current_setup_strategy);
 }
 
@@ -4115,5 +4080,5 @@
   cmt_string no_cleanup_opt;
 
-  if ((get_setup_strategy () & SetupCleanupMask) != SetupCleanup)
+  if (get_strategy ("SetupCleanup"))
     {
       no_cleanup_opt = " -no_cleanup";
@@ -4307,5 +4272,5 @@
   cmt_string no_cleanup_opt;
 
-  if ((get_setup_strategy () & SetupCleanupMask) != SetupCleanup)
+  if (get_strategy ("SetupCleanup"))
     {
       no_cleanup_opt = " -no_cleanup";
@@ -4645,5 +4610,5 @@
 bool Cmt::need_prototypes ()
 {
-  if ((get_build_strategy () & PrototypesMask) == Prototypes) return (true);
+  if (get_strategy ("BuildPrototypes")) return (true);
   else return (false);
 }
@@ -5680,10 +5645,6 @@
   cmt_string system = CmtSystem::get_cmt_config ();
 
-  int strategy = 0;
-
-  strategy = get_setup_strategy (use);
-
-  bool do_config = ((strategy & SetupConfigMask) == SetupConfig);
-  bool do_root = ((strategy & SetupRootMask) == SetupRoot);
+  bool do_config = get_strategy ("SetupConfig");
+  bool do_root = get_strategy ("SetupRoot");
 
   switch (mode)
@@ -7226,5 +7187,5 @@
     CmtPathPattern::apply_all ();
 
-    if ((get_build_strategy () & InstallAreaMask) == WithInstallArea)
+    if (get_strategy ("InstallArea"))
       {
 	CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
@@ -7266,16 +7227,4 @@
 
 //----------------------------------------------------------
-void Cmt::set_current_build_strategy (int strategy)
-{
-  Me.m_current_build_strategy = strategy;
-}
-
-//----------------------------------------------------------
-void Cmt::set_current_setup_strategy (int strategy)
-{
-  Me.m_current_setup_strategy = strategy;
-}
-
-//----------------------------------------------------------
 void Cmt::set_scope_filtering_mode (CmtScopeFilteringMode mode)
 {
@@ -7372,5 +7321,5 @@
     //
   /*
-  if ((get_build_strategy () & InstallAreaMask) == WithInstallArea)
+  if (get_strategy ("InstallArea"))
     {
       CmtInstallAreaMgr& ia_mgr = CmtInstallAreaMgr::instance ();
Index: CMT/v1r19/source/cmt_project.cxx
===================================================================
--- CMT/v1r19/source/cmt_project.cxx	(revision 11)
+++ CMT/v1r19/source/cmt_project.cxx	(revision 15)
@@ -153,5 +153,5 @@
     Now Figure out the project name from the project file
     Or construct an automatic project name when project file does no exist
-    or does not specify the project name
+       or does not specify the project name
    */
   if (CmtSystem::cd ("cmt") && CmtSystem::test_file (Project::get_project_file_name ()))
@@ -841,22 +841,7 @@
   m_children.clear ();
 
-  m_build_strategy_mask = 0;
-  m_build_strategy = DefaultBuildStrategy;
-  m_setup_strategy_mask = 0;
-  m_setup_strategy = DefaultSetupStrategy;
-
   m_configured = false;
 
-  m_prototypes_tag = 0;
-  m_no_prototypes_tag = 0;
-  m_with_installarea_tag = 0;
-  m_without_installarea_tag = 0;
-  
-  m_setup_config_tag = 0;
-  m_setup_no_config_tag = 0;
-  m_setup_root_tag = 0;
-  m_setup_no_root_tag = 0;
-  m_setup_cleanup_tag = 0;
-  m_setup_no_cleanup_tag = 0;
+  m_strategies.clear ();
 }
 
@@ -887,5 +872,5 @@
       if (parent->get_name () == p->get_name ())
 	{
-	  // Already registered
+	  // Already registered as a parent
 	  return;
 	}
@@ -896,16 +881,5 @@
   // Since p is a new parent, we should propagate the settings UP.
 
-  if (m_setup_strategy_mask != 0)
-    {
-      p->set_setup_strategy (m_setup_strategy_mask, m_setup_strategy & PrototypesMask);
-      p->set_setup_strategy (m_setup_strategy_mask, m_setup_strategy & InstallAreaMask);
-    }
-
-  if (m_build_strategy_mask != 0)
-    {
-      p->set_build_strategy (m_build_strategy_mask, m_build_strategy & SetupConfigMask);
-      p->set_build_strategy (m_build_strategy_mask, m_build_strategy & SetupRootMask);
-      p->set_build_strategy (m_build_strategy_mask, m_build_strategy & SetupCleanupMask);
-    }
+  p->update_strategies_from_children ();
 }
 
@@ -936,5 +910,5 @@
       if (child->get_name () == p->get_name ())
 	{
-	  // Already registered
+	  // Already registered as a child
 	  return;
 	}
@@ -947,107 +921,17 @@
 void Project::configure ()
 {
-  /*
-
-  <project>_prototypes
-  <project>_no_prototypes
-  <project>_rebuild_makefile
-  <project>_keep_makefile
-  <project>_with_installarea
-  <project>_without_installarea
-
-  <project>_setup_config
-  <project>_setup_no_config
-  <project>_setup_root
-  <project>_setup_no_root
-  <project>_setup_cleanup
-  <project>_setup_no_cleanup
-
-  */
-
   if (m_configured) return;
   m_configured = true;
 
-  cmt_string tag_name;
-
-  tag_name = m_name;
-  tag_name += "_prototypes";
-  m_prototypes_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0);
-  
-  tag_name = m_name;
-  tag_name += "_no_prototypes";
-  m_no_prototypes_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0);
-  
-  m_prototypes_tag->add_tag_exclude (m_no_prototypes_tag);
-  m_no_prototypes_tag->add_tag_exclude (m_prototypes_tag);
-  m_prototypes_tag->mark ();
-  
-  tag_name = m_name;
-  tag_name += "_with_installarea";
-  m_with_installarea_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0);
-  
-  tag_name = m_name;
-  tag_name += "_without_installarea";
-  m_without_installarea_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0);
-  
-  m_with_installarea_tag->add_tag_exclude (m_without_installarea_tag);
-  m_without_installarea_tag->add_tag_exclude (m_with_installarea_tag);
-  m_without_installarea_tag->mark ();
-
-
-
-  tag_name = m_name;
-  tag_name += "_setup_config";
-  m_setup_config_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0);
-  
-  tag_name = m_name;
-  tag_name += "_setup_no_config";
-  m_setup_no_config_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0);
-  
-  m_setup_config_tag->add_tag_exclude (m_setup_no_config_tag);
-  m_setup_no_config_tag->add_tag_exclude (m_setup_config_tag);
-  m_setup_config_tag->mark ();
-
-  tag_name = m_name;
-  tag_name += "_setup_root";
-  m_setup_root_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0);
-  
-  tag_name = m_name;
-  tag_name += "_setup_no_root";
-  m_setup_no_root_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0);
-  
-  m_setup_root_tag->add_tag_exclude (m_setup_no_root_tag);
-  m_setup_no_root_tag->add_tag_exclude (m_setup_root_tag);
-  m_setup_root_tag->mark ();
-
-  tag_name = m_name;
-  tag_name += "_setup_cleanup";
-  m_setup_cleanup_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0);
-  
-  tag_name = m_name;
-  tag_name += "_setup_no_cleanup";
-  m_setup_no_cleanup_tag = Tag::add (tag_name, PriorityConfig, "PROJECT", 0);
-  
-  m_setup_cleanup_tag->add_tag_exclude (m_setup_no_cleanup_tag);
-  m_setup_no_cleanup_tag->add_tag_exclude (m_setup_cleanup_tag);
-  m_setup_cleanup_tag->mark ();
-
-  if (Cmt::get_debug ())
-    {
-      cout << "Project::configure> " << m_name
-	   << " " << m_prototypes_tag
-	   << " " << m_no_prototypes_tag
-	   << " " << m_with_installarea_tag
-	   << " " << m_without_installarea_tag
-	   << " " << m_setup_config_tag
-	   << " " << m_setup_no_config_tag
-	   << " " << m_setup_root_tag
-	   << " " << m_setup_no_root_tag
-	   << " " << m_setup_cleanup_tag
-	   << " " << m_setup_no_cleanup_tag
-	   << endl;
-    }
-}
-
-//----------------------------------------------------------
+  set_default_strategy ("SetupConfig");
+  set_default_strategy ("SetupRoot");
+  set_default_strategy ("SetupCleanup");
+  set_default_strategy ("BuildPrototypes");
+  set_default_strategy ("InstallArea");
+}
+
+/**---------------------------------------------------------
+ A use statement is met in the project file
+*/
 void Project::use_action (const cmt_string& name, const cmt_string& release)
 {
@@ -1059,5 +943,5 @@
   // If not: look for it
   //   + get CMTPROJECTPATH
-  //   + search from all entries of CMTPROJECTPATH : pi/<name>/<release>
+  //   + search from all entries of CMTPROJECTPATH : p(i)/<name>/<release>
   //   + when found, this should become a new CMTPATH entry
   //   +             the new project is then parsed ... etc...
@@ -1065,5 +949,5 @@
   cmt_string cmtprojectpath = CmtSystem::getenv ("CMTPROJECTPATH");
   cmt_string sep;
-  sep += CmtSystem::path_separator ();
+  sep = CmtSystem::path_separator ();
 
   //cerr << "cmtprojectpath = " << cmtprojectpath << endl;
@@ -1081,5 +965,5 @@
       if (CmtSystem::test_directory (p))
 	{
-	  //cerr << "Project directry " << p << " exists " << endl;
+	  //cerr << "Project directory " << p << " exists " << endl;
 
 	  IProjectFactory& factory = ProjectFactory::instance ();
@@ -1177,205 +1061,499 @@
 
 //----------------------------------------------------------
-int Project::get_build_strategy () const
-{
-  int result = 0;
-
-  result = Cmt::get_current_build_strategy ();
-
+bool Project::has_strategy (const StrategyDef* definition) const
+{
   int i;
 
-  bool request_non_default_prototypes = false;
-  bool request_non_default_installarea = false;
-
-  int m_prototypes = 0;
-  int m_installarea = 0;
+  for (i = 0; i < m_strategies.size (); i++)
+    {
+      const Strategy& s = m_strategies[i];
+      if (s.m_definition == definition)
+	{
+	  return (true);
+	}
+    }
+
+  return (false);
+}
+
+//----------------------------------------------------------
+bool Project::get_strategy (const cmt_string& name) const
+{
+  static StrategyMgr& mgr = StrategyMgr::instance ();
+
+  StrategyDef* def = mgr.find_strategy (name);
+  if (def == 0)
+    {
+      cerr << "#CMT> strategy " << name << " undefined" << endl;
+      return (false);
+    }
+
+  return (get_strategy (def));
+}
+
+//----------------------------------------------------------
+bool Project::is_specified (const StrategyDef* definition) const
+{
+  int i;
+
+  for (i = 0; i < m_strategies.size (); i++)
+    {
+      Strategy& s = m_strategies[i];
+      if (s.m_definition == definition)
+	{
+	  // This strategy is applied in this project
+	  return (s.m_specified);
+	}
+    }
+
+  // This strategy is not applied in this project
+  return (false);
+}
+
+//----------------------------------------------------------
+bool Project::get_strategy (const StrategyDef* def) const
+{
+  int i;
+
+  for (i = 0; i < m_strategies.size (); i++)
+    {
+      Strategy& s = m_strategies[i];
+      if (s.m_definition == def)
+	{
+	  // This strategy is applied in this project
+	  if (s.m_specified)
+	    {
+	      return (s.m_specified_value);
+	    }
+	  return (s.m_value);
+	}
+    }
+
+  // This strategy is not applied in this project
+  return (def->m_default_value);
+}
+
+//----------------------------------------------------------
+void Project::set_default_strategy (const cmt_string& name)
+{
+  static StrategyMgr& mgr = StrategyMgr::instance ();
+
+  StrategyDef* def = mgr.find_strategy (name);
+  if (def == 0)
+    {
+      cerr << "#CMT> strategy " << name << " undefined" << endl;
+      return;
+    }
+
+  update_strategy (def, def->m_default_value);
+}
+
+
+//----------------------------------------------------------
+void Project::set_strategy (const cmt_string& name, const cmt_string& value)
+{
+  static StrategyMgr& mgr = StrategyMgr::instance ();
+
+  StrategyDef* def = mgr.find_strategy (name);
+  if (def == 0)
+    {
+      cerr << "#CMT> strategy " << name << " undefined" << endl;
+      return;
+    }
+
+  bool b_value = false;
+
+  if (value == def->m_on_value)
+    {
+      b_value = true;
+    }
+  else if (value == def->m_off_value)
+    {
+      b_value = false;
+    }
+  else
+    {
+      cerr << "#CMT> requested strategy value " << value << " undefined in strategy " << name << endl;
+      return;
+    }
+
+  set_strategy (def, b_value);
+}
+
+//----------------------------------------------------------
+void Project::set_strategy (StrategyDef* definition, bool b_value)
+{
+  bool need_strategy = true;
+
+  int i;
+
+  for (i = 0; i < m_strategies.size (); i++)
+    {
+      Strategy& s = m_strategies[i];
+      if (s.m_definition == definition)
+	{
+	  // This strategy is already applied in this project. Let's change it's value
+	  s.set (definition, b_value, get_name ());
+	  need_strategy = false;
+	  break;
+	}
+    }
+
+  if (need_strategy)
+    {
+      // This strategy is not yet applied in this project.
+
+      Strategy& s = m_strategies.add ();
+      s.set (definition, b_value, get_name ());
+    }
+  
+  for (i = 0; i < m_parents.size (); i++)
+    {
+      Project* project = m_parents[i];
+
+      project->update_strategy (definition, b_value);
+    }
+}
+
+/**----------------------------------------------------------
+   The strategy value is changed because of indirect influences
+   - default strategy at initialization time
+   - change in the children
+   - change in the children list
+
+   (This is not a specification : see the set_strategy method)
+ */
+void Project::update_strategy (StrategyDef* definition, bool b_value)
+{
+  bool need_strategy = true;
+
+  int i;
+
+  for (i = 0; i < m_strategies.size (); i++)
+    {
+      Strategy& s = m_strategies[i];
+      if (s.m_definition == definition)
+	{
+	  // This strategy is already applied in this project. Let's change it's value
+	  s.update (definition, b_value, get_name ());
+	  need_strategy = false;
+	  break;
+	}
+    }
+
+  if (need_strategy)
+    {
+      // This strategy is not yet applied in this project.
+
+      Strategy& s = m_strategies.add ();
+      s.update (definition, b_value, get_name ());
+    }
+  
+  for (i = 0; i < m_parents.size (); i++)
+    {
+      Project* project = m_parents[i];
+
+      if (project->has_strategy (definition))
+	{
+	  project->update_strategy (definition, b_value);
+	}
+    }
+}
+
+/**----------------------------------------------------------
+   At least one of the children has changed this strategy
+   Or the list of children has changed.
+   We need to update the strategy value accordingly
+   This will not change the specified value for this strategy
+ */
+void Project::update_strategy_from_children (StrategyDef* definition)
+{
+  // If this strategy is specified we don't care what happens from the children
+
+  cerr << "Updating strategy " << definition->m_name << " from children for project " << m_name << endl;
+
+  int i;
+
+  for (i = 0; i < m_strategies.size (); i++)
+    {
+      Strategy& s = m_strategies[i];
+      if (s.m_definition == definition)
+	{
+	  // This strategy is applied in this project.
+
+	  if (s.m_specified)
+	    {
+	      // There will be no impact since the strategy is specified
+
+	      cerr << "This strategy is specified in this project" << endl;
+	      return;
+	    }
+
+	  break;
+	}
+    }
+
+  // The strategy is not specified locally so we will now figure out
+  // which strategy has to be considered from the mixture of specifications
+  // from all children.
+
+  // Algorithm:
+  // - We consider children by pairs
+  // - a child that specifies its strategy wins over a child that does not
+  // - when the two children have the same level of priority we consider the priority value
+
+  Project* selected = 0;
+  bool selected_is_specified = false;
+  bool selected_value = false;
 
   for (i = 0; i < m_children.size (); i++)
     {
-      const Project* p = m_children[i];
-      int s = p->get_build_strategy ();
-
-      int s_prototypes = s & ~PrototypesMask;
-
-      if (s_prototypes != DefaultPrototypesStrategy)
-	{
-	  // keep it. At least one of the children has specified a non-default strategy
-	  request_non_default_prototypes = true;
-	  m_prototypes = s_prototypes;
-	}
-
-      int s_installarea = s & ~InstallAreaMask;
-
-      if (s_installarea != DefaultInstallAreaStrategy)
-	{
-	  // keep it. At least one of the children has specified a non-default strategy
-	  request_non_default_installarea = true;
-	  m_installarea = s_installarea;
-	}
-    }
-
-  if (m_build_strategy_mask != 0)
-    {
-      result &= ~m_build_strategy_mask;
-      result |= m_build_strategy;
+      Project* p = m_children[i];
+
+      cerr << "Checking strategy for child " << p->get_name () << endl;
+
+      bool is_specified = p->is_specified (definition);
+      bool value = p->get_strategy (definition);
+
+      if (selected == 0)
+	{
+	  selected = p;
+	  selected_is_specified = is_specified;
+	  selected_value = value;
+	  continue;
+	}
+
+      if (is_specified == selected_is_specified)
+	{
+	  if (selected_value != value)
+	    {
+	      // same level of priority but different values -> we must decide
+	      bool priority_value = definition->m_priority_value;
+	      if (value == priority_value)
+		{
+		  selected = p;
+		  selected_is_specified = is_specified;
+		  selected_value = value;
+		}
+	    }
+	}
+      else
+	{
+	  if (is_specified)
+	    {
+	      selected = p;
+	      selected_is_specified = is_specified;
+	      selected_value = value;
+	    }
+	}
+    }
+
+  update_strategy (definition, selected_value);  
+}
+
+/**----------------------------------------------------------
+   At least one of the children has changed its strategies
+   Or the list of children has changed.
+   We need to update the strategy values accordingly
+   This will not change the specified values
+ */
+void Project::update_strategies_from_children ()
+{
+  StrategyDef::StrategyDefs& defs = StrategyMgr::get_definitions ();
+
+  cerr << "Updating strategies from children for project " << m_name << endl;
+
+  int i;
+
+  for (i = 0; i < defs.size (); i++)
+    {
+      StrategyDef* def = defs[i];
+
+      update_strategy_from_children (def);
+    }
+}
+
+/**----------------------------------------------------------
+   The StrategyMgr singleton
+ */
+StrategyMgr& StrategyMgr::instance ()
+{
+  static StrategyMgr me;
+  return (me);
+}
+
+/**----------------------------------------------------------
+   The StrategyMgr constructor
+   Here are primarily constructed all strategy definitions
+ */
+StrategyMgr::StrategyMgr ()
+{
+  m_defs.clear ();
+
+  StrategyDef* s;
+
+  s = new StrategyDef;
+  s->m_name = "BuildPrototypes";
+  s->m_on_value = "prototypes";
+  s->m_off_value = "no_prototypes";
+  s->m_default_value = true;
+  s->m_priority_value = false;
+
+  m_defs.push_back (s);
+
+  s = new StrategyDef;
+  s->m_name = "InstallArea";
+  s->m_on_value = "with_installarea";
+  s->m_off_value = "without_installarea";
+  s->m_default_value = false;
+  s->m_priority_value = true;
+
+  m_defs.push_back (s);
+
+  s = new StrategyDef;
+  s->m_name = "SetupConfig";
+  s->m_on_value = "config";
+  s->m_off_value = "no_config";
+  s->m_default_value = true;
+  s->m_priority_value = false;
+
+  m_defs.push_back (s);
+
+  s = new StrategyDef;
+  s->m_name = "SetupRoot";
+  s->m_on_value = "root";
+  s->m_off_value = "no_root";
+  s->m_default_value = true;
+  s->m_priority_value = false;
+
+  m_defs.push_back (s);
+
+  s = new StrategyDef;
+  s->m_name = "SetupCleanup";
+  s->m_on_value = "cleanup";
+  s->m_off_value = "no_cleanup";
+  s->m_default_value = true;
+  s->m_priority_value = false;
+
+  m_defs.push_back (s);
+}
+
+/**----------------------------------------------------------
+   Find a strategy definition by its name
+ */
+StrategyDef* StrategyMgr::find_strategy (const cmt_string& name)
+{
+  static StrategyMgr& me = instance ();
+
+  int i;
+
+  for (i = 0; i < me.m_defs.size (); i++)
+    {
+      StrategyDef* def = me.m_defs[i];
+      if (def->m_name == name)
+	{
+	  return (def);
+	}
+    }
+
+  return (0);
+}
+
+/**----------------------------------------------------------
+   Retreive the default value defined for a given strategy
+ */
+bool StrategyMgr::get_default_strategy (const cmt_string& name)
+{
+  StrategyDef* def = find_strategy (name);
+  if (def == 0) return (false);
+  return (def->m_default_value);
+}
+
+/**----------------------------------------------------------
+   Retreive the priority value defined for a given strategy
+   This value is used when two children of a project request two conflicting strategy values
+ */
+bool StrategyMgr::get_priority_strategy (const cmt_string& name)
+{
+  StrategyDef* def = find_strategy (name);
+  if (def == 0) return (false);
+  return (def->m_priority_value);
+}
+
+/**----------------------------------------------------------
+   Return the vector of all existing strategy definitions
+ */
+StrategyDef::StrategyDefs& StrategyMgr::get_definitions ()
+{
+  static StrategyMgr& me = instance ();
+
+  return (me.m_defs);
+}
+
+/**----------------------------------------------------------
+   Specify a new value for this strategy.
+   This only happens when a strategy statement is met in a project file or in a requirements file.
+ */
+void Strategy::set (StrategyDef* definition, bool value, const cmt_string& project_name)
+{
+  m_definition = definition;
+  m_specified = true;
+  m_specified_value = value;
+
+  update (definition, value, project_name);
+}
+
+/**----------------------------------------------------------
+   Change the effective value for this strategy.
+   This has no impact on to the specified value.
+   This will adapt the tag settings
+ */
+void Strategy::update (StrategyDef* definition, bool value, const cmt_string& project_name)
+{
+  m_value = value;
+
+  cmt_string to_tag_name = project_name;
+  cmt_string to_untag_name = project_name;
+
+  to_tag_name += "_";
+  to_untag_name += "_";
+
+  if (m_value)
+    {
+      to_tag_name += m_definition->m_on_value;
+      to_untag_name += m_definition->m_off_value;
     }
   else
     {
-      if (request_non_default_prototypes)
-	{
-	  result |= m_prototypes;
-	}
-
-      if (request_non_default_installarea)
-	{
-	  result |= m_installarea;
-	}
-    }
-
-  return (result);
-}
-
-//----------------------------------------------------------
-int Project::get_setup_strategy () const
-{
-  int result = 0;
-
-  /*
-  if (m_reference != 0) result = m_reference->get_setup_strategy ();
-  else if (m_predecessor != 0) result = m_predecessor->get_setup_strategy ();
-  else result = Cmt::get_current_setup_strategy ();
-  */
-
-  result = Cmt::get_current_setup_strategy ();
-
-  if (m_setup_strategy_mask != 0)
-    {
-      result &= ~m_setup_strategy_mask;
-      result |= m_setup_strategy;
-    }
-
-  return (result);
-}
-
-//----------------------------------------------------------
-void Project::set_build_strategy (int mask, int strategy)
-{
-  m_build_strategy_mask |= mask;
-  m_build_strategy &= ~mask;
-  m_build_strategy |= strategy;
-
-  cmt_string to_tag_name = m_name;
-  cmt_string to_untag_name = m_name;
-
-  Tag* to_tag = 0;
-  Tag* to_untag = 0;
-
-  switch (strategy)
-    {
-    case Prototypes:
-      to_tag_name += "_prototypes";
-      to_untag_name += "_no_prototypes";
-      break;
-    case NoPrototypes:
-      to_tag_name += "_no_prototypes";
-      to_untag_name += "_prototypes";
-      break;
-    case WithInstallArea:
-      to_tag_name += "_with_installarea";
-      to_untag_name += "_without_installarea";
-      break;
-    case WithoutInstallArea:
-      to_tag_name += "_without_installarea";
-      to_untag_name += "_with_installarea";
-      break;
-    }
-
-  to_tag = Tag::find (to_tag_name);
-  to_untag = Tag::find (to_untag_name);
-
-  if (to_untag != 0)
-    {
-      to_untag->unmark ();
-    }
-
-  if (to_tag != 0)
-    {
-      to_tag->mark ();
-    }
-  
-  for (int i = 0; i < m_parents.size (); i++)
-    {
-      Project* project = m_parents[i];
-
-      if ((project->m_build_strategy_mask & mask) == 0)
-	{
-	  project->set_build_strategy (mask, strategy);
-	}
-    }
-}
-
-//----------------------------------------------------------
-void Project::set_setup_strategy (int mask, int strategy)
-{
-  m_setup_strategy_mask |= mask;
-  m_setup_strategy &= ~mask;
-  m_setup_strategy |= strategy;
-
-  cmt_string to_tag_name = m_name;
-  cmt_string to_untag_name = m_name;
-
-  Tag* to_tag = 0;
-  Tag* to_untag = 0;
-
-  switch (strategy)
-    {
-    case SetupConfig:
-      to_tag_name += "_setup_config";
-      to_untag_name += "_setup_no_config";
-      break;
-    case SetupNoConfig:
-      to_tag_name += "_setup_no_config";
-      to_untag_name += "_setup_config";
-      break;
-    case SetupRoot:
-      to_tag_name += "_setup_root";
-      to_untag_name += "_setup_no_root";
-      break;
-    case SetupNoRoot:
-      to_tag_name += "_setup_no_root";
-      to_untag_name += "_setup_root";
-      break;
-    case SetupCleanup:
-      to_tag_name += "_setup_cleanup";
-      to_untag_name += "_setup_no_cleanup";
-      break;
-    case SetupNoCleanup:
-      to_tag_name += "_setup_no_cleanup";
-      to_untag_name += "_setup_cleanup";
-      break;
-    }
-
-  to_tag = Tag::find (to_tag_name);
-  to_untag = Tag::find (to_untag_name);
-
-  if (to_untag != 0)
-    {
-      to_untag->unmark ();
-    }
-
-  if (to_tag != 0)
-    {
-      to_tag->mark ();
-    }
-  
-  for (int i = 0; i < m_parents.size (); i++)
-    {
-      Project* project = m_parents[i];
-
-      if ((project->m_setup_strategy_mask & mask) == 0)
-	{
-	  project->set_setup_strategy (mask, strategy);
-	}
-    }
-}
-
+      to_tag_name += m_definition->m_off_value;
+      to_untag_name += m_definition->m_on_value;
+    }
+
+  m_on_tag = Tag::find (to_tag_name);
+  m_off_tag = Tag::find (to_untag_name);
+
+  if (m_on_tag == 0) 
+    {
+      m_on_tag = Tag::add (to_tag_name, PriorityConfig, "PROJECT", 0);
+      m_off_tag = Tag::add (to_untag_name, PriorityConfig, "PROJECT", 0);
+
+      m_on_tag->add_tag_exclude (m_off_tag);
+      m_off_tag->add_tag_exclude (m_on_tag);
+    }
+
+  m_off_tag->unmark ();
+  m_on_tag->mark ();
+}
+
+const cmt_string& StrategyDef::get_default_value () const
+{
+  if (m_default_value)
+    {
+      return (m_on_value);
+    }
+  else
+    {
+      return (m_off_value);
+    }
+}
+
Index: CMT/v1r19/source/cmt_project.h
===================================================================
--- CMT/v1r19/source/cmt_project.h	(revision 11)
+++ CMT/v1r19/source/cmt_project.h	(revision 15)
@@ -13,4 +13,46 @@
 
 class Project;
+
+class StrategyDef
+{
+public:
+  typedef cmt_vector <StrategyDef*> StrategyDefs;
+
+  cmt_string m_name;
+  cmt_string m_on_value;
+  cmt_string m_off_value;
+  bool m_default_value;
+  bool m_priority_value;
+
+  const cmt_string& get_default_value () const; 
+};
+
+class Strategy
+{
+public:
+  StrategyDef* m_definition;
+  bool m_specified;
+  bool m_specified_value;
+  bool m_value;
+  Tag* m_on_tag;
+  Tag* m_off_tag;
+
+  void set (StrategyDef* definition, bool value, const cmt_string& project_name);
+  void update (StrategyDef* definition, bool value, const cmt_string& project_name);
+};
+
+class StrategyMgr
+{
+public:
+  static StrategyMgr& instance ();
+  static StrategyDef* find_strategy (const cmt_string& name);
+  static bool get_default_strategy (const cmt_string& name);
+  static bool get_priority_strategy (const cmt_string& name);
+  static StrategyDef::StrategyDefs& get_definitions ();
+
+private:
+  StrategyMgr ();
+  StrategyDef::StrategyDefs m_defs;
+};
 
 class ProjectFactory : public IProjectFactory
@@ -110,8 +152,15 @@
   void show ();
   void show_strategies () const;
-  int get_build_strategy () const;
-  int get_setup_strategy () const;
-  void set_build_strategy (int mask, int strategy);
-  void set_setup_strategy (int mask, int strategy);
+
+  bool has_strategy (const StrategyDef* definition) const;
+  bool is_specified (const StrategyDef* definition) const;
+  bool get_strategy (const StrategyDef* definition) const;
+  bool get_strategy (const cmt_string& name) const;
+  void set_default_strategy (const cmt_string& name);
+  void set_strategy (const cmt_string& name, const cmt_string& value);
+  void set_strategy (StrategyDef* definition, bool b_value);
+  void update_strategy (StrategyDef* definition, bool b_value);
+  void update_strategy_from_children (StrategyDef* definition);
+  void update_strategies_from_children ();
 
   void visit (IProjectVisitor& visitor);
@@ -133,23 +182,7 @@
   cmt_string m_cmtpath_source;
 
-  int m_build_strategy_mask;
-  int m_build_strategy;
-  int m_setup_strategy_mask;
-  int m_setup_strategy;
-
   bool m_configured;
 
-  Tag* m_prototypes_tag;
-  Tag* m_no_prototypes_tag;
-  Tag* m_with_installarea_tag;
-  Tag* m_without_installarea_tag;
-
-  Tag* m_setup_config_tag;
-  Tag* m_setup_no_config_tag;
-  Tag* m_setup_root_tag;
-  Tag* m_setup_no_root_tag;
-  Tag* m_setup_cleanup_tag;
-  Tag* m_setup_no_cleanup_tag;
-
+  cmt_vector <Strategy> m_strategies;
 };
 
Index: CMT/v1r19/source/cmt_syntax.cxx
===================================================================
--- CMT/v1r19/source/cmt_syntax.cxx	(revision 11)
+++ CMT/v1r19/source/cmt_syntax.cxx	(revision 15)
@@ -118,29 +118,27 @@
 {
 public:
-  bool decode (const cmt_string& w,
-	       int& mask,
-	       int& strategy)
+  bool decode (const cmt_string& w, cmt_string& strategy, cmt_string& value)
   {
     bool result = true;
 
+    value = w;
+
     if (w == "prototypes")
       {
-	mask = PrototypesMask;
-	strategy = Prototypes;
+	strategy = "BuildPrototypes";
       }
     else if (w == "no_prototypes")
       {
-	mask = PrototypesMask;
-	strategy = NoPrototypes;
+	strategy = "BuildPrototypes";
       }
     else if ((w == "with_installarea") || (w == "with_install_area"))
       {
-	mask = InstallAreaMask;
-	strategy = WithInstallArea;
+	value = "with_installarea";
+	strategy = "InstallArea";
       }
     else if ((w == "without_installarea") || (w == "without_install_area"))
       {
-	mask = InstallAreaMask;
-	strategy = WithoutInstallArea;
+	value = "without_installarea";
+	strategy = "InstallArea";
       }
     else
@@ -168,20 +166,18 @@
 	const cmt_string& w = words[i];
 
-	int mask = 0;
-	int strategy = 0;
+	cmt_string strategy;
+	cmt_string value;
 
 	bool in_error = false;
 
-	if (!decode (w, mask, strategy))
+	if (decode (w, strategy, value))
+	  {
+	    if (p != 0) p->set_strategy (strategy, value);
+	  }
+	else
 	  {
 	    in_error = true;
 
 	    CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
-	  }
-
-	if (mask != 0)
-	  {
-	    if (p == 0) Cmt::set_current_build_strategy (strategy);
-	    else p->set_build_strategy (mask, strategy);
 	  }
 
@@ -211,20 +207,18 @@
 	const cmt_string& w = words[i];
 
-	int mask = 0;
-	int strategy = 0;
+	cmt_string strategy;
+	cmt_string value;
 
 	bool in_error = false;
 
-	if (!decode (w, mask, strategy))
+	if (decode (w, strategy, value))
+	  {
+	    if (project != 0) project->set_strategy (strategy, value);
+	  }
+	else
 	  {
 	    in_error = true;
 
 	    CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
-	  }
-
-	if (mask != 0)
-	  {
-	    if (project == 0) Cmt::set_current_build_strategy (strategy);
-	    else project->set_build_strategy (mask, strategy);
 	  }
 
@@ -729,37 +723,33 @@
 {
 public:
-  bool decode (const cmt_string& w, int& mask, int& strategy)
+  bool decode (const cmt_string& w, cmt_string& strategy, cmt_string& value)
   {
     bool result = true;
 
+    value = w;
+
     if (w == "config")
       {
-	mask = SetupConfigMask;
-	strategy = SetupConfig;
+	strategy = "SetupConfig";
       }
     else if (w == "no_config")
       {
-	mask = SetupConfigMask;
-	strategy = SetupNoConfig;
+	strategy = "SetupConfig";
       }
     else if (w == "root")
       {
-	mask = SetupRootMask;
-	strategy = SetupRoot;
+	strategy = "SetupRoot";
       }
     else if (w == "no_root")
       {
-	mask = SetupRootMask;
-	strategy = SetupNoRoot;
+	strategy = "SetupRoot";
       }
     else if (w == "cleanup")
       {
-	mask = SetupCleanupMask;
-	strategy = SetupCleanup;
+	strategy = "SetupCleanup";
       }
     else if (w == "no_cleanup")
       {
-	mask = SetupCleanupMask;
-	strategy = SetupNoCleanup;
+	strategy = "SetupCleanup";
       }
     else
@@ -787,20 +777,18 @@
 	const cmt_string& w = words[i];
 
-	int mask = 0;
-	int strategy = 0;
+	cmt_string strategy;
+	cmt_string value;
 
 	bool in_error = false;
 
-	if (!decode (w, mask, strategy))
+	if (decode (w, strategy, value))
+	  {
+	    if (p != 0) p->set_strategy (strategy, value);
+	  }
+	else
 	  {
 	    in_error = true;
 
 	    CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
-	  }
-	
-	if (mask != 0)
-	  {
-	    if (p == 0) Cmt::set_current_setup_strategy (strategy);
-	    else p->set_setup_strategy (mask, strategy);
 	  }
 
@@ -830,20 +818,18 @@
 	const cmt_string& w = words[i];
 
-	int mask = 0;
-	int strategy = 0;
+	cmt_string strategy;
+	cmt_string value;
 
 	bool in_error = false;
 
-	if (!decode (w, mask, strategy))
+	if (decode (w, strategy, value))
+	  {
+	    if (project != 0) project->set_strategy (strategy, value);
+	  }
+	else
 	  {
 	    in_error = true;
 
 	    CmtError::set (CmtError::syntax_error, "ParseRequirements> bad strategy keyword");
-	  }
-	
-	if (mask != 0)
-	  {
-	    if (project == 0) Cmt::set_current_setup_strategy (strategy);
-	    else project->set_setup_strategy (mask, strategy);
 	  }
 
