// 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;
package com.github.phantomthief.util;






/**
 * @author w.vela
 * Created on 2019-12-25.
 */
public class NameServiceUtils {

    private static final byte[] LOCAL_HOST = {127, 0, 0, 1};

    private static <T, R> R doInvoke(Object object, String method, T it) throws UnknownHostException {
        try {
            //noinspection unchecked
            return (R) MethodUtils.invokeMethod(object, true, method, it);
        } catch (NoSuchMethodException | IllegalAccessException e) {
            throw new AssertionError(e);
        } catch (InvocationTargetException e) {
            Throwable cause = e.getCause();
            if (cause instanceof UnknownHostException) {
                throw (UnknownHostException) cause;
            }
            throwIfUnchecked(cause);
            throw new AssertionError(cause);
        }
    }

    private static TwoTuple<Object, List<Object>> unwrapList(Object object) {
        if (object instanceof List) {
            List<Object> list = (List<Object>) object;
            checkState(!list.isEmpty(), "empty nameService in jdk8");
            checkState(list.size() == 1, "multiple nameServices in jdk8");
// 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;

package com.github.phantomthief.util;






/**
 * @author w.vela
 * Created on 2019-12-25.
 */
public class NameServiceUtils {

    private static final byte[] LOCAL_HOST = {127, 0, 0, 1};

    private static <T, R> R doInvoke(Object object, String method, T it) throws UnknownHostException {
        try {
            //noinspection unchecked
            return (R) MethodUtils.invokeMethod(object, true, method, it);
        } catch (NoSuchMethodException | IllegalAccessException e) {
            throw new AssertionError(e);
        } catch (InvocationTargetException e) {
            Throwable cause = e.getCause();
            if (cause instanceof UnknownHostException) {
                throw (UnknownHostException) cause;
            }
            throwIfUnchecked(cause);
            throw new AssertionError(cause);
        }
    }

    private static TwoTuple<Object, List<Object>> unwrapList(Object object) {
        if (object instanceof List) {
            List<Object> list = (List<Object>) object;
            checkState(!list.isEmpty(), "empty nameService in jdk8");
            checkState(list.size() == 1, "multiple nameServices in jdk8");
            return Tuple.tuple(list.get(0), list);