From 43b4d711f3ff80e52c9cad5fe85f31431ef0998d 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 |   36 ++++++++++++++++++++++++++++
 Source/cmVisualStudio10TargetGenerator.h   |    4 +++
 2 files changed, 40 insertions(+), 0 deletions(-)

diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 4a8e161..8ad99c6 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -23,6 +23,7 @@
 #include "cmVS10LibFlagTable.h"
 
 #include <cmsys/auto_ptr.hxx>
+#include <algorithm>
 
 static std::string cmVS10EscapeXML(std::string arg)
 {
@@ -435,6 +436,9 @@ void cmVisualStudio10TargetGenerator::WriteGroups()
       none.push_back(sf);
       }
     }
+
+  AddMissingSourceGroups(groupsUsed, sourceGroups);
+  
   // Write out group file
   std::string path =  this->Makefile->GetStartOutputDirectory();
   path += "/";
@@ -486,6 +490,38 @@ 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 = children.begin();
+    cmSourceGroup* child_ptr = const_cast<cmSourceGroup*>(&(*child));
+    while(child != children.end() && 
+          groupsUsed.find(child_ptr) == groupsUsed.end()) 
+      child++;
+    if(child == children.end()) continue; // no descendants have source files
+
+    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

