VS: add target property VS_PROJECT_IMPORT_<propspath>

Fixes: #18998
diff --git a/Help/manual/cmake-properties.7.rst b/Help/manual/cmake-properties.7.rst
index 4d4b9ff..bd19ccf 100644
--- a/Help/manual/cmake-properties.7.rst
+++ b/Help/manual/cmake-properties.7.rst
@@ -335,6 +335,7 @@
    /prop_tgt/VS_KEYWORD
    /prop_tgt/VS_MOBILE_EXTENSIONS_VERSION
    /prop_tgt/VS_NO_SOLUTION_DEPLOY
+   /prop_tgt/VS_PROJECT_IMPORT
    /prop_tgt/VS_SCC_AUXPATH
    /prop_tgt/VS_SCC_LOCALPATH
    /prop_tgt/VS_SCC_PROJECTNAME
diff --git a/Help/prop_tgt/VS_PROJECT_IMPORT.rst b/Help/prop_tgt/VS_PROJECT_IMPORT.rst
new file mode 100644
index 0000000..569c8ea
--- /dev/null
+++ b/Help/prop_tgt/VS_PROJECT_IMPORT.rst
@@ -0,0 +1,8 @@
+VS_PROJECT_IMPORT
+-----------------
+
+Visual Studio managed project imports
+
+Adds to a generated Visual Studio project one or more semicolon-delimited paths
+to .props files needed when building projects from some NuGet packages.
+For example, ``my_packages_path/MyPackage.1.0.0/build/MyPackage.props``.
diff --git a/Help/release/dev/vs-project-import.rst b/Help/release/dev/vs-project-import.rst
new file mode 100644
index 0000000..de6024d
--- /dev/null
+++ b/Help/release/dev/vs-project-import.rst
@@ -0,0 +1,5 @@
+vs-project-import
+-----------------
+
+* The :prop_tgt:`VS_PROJECT_IMPORT` target property was added which allows
+  to import external .props files in managed Visual Studio targets.
diff --git a/Source/cmVisualStudio10TargetGenerator.cxx b/Source/cmVisualStudio10TargetGenerator.cxx
index 5c9f25e..6ec47c2 100644
--- a/Source/cmVisualStudio10TargetGenerator.cxx
+++ b/Source/cmVisualStudio10TargetGenerator.cxx
@@ -662,6 +662,7 @@
     this->WriteCustomCommands(e0);
     this->WriteAllSources(e0);
     this->WriteDotNetReferences(e0);
+    this->WriteImports(e0);
     this->WriteEmbeddedResourceGroup(e0);
     this->WriteXamlFilesGroup(e0);
     this->WriteWinRTReferences(e0);
@@ -810,6 +811,24 @@
   this->WriteDotNetReferenceCustomTags(e2, ref);
 }
 
+void cmVisualStudio10TargetGenerator::WriteImports(Elem& e0)
+{
+  const char* imports =
+    this->GeneratorTarget->Target->GetProperty("VS_PROJECT_IMPORT");
+  if (imports) {
+    std::vector<std::string> argsSplit;
+    cmSystemTools::ExpandListArgument(std::string(imports), argsSplit, false);
+    for (auto& path : argsSplit) {
+      if (!cmsys::SystemTools::FileIsFullPath(path)) {
+        path = this->Makefile->GetCurrentSourceDirectory() + "/" + path;
+      }
+      ConvertToWindowsSlash(path);
+      Elem e1(e0, "Import");
+      e1.Attribute("Project", path);
+    }
+  }
+}
+
 void cmVisualStudio10TargetGenerator::WriteDotNetReferenceCustomTags(
   Elem& e2, std::string const& ref)
 {
diff --git a/Source/cmVisualStudio10TargetGenerator.h b/Source/cmVisualStudio10TargetGenerator.h
index 5901004..b5b7a4a 100644
--- a/Source/cmVisualStudio10TargetGenerator.h
+++ b/Source/cmVisualStudio10TargetGenerator.h
@@ -76,6 +76,7 @@
   void WriteDotNetReference(Elem& e1, std::string const& ref,
                             std::string const& hint,
                             std::string const& config);
+  void WriteImports(Elem& e0);
   void WriteDotNetReferenceCustomTags(Elem& e2, std::string const& ref);
   void WriteEmbeddedResourceGroup(Elem& e0);
   void WriteWinRTReferences(Elem& e0);
diff --git a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
index df253a9..219e529 100644
--- a/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
+++ b/Tests/RunCMake/VS10Project/RunCMakeTest.cmake
@@ -18,3 +18,4 @@
 run_cmake(VSCSharpDefines)
 run_cmake(VsSdkDirectories)
 run_cmake(VsGlobals)
+run_cmake(VsProjectImport)
diff --git a/Tests/RunCMake/VS10Project/VsProjectImport-check.cmake b/Tests/RunCMake/VS10Project/VsProjectImport-check.cmake
new file mode 100644
index 0000000..e438bf4
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsProjectImport-check.cmake
@@ -0,0 +1,28 @@
+set(vcProjectFile "${RunCMake_TEST_BINARY_DIR}/foo.vcxproj")
+if(NOT EXISTS "${vcProjectFile}")
+  set(RunCMake_TEST_FAILED "Project file ${vcProjectFile} does not exist.")
+  return()
+endif()
+
+set(test1Import "path\\\\to\\\\nuget_packages\\\\Foo.1.0.0\\\\build\\\\Foo.props")
+set(test2Import "path\\\\to\\\\nuget_packages\\\\Bar.1.0.0\\\\build\\\\Bar.props")
+
+set(import1Found FALSE)
+set(import2Found FALSE)
+
+file(STRINGS "${vcProjectFile}" lines)
+
+foreach(i 1 2)
+  set(testImport "${test${i}Import}")
+  foreach(line IN LISTS lines)
+    if(line MATCHES "^ *<Import Project=\".*${test1Import}\" />$")
+      message(STATUS "foo.vcxproj is using project import ${testImport}")
+      set(import${i}Found TRUE)
+    endif()
+  endforeach()
+endforeach()
+
+if(NOT import1Found OR NOT import2Found)
+  set(RunCMake_TEST_FAILED "Imported project not found.")
+  return()
+endif()
diff --git a/Tests/RunCMake/VS10Project/VsProjectImport.cmake b/Tests/RunCMake/VS10Project/VsProjectImport.cmake
new file mode 100644
index 0000000..70bdded
--- /dev/null
+++ b/Tests/RunCMake/VS10Project/VsProjectImport.cmake
@@ -0,0 +1,11 @@
+enable_language(CXX)
+add_library(foo foo.cpp)
+
+set(test1Import "path/to/nuget_packages/Foo.1.0.0/build/Foo.props")
+set(test2Import "path/to/nuget_packages/Bar.1.0.0/build/Bar.props")
+
+set_property(TARGET foo PROPERTY
+  VS_PROJECT_IMPORT
+    ${test1Import}
+    ${test2Import}
+  )