/// <summary>
 /// Returns true if a new file was generated, false if an existing one is returned.
 /// </summary>
 /// <param name="baseOutputDir"></param>
 /// <param name="publicKeyData"></param>
 /// <param name="signedTaskItem"></param>
 /// <returns></returns>
 public bool TrySign(string baseOutputDir, PublicKeyData publicKeyData, out ITaskItem signedTaskItem)
 {
     if (IsSigned)
     {
         signedTaskItem = InitialTaskItem;
         return(false);
     }
     // Replace the assemblydefinition with an open one for the duration of the write calls.
     using (_assemblyDefinition =
                Mono.Cecil.AssemblyDefinition.ReadAssembly(InitialTaskItem.ItemSpec, GetReaderParameters()))
     {
         var outputFile = GetOutputFile(baseOutputDir);
         signedTaskItem = new TaskItem(InitialTaskItem)
         {
             ItemSpec = outputFile
         };
         if (File.Exists(outputFile))
         {
             // If the file already exists, assume we already fixed it up correctly.
             return(false);
         }
         SetPublicKeyTokenOnReferences(publicKeyData.PublicKeyToken);
         FixInternalsVisibleTo(publicKeyData);
         try
         {
             _assemblyDefinition.Write(outputFile, GetWriterParameters(publicKeyData.StrongNameKeyPair));
         }
         catch (Exception e)
         {
             Debugger.Launch();
         }
         return(true);
     }
 }
        private void FixInternalsVisibleTo(PublicKeyData publicKeyData)
        {
            var internalsVisibleToAttributes = _assemblyDefinition.CustomAttributes.Where(attr =>
                                                                                          attr.AttributeType.FullName == typeof(InternalsVisibleToAttribute).FullName).ToList();

            foreach (var att in internalsVisibleToAttributes)
            {
                // TODO [DaS] Assume for now that InternalsVisibleToAttribute is only used
                // for tests. The problem here is that we need a list of assembly name to public key token
                // since unsigned assemblies generally don't add the public key token when
                // setting the InternalsVisibleToAttribute.
                _assemblyDefinition.CustomAttributes.Remove(att);
                //if (att.ConstructorArguments.Count != 1)
                //{
                //    throw new InvalidOperationException("InternalsVisibleToAttribute does not have a single constructor argument.");
                //}
                //var assemblyNameArgument = att.ConstructorArguments.First();
                //var assemblyName = (string) assemblyNameArgument.Value;
                //if (!assemblyName.Contains("PublicKey"))
                //{
                //    assemblyName = $"{assemblyName},PublicKey={publicKeyData.PublicKeyTokenAsString}";
                //    att.ConstructorArguments.Clear();
                //    att.ConstructorArguments.Add(new CustomAttributeArgument(assemblyNameArgument.Type, assemblyName));
                //}
            }
        }
        private void SignAllAssemblies()
        {
            // If this is renamed also fix the reference in the cleanup task in Das.StrongNameSigner.targets
            var signedAssemblyDirectory      = Path.Combine(OutputPath.ItemSpec, "DaS.StrongNameSigner");
            var copyLocalReferencesDirectory = Path.Combine(signedAssemblyDirectory, "copyLocalReferences");
            var referencesDirectory          = Path.Combine(signedAssemblyDirectory, "references");

            CreateDirectoryIfNotExists(signedAssemblyDirectory);
            CreateDirectoryIfNotExists(copyLocalReferencesDirectory);
            CreateDirectoryIfNotExists(referencesDirectory);

            _publicKeyData = GetPublicKeyData();
            _probingPaths  = References.Union(ReferenceCopyLocalPaths)
                             .Select(reference => Path.GetDirectoryName(reference.ItemSpec))
                             .ToImmutableList();
            _assemblyResolver = GetAssemblyResolver();

            SignedReferenceCopyLocalPaths = ReferenceCopyLocalPaths
                                            .Select(reference => SignAssembly(copyLocalReferencesDirectory, reference))
                                            .ToArray();
            SignedReferences = References
                               .Select(reference => SignAssembly(referencesDirectory, reference))
                               .ToArray();
        }