text: ﻿$Script:ErrorActionPreference = 'Stop'
  
  $exclusions = @(
      'EventFlow\Core\AsyncHelper.cs'
      'EventFlow\Core\HashHelper.cs'
      'EventFlow\Logs\Internals\ImportedLibLog.cs'
  )
  
  $defaultAuthors = @(
      'Rasmus Mikkelsen'
      'eBay Software Foundation'
  )
  
  $files = Get-ChildItem -Path $PSScriptRoot -Directory -Recurse |
      Where-Object { $_.FullName -notmatch '\\(bin|obj)(\\|$)' } |
      Get-ChildItem -File -Filter *.cs |
      Select-Object -ExpandProperty FullName
  
  $year = [datetime]::Now.Year
  
  function IsExcluded([string] $File) {
      foreach ($exclusion in $exclusions) {
          if ($File.EndsWith($exclusion)) { return $true }
      }
  }
  
  function CreateCopyright([string] $FromYear, [string] $Name) {
      if ($FromYear -eq $year) {
          "// Copyright (c) $year $Name"
      }
      else {
          "// Copyright (c) $FromYear-$year $Name"
      }
  }
  
  function CreateHeader($Copyrights) {
      @"
  // The MIT License (MIT)
  // 
  $(@($Copyrights | ForEach-Object { CreateCopyright $_.FromYear $_.Name }) -join "`r`n")
  // https://github.com/eventflow/EventFlow
  // 
  // Permission is hereby granted, free of charge, to any person obtaining a copy of
  // this software and associated documentation files (the "Software"), to deal in
  // the Software without restriction, including without limitation the rights to
  // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
  // the Software, and to permit persons to whom the Software is furnished to do so,
  // subject to the following conditions:
  // 
  // The above copyright notice and this permission notice shall be included in all
  // copies or substantial portions of the Software.
  // 
  // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
  // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
  // COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
  // IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  
  
  "@
  }
  
  function UpdateFileHeaders {
  
      $headerRegex = [regex]::new('^\s*\/\/ The MIT License .+(?:\n\/\/.*)+\s*', 'Compiled')
      $copyrightRegex = [regex]::new('\/\/ Copyright \(c\) (\d{4})(?:-\d{4})? (.+)', 'Compiled')
  
      $defaultHeader = CreateHeader ($defaultAuthors | ForEach-Object {
              [PSCustomObject]@{
                  FromYear = 2015
                  Name     = $_
              } 
          })
  
      foreach ($file in $files) {
          if (IsExcluded $file) { continue }
  
          $content = Get-Content -Path $file -Raw
          $headerMatch = $headerRegex.Match($content)
  
          $result = if ($headerMatch.Success) {
              $currentHeader = $headerMatch.Value
              $copyrightMatches = $copyrightRegex.Matches($currentHeader)
              $copyrights = $copyrightMatches | ForEach-Object { 
                  [PSCustomObject]@{
                      FromYear = $_.Groups[1].Value
                      Name     = $_.Groups[2].Value.Trim()
                  } 
              }
          
              $generatedHeader = CreateHeader($copyrights)
              if ($generatedHeader -eq $currentHeader) { continue }    
  
              $newContent = $generatedHeader + $content.Substring($headerMatch.Length)
  
              $currentLines = $currentHeader -split "`r`n"
              $generatedLines = $generatedHeader -split "`r`n"
              $differences = Compare-Object $currentLines $generatedLines |
                  Where-Object SideIndicator -EQ '<=' |
                  ForEach-Object {
                      [PSCustomObject]@{
                          File   = $file
                          Change = $_.InputObject
                      }
                  }
              
              [PSCustomObject]@{
                  NewContent  = $newContent
                  Differences = $differences
              }
          }
          else {
              [PSCustomObject]@{
                  NewContent  = $defaultHeader + $content.TrimStart()
                  Differences = @(
                      [PSCustomObject]@{
                          File   = $file
                          Change = "New header"
                      })
              } 
          }
  
          $result.NewContent | Set-Content -Path $file -NoNewline
          $result.Differences
      }
  }
  
  UpdateFileHeaders |
      Group-Object Change |
      ForEach-Object {
          [PSCustomObject]@{
              Count  = $_.Count
              Change = $_.Name
              Files  = $_.Group | Select-Object -ExpandProperty File
          }
      }