From 3b042098b550d68979c8d39fb0314ced770abd0a Mon Sep 17 00:00:00 2001
From: unknown <christoph.watzl@gmail.com>
Date: Wed, 19 May 2010 22:16:14 +0200
Subject: [PATCH] fixed bug: http://www.itk.org/Bug/view.php?id=9863

---
 Source/cmVisualStudio10TargetGenerator.cxx |   41 ++++++++++++++++++++++++++++
 Source/cmVisualStudio10TargetGenerator.h   |    4 +++
 2 files changed, 45 insertions(+), 0 deletions(-)

diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 4a8e161..b3c3586 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -435,6 +435,9 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
       none.push_back(sf);
       }
     }
+
+  AddMissingSourceGroups(groupsUsed, sourceGroups);
+  
   // Write out group file
   std::string path =  this->Makefile->GetStartOutputDirectory();
   path += "/";
@@ -486,6 +489,44 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
   this->BuildFileStream = save;
 }
 
+// adds the source groups to groupsUsed that have no source
+//files in them, but do have children which do
+void cmVisualStudio10TargetGenerator::AddMissingSourceGroups(
+  std::set<cmSourceGroup*>& groupsUsed,
+  const std::vector<cmSourceGroup>& allGroups)
+{
+  for(std::vector<cmSourceGroup>::const_iterator current = allGroups.begin(); 
+      current != allGroups.end(); current++) 
+    {
+    const std::vector<cmSourceGroup>& children = current->GetGroupChildren();
+
+    if(children.size() == 0) 
+        continue; // the group is really empty
+    
+    AddMissingSourceGroups(groupsUsed, children); // traverse children recursively
+
+    cmSourceGroup* current_ptr = const_cast<cmSourceGroup*>(&(*current));
+    if(groupsUsed.find(current_ptr) != groupsUsed.end())
+      continue; // group has already been added to set
+
+    // check if it least one of the group's descendants is not empty
+    // (at least one child must already have been added)
+    std::vector<cmSourceGroup>::const_iterator child_it = children.begin();
+    while(child_it != children.end())
+      {
+      cmSourceGroup* child_ptr = const_cast<cmSourceGroup*>(&(*child_it));
+      if(groupsUsed.find(child_ptr) != groupsUsed.end()) 
+          break; // found a child that was already added => add current group too
+      child_it++;
+      }
+    
+    if(child_it == children.end()) 
+        continue; // no descendants have source files => ignore this group
+
+    groupsUsed.insert(current_ptr);
+    }
+}
+
 void 
 cmVisualStudio10TargetGenerator::
 WriteGroupSources(const char* name,
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 989db71..64b2361 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -77,6 +77,10 @@ private:
   void WriteGroupSources(const char* name,
                          std::vector<cmSourceFile*> const& sources,
                          std::vector<cmSourceGroup>& );
+  void AddMissingSourceGroups(std::set<cmSourceGroup*>& groupsUsed,
+                              const std::vector<cmSourceGroup>& allGroups);
+
+
 private:
   typedef cmVisualStudioGeneratorOptions Options;
   typedef std::map<cmStdString, Options*> OptionsMap;
-- 
1.7.0.2.msysgit.0

