package stexfires.util;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * This class consists of {@code static} utility methods for operating on {@code String} objects.
 *
 * @author Mathias Kalb
 * @see java.lang.String
 * @see java.util.stream.Stream
 * @see java.util.List
 * @since 0.1
 */
@SuppressWarnings("OverloadedVarargsMethod")
public final class Strings {

    /**
     * A default delimiter for joining strings: {@code ", "}
     */
    public static final String DEFAULT_DELIMITER = ", ";

    private static final String EMPTY = "";

    private Strings() {
    }

    @SuppressWarnings("ReturnOfNull")
    public static String asString(Object o) {
        return o == null ? null : o.toString();
    }

    public static String empty() {
        return EMPTY;
    }

    public static List<String> list(String stringValue) {
        return Collections.singletonList(stringValue);
    }

    public static List<String> list(String... stringValues) {
        return Arrays.stream(stringValues).collect(Collectors.toList());
    }

    public static Stream<String> stream(String stringValue) {
        return Stream.of(stringValue);
    }

    public static Stream<String> stream(String... stringValues) {
        return Stream.of(stringValues);
    }

    public static Stream<String> streamOfNullable(String stringValue) {
        return stringValue == null ? Stream.empty() : Stream.of(stringValue);
    }

    public static Stream<String> concat(Stream<String> firstStream, Stream<String> secondStream) {
        return Stream.concat(firstStream, secondStream);
    }

    @SafeVarargs
    public static Stream<String> concat(Stream<String>... streams) {
        return Stream.of(streams).flatMap(Function.identity());
    }

    public static List<String> collect(Stream<String> stream) {
        return stream.collect(Collectors.toList());
    }

    public static String join(Stream<String> stream) {
        return join(stream, DEFAULT_DELIMITER);
    }

    public static String join(Stream<String> stream, CharSequence delimiter) {
        return stream.collect(Collectors.joining(delimiter));
    }

    public static void printLine(Stream<String> stream, CharSequence delimiter) {
        System.out.println(join(stream, delimiter));
    }

    public static void printLines(Stream<String> stream) {
        stream.forEachOrdered(System.out::println);
    }

}

@@ -18,16 +18,60 @@
 .util;%0A%0A
+import org.jetbrains.annotations.Nullable;%0A%0A
 import j
@@ -140,16 +140,69 @@
 l.List;%0A
+import java.util.Objects;%0Aimport java.util.Optional;%0A
 import j
@@ -529,53 +529,8 @@
  */%0A
-@SuppressWarnings(%22OverloadedVarargsMethod%22)%0A
 publ
@@ -774,41 +774,114 @@
     
-@SuppressWarnings(%22ReturnOfNull%22)
+public static @Nullable String asString(Object o) %7B%0A        return o == null ? null : o.toString();%0A    %7D%0A
 %0A   
@@ -895,25 +895,43 @@
  static 
+Optional%3C
 String
+%3E
  as
+Optional
 String(O
@@ -960,39 +960,63 @@
 urn o == null ? 
-null : 
+Optional.empty() : Optional.of(
 o.toString();%0A  
@@ -1003,32 +1003,33 @@
 .of(o.toString()
+)
 ;%0A    %7D%0A%0A    pub
@@ -1197,32 +1197,81 @@
 gValue);%0A    %7D%0A%0A
+    @SuppressWarnings(%22OverloadedVarargsMethod%22)%0A
     public stati
@@ -1496,32 +1496,81 @@
 gValue);%0A    %7D%0A%0A
+    @SuppressWarnings(%22OverloadedVarargsMethod%22)%0A
     public stati
@@ -1756,47 +1756,8 @@
 turn
- stringValue == null ? Stream.empty() :
  Str
@@ -1754,32 +1754,40 @@
 return Stream.of
+Nullable
 (stringValue);%0A 
@@ -1883,32 +1883,123 @@
 secondStream) %7B%0A
+        Objects.requireNonNull(firstStream);%0A        Objects.requireNonNull(secondStream);%0A
         return S
@@ -2042,24 +2042,73 @@
 am);%0A    %7D%0A%0A
+    @SuppressWarnings(%22OverloadedVarargsMethod%22)%0A
     @SafeVar
@@ -2177,24 +2177,65 @@
  streams) %7B%0A
+        Objects.requireNonNull(streams);%0A
         retu
@@ -2349,32 +2349,72 @@
 ring%3E stream) %7B%0A
+        Objects.requireNonNull(stream);%0A
         return s
@@ -2503,32 +2503,72 @@
 ring%3E stream) %7B%0A
+        Objects.requireNonNull(stream);%0A
         return j
@@ -2677,32 +2677,115 @@
 ce delimiter) %7B%0A
+        Objects.requireNonNull(stream);%0A        Objects.requireNonNull(delimiter);%0A
         return s
@@ -2911,32 +2911,115 @@
 ce delimiter) %7B%0A
+        Objects.requireNonNull(stream);%0A        Objects.requireNonNull(delimiter);%0A
         System.o
@@ -3113,32 +3113,72 @@
 ring%3E stream) %7B%0A
+        Objects.requireNonNull(stream);%0A
         stream.f

Refactor util.Strings