text:
package com.rtg.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.StringReader;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;

import org.junit.Assert;

import com.rtg.mode.DNA;
import com.rtg.mode.Protein;
import com.rtg.mode.TranslatedFrame;
import com.rtg.util.integrity.Exam.ExamException;
import com.rtg.util.integrity.IntegralAbstract;
import com.rtg.util.test.FileHelper;

/**
 * Utilities useful when doing testing.
 */
public final class TestUtils {

  private TestUtils() {
  }

  /**
   * Test standard properties of an Enum.  Checks that the string
   * representation of the Enum elements matches the expected
   * representation.  Checks the ordinal values match their position
   * in the values() array.  Checks the valueOf() method functions
   * correctly.
   *
   * @param clazz the class of the Enum to test
   * @param expectedToString the expected output of the array representation of the enum.
   * @param <T> the enum type being tested
   */
  public static <T extends Enum<T>> void testEnum(final Class<T> clazz, final String expectedToString) {
    // Check toString of values
    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
      try {
        final Method values = clazz.getMethod("values");
        values.setAccessible(true);
        final Object[] r = (Object[]) values.invoke(null);
        Assert.assertEquals(expectedToString, Arrays.toString(r));

        final Method valueOf = clazz.getMethod("valueOf", String.class);
        valueOf.setAccessible(true);

        final Method ordinal = clazz.getMethod("ordinal");
        ordinal.setAccessible(true);

        final Method nameMethod = clazz.getMethod("name");
        nameMethod.setAccessible(true);

        // Check ordinal and valueOf
        for (int i = 0; i < r.length; ++i) {
          final int oi = (Integer) ordinal.invoke(r[i]);
          Assert.assertEquals("Enum member " + r[i] + " at position " + i + " had ordinal " + oi, i, oi);
          final String name = (String) nameMethod.invoke(r[i]);
          Assert.assertEquals(r[i], valueOf.invoke(null, name));
          Assert.assertEquals(Enum.valueOf(clazz, name), r[i]);
        }
      } catch (final RuntimeException e) {
        throw e;
      } catch (final Exception e) {
        throw new RuntimeException(e);
      }
      return null;
    });
  }

  /**
   * Test standard properties of a PsuedoEnum.  Checks that the string
   * representation of the PsuedoEnum elements matches the expected
   * representation.  Checks the ordinal values match their position
   * in the values() array.  Checks the valueOf() method functions
   * correctly.
   *
   * @param clazz the class of the Enum to test
   * @param expectedToString the expected output of the array representation of the enum.
   * @param <T> the enum type being tested
   */
  public static <T extends PseudoEnum> void testPseudoEnum(final Class<T> clazz, final String expectedToString) {
    // Check toString of values
    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
      try {
        final Method values = clazz.getMethod("values");
        values.setAccessible(true);
        final Object[] r = (Object[]) values.invoke(null);
        Assert.assertEquals(expectedToString, Arrays.toString(r));

        final Method valueOf = clazz.getMethod("valueOf", String.class);
        valueOf.setAccessible(true);

        final Method ordinal = clazz.getMethod("ordinal");
        ordinal.setAccessible(true);

        final Method nameMethod = clazz.getMethod("name");
        nameMethod.setAccessible(true);

        // Check ordinal and valueOf
        for (int i = 0; i < r.length; ++i) {
          final int oi = (Integer) ordinal.invoke(r[i]);
          Assert.assertEquals("Enum member " + r[i] + " at position " + i + " had ordinal " + oi, i, oi);
          final String name = (String) nameMethod.invoke(r[i]);
          Assert.assertEquals(r[i], valueOf.invoke(null, name));
        }
      } catch (final RuntimeException e) {
        throw e;
      } catch (final Exception e) {
        throw new RuntimeException(e);
      }
      return null;
    });
  }

  /**
   * Test equals function of a set of objects. The input is grouped.
   * All objects within the group should be equal to each other and not
   * equal to all objects outside the group. Also tests that nothing
   * equal to null.
   *
   * @param groups to be checked against each other.
   */
  public static void equalsTest(final Object[][] groups) {
    for (int i = 0; i < groups.length; ++i) {
      final Object[] gi = groups[i];

      //Test nothing in this group equal to null
      for (Object aGi1 : gi) {
        Assert.assertTrue(!aGi1.equals(null));
      }

      //test everything in this group equal to each other.
      for (final Object element : gi) {
        for (final Object element2 : gi) {
          Assert.assertEquals(element, element2);
          Assert.assertEquals(element.hashCode(), element2.hashCode());
        }
      }

      //test everything in this group not equal to things in other groups
      for (int j = 0; j < groups.length; ++j) {
        if (j != i) {
          final Object[] gj = groups[j];
          for (Object aGi : gi) {
            for (Object aGj : gj) {
              Assert.assertTrue(!aGi.equals(aGj));
            }
          }
        }
      }
    }
  }

  /**
   * Test equals and hashCode() function of a set of objects. The input is grouped.
   * All objects within the group should be equal to each other and not
   * equal to all objects outside the group. Also tests that nothing
   * equal to null.
   *
   * @param groups to be checked against each other.
   */
  public static void equalsHashTest(final Object[][] groups) {
    for (int i = 0; i < groups.length; ++i) {
      final Object[] gi = groups[i];

      //Test nothing in this group equal to null
      for (final Object element : gi) {
        Assert.assertFalse(element.equals(null));
        Assert.assertTrue("gi=" + element.toString() + " gi.hashCode()=" + element.hashCode(), element.hashCode() != 0); //strictly neednt be true but very likely to be
      }

      //test everything in this group equal to each other.
      for (final Object element : gi) {
        for (final Object element2 : gi) {
          Assert.assertEquals(element, element2);
          Assert.assertEquals(element.hashCode(), element2.hashCode());
        }
      }

      //test everything in this group not equal to things in other groups
      for (int j = 0; j < groups.length; ++j) {
        if (j != i) {
          final Object[] gj = groups[j];
          for (int k = 0; k < gi.length; ++k) {
            for (int l = 0; l < gj.length; ++l) {
              Assert.assertFalse("Objects should not be equals(): i=" + i + " j=" + j + " k=" + k + " l=" + l + " g[i,k]=" + gi[k] + " g[j,l]=" + gj[l], gi[k].equals(gj[l]));
              //            strictly this next neednt be true - but highly likely to be if the job has been done well
              Assert.assertTrue(gi[k].toString() + " has same hashcode as " + gj[l].toString(), gi[k].hashCode() != gj[l].hashCode());
            }
          }
        }
      }
    }
  }

  /**
   * Check that the objects in an array are equal to themselves and
   * different to all other objects in the array.
   * Also check that nothing equals null and run all integrity checks.
   * @param array being checked.
   */
  public static void equalsTest(final Object[] array) {
    for (int i = 0; i < array.length; ++i) {
      final Object objectI = array[i];
      if (objectI instanceof IntegralAbstract) {
        try {
          ((IntegralAbstract) objectI).integrity();
        } catch (final ExamException e) {
          throw new RuntimeException("i=" + i + " " + objectI.toString(), e);
        }
      }
    }
    for (int i = 0; i < array.length; ++i) {
      final Object objectI = array[i];
      Assert.assertEquals(objectI, objectI);
      Assert.assertFalse(objectI.equals(null));
      for (int j = 0; j < i; ++j) {
        Assert.assertTrue(!array[j].equals(objectI));
      }
      for (int j = i + 1; j < array.length; ++j) {
        Assert.assertTrue(i + ":" + objectI + " == " + j + ":" + array[j], !array[j].equals(objectI));
      }
    }
  }

  /**
   * Check that the objects in an array are equal to themselves and
   * different to all other objects in the array.
   * Also check that nothing equals null, run all integrity checks and check hash codes.
   * @param array being checked.
   */
  public static void equalsHashTest(final Object[] array) {
    for (int i = 0; i < array.length; ++i) {
      final Object objectI = array[i];
      Assert.assertFalse(objectI.hashCode() == 0);
      if (objectI instanceof IntegralAbstract) {
        try {
          ((IntegralAbstract) objectI).integrity();
        } catch (final ExamException e) {
          throw new RuntimeException("i=" + i + " " + objectI.toString(), e);
        }
      }
    }
    for (int i = 0; i < array.length; ++i) {
      final Object objectI = array[i];
      Assert.assertEquals(objectI, objectI);
      Assert.assertFalse(objectI.equals(null));
      for (int j = 0; j < i; ++j) {
        Assert.assertTrue(!array[j].equals(objectI));
        Assert.assertTrue(array[j].hashCode() != objectI.hashCode());
      }
      for (int j = i + 1; j < array.length; ++j) {
        Assert.assertTrue(i + ":" + objectI + " == " + j + ":" + array[j], !array[j].equals(objectI));
      }
    }
  }

  /**
   * Test the ordering of a set of objects.
   * They should be ordered strictly monotonicly in the array.
   * Also checks consistency of equals and hashCode with the ordering.
   * This is the generic version.
   * @param ator a comparator to use when doing test.
   * @param compare an array of objects which should be in strictly
   * ascending order.
   * @param checkHash if true then check that all hash codes different
   * (needn't strictily be true so may need to turn this off in tricky cases).
   * @param <T> type to compare.
   */
  public static <T> void testOrder(final Comparator<T> ator, final T[] compare, final boolean checkHash) {
    for (int i = 0; i < compare.length; ++i) {
      for (int j = 0; j < i; ++j) {
        //System.err.println(i+":"+j);
        Assert.assertTrue(ator + ":" + compare[j] + ":" + compare[i], ator.compare(compare[j], compare[i]) < 0);
        Assert.assertFalse(compare[j].equals(compare[i]));
        Assert.assertTrue(String.valueOf(ator.compare(compare[i], compare[j])), ator.compare(compare[i], compare[j]) > 0);
        Assert.assertFalse(compare[i].equals(compare[j]));
        if (checkHash) {
          Assert.assertFalse(compare[i].hashCode() == compare[j].hashCode());
        }
      }
      Assert.assertEquals(0, ator.compare(compare[i], compare[i]));
      Assert.assertTrue(compare[i].equals(compare[i]));
      Assert.assertFalse(compare[i].equals(null));
    }
  }

  /**
   * Test the ordering of a set of comparable objects.
   * They should be ordered strictly monotonicly in the array.
   * Also tests that equals and hashCode are consistent with the ordering.
   * @param array a set of Comparable objects which should be in strictly
   * ascending order.
   * @param checkHash if true then check that all hash codes different
   * (needn't strictily be true so may need to turn this off in tricky cases).
   * @param <T> the type being compared
   */
  public static <T extends Comparable<T>> void testOrder(final T[] array, final boolean checkHash) {
    for (int i = 0; i < array.length; ++i) {
      Assert.assertEquals(0, array[i].compareTo(array[i]));
      Assert.assertFalse(array[i].equals(null));
      try {
        array[i].compareTo(null);
        Assert.fail();
      } catch (final NullPointerException e) {
        // expected
      }
      for (int j = 0; j < i; ++j) {
        Assert.assertTrue(array[j].compareTo(array[i]) < 0);
        Assert.assertTrue(array[i].compareTo(array[j]) > 0);
        Assert.assertFalse(array[j].equals(array[i]));
        if (checkHash) {
          Assert.assertFalse(array[j].hashCode() == array[i].hashCode());
        }
      }
    }
  }

  /**
   * Check if two arrays are equal allowing for the tricky case when the items are themselves arrays.
   * The methods in Arrays don't go this far.
   * Two objects are counted as equal if they arent arrays and their equals method succeeds or if they are
   * both null.
   * If they are both arrays then they are equal if they have the same length and each individual member is equal
   * recursively according to the definition here.
   * @param a first object to be tested.
   * @param b second object to be tested.
   * @return true iff a and b are equal. (See above for details).
   */
  public static boolean equals(final Object a, final Object b) {
    if (a == b) {
      return true;
    }
    if (a == null || b == null) {
      return false;
    }
    if ((a instanceof Object[]) && (b instanceof Object[])) {
      final Object[] aa = (Object[]) a;
      final Object[] ba = (Object[]) b;
      if (aa.length != ba.length) {
        return false;
      }
      for (int i = 0; i < aa.length; ++i) {
        if (!equals(aa[i], ba[i])) { //note recursive call
          return false;
        }
      }
      return true;
    } else {
      return a.equals(b);
    }
  }

  /**
   * Check if two arrays are equal - if not then print a message displaying them.
   * @param a first array to be checked
   * @param b second array to be checked
   */
  public static void assertEquals(final Object[] a, final Object[] b) {
    if (equals(a, b)) {
      return;
    }
    final String msg =
      "Expected: " + Arrays.toString(a) + " Actual:" + Arrays.toString(b);
    Assert.fail(msg);
  }

  /**
   * Check if two int arrays are equal - if not then print a message displaying them.
   * @param a first array to be checked
   * @param b second array to be checked
   */
  public static void assertEquals(final int[] a, final int[] b) {
    if (Arrays.equals(a, b)) {
      return;
    }
    final String msg =
      "Expected: " + Arrays.toString(a) + " Actual:" + Arrays.toString(b);
    Assert.fail(msg);
  }

  /**
   * Check if two byte arrays are equal - if not then print a message displaying them.
   * @param a first array to be checked
   * @param b second array to be checked
   */
  public static void assertEquals(final byte[] a, final byte[] b) {
    if (Arrays.equals(a, b)) {
      return;
    }
    final String msg =
      "Expected: " + Arrays.toString(a) + " Actual:" + Arrays.toString(b);
    Assert.fail(msg);
  }

  /**
   * Retrieves a field in the given object. Private fields are retrieved as well
   * as other ones.
   *
   * @param fieldName name of the field to retrieve.
   * @param instance the object to retrieve the field from.
   * @return the field value.
   * @throws RuntimeException on a reflection error. Since this is primarily a
   * testing method, there is no need to throw a checked exception.
   */
  public static Object getField(final String fieldName, final Object instance) {
    return AccessController.doPrivileged(new PrivilegedAction<Object>() {
      @Override
      public Object run() {
        try {
          final Field f = instance.getClass().getDeclaredField(fieldName);
          f.setAccessible(true);
          return f.get(instance);
        } catch (final NoSuchFieldException | IllegalAccessException e) {
          throw new RuntimeException(e);
        }
      }
    });
  }

  /**
   * Retrieves a static field in the given object. Private fields are retrieved as well
   * as other ones.
   *
   * @param fieldName name of the field to retrieve.
   * @param theClass the name of the class.
   * @return the field value.
   * @throws RuntimeException on a reflection error. Since this is primarily a
   * testing method, there is no need to throw a checked exception.
   */
  public static Object getField(final String fieldName, final Class<?> theClass) {
    return AccessController.doPrivileged(new PrivilegedAction<Object>() {
      @Override
      public Object run() {
        try {
          final Field f = theClass.getDeclaredField(fieldName);
          f.setAccessible(true);
          return f.get(null);
        } catch (final NoSuchFieldException | IllegalAccessException e) {
          throw new RuntimeException(e);
        }
      }
    });
  }

  /**
   * Check that a number of strings are contained in str.
   * @param str string to be checked.
   * @param subs all the items that should be in the string.
   */
  public static void containsAll(final String str, final String... subs) {
    containsAll(false, str, subs);
  }

  /**
   * Check that a number of strings are contained in str, which is unwrapped before checking. This method is
   * appropriate for checking help error message output.
   * @param str string to be checked.
   * @param subs all the items that should be in the string.
   */
  public static void containsAllUnwrapped(final String str, final String... subs) {
    containsAll(true, str, subs);
  }

  /**
   * Check that a number of strings are contained in str.
   * @param unwrap if true, the input string will be "unwrapped"
   * @param str string to be checked.
   * @param subs all the items that should be in the string.
   */
  private static void containsAll(boolean unwrap, final String str, final String... subs) {
    boolean ok = true;
    final StringBuilder sb = new StringBuilder();
    final String unw = unwrap ? unwrap(str) : str;
    for (final String sub : subs) {
      if (!unw.contains(sub)) {
        sb.append("'").append(sub).append("' was not contained in:").append(str).append(StringUtils.LS);
        ok = false;
      }
      Assert.assertTrue(sb.toString(), ok);
    }
  }

  /**
   * Checks that the contents of a string match those contained in a resource.
   * @param resource the resource name
   * @param actual the actual string
   */
  public static void assertResourceEquals(final String resource, final String actual) {
    final String expected;
    try {
      expected = FileHelper.resourceToString(resource).trim();
    } catch (final IOException e) {
      throw new RuntimeException(e);
    }
    final String exp = StringUtils.convertLineEndings(expected);
    Assert.assertEquals(exp, actual.trim());
  }

  /**
   * Test the ordering of a set of comparable objects.
   * They should be ordered strictly monotonicly in the array.
   * Each item in the sub arrays should be equal and be equivalent according to
   * compareTo and have equal hashCodes.
   * Also tests that equals and hashCode are consistent with the ordering.
   * Provides a more stringent test of an impelemention of Comparable
   * than testOrder(Comparable[], boolean).
   * @param array a set of sets of Comparable objects which should be in strictly
   * ascending order.
   * @param checkHash if true then check that all hash codes different
   * (needn't strictily be true so may needto turn this off in tricky cases).
   * @param <T> Comparable type
   */
  public static <T extends Comparable<T>> void testOrder(final T[][] array, final boolean checkHash) {
    for (int i = 0; i < array.length; ++i) {
      TestUtils.testEquivalent("" + i, array[i]);
      Assert.assertFalse("Array element: " + i + " is null", array[i].equals(null));
      for (int j = 0; j < i; ++j) {
        TestUtils.testLess(j + ":" + i, array[j], array[i], checkHash);
      }
    }
  }

  /**
   * All members of array should be equal and compareTo between all pairs
   * should be 0.
   * @param message to be used when reporting errors.
   * @param array to be checked for equivalence.
   */
  private static <T extends Comparable<T>> void testEquivalent(final String message, final T[] array) {
    if (array.length == 0) {
      return;
    }
    final int hash = array[0].hashCode();
    for (int i = 0; i < array.length; ++i) {
      final String msg = message + ":" + i;
      final T ai = array[i];
      Assert.assertFalse(msg, ai.equals(null));
      Assert.assertEquals(msg, hash, ai.hashCode());
      for (int j = 0; j < array.length; ++j) {
        final String ms = msg + ":" + j;
        Assert.assertEquals(ms, 0, ai.compareTo(array[j]));
        Assert.assertTrue(ms, ai.equals(array[j]));
      }
    }
  }

  /**
   * All pairs of items from the arrays should be not equal and
   * if checkHash is true then their hashCodes should differ.
   * All items from a should compare less than all the items from b.
   * @param msg to be used when reporting errors.
   * @param a lesser array to be checked.
   * @param b greater array to be checked.
   * @param checkHash if true then do hashCode checks (because if the inherent unpredicatbility
   * of hashCode it may be necessary to leave this false in some cases).
   */
  private static <T extends Comparable<T>> void testLess(final String msg, final T[] a, final T[] b, final boolean checkHash) {
    for (int i = 0; i < a.length; ++i) {
      final T ai = a[i];
      for (int j = 0; j < b.length; ++j) {
        final T bj = b[j];
        final String m = msg + ": " + i + ":" + j + " : " + ai + " : " + bj;
        Assert.assertTrue(m, ai.compareTo(bj) < 0);
        Assert.assertTrue(m, bj.compareTo(ai) > 0);
        Assert.assertFalse(m, ai.equals(bj));
        Assert.assertFalse(m, bj.equals(ai));
        if (checkHash) {
          Assert.assertFalse(m, ai.hashCode() == bj.hashCode());
        }
      }
    }
  }

  /**
   * Take a string of LS (either platform) separated strings and split them into an array containing one string per line.
   * @param in string of lines to be split.
   * @return an array containing individual lines.
   */
  public static String[] splitLines(final String in) {
    //return StringUtils.LS.equals("\n") ? in.split("\\\n") : in.split("\\\r\\\n"); //there must be a better way
    final BufferedReader sr = new BufferedReader(new StringReader(in));
    final ArrayList<String> results = new ArrayList<>();
    String line;
    try {
      while ((line = sr.readLine()) != null) {
        results.add(line);
      }
    } catch (final IOException ioe) {
      throw new RuntimeException(ioe);
    }
    return results.toArray(new String[0]);
  }

  /**
   * Take a string of LS separated strings and sort them and return them as a concatenated (LS separated) string.
   * @param in string of lines to be sorted.
   * @return sorted result.
   */
  public static String sortLines(final String in) {
    final String[] split = splitLines(in);
    Arrays.sort(split);
    //System.err.println(Arrays.toString(split));
    final StringBuilder sb = new StringBuilder();
    for (final String s : split) {
      sb.append(s).append(StringUtils.LS);
    }
    return sb.toString();
  }

  /**
   * Concatenates lines in input
   * @param lines an array of lines
   * @return a string with the lines in reverse order.
   */
  public static String cat(final String[] lines) {
    final StringBuilder sb = new StringBuilder();
    for (String line : lines) {
      sb.append(line).append(StringUtils.LS);
    }
    return sb.toString();
  }

  /**
   * Joins whitespace-trimmed lines of input, separated by space.
   * @param input a string
   * @return a string with the lines unwrapped.
   */
  public static String unwrap(final String input) {
    final String[] lines = splitLines(input);
    final StringBuilder sb = new StringBuilder();
    for (int i = 0; i < lines.length; ++i) {
      if (i > 0) {
        sb.append(" ");
      }
      sb.append(lines[i].trim());
    }
    return sb.toString();
  }

  /**
   * Compares the lines in two strings for equivalence, ignoring line endings and whitespace.
   *
   * @param expected a string.
   * @param actual a string.
   * @param sort true iff the lines aer to be sorted before a comparison is done
   * (use it if there is non-determinism in the order of the results)
   * @return true if the lines are the same.
   */
  public static boolean sameLines(final String expected, final String actual, final boolean sort) {
    final String[] erecs = splitLines(expected.trim());
    if (sort) {
      Arrays.sort(erecs);
    }
    final String[] arecs = splitLines(actual.trim());
    if (sort) {
      Arrays.sort(arecs);
    }
    final boolean same = sameLines(erecs, arecs);
    if (!same) {
      System.err.println("Actual output was:\n" + actual);
      System.err.println("Expected output was:\n" + expected);
    }
    return same;
  }

  /**
   * Checks whether two arrays of lines are the same.
   * @param erecs expected array of lines to be checked.
   * @param arecs actual array of lines to be checked.
   * @return true iff the arrays are the same length and all  expected lines are equal to the actual lines.
   */
  public static boolean sameLines(final String[] erecs, final String[] arecs) {
    final String result = compareLines(erecs, arecs);
    if (result != null) {
      System.err.println(result);
    }
    return result == null;
  }

  /**
   * Checks whether two arrays of lines are the same.
   * @param erecs expected array of lines to be checked.
   * @param arecs actual array of lines to be checked.
   * @return null if the lines are equal, otherwise a message describing the differences.
   */
  public static String compareLines(final String[] erecs, final String[] arecs) {
    int i = 0;
    for (; i < erecs.length && i < arecs.length; ++i) {
      if (!erecs[i].trim().equals(arecs[i].trim())) {
        return "" + (i + 1) + "c" + (i + 1) + StringUtils.LS
          + "< " + erecs[i].trim() + StringUtils.LS
          + "---" + StringUtils.LS
          + "> " + arecs[i].trim() + StringUtils.LS + StringUtils.LS;
      }
    }
    if (i < erecs.length) {
      return "" + (i + 1) + "d" + (i + 1) + StringUtils.LS
        + "< " + erecs[i].trim() + StringUtils.LS;
    } else if (i < arecs.length) {
      return "" + (i + 1) + ">" + (i + 1) + StringUtils.LS
        + "> " + arecs[i].trim() + StringUtils.LS;
    }
    return null;
  }

  /**
   * Compares the lines in two strings checking that the expected lines are prefixes of the actual lines.
   *
   * @param expected a string.
   * @param actual a string.
   * @param sort true iff the lines aer to be sorted before a comparison is done
   * (use it if there is non-determinism in the order of the results)
   * @return true if ll the expected lines are prefixes of the actual lines.
   */
  public static boolean startLines(final String expected, final String actual, final boolean sort) {
    final String[] erecs = splitLines(expected.trim());
    if (sort) {
      Arrays.sort(erecs);
    }
    final String[] arecs = splitLines(actual.trim());
    if (sort) {
      Arrays.sort(arecs);
    }
    final boolean same = startLines(erecs, arecs);
    if (!same) {
      System.err.println("Actual output was:\n" + actual);
      System.err.println("Expected output was:\n" + expected);
    }
    return same;
  }

  /**
   * Checks whether the expected lines are prefixes of the actual lines.
   * @param erecs expected array of lines to be checked.
   * @param arecs another array of lines to be checked.
   * @return true iff the arrays are the same length and all expected lines are prefixes of the actual lines.
   */
  public static boolean startLines(final String[] erecs, final String[] arecs) {
    boolean same = true;
    if (erecs.length != arecs.length) {
      System.err.println("Expected " + erecs.length + " actual " + arecs.length);
      same = false;
    } else {
      for (int i = 0; i < erecs.length; ++i) {
        if (!arecs[i].trim().startsWith(erecs[i].trim())) {
          System.err.println("Line " + i + StringUtils.LS + ">Expected: " + erecs[i].trim()
            + StringUtils.LS + ">actual  : " + arecs[i].trim());
          same = false;
          break;
        }
      }
    }
    return same;
  }

  /**
   * Strips the SAM header lines out of a string containing SAM output.
   *
   * @param sam the SAM output
   * @return a string which has had SAM header lines removed.
   * @exception java.io.IOException if an error occurs.
   */
  public static String stripSAMHeader(final String sam) throws IOException {
    return stripLines(sam, "@", "\n");
  }

  /**
   * Takes a SAM string and strips out header fields that typically change from run to run.
   * @param samString the full SAM string
   * @return the sanitized SAM
   */
  public static String sanitizeSAMHeader(String samString) {
    return samString.replaceAll("@PG.*\n", "")
      .replaceAll("@CO.*\n", "");
  }

  /**
   * Strips all lines starting with a character out of a string.
   *
   * @param text the textual output
   * @param prefix the prefix indicating lines to strip.
   * @param outLs the line separator to use on output.
   * @return a string which has had lines removed, and using \n as the line separator.
   * @exception java.io.IOException if an error occurs.
   */
  public static String stripLines(final String text, final String prefix, final String outLs) throws IOException {

    final StringBuilder sb = new StringBuilder();
    final BufferedReader sr = new BufferedReader(new StringReader(text));
    String line;
    while ((line = sr.readLine()) != null) {
      if (!line.startsWith(prefix)) {
        sb.append(line).append(outLs);
      }
    }
    return sb.toString();
  }

  /**
   * Stream that discards stuff written to it
   * @return the stream
   */
  public static OutputStream getNullOutputStream() {
    return NullStreamUtils.getNullOutputStream();
  }

  /**
   * Stream that discards stuff written to it
   * @return the stream
   */
  public static PrintStream getNullPrintStream() {
    return NullStreamUtils.getNullPrintStream();
  }

  /**
   * Turns dna string into protein
   * @param dna the base string
   * @return the protein string
   */
  public static String dnaToProtein(final String dna) {
    final byte[] dnaBytes = new byte[dna.length()];
    for (int i = 0; i < dna.length(); ++i) {
      final byte b;
      switch (dna.charAt(i)) {
        case 'a':
        case 'A':
          b = (byte) DNA.A.ordinal();
          break;
        case 'C':
        case 'c':
          b = (byte) DNA.C.ordinal();

          break;
        case 'G':
        case 'g':
          b = (byte) DNA.G.ordinal();
          break;
        case 'T':
        case 't':
        case 'U':
        case 'u':
          b = (byte) DNA.T.ordinal();
          break;
        default:
          b = (byte) DNA.N.ordinal();
          break;
      }
      dnaBytes[i] = b;
    }
    final StringBuilder ret = new StringBuilder();
    for (int i = 0; i + 2 < dnaBytes.length; i += 3) {
      ret.append(Protein.values()[TranslatedFrame.codonToAmino(dnaBytes[i], dnaBytes[i + 1], dnaBytes[i + 2])].toString());
    }
    return ret.toString();
  }

  /**
   * Takes a VCF string and strips out header fields that typically change from run to run.
   * @param vcfString the full VCF string
   * @return the sanitized VCF
   */
  public static String sanitizeVcfHeader(String vcfString) {
    return vcfString
      .replaceAll("##CL=.*\n", "##CL=[...]\n")
      .replaceAll("##TEMPLATE-SDF-ID=.*\n", "##TEMPLATE-SDF-ID=[...]\n")
      .replaceAll("##RUN-ID=.*\n", "##RUN-ID=[...]\n")
      .replaceAll("##fileDate=.*\n", "##fileDate=[...]\n")
      .replaceAll("##reference=.*\n", "##reference=[...]\n")
      .replaceAll("##source=.*\n", "##source=[...]\n");
  }

  /**
   * Takes a VCF string and strips out all of the header except the CHROM line.
   * @param vcfString the full VCF string
   * @return the sanitized VCF
   */
  public static String stripVcfHeader(String vcfString) {
    return vcfString.replaceAll("##.*\n", "");
  }

  /**
   * Takes a TSV string and strips out header fields that typically change from run to run.
   * @param inString the full input string
   * @return the sanitized string
   */
  public static String sanitizeTsvHeader(String inString) {
    return inString
      .replaceAll("#CL.*" + StringUtils.LS, "#CL [...]" + StringUtils.LS)
      .replaceAll("#Version.*" + StringUtils.LS, "#Version [...]" + StringUtils.LS);
  }
}


