// Path: core/src/main/java/com/github/phantomthief/tuple/Tuple.java
// public final class Tuple {
// 
//     private Tuple() {
//         throw new UnsupportedOperationException();
//     }
// 
//     public static <A, B> TwoTuple<A, B> tuple(final A a, final B b) {
//         return new TwoTuple<>(a, b);
//     }
// 
//     public static <A, B, C> ThreeTuple<A, B, C> tuple(final A a, final B b, final C c) {
//         return new ThreeTuple<>(a, b, c);
//     }
// 
//     public static <A, B, C, D> FourTuple<A, B, C, D> tuple(final A a, final B b, final C c,
//             final D d) {
//         return new FourTuple<>(a, b, c, d);
//     }
// 
// }
// 
// Path: core/src/main/java/com/github/phantomthief/tuple/TwoTuple.java
// public class TwoTuple<A, B> {
// 
//     public final A first;
// 
//     public final B second;
// 
//     /**
//      * use {@link Tuple#tuple(Object, Object)} instead
//      */
//     @Deprecated
//     public TwoTuple(final A a, final B b) {
//         first = a;
//         second = b;
//     }
// 
//     public A getFirst() {
//         return first;
//     }
// 
//     public B getSecond() {
//         return second;
//     }
// 
//     @Override
//     public String toString() {
//         return "(" + first + ", " + second + ")";
//     }
// 
//     @Override
//     public int hashCode() {
//         final int prime = 31;
//         int result = 1;
//         result = prime * result + (first == null ? 0 : first.hashCode());
//         result = prime * result + (second == null ? 0 : second.hashCode());
//         return result;
//     }
// 
//     @Override
//     public boolean equals(final Object obj) {
//         if (this == obj) {
//             return true;
//         }
//         if (obj == null) {
//             return false;
//         }
//         if (getClass() != obj.getClass()) {
//             return false;
//         }
//         final TwoTuple<?, ?> other = (TwoTuple<?, ?>) obj;
//         if (first == null) {
//             if (other.first != null) {
//                 return false;
//             }
//         } else if (!first.equals(other.first)) {
//             return false;
//         }
//         if (second == null) {
//             return other.second == null;
//         } else {
//             return second.equals(other.second);
//         }
//     }
// 
// }


