code: @SuppressWarnings("PMD.AvoidLiteralsInIfCondition")
      public static String toStringTypes(final Type[] types,
                                         final String separator,
                                         final Map<String, Type> generics) {
          final String res;
          if (types.length == 0) {
              res = "";
          } else if (types.length == 1) {
              // only one argument
              res = toStringType(types[0], generics);
          } else {
              final StringBuilder buf = new StringBuilder(types.length * 20);
              boolean first = true;
              for (Type type : types) {
                  if (!first) {
                      buf.append(separator);
                  }
                  buf.append(toStringType(type, generics));
                  first = false;
              }
              res = buf.toString();
          }
          return res;
      }
docs: Calls {@link #toStringType(Type, Map)} for all types and join resulted strings with provided separator.
  All types must be either without generics or from the single scope (same class or method) so provided generics
  map contains generics for all types.
  <p>
  Useful for example, to format types in error message.
  
  @param types     types to convert to string
  @param separator separator string
  @param generics  generics (common for all types)
  @return string with all types divided by separator
  @throws UnknownGenericException when found generic not declared on type (e.g. method generic)
  @see #toStringTypes(Type[], Map) shortcut for comma - separated types (most useful)