filter _ExpandConfigPath {
    $_ | ForEach-Object {
        $local:c = Join-Path $(Join-Path $MyPSScriptRoot $(Join-Path '###' 'src')) $_
        $c -replace "###","base"
        $c -replace "###","*" | Get-Item -ErrorAction SilentlyContinue |
            Select-Object -ExpandProperty FullName
    } | Select-Object -Unique
 }
 
class MyConfig { #: System.Management.Automation.IValidateSetValuesGenerator {
   hidden static [hashtable]$_HardCodedConfigDict = @{
        'myconfig' = @('config.files.json','config.files.local.json') | _ExpandConfigPath
        'mymodules' = @('modules.json', 'modules.local.json') | _ExpandConfigPath
    }

    static [hashtable]GetConfigDictionary() {
        $local:result = @{}
        [MyConfig]::_HardCodedConfigDict.Keys |
            ForEach-Object {
                $result[$_] = [MyConfig]::_HardCodedConfigDict[$_]
            }
        if( Test-Path Function:/_ExpandConfigPath ) { Remove-Item Function:/_ExpandConfigPath }
        foreach( $local:jsonSource in $result.myconfig ) {
            if( -not ( Test-Path $jsonSource ) ) { continue }
            $local:props = $(Get-Item $jsonSource | Get-Content | ConvertFrom-Json).PSObject.Properties
            foreach( $local:prop in $props ) {
                $result[$prop.Name] = $prop.Value
            }
        }
        return $result;
    }
    static [string[]] GetConfigPaths([string[]]$ConfigNames,[switch]$Force) {
        $local:configDirectory = [MyConfig]::GetConfigDictionary()
        $local:result = [string[]]@()
        $local:flat = $false
        while(-not $flat) {
            $flat = $true
            $ConfigNames += $ConfigNames | ForEach-Object {
                $configDirectory[$_]
            } | Where-Object { $_ -match '^#[\w-\.]+$' } | ForEach-Object {
                $_.Substring(1)
            } | Where-Object { $_ -notin $ConfigNames } | ForEach-Object {
                $flat = false; $_;
            }
        }

        $local:flatConfigList = $ConfigNames | ForEach-Object {
                $configDirectory[$_]
            } | Where-Object { $_ -notmatch '^#[\w-\.]+$' }

        $local:exists = $false;
        $local:first = $null
        foreach( $local:configPath in $flatConfigList ) {
            $configPath = Get-Path $configPath
            if( -not $first ) { $first = $configPath }
            if( $Force -or (Test-Path $configPath) ) {
                $result += $configPath
                $exists = $true
            }
        }
        if( -not $exists -and -not $Force ) {
            $result += $first
        }
        return $result
    }
    static [string[]] _GetValidValues([string]$wordToComplete,[bool]$Strict) {
        $local:possibleValues = [MyConfig]::GetConfigDictionary().Keys
            return $(Get-PossibleArguments -WordToComplete $wordToComplete -FullValueSet $possibleValues -Strict:$Strict );
    }

    [String[]] GetValidValues() {
        return [MyConfig]::_GetValidValues('',$true)
    }
}