import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Throwables.throwIfUnchecked;
import static com.google.common.reflect.Reflection.newProxy;
import static org.apache.commons.lang3.reflect.FieldUtils.readDeclaredStaticField;
import static org.apache.commons.lang3.reflect.FieldUtils.writeStaticField;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import javax.annotation.Nonnull;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import com.github.phantomthief.tuple.Tuple;
import com.github.phantomthief.tuple.TwoTuple;
        Class<?> nameServiceInterface = originalNameService.getClass().getInterfaces()[0];
        Object wrappedNameService = adapterFromUnifiedNameService(unifiedNameService, nameServiceInterface);
        list.set(0, wrappedNameService);
    }

    private static void setNameServiceJdk9(UnifiedNameService unifiedNameService, Object originalNameService)
            throws IllegalAccessException {
        Class<?> nameServiceInterface = originalNameService.getClass().getInterfaces()[0];
        Object wrappedNameService = adapterFromUnifiedNameService(unifiedNameService, nameServiceInterface);
        writeStaticField(InetAddress.class, "nameService", wrappedNameService, true);
    }

    /**
     * @throws IllegalStateException 如果jdk8模式下已经使用SPI方式注入过多个实现时，或者开启JPMS时，权限不够
     */
    public static UnifiedNameService getCurrentNameService() {
        try {
            // jdk9
            Object nameService9 = readDeclaredStaticField(InetAddress.class, "nameService", true);
            if (nameService9 != null) {
                checkJdk9(nameService9);
                return new UnifiedNameServiceAdapter(nameService9);
            }
        } catch (IllegalArgumentException | IllegalAccessException | NullPointerException e) {
            // ignore
        }

        try {   // jdk8
            Object nameServices8 = readDeclaredStaticField(InetAddress.class, "nameServices", true);
            if (nameServices8 != null) {
// Path: core/src/main/java/com/github/phantomthief/tuple/Tuple.java
// public final class Tuple {
// 
//     private Tuple() {
//         throw new UnsupportedOperationException();
//     }
// 
//     public static <A, B> TwoTuple<A, B> tuple(final A a, final B b) {
//         return new TwoTuple<>(a, b);
//     }
// 
//     public static <A, B, C> ThreeTuple<A, B, C> tuple(final A a, final B b, final C c) {
//         return new ThreeTuple<>(a, b, c);
//     }
// 
//     public static <A, B, C, D> FourTuple<A, B, C, D> tuple(final A a, final B b, final C c,
//             final D d) {
//         return new FourTuple<>(a, b, c, d);
//     }
// 
// }
// 
// Path: core/src/main/java/com/github/phantomthief/tuple/TwoTuple.java
// public class TwoTuple<A, B> {
// 
//     public final A first;
// 
//     public final B second;
// 
//     /**
//      * use {@link Tuple#tuple(Object, Object)} instead
//      */
//     @Deprecated
//     public TwoTuple(final A a, final B b) {
//         first = a;
//         second = b;
//     }
// 
//     public A getFirst() {
//         return first;
//     }
// 
//     public B getSecond() {
//         return second;
//     }
// 
//     @Override
//     public String toString() {
//         return "(" + first + ", " + second + ")";
//     }
// 
//     @Override
//     public int hashCode() {
//         final int prime = 31;
//         int result = 1;
//         result = prime * result + (first == null ? 0 : first.hashCode());
//         result = prime * result + (second == null ? 0 : second.hashCode());
//         return result;
//     }
// 
//     @Override
//     public boolean equals(final Object obj) {
//         if (this == obj) {
//             return true;
//         }
//         if (obj == null) {
//             return false;
//         }
//         if (getClass() != obj.getClass()) {
//             return false;
//         }
//         final TwoTuple<?, ?> other = (TwoTuple<?, ?>) obj;
//         if (first == null) {
//             if (other.first != null) {
//                 return false;
//             }
//         } else if (!first.equals(other.first)) {
//             return false;
//         }
//         if (second == null) {
//             return other.second == null;
//         } else {
//             return second.equals(other.second);
//         }
//     }
// 
// }


// Path: core/src/main/java/com/github/phantomthief/util/NameServiceUtils.java
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.base.Throwables.throwIfUnchecked;
import static com.google.common.reflect.Reflection.newProxy;
import static org.apache.commons.lang3.reflect.FieldUtils.readDeclaredStaticField;
import static org.apache.commons.lang3.reflect.FieldUtils.writeStaticField;
import java.lang.reflect.InvocationTargetException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.List;
import javax.annotation.Nonnull;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.reflect.MethodUtils;
import com.github.phantomthief.tuple.Tuple;
import com.github.phantomthief.tuple.TwoTuple;

        Class<?> nameServiceInterface = originalNameService.getClass().getInterfaces()[0];
        Object wrappedNameService = adapterFromUnifiedNameService(unifiedNameService, nameServiceInterface);
        list.set(0, wrappedNameService);
    }

    private static void setNameServiceJdk9(UnifiedNameService unifiedNameService, Object originalNameService)
            throws IllegalAccessException {
        Class<?> nameServiceInterface = originalNameService.getClass().getInterfaces()[0];
        Object wrappedNameService = adapterFromUnifiedNameService(unifiedNameService, nameServiceInterface);
        writeStaticField(InetAddress.class, "nameService", wrappedNameService, true);
    }

    /**
     * @throws IllegalStateException 如果jdk8模式下已经使用SPI方式注入过多个实现时，或者开启JPMS时，权限不够
     */
    public static UnifiedNameService getCurrentNameService() {
        try {
            // jdk9
            Object nameService9 = readDeclaredStaticField(InetAddress.class, "nameService", true);
            if (nameService9 != null) {
                checkJdk9(nameService9);
                return new UnifiedNameServiceAdapter(nameService9);
            }
        } catch (IllegalArgumentException | IllegalAccessException | NullPointerException e) {
            // ignore
        }

        try {   // jdk8
            Object nameServices8 = readDeclaredStaticField(InetAddress.class, "nameServices", true);
            if (nameServices8 != null) {
                TwoTuple<Object, List<Object>> nameService8 = unwrapList(nameServices8);