Centralize fix for nullability annotations in netstandard builds (dotnet/corefx#42391)
authorEirik Tsarpalis <eirik.tsarpalis@gmail.com>
Wed, 6 Nov 2019 23:10:27 +0000 (23:10 +0000)
committerGitHub <noreply@github.com>
Wed, 6 Nov 2019 23:10:27 +0000 (23:10 +0000)
* centralize fix for nullability in netstandard2.0

* remove project property from conditional

* Revert "remove project property from conditional"

This reverts commit dotnet/corefx@ffc54a15a4589381b3bd78aa5b3ef020c8a1c75e.

* move to Directory.Build.targets

* Add netcoreapp2.x check

* update logic for projects that use nullable annotations without it being enabled

* add nullable property to System.Data.SqlClient

* address newly added annotated project

* add nullable annotations to System.Security.Cryptography.Pkcs

Commit migrated from https://github.com/dotnet/corefx/commit/e52be6965496af9de49de585e6c62bdb0915c775

12 files changed:
src/libraries/Directory.Build.targets
src/libraries/Microsoft.Diagnostics.Tracing.EventSource.Redist/src/Microsoft.Diagnostics.Tracing.EventSource.Redist.csproj
src/libraries/Microsoft.IO.Redist/src/Microsoft.IO.Redist.csproj
src/libraries/System.Data.SqlClient/src/System.Data.SqlClient.csproj
src/libraries/System.IO.FileSystem.AccessControl/src/System.IO.FileSystem.AccessControl.csproj
src/libraries/System.IO.Pipelines/src/System.IO.Pipelines.csproj
src/libraries/System.Resources.Extensions/src/System.Resources.Extensions.csproj
src/libraries/System.Security.Cryptography.Pkcs/src/System.Security.Cryptography.Pkcs.csproj
src/libraries/System.Text.Encoding.CodePages/src/System.Text.Encoding.CodePages.csproj
src/libraries/System.Text.Encodings.Web/src/System.Text.Encodings.Web.csproj
src/libraries/System.Threading.Channels/ref/System.Threading.Channels.csproj
src/libraries/System.Threading.Channels/src/System.Threading.Channels.csproj

index 345ac4a..42ec782 100644 (file)
@@ -7,6 +7,18 @@
     <ErrorReport Condition="'$(ErrorReport)' == 'prompt'" />
     <WarningsAsErrors Condition="'$(WarningsAsErrors)' == 'NU1605'" />
   </PropertyGroup>
+  
+  <!-- Adds Nullable annotation attributes to netstandard <= 2.0 builds -->
+  <Choose>
+    <When Condition="'$(Nullable)' != '' and ($(TargetFramework.StartsWith('netstandard1')) or '$(TargetFramework)' == 'netstandard2.0' or $(TargetFramework.StartsWith('netcoreapp2')) or '$(TargetsNetFx)' == 'true')">
+      <PropertyGroup>
+        <DefineConstants>$(DefineConstants),INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
+      </PropertyGroup>
+      <ItemGroup>
+        <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Link="System\Diagnostics\CodeAnalysis\NullableAttributes.cs" />
+      </ItemGroup>
+    </When>
+  </Choose>
 
   <PropertyGroup>
     <!--
index a30ee5c..7fea2d8 100644 (file)
@@ -2,7 +2,7 @@
   <PropertyGroup>
     <AssemblyName>Microsoft.Diagnostics.Tracing.EventSource</AssemblyName>
     <NoWarn>$(NoWarn);CS1573</NoWarn>
-    <DefineConstants>$(DefineConstants);NO_EVENTCOMMANDEXECUTED_SUPPORT;ES_BUILD_STANDALONE;FEATURE_MANAGED_ETW;PLATFORM_WINDOWS;INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
+    <DefineConstants>$(DefineConstants);NO_EVENTCOMMANDEXECUTED_SUPPORT;ES_BUILD_STANDALONE;FEATURE_MANAGED_ETW;PLATFORM_WINDOWS</DefineConstants>
     <Configurations>net461-Windows_NT-Debug;net461-Windows_NT-Release;netfx-Windows_NT-Debug;netfx-Windows_NT-Release</Configurations>
     <Nullable>enable</Nullable>
   </PropertyGroup>
@@ -24,7 +24,6 @@
     <Compile Include="$(CommonPath)\CoreLib\Interop\Windows\Advapi32\Interop.EventUnregister.cs" />
     <Compile Include="$(CommonPath)\CoreLib\Interop\Windows\Advapi32\Interop.EventWriteString.cs" />
     <Compile Include="$(CommonPath)\CoreLib\Interop\Windows\Advapi32\Interop.EventWriteTransfer.cs" />
-    <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" />
     <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\Tracing\*.cs" />
     <Compile Remove="$(CommonPath)\CoreLib\System\Diagnostics\Tracing\FrameworkEventSource.cs" />
     <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\Tracing\TraceLogging\*.cs" />
@@ -33,4 +32,4 @@
     <Reference Include="mscorlib" />
     <Reference Include="System" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 173f403..1b60e9e 100644 (file)
@@ -2,10 +2,11 @@
   <PropertyGroup>
     <AssemblyName>Microsoft.IO.Redist</AssemblyName>
     <Configurations>netfx-Debug;netfx-Release</Configurations>
-    <DefineConstants>$(DefineConstants);MS_IO_REDIST;INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
+    <DefineConstants>$(DefineConstants);MS_IO_REDIST</DefineConstants>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <NoWarn>$(NoWarn);CS1573</NoWarn>
     <ClsCompliant>false</ClsCompliant>
+    <Nullable>annotations</Nullable>
   </PropertyGroup>
   <ItemGroup>
     <Compile Include="..\..\System.IO.FileSystem\src\System\IO\Directory.cs" Link="Microsoft\IO\Directory.cs" />
@@ -55,7 +56,6 @@
     <Compile Include="$(CommonPath)\CoreLib\Interop\Windows\Kernel32\Interop.SetThreadErrorMode.cs" Link="Common\CoreLib\Interop\Windows\Interop.SetThreadErrorMode.cs" />
     <Compile Include="$(CommonPath)\CoreLib\Interop\Windows\Kernel32\Interop.WIN32_FILE_ATTRIBUTE_DATA.cs" Link="Common\Interop\Windows\Interop.WIN32_FILE_ATTRIBUTE_DATA.cs" />
     <Compile Include="$(CommonPath)\CoreLib\Interop\Windows\Kernel32\Interop.WIN32_FIND_DATA.cs" Link="Common\Interop\Windows\Interop.WIN32_FIND_DATA.cs" />
-    <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Link="Common\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" />
     <Compile Include="$(CommonPath)\CoreLib\System\IO\DisableMediaInsertionPrompt.cs" Link="Common\System\IO\DisableMediaInsertionPrompt.cs" />
     <Compile Include="$(CommonPath)\CoreLib\System\IO\DriveInfoInternal.Windows.cs" Link="Common\System\IO\DriveInfoInternal.Windows.cs" />
     <Compile Include="$(CommonPath)\CoreLib\System\IO\Path.cs" Link="Common\CoreLib\System\IO\Path.cs" />
index 2eff3e8..11ac29a 100644 (file)
@@ -9,14 +9,9 @@
     <AssemblyVersion Condition="'$(TargetGroup)' == 'netstandard1.3'">4.1.0.0</AssemblyVersion>
     <DefineConstants Condition="'$(TargetsNetCoreApp)' != 'true'">$(DefineConstants);NETSTANDARD2_0</DefineConstants>
     <DefineConstants Condition="'$(TargetGroup)' == 'netcoreapp'">$(DefineConstants);FEATURE_TCPKEEPALIVE</DefineConstants>
-    <DefineConstants Condition="'$(TargetGroup)' != 'netcoreapp'">$(DefineConstants);INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
     <Configurations>net461-Windows_NT-Debug;net461-Windows_NT-Release;netcoreapp-Debug;netcoreapp-Release;netcoreapp-Unix-Debug;netcoreapp-Unix-Release;netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;netcoreapp2.1-Debug;netcoreapp2.1-Release;netcoreapp2.1-Unix-Debug;netcoreapp2.1-Unix-Release;netcoreapp2.1-Windows_NT-Debug;netcoreapp2.1-Windows_NT-Release;netfx-Windows_NT-Debug;netfx-Windows_NT-Release;netstandard2.0-Debug;netstandard2.0-Release;netstandard2.0-Unix-Debug;netstandard2.0-Unix-Release;netstandard2.0-Windows_NT-Debug;netstandard2.0-Windows_NT-Release;netstandard1.2-Debug;netstandard1.2-Release;netstandard1.3-Debug;netstandard1.3-Release</Configurations>
+    <Nullable>annotations</Nullable>
   </PropertyGroup>
-  <ItemGroup Condition="'$(TargetGroup)' != 'netcoreapp'">
-    <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs">
-      <Link>Common\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs</Link>
-    </Compile>
-  </ItemGroup>
   <ItemGroup Condition="'$(TargetFramework)' == 'netstandard2.0' OR '$(TargetsNetCoreApp)' == 'true'">
     <Compile Include="System.Data.SqlClient.TypeForwards.cs" />
   </ItemGroup>
index e63f5c2..0fdd679 100644 (file)
@@ -1,15 +1,10 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <DefineConstants Condition="'$(TargetsNetCoreApp)' != 'true'">$(DefineConstants);INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
     <AllowUnsafeBlocks Condition="'$(TargetsWindows)' == 'true'">true</AllowUnsafeBlocks>
     <IsPartialFacadeAssembly Condition="'$(TargetsNetFx)' == 'true'">true</IsPartialFacadeAssembly>
     <GeneratePlatformNotSupportedAssemblyMessage Condition="'$(TargetsWindows)' != 'true'">SR.PlatformNotSupported_AccessControl</GeneratePlatformNotSupportedAssemblyMessage>
     <Configurations>net461-Windows_NT-Debug;net461-Windows_NT-Release;netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;netfx-Windows_NT-Debug;netfx-Windows_NT-Release;netstandard2.0-Debug;netstandard2.0-Release;netstandard2.0-Windows_NT-Debug;netstandard2.0-Windows_NT-Release</Configurations>
   </PropertyGroup>
-  <!-- Handle nullability in NetFX/NetStandard -->
-  <ItemGroup Condition="'$(TargetsNetCoreApp)' != 'true'">
-    <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Link="System\Diagnostics\CodeAnalysis\NullableAttributes.cs" />
-  </ItemGroup>
   <!-- Source includes -->
   <ItemGroup Condition="'$(TargetsWindows)' == 'true' and '$(TargetsNetFx)' != 'true'">
     <Compile Include="$(CommonPath)\Interop\Windows\Interop.Errors.cs" Link="Common\Interop\Windows\Interop.Errors.cs" />
@@ -88,4 +83,4 @@
     <Reference Include="System.Security.AccessControl" />
     <Reference Include="System.Security.Principal.Windows" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 024eff9..955bc03 100644 (file)
@@ -1,7 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <Configurations>netcoreapp-Debug;netcoreapp-Release;netcoreapp3.0-Debug;netcoreapp3.0-Release;netstandard2.0-Debug;netstandard2.0-Release</Configurations>
-    <DefineConstants Condition="'$(TargetFramework)' == 'netstandard2.0'">$(DefineConstants);INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
     <Nullable>enable</Nullable>
   </PropertyGroup>
   <ItemGroup>
@@ -45,7 +44,6 @@
     <Compile Include="System\IO\Pipelines\StreamExtensions.netstandard.cs" />
     <Compile Include="System\IO\Pipelines\ThreadPoolScheduler.netstandard.cs" />
     <Compile Include="System\IO\Pipelines\CancellationTokenExtensions.netstandard.cs" />
-    <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Link="System\Diagnostics\CodeAnalysis\NullableAttributes.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System.Buffers" />
@@ -60,4 +58,4 @@
     <Reference Include="System.Threading.Tasks" />
     <Reference Include="System.Threading.ThreadPool" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index a6ea52e..14787f0 100644 (file)
@@ -2,7 +2,8 @@
   <PropertyGroup>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <Configurations>netstandard2.0-Debug;netstandard2.0-Release</Configurations>
-    <DefineConstants>$(DefineConstants);RESOURCES_EXTENSIONS;INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
+    <DefineConstants>$(DefineConstants);RESOURCES_EXTENSIONS</DefineConstants>
+    <Nullable>annotations</Nullable>
   </PropertyGroup>
   <PropertyGroup>
   </PropertyGroup>
@@ -13,7 +14,6 @@
     <Compile Include="$(CommonPath)\CoreLib\System\Resources\ResourceReader.cs" Link="System\Resources\Extensions\ResourceReader.cs" />
     <Compile Include="$(CommonPath)\CoreLib\System\Resources\ResourceTypeCode.cs" Link="System\Resources\ResourceTypeCode.cs" />
     <Compile Include="$(CommonPath)\CoreLib\System\Resources\RuntimeResourceSet.cs" Link="System\Resources\Extensions\RuntimeResourceSet.cs" />
-    <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Link="System\Diagnostics\CodeAnalysis\NullableAttributes.cs" />
     <Compile Include="BinaryReaderExtensions.cs" />
     <Compile Include="System\Resources\Extensions\DeserializingResourceReader.cs" />
     <Compile Include="System\Resources\Extensions\PreserializedResourceWriter.cs" />
index 02c1635..d019d4d 100644 (file)
@@ -6,8 +6,8 @@
     <UsePackageTargetRuntimeDefaults Condition="'$(IsPartialFacadeAssembly)' != 'true'">true</UsePackageTargetRuntimeDefaults>
     <IncludeDllSafeSearchPathAttribute>true</IncludeDllSafeSearchPathAttribute>
     <NoWarn>$(NoWarn);CS1574;CS3016;CA5379;CA5384</NoWarn>
+    <Nullable>annotations</Nullable>
     <Configurations>net461-Windows_NT-Debug;net461-Windows_NT-Release;netcoreapp-Debug;netcoreapp-Release;netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;netcoreapp3.0-Debug;netcoreapp3.0-Release;netcoreapp3.0-Windows_NT-Debug;netcoreapp3.0-Windows_NT-Release;netfx-Windows_NT-Debug;netfx-Windows_NT-Release;netstandard2.0-Debug;netstandard2.0-Release;netstandard2.0-Windows_NT-Debug;netstandard2.0-Windows_NT-Release;netstandard2.1-Debug;netstandard2.1-Release;netstandard2.1-Windows_NT-Debug;netstandard2.1-Windows_NT-Release</Configurations>
-    <DefineConstants Condition="'$(IsPartialFacadeAssembly)' != 'true' AND '$(TargetsNetCoreApp)' != 'true'">$(DefineConstants);INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
   </PropertyGroup>
   <Import Project="$(CommonPath)\System\Security\Cryptography\Asn1\AsnXml.targets" Condition="'$(IsPartialFacadeAssembly)' != 'true'" />
   <Import Project="$(CommonPath)\System\Security\Cryptography\Asn1Reader\System.Security.Cryptography.Asn1Reader.Shared.projitems" Condition="'$(IsPartialFacadeAssembly)' != 'true'" />
@@ -54,7 +54,6 @@
     <Compile Include="Internal\Cryptography\PkcsHelpers.cs" />
     <Compile Include="Internal\Cryptography\PkcsPal.cs" />
     <Compile Include="Internal\Cryptography\RecipientInfoPal.cs" />
-    <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Link="System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Condition="'$(TargetsNetCoreApp)' != 'true' AND  '$(TargetGroup)' != 'netstandard2.1'" />
     <Compile Include="$(CommonPath)\Internal\Cryptography\Helpers.cs">
       <Link>Internal\Cryptography\Helpers.cs</Link>
     </Compile>
   <ItemGroup>
     <None Include="@(AsnXml)" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 4372dfd..156986e 100644 (file)
@@ -4,7 +4,6 @@
     <Nullable>enable</Nullable>
     <!-- copy the Windows-specific implementation to net461 folder so that restore without a RID works -->
     <PackageTargetFramework Condition="'$(TargetsNetStandard)' == 'true' and '$(TargetsWindows)' == 'true'">netstandard2.0;net461</PackageTargetFramework>
-    <DefineConstants Condition="'$(TargetGroup)'!='netcoreapp'">$(DefineConstants);INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
     <Configurations>netcoreapp-Windows_NT-Debug;netcoreapp-Windows_NT-Release;netcoreapp2.0-Windows_NT-Debug;netcoreapp2.0-Windows_NT-Release;netstandard2.0-Debug;netstandard2.0-Release;netstandard2.0-Windows_NT-Debug;netstandard2.0-Windows_NT-Release</Configurations>
   </PropertyGroup>
   <ItemGroup>
@@ -29,9 +28,6 @@
     <Compile Include="System\Text\ISCIIEncoding.cs" />
     <Compile Include="System\Text\SBCSCodePageEncoding.cs" />
   </ItemGroup>
-  <ItemGroup Condition="'$(TargetGroup)'!='netcoreapp'">
-    <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Link="System\Diagnostics\CodeAnalysis\NullableAttributes.cs" />
-  </ItemGroup>
   <ItemGroup Condition=" '$(TargetsWindows)' == 'true' ">
     <Compile Include="System\Text\CodePagesEncodingProvider.Windows.cs" />
     <Compile Include="$(CommonPath)\Interop\Windows\Interop.Libraries.cs">
index db96caa..9d1cf95 100644 (file)
@@ -2,7 +2,6 @@
   <PropertyGroup>
     <AllowUnsafeBlocks>true</AllowUnsafeBlocks>
     <Configurations>netcoreapp-Debug;netcoreapp-Release;netcoreapp3.0-Debug;netcoreapp3.0-Release;netstandard2.0-Debug;netstandard2.0-Release;netstandard2.1-Debug;netstandard2.1-Release</Configurations>
-    <DefineConstants Condition="'$(TargetsNetCoreApp)' != 'true'">$(DefineConstants);INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
     <Nullable>enable</Nullable>
   </PropertyGroup>
   <ItemGroup>
@@ -35,9 +34,6 @@
       <Link>System\Text\UnicodeUtility.cs</Link>
     </Compile>
     </ItemGroup>
-  <ItemGroup Condition="'$(TargetsNetCoreApp)' != 'true' And '$(TargetFramework)' != 'netstandard2.1' ">
-    <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Link="System\Diagnostics\CodeAnalysis\NullableAttributes.cs" />
-  </ItemGroup>
   <ItemGroup>
     <Reference Include="System.Memory" />
     <Reference Include="System.Resources.ResourceManager" />
index 43dce86..e4e1b54 100644 (file)
@@ -1,7 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <Configurations>netcoreapp-Debug;netcoreapp-Release;netcoreapp3.0-Debug;netcoreapp3.0-Release;netstandard2.0-Debug;netstandard2.0-Release;netstandard1.3-Debug;netstandard1.3-Release</Configurations>
-    <DefineConstants Condition="'$(TargetsNetCoreApp)' != 'true'">$(DefineConstants);INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
     <Nullable>enable</Nullable>
   </PropertyGroup>
   <ItemGroup>
@@ -11,7 +10,6 @@
     <Compile Include="System.Threading.Channels.netcoreapp.cs" />
   </ItemGroup>
   <ItemGroup Condition="'$(TargetsNetCoreApp)' != 'true'">
-    <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Link="System\Diagnostics\CodeAnalysis\NullableAttributes.cs" />
     <Reference Include="System.Threading.Tasks.Extensions" />
   </ItemGroup>
   <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp3.0'">
@@ -24,4 +22,4 @@
     <Reference Include="System.Runtime" />
     <Reference Include="System.Threading.Tasks" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>
index 90578d8..bac5f58 100644 (file)
@@ -1,7 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
     <Configurations>netcoreapp-Debug;netcoreapp-Release;netcoreapp3.0-Debug;netcoreapp3.0-Release;netstandard2.0-Debug;netstandard2.0-Release;netstandard1.3-Debug;netstandard1.3-Release</Configurations>
-    <DefineConstants>$(DefineConstants);INTERNAL_NULLABLE_ATTRIBUTES</DefineConstants>
     <Nullable>enable</Nullable>
   </PropertyGroup>
   <ItemGroup>
@@ -25,7 +24,6 @@
     <Compile Include="System\Threading\Channels\IDebugEnumerator.cs" />
     <Compile Include="System\Threading\Channels\SingleConsumerUnboundedChannel.cs" />
     <Compile Include="System\Threading\Channels\UnboundedChannel.cs" />
-    <Compile Include="$(CommonPath)\CoreLib\System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Link="System\Diagnostics\CodeAnalysis\NullableAttributes.cs" Condition="'$(TargetsNetCoreApp)' != 'true'" />
     <Compile Include="$(CommonPath)\Internal\Padding.cs" Link="Common\Internal\Padding.cs" />
     <Compile Include="$(CommonPath)\System\Collections\Concurrent\SingleProducerConsumerQueue.cs" Link="Common\System\Collections\Concurrent\SingleProducerConsumerQueue.cs" />
   </ItemGroup>
@@ -41,4 +39,4 @@
     <Reference Include="System.Threading.Tasks" />
     <Reference Include="System.Threading.Tasks.Extensions" />
   </ItemGroup>
-</Project>
\ No newline at end of file
+</Project>