text:
# Changelog

## 0.7.0 (2017-04-02)

* Feature / BC break: Add main `Connector` facade
  (#93 by @clue)

  The new `Connector` class acts as a facade for all underlying connectors,
  which are now marked as "advanced usage", but continue to work unchanged.
  This now makes it trivially easy to create plaintext TCP/IP, secure TLS and
  Unix domain socket (UDS) connection streams simply like this:

  ```php
  $connector = new Connector($loop);

  $connector->connect('tls://google.com:443')->then(function (ConnectionInterface $conn) {
      $conn->write("GET / HTTP/1.0\r\n\r\n");
  });
  ```

  Optionally, it accepts options to configure all underlying connectors, such
  as using a custom DNS setup, timeout values and disabling certain protocols
  and much more. See the README for more details.

## 0.6.2 (2017-03-17)

* Feature / Fix: Support SNI on legacy PHP < 5.6 and add documentation for
  supported PHP and HHVM versions.
  (#90 and #91 by @clue)

## 0.6.1 (2017-03-10)

* Feature: Forward compatibility with Stream v0.5 and upcoming v0.6
  (#89 by @clue)

* Fix: Fix examples to use updated API
  (#88 by @clue)

## 0.6.0 (2017-02-17)

* Feature / BC break: Use `connect($uri)` instead of `create($host, $port)`
  and resolve with a `ConnectionInterface` instead of `Stream`
  and expose remote and local addresses through this interface
  and remove superfluous and undocumented `ConnectionException`.
  (#74, #82 and #84 by @clue)

  ```php
  // old
  $connector->create('google.com', 80)->then(function (Stream $conn) {
      echo 'Connected' . PHP_EOL;
      $conn->write("GET / HTTP/1.0\r\n\r\n");
  });

  // new
  $connector->connect('google.com:80')->then(function (ConnectionInterface $conn) {
      echo 'Connected to ' . $conn->getRemoteAddress() . PHP_EOL;
      $conn->write("GET / HTTP/1.0\r\n\r\n");
  });
  ```

  > Note that both the old `Stream` and the new `ConnectionInterface` implement
    the same underlying `DuplexStreamInterface`, so their streaming behavior is
    actually equivalent.
    In order to upgrade, simply use the new typehints.
    Existing stream handlers should continue to work unchanged.

* Feature / BC break: All connectors now MUST offer cancellation support.
  You can now rely on getting a rejected promise when calling `cancel()` on a
  pending connection attempt.
  (#79 by @clue)

  ```php
  // old: promise resolution not enforced and thus unreliable
  $promise = $connector->create($host, $port);
  $promise->cancel();
  $promise->then(/* MAY still be called */, /* SHOULD be called */);

  // new: rejecting after cancellation is mandatory
  $promise = $connector->connect($uri);
  $promise->cancel();
  $promise->then(/* MUST NOT be called */, /* MUST be called */);
  ```

  > Note that this behavior is only mandatory for *pending* connection attempts.
    Once the promise is settled (resolved), calling `cancel()` will have no effect.

* BC break: All connector classes are now marked `final`
  and you can no longer `extend` them
  (which was never documented or recommended anyway).
  Please use composition instead of extension.
  (#85 by @clue)

## 0.5.3 (2016-12-24)

* Fix: Skip IPv6 tests if not supported by the system
  (#76 by @clue)

* Documentation for `ConnectorInterface`
  (#77 by @clue)

## 0.5.2 (2016-12-19)

* Feature: Replace `SecureStream` with unlimited read buffer from react/stream v0.4.5
  (#72 by @clue)

* Feature: Add examples
  (#75 by @clue)

## 0.5.1 (2016-11-20)

* Feature: Support Promise cancellation for all connectors
  (#71 by @clue)

  ```php
  $promise = $connector->create($host, $port);

  $promise->cancel();
  ```

* Feature: Add TimeoutConnector decorator
  (#51 by @clue)

  ```php
  $timeout = new TimeoutConnector($connector, 3.0, $loop);
  $timeout->create($host, $port)->then(function(Stream $stream) {
      // connection resolved within 3.0s
  });
  ```

## 0.5.0 (2016-03-19)

* Feature / BC break: Support Connector without DNS
  (#46 by @clue)

  BC break: The `Connector` class now serves as a BC layer only.
  The `TcpConnector` and `DnsConnector` classes replace its functionality.
  If you're merely *using* this class, then you're *recommended* to upgrade as
  per the below snippet – existing code will still work unchanged.
  If you're `extend`ing the `Connector` (generally not recommended), then you
  may have to rework your class hierarchy.

  ```php
// old (still supported, but marked deprecated)
$connector = new Connector($loop, $resolver);

// new equivalent
$connector = new DnsConnector(new TcpConnector($loop), $resolver);

// new feature: supports connecting to IP addresses only
$connector = new TcpConnector($loop);
```

* Feature: Add socket and SSL/TLS context options to connectors
  (#52 by @clue)

* Fix: PHP 5.6+ uses new SSL/TLS context options
  (#61 by @clue)

* Fix: Move SSL/TLS context options to SecureConnector
  (#43 by @clue)

* Fix: Fix error reporting for invalid addresses
  (#47 by @clue)

* Fix: Close stream resource if connection fails
  (#48 by @clue)

* First class support for PHP 5.3 through PHP 7 and HHVM
  (#53, #54 by @clue)

* Add integration tests for SSL/TLS sockets
  (#62 by @clue)

## 0.4.4 (2015-09-23)

* Feature: Add support for Unix domain sockets (UDS) (#41 by @clue)
* Bugfix: Explicitly set supported TLS versions for PHP 5.6+ (#31 by @WyriHaximus)
* Bugfix: Ignore SSL non-draining buffer workaround for PHP 5.6.8+ (#33 by @alexmace)

## 0.4.3 (2015-03-20)

* Bugfix: Set peer name to hostname to correct security concern in PHP 5.6 (@WyriHaximus)
* Bugfix: Always wrap secure to pull buffer due to regression in PHP
* Bugfix: SecureStream extends Stream to match documentation preventing BC (@clue)

## 0.4.2 (2014-10-16)

* Bugfix: Only toggle the stream crypto handshake once (@DaveRandom and @rdlowrey)
* Bugfix: Workaround for ext-openssl buffering bug (@DaveRandom)
* Bugfix: SNI fix for PHP < 5.6 (@DaveRandom)

## 0.4.(0/1) (2014-02-02)

* BC break: Bump minimum PHP version to PHP 5.4, remove 5.3 specific hacks
* BC break: Update to React/Promise 2.0
* Dependency: Autoloading and filesystem structure now PSR-4 instead of PSR-0
* Bump React dependencies to v0.4

## 0.3.1 (2013-04-21)

* Feature: [SocketClient] Support connecting to IPv6 addresses (@clue)

## 0.3.0 (2013-04-14)

* Feature: [SocketClient] New SocketClient component extracted from HttpClient (@clue)

redpajama_set_name: RedPajamaGithub


text:
using MetroFramework.Forms;
namespace NeuroDNS
{
    partial class Form1:MetroForm
    {
        /// <summary>
        /// Требуется переменная конструктора.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Освободить все используемые ресурсы.
        /// </summary>
        /// <param name="disposing">истинно, если управляемый ресурс должен быть удален; иначе ложно.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Код, автоматически созданный конструктором форм Windows

        /// <summary>
        /// Обязательный метод для поддержки конструктора - не изменяйте
        /// содержимое данного метода при помощи редактора кода.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
            this.dataGridView1 = new System.Windows.Forms.DataGridView();
            this.tabControl1 = new System.Windows.Forms.TabControl();
            this.tabPage1 = new System.Windows.Forms.TabPage();
            this.toolStrip1 = new System.Windows.Forms.ToolStrip();
            this.toolStripButton1 = new System.Windows.Forms.ToolStripButton();
            this.tabPage4 = new System.Windows.Forms.TabPage();
            this.dataGridView2 = new System.Windows.Forms.DataGridView();
            this.toolStrip2 = new System.Windows.Forms.ToolStrip();
            this.toolStripButton2 = new System.Windows.Forms.ToolStripButton();
            this.tabPage3 = new System.Windows.Forms.TabPage();
            this.listBox1 = new System.Windows.Forms.ListBox();
            this.tabPage2 = new System.Windows.Forms.TabPage();
            this.timer1 = new System.Windows.Forms.Timer(this.components);
            this.notifyIcon1 = new System.Windows.Forms.NotifyIcon(this.components);
            this.contextMenuStrip1 = new System.Windows.Forms.ContextMenuStrip(this.components);
            this.showToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
            this.timer2 = new System.Windows.Forms.Timer(this.components);
            this.toolStripButton3 = new System.Windows.Forms.ToolStripButton();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
            this.tabControl1.SuspendLayout();
            this.tabPage1.SuspendLayout();
            this.toolStrip1.SuspendLayout();
            this.tabPage4.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).BeginInit();
            this.toolStrip2.SuspendLayout();
            this.tabPage3.SuspendLayout();
            this.contextMenuStrip1.SuspendLayout();
            this.SuspendLayout();
            //
            // dataGridView1
            //
            this.dataGridView1.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.AllCells;
            this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.dataGridView1.Location = new System.Drawing.Point(3, 28);
            this.dataGridView1.Name = "dataGridView1";
            this.dataGridView1.Size = new System.Drawing.Size(622, 348);
            this.dataGridView1.TabIndex = 9;
            //
            // tabControl1
            //
            this.tabControl1.Controls.Add(this.tabPage1);
            this.tabControl1.Controls.Add(this.tabPage4);
            this.tabControl1.Controls.Add(this.tabPage3);
            this.tabControl1.Controls.Add(this.tabPage2);
            this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.tabControl1.Location = new System.Drawing.Point(20, 60);
            this.tabControl1.Name = "tabControl1";
            this.tabControl1.SelectedIndex = 0;
            this.tabControl1.Size = new System.Drawing.Size(636, 405);
            this.tabControl1.TabIndex = 11;
            //
            // tabPage1
            //
            this.tabPage1.Controls.Add(this.dataGridView1);
            this.tabPage1.Controls.Add(this.toolStrip1);
            this.tabPage1.Location = new System.Drawing.Point(4, 22);
            this.tabPage1.Name = "tabPage1";
            this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
            this.tabPage1.Size = new System.Drawing.Size(628, 379);
            this.tabPage1.TabIndex = 0;
            this.tabPage1.Text = "DNS Servers";
            this.tabPage1.UseVisualStyleBackColor = true;
            //
            // toolStrip1
            //
            this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.toolStripButton1});
            this.toolStrip1.Location = new System.Drawing.Point(3, 3);
            this.toolStrip1.Name = "toolStrip1";
            this.toolStrip1.Size = new System.Drawing.Size(622, 25);
            this.toolStrip1.TabIndex = 10;
            this.toolStrip1.Text = "toolStrip1";
            //
            // toolStripButton1
            //
            this.toolStripButton1.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton1.Image")));
            this.toolStripButton1.ImageTransparentColor = System.Drawing.Color.Magenta;
            this.toolStripButton1.Name = "toolStripButton1";
            this.toolStripButton1.Size = new System.Drawing.Size(180, 22);
            this.toolStripButton1.Text = "Переинициализировать все";
            this.toolStripButton1.Click += new System.EventHandler(this.toolStripButton1_Click);
            //
            // tabPage4
            //
            this.tabPage4.Controls.Add(this.dataGridView2);
            this.tabPage4.Controls.Add(this.toolStrip2);
            this.tabPage4.Location = new System.Drawing.Point(4, 22);
            this.tabPage4.Name = "tabPage4";
            this.tabPage4.Padding = new System.Windows.Forms.Padding(3);
            this.tabPage4.Size = new System.Drawing.Size(628, 379);
            this.tabPage4.TabIndex = 3;
            this.tabPage4.Text = "Domains";
            this.tabPage4.UseVisualStyleBackColor = true;
            //
            // dataGridView2
            //
            this.dataGridView2.AutoSizeColumnsMode = System.Windows.Forms.DataGridViewAutoSizeColumnsMode.Fill;
            this.dataGridView2.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
            this.dataGridView2.Dock = System.Windows.Forms.DockStyle.Fill;
            this.dataGridView2.Location = new System.Drawing.Point(3, 28);
            this.dataGridView2.Name = "dataGridView2";
            this.dataGridView2.ReadOnly = true;
            this.dataGridView2.ShowEditingIcon = false;
            this.dataGridView2.Size = new System.Drawing.Size(622, 348);
            this.dataGridView2.TabIndex = 0;
            //
            // toolStrip2
            //
            this.toolStrip2.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.toolStripButton2,
            this.toolStripButton3});
            this.toolStrip2.Location = new System.Drawing.Point(3, 3);
            this.toolStrip2.Name = "toolStrip2";
            this.toolStrip2.Size = new System.Drawing.Size(622, 25);
            this.toolStrip2.TabIndex = 1;
            this.toolStrip2.Text = "toolStrip2";
            //
            // toolStripButton2
            //
            this.toolStripButton2.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
            this.toolStripButton2.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton2.Image")));
            this.toolStripButton2.ImageTransparentColor = System.Drawing.Color.Magenta;
            this.toolStripButton2.Name = "toolStripButton2";
            this.toolStripButton2.Size = new System.Drawing.Size(23, 22);
            this.toolStripButton2.Text = "toolStripButton2";
            this.toolStripButton2.Click += new System.EventHandler(this.toolStripButton2_Click);
            //
            // tabPage3
            //
            this.tabPage3.Controls.Add(this.listBox1);
            this.tabPage3.Location = new System.Drawing.Point(4, 22);
            this.tabPage3.Name = "tabPage3";
            this.tabPage3.Size = new System.Drawing.Size(628, 379);
            this.tabPage3.TabIndex = 2;
            this.tabPage3.Text = "Info";
            this.tabPage3.UseVisualStyleBackColor = true;
            //
            // listBox1
            //
            this.listBox1.Dock = System.Windows.Forms.DockStyle.Fill;
            this.listBox1.FormattingEnabled = true;
            this.listBox1.Location = new System.Drawing.Point(0, 0);
            this.listBox1.Name = "listBox1";
            this.listBox1.Size = new System.Drawing.Size(628, 379);
            this.listBox1.TabIndex = 0;
            //
            // tabPage2
            //
            this.tabPage2.Location = new System.Drawing.Point(4, 22);
            this.tabPage2.Name = "tabPage2";
            this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
            this.tabPage2.Size = new System.Drawing.Size(628, 379);
            this.tabPage2.TabIndex = 1;
            this.tabPage2.Text = "Configuration";
            this.tabPage2.UseVisualStyleBackColor = true;
            //
            // timer1
            //
            this.timer1.Enabled = true;
            this.timer1.Tick += new System.EventHandler(this.timer1_Tick_1);
            //
            // notifyIcon1
            //
            this.notifyIcon1.ContextMenuStrip = this.contextMenuStrip1;
            this.notifyIcon1.Icon = ((System.Drawing.Icon)(resources.GetObject("notifyIcon1.Icon")));
            this.notifyIcon1.Text = "NeuroDNS";
            this.notifyIcon1.Visible = true;
            //
            // contextMenuStrip1
            //
            this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
            this.showToolStripMenuItem,
            this.exitToolStripMenuItem});
            this.contextMenuStrip1.Name = "contextMenuStrip1";
            this.contextMenuStrip1.Size = new System.Drawing.Size(104, 48);
            //
            // showToolStripMenuItem
            //
            this.showToolStripMenuItem.Name = "showToolStripMenuItem";
            this.showToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
            this.showToolStripMenuItem.Text = "Show";
            this.showToolStripMenuItem.Click += new System.EventHandler(this.showToolStripMenuItem_Click);
            //
            // exitToolStripMenuItem
            //
            this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
            this.exitToolStripMenuItem.Size = new System.Drawing.Size(103, 22);
            this.exitToolStripMenuItem.Text = "Exit";
            this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
            //
            // timer2
            //
            this.timer2.Enabled = true;
            this.timer2.Interval = 600000;
            this.timer2.Tick += new System.EventHandler(this.timer2_Tick);
            //
            // toolStripButton3
            //
            this.toolStripButton3.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
            this.toolStripButton3.Image = ((System.Drawing.Image)(resources.GetObject("toolStripButton3.Image")));
            this.toolStripButton3.ImageTransparentColor = System.Drawing.Color.Magenta;
            this.toolStripButton3.Name = "toolStripButton3";
            this.toolStripButton3.Size = new System.Drawing.Size(23, 22);
            this.toolStripButton3.Text = "toolStripButton3";
            this.toolStripButton3.Click += new System.EventHandler(this.toolStripButton3_Click);
            //
            // Form1
            //
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(676, 485);
            this.Controls.Add(this.tabControl1);
            this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
            this.Name = "Form1";
            this.Text = "NeuroDNS";
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.Form1_FormClosing);
            this.Load += new System.EventHandler(this.Form1_Load);
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
            this.tabControl1.ResumeLayout(false);
            this.tabPage1.ResumeLayout(false);
            this.tabPage1.PerformLayout();
            this.toolStrip1.ResumeLayout(false);
            this.toolStrip1.PerformLayout();
            this.tabPage4.ResumeLayout(false);
            this.tabPage4.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.dataGridView2)).EndInit();
            this.toolStrip2.ResumeLayout(false);
            this.toolStrip2.PerformLayout();
            this.tabPage3.ResumeLayout(false);
            this.contextMenuStrip1.ResumeLayout(false);
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.DataGridView dataGridView1;
        private System.Windows.Forms.TabControl tabControl1;
        private System.Windows.Forms.TabPage tabPage1;
        private System.Windows.Forms.TabPage tabPage2;
        private System.Windows.Forms.TabPage tabPage3;
        private System.Windows.Forms.ToolStrip toolStrip1;
        private System.Windows.Forms.ToolStripButton toolStripButton1;
        private System.Windows.Forms.ListBox listBox1;
        private System.Windows.Forms.Timer timer1;
        private System.Windows.Forms.NotifyIcon notifyIcon1;
        private System.Windows.Forms.ContextMenuStrip contextMenuStrip1;
        private System.Windows.Forms.ToolStripMenuItem showToolStripMenuItem;
        private System.Windows.Forms.ToolStripMenuItem exitToolStripMenuItem;
        private System.Windows.Forms.TabPage tabPage4;
        private System.Windows.Forms.DataGridView dataGridView2;
        private System.Windows.Forms.ToolStrip toolStrip2;
        private System.Windows.Forms.ToolStripButton toolStripButton2;
        private System.Windows.Forms.Timer timer2;
        private System.Windows.Forms.ToolStripButton toolStripButton3;
    }
}


text:
class Hobson::Client::TestRun::Test < Hobson::Client::Resource

  resource_name :test

  attributes :id, :path, :project_origin, :sha, :requestor, :created_at

end


text:
package de.hub.cs.dbis.lrb.queries.utils;

import backtype.storm.tuple.Tuple;
import de.hub.cs.dbis.aeolus.utils.TimeStampExtractor;
import de.hub.cs.dbis.aeolus.utils.TimestampMerger;
import de.hub.cs.dbis.lrb.types.PositionReport;
import de.hub.cs.dbis.lrb.types.internal.AccidentTuple;

/**
 * {@link AccInputStreamsTsExtractor} extracts the minute number of the input tuples as timestamps for a
 * {@link TimestampMerger}.

 *

 * It expects {@link PositionReport} tuples for input stream {@link TopologyControl#POSITION_REPORTS_STREAM_ID}. Tuples
 * from all other input streams are expected to be of type {@link AccidentTuple}.
 *
 * @author mjsax
 */
public class AccInputStreamsTsExtractor implements TimeStampExtractor<Tuple> {
	private static final long serialVersionUID = -8976869891555736418L;

	@Override
	public long getTs(Tuple tuple) {
		if(tuple.getSourceStreamId().equals(TopologyControl.POSITION_REPORTS_STREAM_ID)) {
			return tuple.getShort(PositionReport.TIME_IDX).longValue();
		} else {
			return tuple.getShort(AccidentTuple.TIME_IDX).longValue();
		}
	}
}


text:
module QA
  module Page
    module File
      module Shared
        module Editor
          def self.included(base)
            base.view 'app/views/projects/blob/_editor.html.haml' do
              element :editor
            end
          end

          def add_content(content)
            text_area.set content
          end

          def remove_content
            text_area.send_keys([:command, 'a'], :backspace)
          end

          private

          def text_area
            within_element :editor do
              find('textarea', visible: false)
            end
          end
        end
      end
    end
  end
end


text:
using System;
using System.Web.Caching;

using Nohros.Caching.Providers;
using Nohros.Resources;

namespace Nohros.Caching
{
  /// <summary>
  /// A <see cref="ICacheProvider"/> implementation that uses the
  /// <see cref="System.Web.Caching.Cache"/> class as the underlying cache
  /// mechanism.
  /// </summary>
  public class WebCacheProvider : ICacheProvider
  {
    Cache cache_;

    /// <summary>
    /// Initializes a new instance of the <see cref="WebCacheProvider"/>
    /// class by using the specified <see cref="Cache"/> object.
    /// </summary>
    /// <param name="cache">
    /// </param>
    public WebCacheProvider(Cache cache) {
      cache_ = cache;
    }

    /// <inheritdoc/>
    public T Get<T>(string key) {
      object local_item = cache_.Get(key);
      if (local_item != null && local_item is T) {
        return (T)local_item;
      }
      return default(T);
    }

    /// <inheritdoc/>
    public bool Get<T>(string key, out T item) {
      object local_item = cache_.Get(key);
      if (local_item != null && local_item is T) {
        item = (T) local_item;
        return true;
      }
      item = default(T);
      return false;
    }

    /// <inheritdoc/>
    public void Set(string key, object value) {
      cache_[key] = value;
    }

    /// <inheritdoc/>
    public void Set(string key, object value, long duration, TimeUnit unit) {
      cache_.Insert(key, value, null,
        DateTime.Now.AddMilliseconds(TimeUnitHelper.ToSeconds(duration, unit)),
        Cache.NoSlidingExpiration);
    }

    /// <inheritdoc/>
    public void Add(string key, object value) {
      object local_item = cache_.Get(key);
      if (local_item != null) {
        throw new ArgumentException(
          string.Format(StringResources.Argument_AddingDuplicateKey), key);
      }
      Set(key, value);
    }

    /// <inheritdoc/>
    public void Add(string key, object value, long duration, TimeUnit unit) {
      object local_item = cache_.Get(key);
      if (local_item != null) {
        throw new ArgumentException(
          string.Format(StringResources.Argument_AddingDuplicateKey), key);
      }
      Set(key, value, duration, unit);
    }

    /// <inheritdoc/>
    public void Remove(string key) {
      cache_.Remove(key);
    }

    /// <inheritdoc/>
    public void Clear() {
    }
  }
}


text:
package org.sistemafinanciero.rest.impl;

import java.math.BigInteger;
import java.util.List;

import javax.ejb.EJB;
import javax.ws.rs.core.Response;

import org.sistemafinanciero.entity.PendienteCaja;
import org.sistemafinanciero.entity.dto.VoucherPendienteCaja;
import org.sistemafinanciero.rest.PendienteREST;
import org.sistemafinanciero.service.nt.PendienteServiceNT;

public class PendienteRESTService implements PendienteREST {

	@EJB
	private PendienteServiceNT pendienteServiceNT;

	@Override
	public Response findAll() {
		List<PendienteCaja> list = pendienteServiceNT.findAll();
		Response response = Response.status(Response.Status.OK).entity(list).build();
		return response;
	}

	@Override
	public Response findById(BigInteger id) {
		PendienteCaja pendiente = pendienteServiceNT.findById(id);
		Response response = Response.status(Response.Status.OK).entity(pendiente).build();
		return response;
	}

	@Override
	public Response getVoucherPendienteCaja(BigInteger idPendienteCaja) {
		VoucherPendienteCaja voucher = pendienteServiceNT.getVoucherPendienteCaja(idPendienteCaja);
		Response response = Response.status(Response.Status.OK).entity(voucher).build();
		return response;
	}

}


text:
const $               = require('jquery');
const m               = require('mithril');
const Stream          = require('mithril/stream');
const DashboardVM     = require('views/dashboard/models/dashboard_view_model');
const Dashboard       = require('models/dashboard/dashboard');
const DashboardWidget = require('views/dashboard/dashboard_widget');

const VersionUpdater = require('models/shared/version_updater');
const AjaxPoller     = require('helpers/ajax_poller');

require('foundation-sites');
require('helpers/server_health_messages_helper');

$(() => {
  new VersionUpdater().update();
  const dashboardElem = $('#dashboard');

  const dashboardVM            = new DashboardVM();
  const isQuickEditPageEnabled = JSON.parse(dashboardElem.attr('data-is-quick-edit-page-enabled'));
  const isNewDashboardPageDefault = JSON.parse(dashboardElem.attr('data-is-new-dashboard-page-default'));

  $(document).foundation();

  const dashboard = new Dashboard();

  function onResponse(dashboardData, message = undefined) {
    dashboard.initialize(dashboardData);
    dashboard.message(message);
  }

  function createRepeater() {
    const onsuccess = (data, _textStatus, jqXHR) => {
      if (jqXHR.status === 202) {
        const message = {
          type:    "info",
          content: data.message
        };
        onResponse({}, message);
        return;
      }
      onResponse(data);
    };
    const onerror   = (jqXHR, textStatus, errorThrown) => {
      if (textStatus === 'parsererror') {
        const message = {
          type:    "alert",
          content: "Error occurred while parsing dashboard API response. Check server logs for more information."
        };
        onResponse({}, message);
        console.error(errorThrown); // eslint-disable-line no-console
        return;
      }

      if (jqXHR.status === 424) {
        const message = {
          type:    'warning',
          content: jqXHR.responseJSON.message,
        };
        onResponse({}, message);
        return;
      }

      const message = {
        type:    'warning',
        content: 'There was an unknown error ',
      };
      onResponse({}, message);
      return;
    };

    return new AjaxPoller(() => Dashboard.get().then(onsuccess, onerror));
  }

  const repeater = Stream(createRepeater());

  const renderView = () => {
    const component = {
      view() {
        return m(DashboardWidget, {
          dashboard,
          isQuickEditPageEnabled,
          isNewDashboardPageDefault,
          vm:                   dashboardVM,
          doCancelPolling:      () => repeater().stop(),
          doRefreshImmediately: () => {
            repeater().stop();
            repeater().start();
          }
        });
      }
    };

    m.route($("#dashboard").get(0), '', {
      '':             component,
      '/:searchedBy': component
    });

    dashboard.searchText(m.route.param('searchedBy') || '');
  };

  repeater().start();
  renderView();
});


text:
package swoop.route;

import java.util.Collections;
import java.util.List;
import java.util.Set;

import swoop.util.Multimap;

public class RouteParameters {

    private Multimap<String,String> underlying;
    public void setUnderlying(Multimap<String, String> underlying) {
        this.underlying = underlying;
    }

    public Multimap<String, String> getUnderlying() {
        return underlying;
    }

    public String routeParam(String name) {
        if(underlying==null)
            return null;
        if(name.startsWith(":"))
            return underlying.first(name.substring(1));
        else
            return underlying.first(name);
    }

    public List<String> routeParams(String name) {
        if(underlying==null)
            return Collections.emptyList();
        if(name.startsWith(":"))
            return underlying.get(name.substring(1));
        else
            return underlying.get(name);
    }

    public Set<String> routeParamKeys() {
        if(underlying==null)
            return Collections.emptySet();
        return underlying.keySet();
    }
}


text:
package edu.asu.scrapbook.digital.api;

import org.glassfish.jersey.server.ResourceConfig;

public class AppConfig extends ResourceConfig {

	public AppConfig() {
		register(UserResource.class);
		register(ImageResource.class);
	}

}


text:
// Copyright © Microsoft Open Technologies, Inc.
//
// All Rights Reserved
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION
// ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A
// PARTICULAR PURPOSE, MERCHANTABILITY OR NON-INFRINGEMENT.
//
// See the Apache License, Version 2.0 for the specific language
// governing permissions and limitations under the License.

#import "ADALiOS.h"
#import "ADAuthenticationResult.h"
#import "ADAuthenticationResult+Internal.h"
#import "ADTokenCacheStoreItem.h"
#import "ADOAuth2Constants.h"
#import "ADUserInformation.h"

@implementation ADAuthenticationResult (Internal)

-(id) initWithCancellation
{
    ADAuthenticationError* error = [ADAuthenticationError errorFromCancellation];

    return [self initWithError:error status:AD_USER_CANCELLED];
}

-(id) initWithItem: (ADTokenCacheStoreItem*) item
multiResourceRefreshToken: (BOOL) multiResourceRefreshToken
{
    self = [super init];
    if (self)
    {
        _status = AD_SUCCEEDED;
        _tokenCacheStoreItem = item;
        _multiResourceRefreshToken = multiResourceRefreshToken;
    }
    return self;
}

-(id) initWithError: (ADAuthenticationError*)error
             status: (ADAuthenticationResultStatus) status
{
    THROW_ON_NIL_ARGUMENT(error);

    self = [super init];
    if (self)
    {
        _status = status;
        _error = error;
    }
    return self;
}

/*! Creates an instance of the result from the cache store. */
+(ADAuthenticationResult*) resultFromTokenCacheStoreItem: (ADTokenCacheStoreItem*) item
                               multiResourceRefreshToken: (BOOL) multiResourceRefreshToken
{
    if (item)
    {
        ADAuthenticationError* error;
        [item extractKeyWithError:&error];
        if (error)
        {
            //Bad item, return error:
            return [ADAuthenticationResult resultFromError:error];
        }
        if ([NSString adIsStringNilOrBlank:item.accessToken])
        {
            //Bad item, the access token should be accurate, else an error should be
            //reported instead of this creator:
            ADAuthenticationError* error = [ADAuthenticationError unexpectedInternalError:@"ADAuthenticationResult created from item with no access token."];
            return [ADAuthenticationResult resultFromError:error];
        }
        //The item can be used, just use it:
        return [[ADAuthenticationResult alloc] initWithItem:item multiResourceRefreshToken:multiResourceRefreshToken];
    }
    else
    {
        ADAuthenticationError* error = [ADAuthenticationError unexpectedInternalError:@"ADAuthenticationResult created from nil token item."];
        return [ADAuthenticationResult resultFromError:error];
    }
}

+(ADAuthenticationResult*) resultFromError: (ADAuthenticationError*) error
{
    ADAuthenticationResult* result = [ADAuthenticationResult alloc];
    return [result initWithError:error status:AD_FAILED];
}

+(ADAuthenticationResult*) resultFromCancellation
{
    ADAuthenticationResult* result = [ADAuthenticationResult alloc];
    return [result initWithCancellation];
}

+(ADAuthenticationResult*) resultFromBrokerResponse: (NSDictionary*) response
{
    ADAuthenticationError* error;
    ADAuthenticationResult* result;
    ADTokenCacheStoreItem* item = nil;
    if([response valueForKey:OAUTH2_ERROR_DESCRIPTION]){
        error = [ADAuthenticationError errorFromNSError:[NSError errorWithDomain:ADBrokerResponseErrorDomain code:0 userInfo:nil] errorDetails:[response valueForKey:OAUTH2_ERROR_DESCRIPTION]];
    }
    else
    {
        item = [ADTokenCacheStoreItem new];
        item.authority =  [response valueForKey:OAUTH2_AUTHORITY];
        item.resource = [response valueForKey:OAUTH2_RESOURCE];
        item.clientId = [response valueForKey:OAUTH2_CLIENT_ID];
        item.accessToken = [response valueForKey:OAUTH2_ACCESS_TOKEN];
        if([response valueForKey:OAUTH2_ID_TOKEN])
        {
            ADUserInformation* info = [ADUserInformation userInformationWithIdToken:[response valueForKey:OAUTH2_ID_TOKEN] error:&error];
            if(!error)
            {
                item.userInformation = info;
            }
        }
    }
    if(error)
    {
        result = [ADAuthenticationResult resultFromError:error];
    }
    else
    {
        result = [[ADAuthenticationResult alloc ]initWithItem:item multiResourceRefreshToken:NO];
    }

    return result;
}

@end


text:
Pass MongoDB query through URL query string.

## Contributors

  * [Nicolas Thouvenin](https://github.com/touv)

# Installation

With [npm](http://npmjs.org) do:

    $ npm install mongodb-querystring

# Tests

Use [mocha](https://github.com/visionmedia/mocha) to run the tests.

    $ npm install mocha
    $ mocha test

# API Documentation

## stringify(input : Object, [separator : String]) : String

Converts `query` to a URL query string.

```javascript
	var mqs = require('mongodb-querystring');
	var qry = {
     "$query" : {
       "age" : {
         "$gte" : new Date(1976, 11, 14)
       },
       "$or": [
         { "cuisine": "Italian" },
         { "address.zipcode": "10075" }
       ]
     },
     "$limit" : 20,
     "$orderby" : {
       "age" : -1,
       "posts": 1
     }
   };
   console.log(mqs.stringify(qry);

```
Output:

	'$query[age][$gte]=219366000000^D&$query[$or][0][cuisine]=Italian&$query[$or][1][address.zipcode]=10075&$limit=20^N&$orderby[age]=-1^N&$orderby[posts]=1^N'

## parse(input : String) : Object
## parse(input : Object) : Object

Parse `input` to convert to an query.
```javascript
	var mqs = require('mongodb-querystring');
	var qry = '$query[type][$in][0]=food&$query[type][$in][1]=snacks';
	console.dir(mqs.parse(qry));

```
Output:

	{ '$query': { type: { '$in': [ 'food', 'snacks' ] } } }

## create(input : String) : Object
## create(input : Object) : Object

Parse `input` to convert to an Object query.
```javascript
	var mqs = require('mongodb-querystring');
	var qry = mqs.create(req.query);
	console.log(qry.$query());
	console.log(qry.$limit(10));

```
# Also

* https://www.npmjs.com/package/query-to-mongo
* https://www.npmjs.com/package/mongo-querystring


text:
Versus battle series
=================

Angular.js Vs Backbone.js
=================

Angular.js  VS Backbone.js. is a GDG event who toke place in A Coruña. The intent of the event was to compare the frameworks developing the same problem with both live with the participants.

This is the Backbone implementation of the problem. Comments and pull requests are welcome to improve the code and discuss the implementation.


text:
<TITLE>Review for Corruptor, The (1999)</TITLE>
<LINK REL="STYLESHEET" TYPE="text/css" HREF="/ramr.css">

Corruptor, The (1999)

reviewed by
Steve Kong

THE CORRUPTOR (1999)

A film review by Steve Kong
Edited by Steve Kong
Copyright 1999 Steve Kong

I was once asked if I biased my film reviews based on the presence of a
particular performer. Definitely! My admiration of Chow Yun-Fat comes from
his collaborations with legendary action director John Woo (Hard Boiled,
The Killer, Once A Thief). And like anyone who loves the work that these
two have accomplished in Hong Kong, I await the day that these two will
pair up again to do another film together. For now, I have to live with the
above par releases of Woo sans Chow (Face/Off) and the below par releases
of Chow sans Woo (The Replacement Killers). So, I was a little disappointed
by the film The Corruptor, a Chow release without Woo at the helm. The
Corruptor is an above average cop-buddy movie that is lifted up by the
presence of Chow Yun-Fat but then dragged down by Mark Wahlberg and
director James Foley.

Similar to The Replacement Killers, the title of The Corruptor does not
refer to the character portrayed by Chow Yun-Fat. Nick Chen (Chow Yun-Fat)
is a detective in the NYPD Asian Gangs Unit. The AGU is run by a tight knit
group of cops, all Chinese. A bombing at a local convenience store changes
all this. A new gang in town kills a foreigner and the mayor is screaming
to have the AGU expanded. And before you can scream "buddy-film", Mark
Wahlberg (Boogie Nights) shows up.

Chen who is on the take from a Chinatown businessman, Lee (Ric Young),
re-evaluates his beliefs and actions when he has to take on the new
recruit, Danny Wallace (Wahlberg). When Lee tries to put Wallace on the
payroll, this tests Chen's loyalties -- as the film progresses, Wallace is
also forced to take a close look at his loyalties through a great twist in
the story.

The script by first-time pen Robert Pucci has enough twists in it to keep
the attention of the moviegoer looking for a film filled with double-fisted
gunfights, because the action in The Corruptor is sparse. And when the
action fires up, it is done with such MTV style shooting and editing that I
was expecting to find a complimentary airsickness bag.

The one thing that I despise most about the current crop of action films is
the use of the "Shaky Camera" technique. This is a technique in which the
director and cinematographer (Juan Ruiz-Anchia) decide that action is
enhanced by bouncing the camera around. Put this together with quick cuts
and razor sharp editing and what you get are action sequences that no one
can follow. If you've seen the car chase in Michael Bay's The Rock and
thought the camerawork and editing in it was horrible, wait till you see
what James Foley can do with the car chase in The Corruptor. This car chase
had me dizzy. I don't understand why directors haven't learned that the
"Shaky Camera" technique does not heighten the tension in an action scene,
but detriments it.

The one thing that saves The Corruptor is Chow Yun-Fat. And though Foley
does not use Chow's talents to their full potential, there is enough of
Chow in the film to make it a worthwhile screening. In every way Chow is
the epitome of coolness. Whether he has two guns in hand pumping 50 rounds
into a bad guy or just standing around talking to another cop: he is cool.
In The Replacement Killers, Chow was held back by his weak understanding of
English. In that film, his US premiere film, he was stoic and boring -- but
still cool. In The Corruptor, his English is much better -- by leaps and
bounds -- and he is freed to do what he does best: Act. In The Corruptor,
Chow is freed to show off his onscreen charm. His low-key humor shines
onscreen and that makes the film all the more better.

What drags down Chow is Wahlberg. Wahlberg tries to underplay his part,
playing his Wallace more like his character in Boogie Nights than a real
cop. The problem was that I never accepted Wahlberg as a cop. His
performance in The Corruptor was horrible. Wahlberg adds nothing to this
film except for some bare-chested scenes that are guaranteed to bring in
the female audience.

Director James Foley tries his best at putting together an action film, but
fails.  The action in The Corruptor lacks excitement and tension, it is
flat as can be. More often it's just a series of images flashed onscreen
with loud noises. Foley is able to keep the story moving, but unfortunately
he is unprepared for doing the action portion of the film.

I'm convinced that had two small changes been made to The Corruptor, it
would have come out a much better and more highly enjoyable film. The
changes would be the replacement of director James Foley with John Woo and
the recasting of Danny Wallace with a stronger actor than Mark Wahlberg. As
it stands, The Corruptor is still a Don't Miss film, but only because of
Chow Yun-Fat's presence in the film. See The Corruptor for Chow Yun-Fat.

---
 Steve Kong                                    reviews@boiled.sbay.org

 recipe for a hard boiled review:  one egg, two cups water, a pot,
 a helluva attitude, and a guy who loves the cinema.
 i'm your hard boiled movie guide.

 http://boiledmovies.sbay.com/

The review above was posted to the
rec.arts.movies.reviews newsgroup (de.rec.film.kritiken for German reviews).

The Internet Movie Database accepts no responsibility for the contents of the
review and has no editorial control. Unless stated otherwise, the copyright
belongs to the author.

Please direct comments/criticisms of the review to relevant newsgroups.

Broken URLs inthe reviews are the responsibility of the author.

The formatting of the review is likely to differ from the original due
to ASCII to HTML conversion.

Related links: index of all rec.arts.movies.reviews reviews