docs: private List<String> findArgumentNames( List<List<JoinedArgs>> joinedArgs, List<List<String>> explicitParameterValues,
              List<String> explicitParameterNames ) {
          List<String> argumentNames = Lists.newArrayListWithExpectedSize( joinedArgs.get( 0 ).size() );
          Multiset<String> paramNames = TreeMultiset.create();
  
          arguments:
          for( int iArg = 0; iArg < joinedArgs.get( 0 ).size(); iArg++ ) {
              parameters:
              for( int iParam = 0; iParam < explicitParameterNames.size(); iParam++ ) {
                  String paramName = explicitParameterNames.get( iParam );
  
                  boolean formattedValueMatches = true;
                  boolean valueMatches = true;
                  for( int iCase = 0; iCase < joinedArgs.size(); iCase++ ) {
                      JoinedArgs args = joinedArgs.get( iCase ).get( iArg );
  
                      String parameterValue = explicitParameterValues.get( iCase ).get( iParam );
  
                      String formattedValue = args.words.get( 0 ).getFormattedValue();
                      if( !formattedValue.equals( parameterValue ) ) {
                          formattedValueMatches = false;
                      }
  
                      String value = args.words.get( 0 ).getValue();
                      if( !value.equals( parameterValue ) ) {
                          valueMatches = false;
                      }
  
                      if( !formattedValueMatches && !valueMatches ) {
                          continue parameters;
                      }
                  }
  
                  // on this point either all formatted values match or all values match (or both)
                  argumentNames.add( paramName );
                  paramNames.add( paramName );
                  continue arguments;
              }
  
              argumentNames.add( null );
          }
  
          Set<String> usedNames = Sets.newHashSet();
          for( int iArg = 0; iArg < joinedArgs.get( 0 ).size(); iArg++ ) {
              String name = argumentNames.get( iArg );
              if( name == null || paramNames.count( name ) > 1 ) {
                  String origName = getArgumentName( joinedArgs, iArg );
                  name = findFreeName( usedNames, origName );
                  argumentNames.set( iArg, name );
              }
              usedNames.add( name );
  
          }
  
          return argumentNames;
      }