text:
package sbt
package inc

import java.io._
import sbt.{ CompileSetup, Relation }
import xsbti.api.{ Compilation, Source }
import xsbti.compile.{ MultipleOutput, SingleOutput }
import javax.xml.bind.DatatypeConverter

// Very simple timer for timing repeated code sections.
// TODO: Temporary. Remove once we've milked all available performance gains.
private[inc] object FormatTimer {
  private val timers = scala.collection.mutable.Map[String, Long]()
  private val printTimings = "true" == System.getProperty("sbt.analysis.debug.timing")

  def aggregate[T](key: String)(f: => T) = {
    val start = System.nanoTime()
    val ret = f
    val elapsed = System.nanoTime() - start
    timers.update(key, timers.getOrElseUpdate(key, 0) + elapsed)
    ret
  }

  def time[T](key: String)(f: => T) = {
    val ret = aggregate(key)(f)
    close(key)
    ret
  }

  def close(key: String): Unit = {
    if (printTimings) {
      println("[%s] %dms".format(key, timers.getOrElse(key, 0L) / 1000000))
    }
    timers.remove(key)
  }
}

class ReadException(s: String) extends Exception(s) {
  def this(expected: String, found: String) = this("Expected: %s. Found: %s.".format(expected, found))
}

class EOFException extends ReadException("Unexpected EOF.")

// A text-based serialization format for Analysis objects.
// This code has been tuned for high performance, and therefore has non-idiomatic areas.
// Please refrain from making changes that significantly degrade read/write performance on large analysis files.
object TextAnalysisFormat {
  // Some types are not required for external inspection/manipulation of the analysis file,
  // and are complex to serialize as text. So we serialize them as base64-encoded sbinary-serialized blobs.
  // TODO: This is a big performance hit. Figure out a more efficient way to serialize API objects?
  import sbinary.DefaultProtocol.{ immutableMapFormat, immutableSetFormat, StringFormat, tuple2Format }
  import AnalysisFormats._
  implicit val compilationF = xsbt.api.CompilationFormat

  def write(out: Writer, analysis: Analysis, setup: CompileSetup): Unit = {
    VersionF.write(out)
    // We start with writing compile setup which contains value of the `nameHashing`
    // flag that is needed to properly deserialize relations
    FormatTimer.time("write setup") { CompileSetupF.write(out, setup) }
    // Next we write relations because that's the part of greatest interest to external readers,
    // who can abort reading early once they're read them.
    FormatTimer.time("write relations") { RelationsF.write(out, analysis.relations) }
    FormatTimer.time("write stamps") { StampsF.write(out, analysis.stamps) }
    FormatTimer.time("write apis") { APIsF.write(out, analysis.apis) }
    FormatTimer.time("write sourceinfos") { SourceInfosF.write(out, analysis.infos) }
    FormatTimer.time("write compilations") { CompilationsF.write(out, analysis.compilations) }
    out.flush()
  }

  def read(in: BufferedReader): (Analysis, CompileSetup) = {
    VersionF.read(in)
    val setup = FormatTimer.time("read setup") { CompileSetupF.read(in) }
    val relations = FormatTimer.time("read relations") { RelationsF.read(in, setup.nameHashing) }
    val stamps = FormatTimer.time("read stamps") { StampsF.read(in) }
    val apis = FormatTimer.time("read apis") { APIsF.read(in) }
    val infos = FormatTimer.time("read sourceinfos") { SourceInfosF.read(in) }
    val compilations = FormatTimer.time("read compilations") { CompilationsF.read(in) }

    (Analysis.Empty.copy(stamps, apis, relations, infos, compilations), setup)
  }

  private[this] object VersionF {
    val currentVersion = "5"

    def write(out: Writer): Unit = {
      out.write("format version: %s\n".format(currentVersion))
    }

    private val versionPattern = """format version: (\w+)""".r
    def read(in: BufferedReader): Unit = {
      in.readLine() match {
        case versionPattern(version) => validateVersion(version)
        case s: String               => throw new ReadException("\"format version: <version>\"", s)
        case null                    => throw new EOFException
      }
    }

    def validateVersion(version: String): Unit = {
      // TODO: Support backwards compatibility?
      if (version != currentVersion) {
        throw new ReadException("File uses format version %s, but we are compatible with version %s only.".format(version, currentVersion))
      }
    }
  }

  private[this] object RelationsF {
    object Headers {
      val srcProd = "products"
      val binaryDep = "binary dependencies"
      val directSrcDep = "direct source dependencies"
      val directExternalDep = "direct external dependencies"
      val internalSrcDepPI = "public inherited source dependencies"
      val externalDepPI = "public inherited external dependencies"
      val classes = "class names"

      val memberRefInternalDep = "member reference internal dependencies"
      val memberRefExternalDep = "member reference external dependencies"
      val inheritanceInternalDep = "inheritance internal dependencies"
      val inheritanceExternalDep = "inheritance external dependencies"

      val usedNames = "used names"
    }

    def write(out: Writer, relations: Relations): Unit = {
      // This ordering is used to persist all values in order. Since all values will be
      // persisted using their string representation, it makes sense to sort them using
      // their string representation.
      val toStringOrd = new Ordering[Any] {
        def compare(a: Any, b: Any) = a.toString compare b.toString
      }
      def writeRelation[T](header: String, rel: Relation[File, T]): Unit = {
        writeHeader(out, header)
        writeSize(out, rel.size)
        // We sort for ease of debugging and for more efficient reconstruction when reading.
        // Note that we don't share code with writeMap. Each is implemented more efficiently
        // than the shared code would be, and the difference is measurable on large analyses.
        rel.forwardMap.toSeq.sortBy(_._1).foreach {
          case (k, vs) =>
            val kStr = k.toString
            vs.toSeq.sorted(toStringOrd) foreach { v =>
              out.write(kStr); out.write(" -> "); out.write(v.toString); out.write("\n")
            }
        }
      }

      relations.allRelations.foreach {
        case (header, rel) => writeRelation(header, rel)
      }
    }

    def read(in: BufferedReader, nameHashing: Boolean): Relations = {
      def readRelation[T](expectedHeader: String, s2t: String => T): Relation[File, T] = {
        val items = readPairs(in)(expectedHeader, new File(_), s2t).toIterator
        // Reconstruct the forward map. This is more efficient than Relation.empty ++ items.
        var forward: List[(File, Set[T])] = Nil
        var currentItem: (File, T) = null
        var currentFile: File = null
        var currentVals: List[T] = Nil
        def closeEntry(): Unit = {
          if (currentFile != null) forward = (currentFile, currentVals.toSet) :: forward
          currentFile = currentItem._1
          currentVals = currentItem._2 :: Nil
        }
        while (items.hasNext) {
          currentItem = items.next()
          if (currentItem._1 == currentFile) currentVals = currentItem._2 :: currentVals else closeEntry()
        }
        if (currentItem != null) closeEntry()
        Relation.reconstruct(forward.toMap)
      }

      val relations = Relations.existingRelations map { case (header, fun) => readRelation(header, fun) }

      Relations.construct(nameHashing, relations)
    }
  }

  private[this] object StampsF {
    object Headers {
      val products = "product stamps"
      val sources = "source stamps"
      val binaries = "binary stamps"
      val classNames = "class names"
    }

    def write(out: Writer, stamps: Stamps): Unit = {
      def doWriteMap[V](header: String, m: Map[File, V]) = writeMap(out)(header, m, { v: V => v.toString })

      doWriteMap(Headers.products, stamps.products)
      doWriteMap(Headers.sources, stamps.sources)
      doWriteMap(Headers.binaries, stamps.binaries)
      doWriteMap(Headers.classNames, stamps.classNames)
    }

    def read(in: BufferedReader): Stamps = {
      def doReadMap[V](expectedHeader: String, s2v: String => V) = readMap(in)(expectedHeader, new File(_), s2v)
      val products = doReadMap(Headers.products, Stamp.fromString)
      val sources = doReadMap(Headers.sources, Stamp.fromString)
      val binaries = doReadMap(Headers.binaries, Stamp.fromString)
      val classNames = doReadMap(Headers.classNames, identity[String])

      Stamps(products, sources, binaries, classNames)
    }
  }

  private[this] object APIsF {
    object Headers {
      val internal = "internal apis"
      val external = "external apis"
    }

    val stringToSource = ObjectStringifier.stringToObj[Source] _
    val sourceToString = ObjectStringifier.objToString[Source] _

    def write(out: Writer, apis: APIs): Unit = {
      writeMap(out)(Headers.internal, apis.internal, sourceToString, inlineVals = false)
      writeMap(out)(Headers.external, apis.external, sourceToString, inlineVals = false)
      FormatTimer.close("bytes -> base64")
      FormatTimer.close("byte copy")
      FormatTimer.close("sbinary write")
    }

    def read(in: BufferedReader): APIs = {
      val internal = readMap(in)(Headers.internal, new File(_), stringToSource)
      val external = readMap(in)(Headers.external, identity[String], stringToSource)
      FormatTimer.close("base64 -> bytes")
      FormatTimer.close("sbinary read")
      APIs(internal, external)
    }
  }

  private[this] object SourceInfosF {
    object Headers {
      val infos = "source infos"
    }

    val stringToSourceInfo = ObjectStringifier.stringToObj[SourceInfo] _
    val sourceInfoToString = ObjectStringifier.objToString[SourceInfo] _

    def write(out: Writer, infos: SourceInfos): Unit = writeMap(out)(Headers.infos, infos.allInfos, sourceInfoToString, inlineVals = false)
    def read(in: BufferedReader): SourceInfos = SourceInfos.make(readMap(in)(Headers.infos, new File(_), stringToSourceInfo))
  }

  private[this] object CompilationsF {
    object Headers {
      val compilations = "compilations"
    }

    val stringToCompilation = ObjectStringifier.stringToObj[Compilation] _
    val compilationToString = ObjectStringifier.objToString[Compilation] _

    def write(out: Writer, compilations: Compilations): Unit =
      writeSeq(out)(Headers.compilations, compilations.allCompilations, compilationToString)

    def read(in: BufferedReader): Compilations = Compilations.make(
      readSeq[Compilation](in)(Headers.compilations, stringToCompilation))
  }

  private[this] object CompileSetupF {
    object Headers {
      val outputMode = "output mode"
      val outputDir = "output directories"
      val compileOptions = "compile options"
      val javacOptions = "javac options"
      val compilerVersion = "compiler version"
      val compileOrder = "compile order"
      val nameHashing = "name hashing"
    }

    private[this] val singleOutputMode = "single"
    private[this] val multipleOutputMode = "multiple"
    private[this] val singleOutputKey = new File("output dir")

    def write(out: Writer, setup: CompileSetup): Unit = {
      val (mode, outputAsMap) = setup.output match {
        case s: SingleOutput   => (singleOutputMode, Map(singleOutputKey -> s.outputDirectory))
        case m: MultipleOutput => (multipleOutputMode, m.outputGroups.map(x => x.sourceDirectory -> x.outputDirectory).toMap)
      }

      writeSeq(out)(Headers.outputMode, mode :: Nil, identity[String])
      writeMap(out)(Headers.outputDir, outputAsMap, { f: File => f.getPath })
      writeSeq(out)(Headers.compileOptions, setup.options.options, identity[String])
      writeSeq(out)(Headers.javacOptions, setup.options.javacOptions, identity[String])
      writeSeq(out)(Headers.compilerVersion, setup.compilerVersion :: Nil, identity[String])
      writeSeq(out)(Headers.compileOrder, setup.order.name :: Nil, identity[String])
      writeSeq(out)(Headers.nameHashing, setup.nameHashing :: Nil, (b: Boolean) => b.toString)
    }

    def read(in: BufferedReader): CompileSetup = {
      def s2f(s: String) = new File(s)
      def s2b(s: String): Boolean = s.toBoolean
      val outputDirMode = readSeq(in)(Headers.outputMode, identity[String]).headOption
      val outputAsMap = readMap(in)(Headers.outputDir, s2f, s2f)
      val compileOptions = readSeq(in)(Headers.compileOptions, identity[String])
      val javacOptions = readSeq(in)(Headers.javacOptions, identity[String])
      val compilerVersion = readSeq(in)(Headers.compilerVersion, identity[String]).head
      val compileOrder = readSeq(in)(Headers.compileOrder, identity[String]).head
      val nameHashing = readSeq(in)(Headers.nameHashing, s2b).head

      val output = outputDirMode match {
        case Some(s) => s match {
          case `singleOutputMode` => new SingleOutput {
            val outputDirectory = outputAsMap(singleOutputKey)
          }
          case `multipleOutputMode` => new MultipleOutput {
            val outputGroups: Array[MultipleOutput.OutputGroup] = outputAsMap.toArray.map {
              case (src: File, out: File) => new MultipleOutput.OutputGroup {
                val sourceDirectory = src
                val outputDirectory = out
                override def toString = s"OutputGroup($src -> $out)"
              }
            }
            override def toString = s"MultipleOuput($outputGroups)"
          }
          case str: String => throw new ReadException("Unrecognized output mode: " + str)
        }
        case None => throw new ReadException("No output mode specified")
      }

      new CompileSetup(output, new CompileOptions(compileOptions, javacOptions), compilerVersion,
        xsbti.compile.CompileOrder.valueOf(compileOrder), nameHashing)
    }
  }

  private[this] object ObjectStringifier {
    def objToString[T](o: T)(implicit fmt: sbinary.Format[T]) = {
      val baos = new ByteArrayOutputStream()
      val out = new sbinary.JavaOutput(baos)
      FormatTimer.aggregate("sbinary write") { try { fmt.writes(out, o) } finally { baos.close() } }
      val bytes = FormatTimer.aggregate("byte copy") { baos.toByteArray }
      FormatTimer.aggregate("bytes -> base64") { DatatypeConverter.printBase64Binary(bytes) }
    }

    def stringToObj[T](s: String)(implicit fmt: sbinary.Format[T]) = {
      val bytes = FormatTimer.aggregate("base64 -> bytes") { DatatypeConverter.parseBase64Binary(s) }
      val in = new sbinary.JavaInput(new ByteArrayInputStream(bytes))
      FormatTimer.aggregate("sbinary read") { fmt.reads(in) }
    }
  }

  // Various helper functions.

  private[this] def writeHeader(out: Writer, header: String): Unit = out.write(header + ":\n")

  private[this] def expectHeader(in: BufferedReader, expectedHeader: String): Unit = {
    val header = in.readLine()
    if (header != expectedHeader + ":") throw new ReadException(expectedHeader, if (header == null) "EOF" else header)
  }

  private[this] def writeSize(out: Writer, n: Int): Unit = out.write("%d items\n".format(n))

  private val itemsPattern = """(\d+) items""".r
  private[this] def readSize(in: BufferedReader): Int = {
    in.readLine() match {
      case itemsPattern(nStr) => Integer.parseInt(nStr)
      case s: String          => throw new ReadException("\"<n> items\"", s)
      case null               => throw new EOFException
    }
  }

  private[this] def writeSeq[T](out: Writer)(header: String, s: Seq[T], t2s: T => String): Unit = {
    // We write sequences as idx -> element maps, for uniformity with maps/relations.
    def n = s.length
    val numDigits = if (n < 2) 1 else math.log10(n - 1).toInt + 1
    val fmtStr = "%%0%dd".format(numDigits)
    // We only use this for relatively short seqs, so creating this extra map won't be a performance hit.
    val m: Map[String, T] = s.zipWithIndex.map(x => fmtStr.format(x._2) -> x._1).toMap
    writeMap(out)(header, m, t2s)
  }

  private[this] def readSeq[T](in: BufferedReader)(expectedHeader: String, s2t: String => T): Seq[T] =
    (readPairs(in)(expectedHeader, identity[String], s2t).toSeq.sortBy(_._1) map (_._2))

  private[this] def writeMap[K, V](out: Writer)(header: String, m: Map[K, V], v2s: V => String, inlineVals: Boolean = true)(implicit ord: Ordering[K]): Unit = {
    writeHeader(out, header)
    writeSize(out, m.size)
    m.keys.toSeq.sorted foreach { k =>
      out.write(k.toString)
      out.write(" -> ")
      if (!inlineVals) out.write("\n") // Put large vals on their own line, to save string munging on read.
      out.write(v2s(m(k)))
      out.write("\n")
    }
  }

  private[this] def readPairs[K, V](in: BufferedReader)(expectedHeader: String, s2k: String => K, s2v: String => V): Traversable[(K, V)] = {
    def toPair(s: String): (K, V) = {
      if (s == null) throw new EOFException
      val p = s.indexOf(" -> ")
      val k = s2k(s.substring(0, p))
      // Pair is either "a -> b" or "a -> \nb". This saves us a lot of substring munging when b is a large blob.
      val v = s2v(if (p == s.length - 4) in.readLine() else s.substring(p + 4))
      (k, v)
    }
    expectHeader(in, expectedHeader)
    val n = readSize(in)
    for (i <- 0 until n) yield toPair(in.readLine())
  }

  private[this] def readMap[K, V](in: BufferedReader)(expectedHeader: String, s2k: String => K, s2v: String => V): Map[K, V] = {
    readPairs(in)(expectedHeader, s2k, s2v).toMap
  }
}


text:
package com.hazelcast.multimap;

import com.hazelcast.config.Config;
import com.hazelcast.config.MergePolicyConfig;
import com.hazelcast.config.MultiMapConfig;
import com.hazelcast.core.EntryEvent;
import com.hazelcast.core.EntryListener;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.core.MapEvent;
import com.hazelcast.core.MultiMap;
import com.hazelcast.spi.merge.DiscardMergePolicy;
import com.hazelcast.spi.merge.HigherHitsMergePolicy;
import com.hazelcast.spi.merge.LatestAccessMergePolicy;
import com.hazelcast.spi.merge.LatestUpdateMergePolicy;
import com.hazelcast.spi.merge.PassThroughMergePolicy;
import com.hazelcast.spi.merge.PutIfAbsentMergePolicy;
import com.hazelcast.spi.merge.SplitBrainMergePolicy;
import com.hazelcast.test.HazelcastParallelParametersRunnerFactory;
import com.hazelcast.test.SplitBrainTestSupport;
import com.hazelcast.test.annotation.ParallelTest;
import com.hazelcast.test.annotation.QuickTest;
import org.junit.experimental.categories.Category;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;
import org.junit.runners.Parameterized.UseParametersRunnerFactory;

import java.util.Collection;
import java.util.Map;

import static com.hazelcast.multimap.MultiMapTestUtil.getBackupMultiMap;
import static java.util.Arrays.asList;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;

/**
 * Tests different split-brain scenarios for {@link MultiMap}.
 *

 * Most merge policies are tested with {@link MultiMapConfig#isBinary()} as {@code true} only, since they don't check the value.
 *

 * The {@link MergeCollectionOfIntegerValuesMergePolicy} is tested with both in-memory formats,
 * since it's using the value to merge.
 *

 * The {@link DiscardMergePolicy}, {@link PassThroughMergePolicy} and {@link PutIfAbsentMergePolicy} are also
 * tested with a data structure, which is only created in the smaller cluster.
 */
@RunWith(Parameterized.class)
@UseParametersRunnerFactory(HazelcastParallelParametersRunnerFactory.class)
@Category({QuickTest.class, ParallelTest.class})
public class MultiMapSplitBrainTest extends SplitBrainTestSupport {

    @Parameters(name = "mergePolicy:{0}, isBinary:{1}")
    public static Collection<Object[]> parameters() {
        return asList(new Object[][]{
                {DiscardMergePolicy.class, true},
                {DiscardMergePolicy.class, false},
                {HigherHitsMergePolicy.class, true},
                {HigherHitsMergePolicy.class, false},
                {LatestAccessMergePolicy.class, true},
                {LatestAccessMergePolicy.class, false},
                {LatestUpdateMergePolicy.class, true},
                {LatestUpdateMergePolicy.class, false},
                {PassThroughMergePolicy.class, true},
                {PassThroughMergePolicy.class, false},
                {PutIfAbsentMergePolicy.class, true},
                {PutIfAbsentMergePolicy.class, false},
                {RemoveValuesMergePolicy.class, true},
                {RemoveValuesMergePolicy.class, false},
                {ReturnPiCollectionMergePolicy.class, true},
                {ReturnPiCollectionMergePolicy.class, false},
                {MergeCollectionOfIntegerValuesMergePolicy.class, true},
                {MergeCollectionOfIntegerValuesMergePolicy.class, false},
        });
    }

    @Parameter
    public Class<? extends SplitBrainMergePolicy> mergePolicyClass;

    @Parameter(value = 1)
    public boolean isBinary;

    private String multiMapNameA = randomMapName("multiMapA-");
    private String multiMapNameB = randomMapName("multiMapB-");
    private MultiMap<Object, Object> multiMapA1;
    private MultiMap<Object, Object> multiMapA2;
    private MultiMap<Object, Object> multiMapB1;
    private MultiMap<Object, Object> multiMapB2;
    private Map<Object, Collection<Object>> backupMultiMapA;
    private Map<Object, Collection<Object>> backupMultiMapB;
    private MergeLifecycleListener mergeLifecycleListener;

    @Override
    protected Config config() {
        MergePolicyConfig mergePolicyConfig = new MergePolicyConfig()
                .setPolicy(mergePolicyClass.getName())
                .setBatchSize(10);

        Config config = super.config();
        config.getMultiMapConfig(multiMapNameA)
                .setBinary(isBinary)
                .setMergePolicyConfig(mergePolicyConfig)
                .setStatisticsEnabled(true)
                .setBackupCount(1)
                .setAsyncBackupCount(0);
        config.getMultiMapConfig(multiMapNameB)
                .setBinary(isBinary)
                .setMergePolicyConfig(mergePolicyConfig)
                .setStatisticsEnabled(true)
                .setBackupCount(1)
                .setAsyncBackupCount(0);
        return config;
    }

    @Override
    protected void onAfterSplitBrainCreated(HazelcastInstance[] firstBrain, HazelcastInstance[] secondBrain) {
        mergeLifecycleListener = new MergeLifecycleListener(secondBrain.length);
        for (HazelcastInstance instance : secondBrain) {
            instance.getLifecycleService().addLifecycleListener(mergeLifecycleListener);
        }

        multiMapA1 = firstBrain[0].getMultiMap(multiMapNameA);
        multiMapA2 = secondBrain[0].getMultiMap(multiMapNameA);
        multiMapB2 = secondBrain[0].getMultiMap(multiMapNameB);

        EntryListener<Object, Object> listener = new EmptyEntryListener<Object, Object>();
        multiMapA1.addEntryListener(listener, true);
        multiMapA2.addEntryListener(listener, true);
        multiMapB2.addEntryListener(listener, true);

        if (mergePolicyClass == DiscardMergePolicy.class) {
            afterSplitDiscardMergePolicy();
        } else if (mergePolicyClass == HigherHitsMergePolicy.class) {
            afterSplitHigherHitsMergePolicy();
        } else if (mergePolicyClass == LatestAccessMergePolicy.class) {
            afterSplitLatestAccessMergePolicy();
        } else if (mergePolicyClass == LatestUpdateMergePolicy.class) {
            afterSplitLatestUpdateMergePolicy();
        } else if (mergePolicyClass == PassThroughMergePolicy.class) {
            afterSplitPassThroughMergePolicy();
        } else if (mergePolicyClass == PutIfAbsentMergePolicy.class) {
            afterSplitPutIfAbsentMergePolicy();
        } else if (mergePolicyClass == RemoveValuesMergePolicy.class) {
            afterSplitRemoveValuesMergePolicy();
        } else if (mergePolicyClass == ReturnPiCollectionMergePolicy.class) {
            afterSplitReturnPiCollectionMergePolicy();
        } else if (mergePolicyClass == MergeCollectionOfIntegerValuesMergePolicy.class) {
            afterSplitCustomMergePolicy();
        } else {
            fail();
        }
    }

    @Override
    protected void onAfterSplitBrainHealed(HazelcastInstance[] instances) {
        // wait until merge completes
        mergeLifecycleListener.await();

        multiMapB1 = instances[0].getMultiMap(multiMapNameB);

        backupMultiMapA = getBackupMultiMap(instances, multiMapNameA);
        backupMultiMapB = getBackupMultiMap(instances, multiMapNameB);

        if (mergePolicyClass == DiscardMergePolicy.class) {
            afterMergeDiscardMergePolicy();
        } else if (mergePolicyClass == HigherHitsMergePolicy.class) {
            afterMergeHigherHitsMergePolicy();
        } else if (mergePolicyClass == LatestAccessMergePolicy.class) {
            afterMergeLatestAccessMergePolicy();
        } else if (mergePolicyClass == LatestUpdateMergePolicy.class) {
            afterMergeLatestUpdateMergePolicy();
        } else if (mergePolicyClass == PassThroughMergePolicy.class) {
            afterMergePassThroughMergePolicy();
        } else if (mergePolicyClass == PutIfAbsentMergePolicy.class) {
            afterMergePutIfAbsentMergePolicy();
        } else if (mergePolicyClass == RemoveValuesMergePolicy.class) {
            afterMergeRemoveValuesMergePolicy();
        } else if (mergePolicyClass == ReturnPiCollectionMergePolicy.class) {
            afterMergeReturnPiCollectionMergePolicy();
        } else if (mergePolicyClass == MergeCollectionOfIntegerValuesMergePolicy.class) {
            afterMergeCustomMergePolicy();
        } else {
            fail();
        }
    }

    private void afterSplitDiscardMergePolicy() {
        multiMapA1.put("key1", "value1");
        multiMapA1.put("key1", "value2");

        multiMapA2.put("key1", "DiscardedValue1a");
        multiMapA2.put("key1", "DiscardedValue1b");
        multiMapA2.put("key2", "DiscardedValue2a");
        multiMapA2.put("key2", "DiscardedValue2b");

        multiMapB2.put("key", "DiscardedValue1");
        multiMapB2.put("key", "DiscardedValue2");
    }

    private void afterMergeDiscardMergePolicy() {
        assertMultiMapsA("key1", "value1", "value2");
        assertMultiMapsA("key2");
        assertMultiMapsSizeA(2);

        assertMultiMapsB("key");
        assertMultiMapsSizeB(0);
    }

    /**
     * The hits are measured per MultiMapValue, so we can test it with multiple keys on the same map.
     */
    private void afterSplitHigherHitsMergePolicy() {
        multiMapA1.put("key1", "higherHitsValue1");
        multiMapA1.put("key2", "value2");

        // increase hits number
        multiMapA1.get("key1");
        multiMapA1.get("key1");

        multiMapA2.put("key1", "value1");
        multiMapA2.put("key2", "higherHitsValue2");

        // increase hits number
        multiMapA2.get("key2");
        multiMapA2.get("key2");
    }

    private void afterMergeHigherHitsMergePolicy() {
        assertMultiMapsA("key1", "higherHitsValue1");
        assertMultiMapsA("key2", "higherHitsValue2");
        assertMultiMapsSizeA(2);
    }

    /**
     * The lastAccessTime is measured per MultiMapContainer, so we cannot test it with multiple keys on the same map.
     */
    private void afterSplitLatestAccessMergePolicy() {
        multiMapA1.put("key", "value");

        // prevent updating at the same time
        sleepAtLeastMillis(100);

        multiMapA2.put("key", "LatestAccessedValue");

        multiMapB2.put("key", "LatestAccessedValue");
    }

    private void afterMergeLatestAccessMergePolicy() {
        assertMultiMapsA("key", "LatestAccessedValue");
        assertMultiMapsSizeA(1);

        assertMultiMapsB("key", "LatestAccessedValue");
        assertMultiMapsSizeB(1);
    }

    /**
     * The lastUpdateTime is measured per MultiMapContainer, so we cannot test it with multiple keys on the same map.
     */
    private void afterSplitLatestUpdateMergePolicy() {
        multiMapA1.put("key", "value");

        // prevent updating at the same time
        sleepAtLeastMillis(100);

        multiMapA2.put("key", "LatestUpdatedValue");
        multiMapB2.put("key", "LatestUpdatedValue");
    }

    private void afterMergeLatestUpdateMergePolicy() {
        assertMultiMapsA("key", "LatestUpdatedValue");
        assertMultiMapsSizeA(1);

        assertMultiMapsB("key", "LatestUpdatedValue");
        assertMultiMapsSizeB(1);
    }

    private void afterSplitPassThroughMergePolicy() {
        multiMapA1.lock("lockedKey");
        multiMapA1.put("lockedKey", "lockedValue");
        multiMapA1.put("key1", "value1");
        multiMapA1.put("key1", "value2");

        multiMapA2.put("lockedKey", "PassThroughValue");
        multiMapA2.put("key1", "PassThroughValue1a");
        multiMapA2.put("key1", "PassThroughValue1b");
        multiMapA2.put("key2", "PassThroughValue2a");
        multiMapA2.put("key2", "PassThroughValue2b");

        multiMapB2.put("key", "PassThroughValue");
    }

    private void afterMergePassThroughMergePolicy() {
        assertTrue("Expected lockedKey to be locked", multiMapA1.isLocked("lockedKey"));
        multiMapA1.unlock("lockedKey");
        assertFalse("Expected lockedKey to be unlocked", multiMapA1.isLocked("lockedKey"));

        assertMultiMapsA("lockedKey", "lockedValue");
        assertMultiMapsA("key1", "PassThroughValue1a", "PassThroughValue1b");
        assertMultiMapsA("key2", "PassThroughValue2a", "PassThroughValue2b");
        assertMultiMapsSizeA(5);

        assertMultiMapsB("key", "PassThroughValue");
        assertMultiMapsSizeB(1);
    }

    private void afterSplitPutIfAbsentMergePolicy() {
        multiMapA1.put("key1", "PutIfAbsentValue1a");
        multiMapA1.put("key1", "PutIfAbsentValue1b");

        multiMapA2.put("key1", "value");
        multiMapA2.put("key2", "PutIfAbsentValue2a");
        multiMapA2.put("key2", "PutIfAbsentValue2b");

        multiMapB2.put("key", "PutIfAbsentValue");
    }

    private void afterMergePutIfAbsentMergePolicy() {
        assertMultiMapsA("key1", "PutIfAbsentValue1a", "PutIfAbsentValue1b");
        assertMultiMapsA("key2", "PutIfAbsentValue2a", "PutIfAbsentValue2b");
        assertMultiMapsSizeA(4);

        assertMultiMapsB("key", "PutIfAbsentValue");
        assertMultiMapsSizeB(1);
    }

    private void afterSplitRemoveValuesMergePolicy() {
        multiMapA1.put("key1", "discardedValue1a");
        multiMapA1.put("key1", "discardedValue1b");

        multiMapA2.put("key1", "discardedValue2");
        multiMapA2.put("key2", "discardedValue2a");
        multiMapA2.put("key2", "discardedValue2b");

        multiMapB2.put("key", "discardedValue");
    }

    private void afterMergeRemoveValuesMergePolicy() {
        assertMultiMapsA("key1");
        assertMultiMapsA("key2");
        assertMultiMapsSizeA(0);

        assertMultiMapsB("key");
        assertMultiMapsSizeB(0);
    }

    private void afterSplitReturnPiCollectionMergePolicy() {
        multiMapA1.put("key1", "discardedValue1a");
        multiMapA1.put("key1", "discardedValue1b");

        multiMapA2.put("key1", "discardedValue2");
        multiMapA2.put("key2", "discardedValue2a");
        multiMapA2.put("key2", "discardedValue2b");

        multiMapB2.put("key", "discardedValue");
    }

    private void afterMergeReturnPiCollectionMergePolicy() {
        assertEqualsStringFormat("Expected backupMultiMapA to have %s keys, but was %s [" + backupMultiMapA + " ]",
                2, backupMultiMapA.keySet().size());

        assertPiSet(multiMapA1.get("key1"));
        assertPiSet(multiMapA2.get("key1"));
        assertPiSet(backupMultiMapA.get("key1"));

        assertPiSet(multiMapA1.get("key2"));
        assertPiSet(multiMapA2.get("key2"));
        assertPiSet(backupMultiMapA.get("key2"));

        assertPiSet(multiMapB1.get("key"));
        assertPiSet(multiMapB2.get("key"));
    }

    private void afterSplitCustomMergePolicy() {
        // for key1 just the Integer values survive
        multiMapA1.put("key1", "value1");
        multiMapA1.put("key1", 23);
        multiMapA2.put("key1", "value2");
        multiMapA2.put("key1", 42);

        // key2 is completely removed
        multiMapA1.put("key2", "value1");
        multiMapA2.put("key2", "value2");

        // key3 survives, since there is no mergingValue for it
        multiMapA1.put("key3", "value");

        multiMapB2.put("key1", 42);
        multiMapB2.put("key2", "value");
    }

    private void afterMergeCustomMergePolicy() {
        assertMultiMapsA("key1", 23, 42);
        assertMultiMapsA("key2");
        assertMultiMapsA("key3", "value");
        assertMultiMapsSizeA(3);

        assertMultiMapsB("key1", 42);
        assertMultiMapsB("key2");
        assertMultiMapsSizeB(1);
    }

    private void assertMultiMapsA(String key, Object... expectedValues) {
        assertMultiMaps(multiMapA1, multiMapA2, backupMultiMapA, key, expectedValues);
    }

    private void assertMultiMapsB(String key, Object... expectedValues) {
        assertMultiMaps(multiMapB1, multiMapB2, backupMultiMapB, key, expectedValues);
    }

    private static void assertMultiMaps(MultiMap<Object, Object> multiMap1, MultiMap<Object, Object> multiMap2,
                                        Map<Object, Collection<Object>> backupMultiMap, String key, Object... expectedValues) {
        Collection<Object> collection1 = multiMap1.get(key);
        Collection<Object> collection2 = multiMap2.get(key);
        Collection<Object> backupCollection = backupMultiMap.get(key);
        int expectedSize = expectedValues.length;
        if (expectedSize > 0) {
            assertEqualsStringFormat("multiMap1.valueCount() should be %s, but was %s", expectedSize, multiMap1.valueCount(key));
            assertEqualsStringFormat("multiMap2.valueCount() should be %s, but was %s", expectedSize, multiMap2.valueCount(key));

            assertNotNull("backupMultiMap should not be null for " + key + " [" + backupMultiMap + "]", backupCollection);
            assertEqualsStringFormat("backupCollection.size() should be %s, but was %s", expectedSize, backupCollection.size());

            Collection<Object> expected = asList(expectedValues);
            assertContainsAll(collection1, expected);
            assertContainsAll(collection2, expected);
            assertContainsAll(backupCollection, expected);
        } else {
            assertEqualsStringFormat("multiMap1.valueCount() should be %s, but was %s", 0, multiMap1.valueCount(key));
            assertEqualsStringFormat("multiMap2.valueCount() should be %s, but was %s", 0, multiMap2.valueCount(key));

            assertNull("backupMultiMap should be null for " + key + ", but was " + backupCollection, backupCollection);

            assertTrue("multiMap1 should be empty for " + key + ", but was " + collection1, collection1.isEmpty());
            assertTrue("multiMap2 should be empty for " + key + ", but was " + collection2, collection2.isEmpty());
        }
    }

    private void assertMultiMapsSizeA(int expectedSize) {
        assertMultiMapsSize(multiMapA1, multiMapA2, backupMultiMapA, expectedSize);
    }

    private void assertMultiMapsSizeB(int expectedSize) {
        assertMultiMapsSize(multiMapB1, multiMapB2, backupMultiMapB, expectedSize);
    }

    private static void assertMultiMapsSize(MultiMap<?, ?> multiMap1, MultiMap<?, ?> multiMap2,
                                            Map<?, ? extends Collection<?>> backupMultiMap, int expectedSize) {
        assertEqualsStringFormat("multiMap1 should have size %d, but was %d", expectedSize, multiMap1.size());
        assertEqualsStringFormat("multiMap2 should have size %d, but was %d", expectedSize, multiMap2.size());
        int actualBackupSize = 0;
        for (Collection<?> values : backupMultiMap.values()) {
            actualBackupSize += values.size();
        }
        assertEqualsStringFormat("backupMultiMap should have size %d, but was %d", expectedSize, actualBackupSize);
    }

    private static class EmptyEntryListener<K, V> implements EntryListener<K, V> {
        @Override
        public void mapEvicted(MapEvent event) {

        }

        @Override
        public void mapCleared(MapEvent event) {

        }

        @Override
        public void entryUpdated(EntryEvent<K, V> event) {

        }

        @Override
        public void entryRemoved(EntryEvent<K, V> event) {

        }

        @Override
        public void entryEvicted(EntryEvent<K, V> event) {

        }

        @Override
        public void entryAdded(EntryEvent<K, V> event) {

        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
#pragma once

#ifndef __REVERSE_WORD_PAIRS_ATTEMPTS_ATTEMPT_1_H
#define __REVERSE_WORD_PAIRS_ATTEMPTS_ATTEMPT_1_H

#include "../attempt.h"
namespace rwp {
    class CAttempt01 final : public IAttempt {
    public:
        CAttempt01();
        ~CAttempt01();

        virtual std::string GetName() const;
        virtual void Run( const std::string &filename, sAttemptResult &result );
    };
}
#endif


text:
package org.kuali.mobility.academics.controllers;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.kuali.mobility.academics.entity.*;
import org.kuali.mobility.academics.service.AcademicsService;
import org.kuali.mobility.academics.util.AcademicsConstants;
import org.kuali.mobility.academics.util.CareerPredicate;
import org.kuali.mobility.academics.util.CatalogNumberPredicate;
import org.kuali.mobility.academics.util.SubjectPredicate;
import org.springframework.context.MessageSource;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.LocaleResolver;

import javax.annotation.Resource;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.*;

@Controller
@RequestMapping("/academics")
public class AcademicsControllerImpl {

	private static final Logger LOG = LoggerFactory.getLogger(AcademicsControllerImpl.class);
	@Resource(name = "academicsService")
	private AcademicsService service;

	@Resource(name = "academicsProperties")
	private Properties academicsProperties;

	@Resource(name = "kmeProperties")
	private Properties kmeProperties;

	/**
	 * A reference to the locale resolver
	 */
	@Resource(name = "localeResolver")
	private LocaleResolver localeResolver;

	@Resource(name = "messageSource")
	private MessageSource messageSource;

	@RequestMapping(method = RequestMethod.GET)
	public String index(HttpServletRequest request, Model uiModel) {
		HttpSession session = request.getSession();
		session.removeAttribute("currentTerm");
		session.removeAttribute("currentCareer");
		session.removeAttribute("currentSection");
		session.removeAttribute("currentCatalogNumber");
		session.removeAttribute("sectionsAll");
		session.removeAttribute(AcademicsConstants.TERM_ID);
		session.removeAttribute(AcademicsConstants.TERM);
		session.removeAttribute(AcademicsConstants.CAREER_ID);
		session.removeAttribute(AcademicsConstants.CAREER);
		session.removeAttribute(AcademicsConstants.SUBJECT_ID);
		session.removeAttribute(AcademicsConstants.SUBJECT);
		session.removeAttribute(AcademicsConstants.CATALOG_NUMBER);
		session.removeAttribute(AcademicsConstants.CATALOG_DESCRIPTION);
		session.removeAttribute(AcademicsConstants.CLASS_NUMBER);
		session.removeAttribute(AcademicsConstants.CLASS_SECTION);
		session.removeAttribute(AcademicsConstants.COURSE_ID);
		session.removeAttribute(AcademicsConstants.COURSE_OFFER_NBR);
		session.removeAttribute(AcademicsConstants.SECTIONS);
		session.removeAttribute(AcademicsConstants.TERM_DESCRIPTION);

		uiModel.addAttribute(AcademicsConstants.HOME_SCREEN_TOOLS, this.getHomeScreenOrder());

		Cookie cks[] = request.getCookies();
		if (cks != null) {
			for (Cookie c : cks) {
				//LOG.info("---Cookies: " + c.getName() + " " + c.getValue());
				if (c.getName().equals("platform")) {
					uiModel.addAttribute("platform", c.getValue());
				} else if (session.getAttribute("session_platform") != null) {
					uiModel.addAttribute("platform", (String) session.getAttribute("session_platform"));
				} else {
					uiModel.addAttribute("platform", "none");
				}
			}
		}
		if ("3".equalsIgnoreCase(getKmeProperties().getProperty("kme.uiVersion", "classic"))) {
			return "ui3/academics/index";
		} else {
			return "academics/index";
		}
	}

	@RequestMapping(value = "/terms")
	public String getTerms(HttpServletRequest request, Model uiModel) {
		String viewName = null;
		if ("3".equalsIgnoreCase(getKmeProperties().getProperty("kme.uiVersion", "classic"))) {
			viewName = "ui3/academics/scheduleOfClasses";
		} else {
			HttpSession session = request.getSession();

			session.setAttribute(AcademicsConstants.TERM, getService().getTerms());

			//uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, request.getContextPath() + "/academics/");
			viewName = "academics/terms";
		}
		return viewName;
	}

	@RequestMapping(value = "/careers")
	public String getCareers(HttpServletRequest request, Model uiModel,
							 @RequestParam(required = true) final String termId) {
		HttpSession session = request.getSession();
		if (termId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.TERM_ID))) {
			// use cached data
			uiModel.addAttribute(AcademicsConstants.TITLE, ((Term) session.getAttribute("currentTerm")).getDescription());
		} else {
			Term term = getService().getTerm(termId);
			session.setAttribute(AcademicsConstants.TERM_ID, termId);
			session.setAttribute("currentTerm", term);
			List<? extends Career> lCareers = getService().getCareers(termId);
			session.setAttribute(AcademicsConstants.CAREER, lCareers);
			session.setAttribute("watermark", getLocalisedString(request, "academics.searchClasses", term.getDescription()));
			uiModel.addAttribute(AcademicsConstants.TITLE, ((Term) session.getAttribute("currentTerm")).getDescription());
		}

		//uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, request.getContextPath() + "/academics/terms");
		return "academics/careers";
	}

	@RequestMapping(value = "/subjects")
	public String getCareers(HttpServletRequest request, Model uiModel,
							 @RequestParam(required = true) final String termId,
							 @RequestParam(required = true) final String careerId) {
		HttpSession session = request.getSession();
		if (termId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.TERM_ID))
				&& careerId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.CAREER_ID))) {
			// Use cached data.
//			uiModel.addAttribute(AcademicsConstants.TITLE, ((Career)session.getAttribute("currentCareer")).getShortDescription());
			uiModel.addAttribute(AcademicsConstants.TITLE, "Subjects");
		} else {
			Term term = getService().getTerm(termId);
			session.setAttribute(AcademicsConstants.TERM_ID, term.getId());
			session.setAttribute("currentTerm", term);

			session.setAttribute(AcademicsConstants.CAREER_ID, careerId);
			Career career = (Career) CollectionUtils.find((List<Career>) session.getAttribute(AcademicsConstants.CAREER), new CareerPredicate(careerId));
			session.setAttribute("currentCareer", career);

			List<? extends Subject> lSubjects = getService().getSubjects(termId, careerId);
			session.setAttribute(AcademicsConstants.SUBJECT, lSubjects);
//			uiModel.addAttribute(AcademicsConstants.TITLE, ((Career)session.getAttribute("currentCareer")).getShortDescription());
			uiModel.addAttribute(AcademicsConstants.TITLE, "Subjects");
		}
		//uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, request.getContextPath() + "/academics/careers?termId=" + session.getAttribute(AcademicsConstants.TERM_ID));
		return "academics/subjects";
	}

	@RequestMapping(value = "/catalogNumbers")
	public String getCareers(HttpServletRequest request, Model uiModel,
							 @RequestParam(required = true)
							 final String termId,
							 @RequestParam(required = true)
							 final String careerId,
							 @RequestParam(required = true)
							 final String subjectId) {
		HttpSession session = request.getSession();
		if (termId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.TERM_ID))
				&& careerId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.CAREER_ID))
				&& subjectId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.SUBJECT_ID))) {
			// Use cached data.
			uiModel.addAttribute(AcademicsConstants.TITLE, ((Subject) session.getAttribute("currentSubject")).getDescription());
		} else {
			Term term = getService().getTerm(termId);
			session.setAttribute(AcademicsConstants.TERM_ID, term.getId());
			session.setAttribute("currentTerm", term);
			session.setAttribute(AcademicsConstants.CAREER_ID, careerId);
			Career career = (Career) CollectionUtils.find((List<Career>) session.getAttribute(AcademicsConstants.CAREER), new CareerPredicate(careerId));
			session.setAttribute("currentCareer", career);
			session.setAttribute(AcademicsConstants.SUBJECT_ID, subjectId);
			Subject subject = (Subject) CollectionUtils.find((List<Subject>) session.getAttribute(AcademicsConstants.SUBJECT), new SubjectPredicate(subjectId));
			session.setAttribute("currentSubject", subject);
			List<? extends CatalogNumber> lCatalogNumbers = getService().getCatalogNumbers(termId, subjectId);
			session.setAttribute("catalogNumbers", lCatalogNumbers);

			uiModel.addAttribute(AcademicsConstants.TITLE, ((Subject) session.getAttribute("currentSubject")).getDescription());
		}
		//uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, request.getContextPath() + "/academics/subjects?termId=" + session.getAttribute(AcademicsConstants.TERM_ID) + "&careerId=" + session.getAttribute(AcademicsConstants.CAREER_ID));
		return "academics/catalogNumbers";
	}

	@RequestMapping(value = "/browseClasses")
	public String browseClasses(HttpServletRequest request, Model uiModel,
								@RequestParam(required = false) String stage,
								@RequestParam(required = false)
								final String termId,
								@RequestParam(required = false)
								final String subjectId,
								@RequestParam(required = false)
								final String subject,
								@RequestParam(required = false)
								final String careerId,
								@RequestParam(required = false)
								final String catalogNumber,
								@RequestParam(required = false)
								final String catalogDescription) {
		HttpSession session = request.getSession();
		if (stage != null) {
			session.setAttribute(AcademicsConstants.STAGE, stage);
		} else {
			stage = AcademicsConstants.TERM;
		}
		if (termId != null && termId.length() > 0) {
			session.setAttribute(AcademicsConstants.TERM_ID, termId);
		}
		if (subjectId != null && subjectId.length() > 0) {
			session.setAttribute(AcademicsConstants.SUBJECT_ID, subjectId);
		}
		if (subject != null && subject.length() > 0) {
			session.setAttribute(AcademicsConstants.SUBJECT, subject);
		}
		if (careerId != null && careerId.length() > 0) {
			session.setAttribute(AcademicsConstants.CAREER_ID, careerId);
		}
		if (catalogNumber != null && catalogNumber.length() > 0) {
			session.setAttribute(AcademicsConstants.CATALOG_NUMBER, catalogNumber);
		}
		uiModel.addAttribute(AcademicsConstants.STAGE, stage);
		uiModel.addAttribute(AcademicsConstants.TERM_ID, session.getAttribute(AcademicsConstants.TERM_ID));
		uiModel.addAttribute(AcademicsConstants.SUBJECT_ID, session.getAttribute(AcademicsConstants.SUBJECT_ID));
		uiModel.addAttribute(AcademicsConstants.CAREER_ID, session.getAttribute(AcademicsConstants.CAREER_ID));
		uiModel.addAttribute(AcademicsConstants.CATALOG_NUMBER, session.getAttribute(AcademicsConstants.CATALOG_NUMBER));
		uiModel.addAttribute(AcademicsConstants.SUBJECT, session.getAttribute(AcademicsConstants.SUBJECT));
		uiModel.addAttribute("toolContext", "academics");
		if (stage.equalsIgnoreCase(AcademicsConstants.CATALOG_NUMBER)) {
			uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, "browseClasses?stage=" + AcademicsConstants.SUBJECT);
		} else if (stage.equalsIgnoreCase(AcademicsConstants.SUBJECT)) {
			uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, "browseClasses?stage=" + AcademicsConstants.CAREER);
		} else if (stage.equalsIgnoreCase(AcademicsConstants.CAREER)) {
			uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, "browseClasses?stage=" + AcademicsConstants.TERM);
		}

//		Enumeration<String> e = session.getAttributeNames();
//		while (e.hasMoreElements()) {
//			String key = e.nextElement();
//			LOG.debug("Session contains: [" + key + "] [" + session.getAttribute(key) + "]");
//		}

		return "academics/browseClasses";
	}

	@RequestMapping(value = "/sections")
	public String getSections(HttpServletRequest request, Model uiModel,
							  @RequestParam(required = false)
							  final String termId,
							  @RequestParam(required = false)
							  final String subjectId,
							  @RequestParam(required = false)
							  final String catalogNumber,
							  @RequestParam(required = false)
							  final String careerId) {
		HttpSession session = request.getSession();
		if (termId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.TERM_ID))
				&& careerId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.CAREER_ID))
				&& subjectId.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.CAREER_ID))
				&& catalogNumber.equalsIgnoreCase((String) session.getAttribute(AcademicsConstants.CATALOG_NUMBER))) {
			uiModel.addAttribute(AcademicsConstants.TITLE, session.getAttribute(AcademicsConstants.SUBJECT_ID) + " " + session.getAttribute(AcademicsConstants.CATALOG_NUMBER));
		} else {
			List<Section> lSections = (List<Section>) getService().getSections(termId, subjectId, catalogNumber, careerId);
			CatalogNumber number = (CatalogNumber) CollectionUtils.find((List<CatalogNumber>) session.getAttribute("catalogNumbers"), new CatalogNumberPredicate(catalogNumber));
			for (Section s : lSections) {
				if (null == s.getCourseTitle() || s.getCourseTitle().trim().isEmpty()) {
					s.setCourseTitle(number.getDescription());
				}
			}

			session.setAttribute("sectionsAll", lSections);
			session.setAttribute(AcademicsConstants.CATALOG_NUMBER, catalogNumber);
			session.setAttribute(AcademicsConstants.SUBJECT_ID, subjectId);
			uiModel.addAttribute("sectionsAll", lSections);
			uiModel.addAttribute(AcademicsConstants.TITLE, session.getAttribute(AcademicsConstants.SUBJECT_ID) + " " + session.getAttribute(AcademicsConstants.CATALOG_NUMBER));
		}
		uiModel.addAttribute("toolContext", "academics");
		//uiModel.addAttribute(AcademicsConstants.BACKBUTTON_URL, request.getContextPath() + "/academics/catalogNumbers?termId=" + termId + "&careerId=" + careerId + "&subjectId=" + subjectId);
		return "academics/sections";
	}

	@RequestMapping(value = "/sectionsDetail")
	public String getSectionsDetail(HttpServletRequest request, Model uiModel,
									@RequestParam(required = false)
									final String catalogDescription,
									@RequestParam(required = true)
									final String sectionUID) {
		HttpSession session = request.getSession();
		Section sectionDetail = null;
		LOG.debug("Entering getSectionsDetail looking for sectionUID [" + sectionUID + "]");
		if (null != session.getAttribute(AcademicsConstants.SECTIONS)) {
			LOG.debug("Sections are stored in the session.");
			List<Section> allSections = (List<Section>) session.getAttribute(AcademicsConstants.SECTIONS);
			for (Section thisSection : allSections) {
				LOG.debug("Testing section [" + thisSection.getSectionUID() + "]");
				if (sectionUID.equalsIgnoreCase(thisSection.getSectionUID())) {
					LOG.debug("Matching section found, loading remaining details.");
					sectionDetail = getService().getSectionDetail(thisSection);
					break;
				}
			}
		}
//		uiModel.addAttribute(AcademicsConstants.CATALOG_DESCRIPTION, session.getAttribute(AcademicsConstants.CATALOG_DESCRIPTION));
		uiModel.addAttribute(AcademicsConstants.TITLE, sectionDetail.getSubjectId() + " " + sectionDetail.getCatalogNumber());
		uiModel.addAttribute("thisSection", sectionDetail);
		uiModel.addAttribute("toolContext", "academics");
		//LOG.debug("BACKBUTTON_URL from request for sectionDetail: -" + session.getAttribute("backButtonURL"));
//        String backurl = (String) session.getAttribute("backButtonURL");
//        if(backurl.equalsIgnoreCase("search"))
//        {
//           uiModel.addAttribute("backButtonURL","academics/classSearch");
//        }
//        else
//        {
//           uiModel.addAttribute("backButtonURL","academics/sections?termId="+session.getAttribute(AcademicsConstants.TERM_ID)+"&careerId="+session.getAttribute(AcademicsConstants.CAREER_ID)+"&subjectId="+session.getAttribute(AcademicsConstants.SUBJECT_ID)+"&catalogNumber="+session.getAttribute(AcademicsConstants.CATALOG_NUMBER)+"&catalogDescription="+session.getAttribute(AcademicsConstants.CATALOG_DESCRIPTION));
//        }
//		uiModel.addAttribute("backButtonURL", request.getHeader("referer"));
		return "academics/sectionsDetail";
	}

	@RequestMapping(value = "/search")
	public String searchForm(Model uiModel) {
		uiModel.addAttribute(AcademicsConstants.TERM_ID, getService().getTerms());
		uiModel.addAttribute(AcademicsConstants.CAREER_ID, getService().getCareers("ALL"));
		uiModel.addAttribute(AcademicsConstants.SUBJECT_ID, getService().getSubjects("ALL", "ALL"));
		uiModel.addAttribute("toolContext", "academics");
		if ("3".equalsIgnoreCase(getKmeProperties().getProperty("kme.uiVersion", "classic"))) {
			return "ui3/academics/search";
		} else {
			return "academics/search";
		}
	}

	@RequestMapping(value = "/classSearch", method = RequestMethod.POST)
	public String getSearchResults(HttpServletRequest request, Model uiModel) {
		Map<String, String[]> inputMap = request.getParameterMap();

		if (LOG.isDebugEnabled()) {
			LOG.debug("Search request parameter map:");
			Iterator<Map.Entry<String, String[]>> mapIterator = inputMap.entrySet().iterator();
			while (mapIterator.hasNext()) {
				Map.Entry<String, String[]> entry = mapIterator.next();
				LOG.debug(entry.getKey() + ": " + Arrays.toString(entry.getValue()));
			}
		}

		SearchResult result = getService().getSearchResults(inputMap);
		List<Section> lSections = (List<Section>) result.getSections();
		LOG.debug("Sections classSearch POST  " + lSections.size() + " items long.");
		HttpSession session = request.getSession();
		session.setAttribute(AcademicsConstants.SECTIONS, lSections);
		session.setAttribute(AcademicsConstants.SEARCH_RESULT, result);
		session.setAttribute("toolContext", "academics");

		uiModel.addAttribute("searchResult", result);
		uiModel.addAttribute("toolContext", "academics");

		return "academics/searchResult";
	}

	@RequestMapping(value = "/classSearch", method = RequestMethod.GET)
	public String searchResults(HttpServletRequest request, Model uiModel) {
		HttpSession session = request.getSession();
		//uiModel.addAttribute(AcademicsConstants.TITLE, "Search Results");
		//uiModel.addAttribute("sectionsAll", session.getAttribute("sectionsAll"));
		uiModel.addAttribute("searchResult", session.getAttribute(AcademicsConstants.SEARCH_RESULT));
		uiModel.addAttribute("toolContext", session.getAttribute("toolContext"));
		//uiModel.addAttribute("backButtonURL", session.getAttribute("backButtonURL"));
		return "academics/searchResult";
	}

	@RequestMapping(value = "/templates/{key}")
	public String getAngularTemplates(
			@PathVariable("key") String key,
			HttpServletRequest request,
			Model uiModel) {
		return "ui3/academics/templates/" + key;
	}

	@RequestMapping(value = "/js/{key}.js")
	public String getJavaScript(
			@PathVariable("key") String key,
			Model uiModel) {
		if ("academics".equalsIgnoreCase(key)) {
			uiModel.addAttribute(AcademicsConstants.HOME_SCREEN_TOOLS, this.getHomeScreenOrder());
		}
		return "ui3/academics/js/" + key;
	}

	private List<String> getHomeScreenOrder() {
		List<String> toolOrder = new ArrayList<String>();
		if (null == getAcademicsProperties()) {
			LOG.error("Failed to load academics properties");
		}
		LOG.debug("Home screen order is: " + getAcademicsProperties().getProperty("academics.homescreenorder"));
		for (String s : getAcademicsProperties().getProperty("academics.homescreenorder").split(",")) {
			if ("true".equalsIgnoreCase(getAcademicsProperties().getProperty("academics." + s + ".enabled", "false"))) {
				toolOrder.add(s);
			}
		}
		return toolOrder;
	}

	private String getLocalisedString(HttpServletRequest request, String code, String... params) {
		Locale locale = localeResolver.resolveLocale(request);
		return messageSource.getMessage(code, params, locale);
	}

	/**
	 * @return the service
	 */
	public AcademicsService getService() {
		return service;
	}

	/**
	 * @param service the service to set
	 */
	public void setService(AcademicsService service) {
		this.service = service;
	}

	/**
	 * @return the academicsProperties
	 */
	public Properties getAcademicsProperties() {
		return academicsProperties;
	}

	/**
	 * @param academicsProperties the academicsProperties to set
	 */
	public void setAcademicsProperties(Properties academicsProperties) {
		this.academicsProperties = academicsProperties;
	}

	public Properties getKmeProperties() {
		return kmeProperties;
	}

	public void setKmeProperties(Properties kmeProperties) {
		this.kmeProperties = kmeProperties;
	}
}


text:
export class WildDog {
  public bark():void {
    console.log('woof woof');
  }
}


text:
using System;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Ponics.Analysis.Levels;
using Ponics.Components;
using Ponics.Organisms;
using ServiceStack;

namespace Ponics
{
    public abstract class PonicsSystem
    {
        [ApiMember(ExcludeInSchema = true)]
        public Guid Id { get; set; }

        [ApiMember(Name = "Name", Description = "The name of the aquaponic system",
            ParameterType = "body", DataType = "string", IsRequired = true)]
        public string Name { get; set; }

        [ApiMember(ExcludeInSchema = true)]
        [IgnoreDataMember]
        public List<LevelReading> LevelReadings { get; set; }

        [ApiMember(ExcludeInSchema = true)]
        public List<Component> Components { get; set; }

        public List<Guid> SystemWideOrganisms { get; set; }

        protected PonicsSystem()
        {
            LevelReadings = new List<LevelReading>();
            Components = new List<Component>();
            SystemWideOrganisms = new List<Guid>();
        }
    }
}


text:
'use strict';

module.exports = function (self, options) {
	options = Object.assign({}, options);

	var filter = function filter(key) {
		var match = function match(pattern) {
			return typeof pattern === 'string' ? key === pattern : pattern.test(key);
		};

		if (options.include) {
			return options.include.some(match);
		}

		if (options.exclude) {
			return !options.exclude.some(match);
		}

		return true;
	};

	var _iteratorNormalCompletion = true;
	var _didIteratorError = false;
	var _iteratorError = undefined;

	try {
		for (var _iterator = Object.getOwnPropertyNames(self.constructor.prototype)[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
			var key = _step.value;

			var val = self[key];

			if (key !== 'constructor' && typeof val === 'function' && filter(key)) {
				self[key] = val.bind(self);
			}
		}
	} catch (err) {
		_didIteratorError = true;
		_iteratorError = err;
	} finally {
		try {
			if (!_iteratorNormalCompletion && _iterator.return) {
				_iterator.return();
			}
		} finally {
			if (_didIteratorError) {
				throw _iteratorError;
			}
		}
	}

	return self;
};

var excludedReactMethods = ['componentWillMount', 'render', 'componentDidMount', 'componentWillReceiveProps', 'shouldComponentUpdate', 'componentWillUpdate', 'componentDidUpdate', 'componentWillUnmount', 'componentDidCatch', 'setState', 'forceUpdate'];

module.exports.react = function (self, options) {
	options = Object.assign({}, options);
	options.exclude = (options.exclude || []).concat(excludedReactMethods);
	return module.exports(self, options);
};


text:
require 'test_helper'

class HealthHistoryTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end


text:
//////////////////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2014-2015, Egret Technology Inc.
//  All rights reserved.
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above copyright
//       notice, this list of conditions and the following disclaimer in the
//       documentation and/or other materials provided with the distribution.
//     * Neither the name of the Egret nor the
//       names of its contributors may be used to endorse or promote products
//       derived from this software without specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY EGRET AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
//  OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
//  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
//  IN NO EVENT SHALL EGRET AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
//  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
//  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;LOSS OF USE, DATA,
//  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
//  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
//  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////////////
/// <reference path="../types.d.ts" />
var __global = global;
var xml = require("../xml/index");
egret.XML = xml;
/**
 * @private
 * Swan 命名空间
 */
exports.NS_S = "http://ns.egret.com/eui";
exports.NS_W = "http://ns.egret.com/wing";
var MODULE_NAME = "eui.";
var basicTypes = ["Array", "boolean", "string", "number"];
var allClasses = {};
var allEXMLs = {};
function sort(exmlFiles) {
    parseEXML(exmlFiles);
    exmlFiles.forEach(function (file) { return addDepends(file); });
    var sorted = [];
    var sortedMap = {};
    var preloads = exmlFiles.filter(function (e) { return e.preload; });
    preloads.forEach(function (e) {
        insert(e);
    });
    exmlFiles.forEach(function (e) {
        insert(e);
    });
    function insert(file) {
        if (file.path in sortedMap)
            return;
        for (var i in file.depends)
            insert(allEXMLs[i]);
        sorted.push(file);
        sortedMap[file.path] = true;
    }
    return sorted;
}
exports.sort = sort;
function parseEXML(exmlFiles) {
    exmlFiles.forEach(function (file) {
        var xml = egret.XML.parse(file.content);
        file.className = parseClassName(xml);
        file.usedClasses = parseUsedClass(xml);
        file.usedEXML = parseUsedEXML(xml);
        allClasses[file.className] = allClasses[file.className] || [];
        allClasses[file.className].push(file);
        allEXMLs[file.path] = file;
    });
}
function addDepends(file) {
    var depends = {};
    file.usedClasses && file.usedClasses.forEach(function (className) {
        var files = allClasses[className];
        if (!files) {
            console.log("Cannot find:", className);
            return;
        }
        files.forEach(function (it) {
            if (!it.depends)
                addDepends(it);
            for (var i in it.depends)
                depends[i] = true;
            depends[it.path] = true;
        });
    });
    file.usedEXML && file.usedEXML.forEach(function (path) {
        var it = allEXMLs[path];
        if (!it.depends)
            addDepends(it);
        for (var i in it.depends)
            depends[i] = true;
        depends[it.path] = true;
    });
    file.depends = depends;
}
function parseClassName(xml) {
    if (!xml)
        return null;
    return xml["$class"];
}
function parseUsedClass(xml) {
    var classes = [];
    visitNodes(xml, function (node) { return parseNodeClassName(node); }, function (classNames) { return classNames.forEach(function (className) { return classes.push(className); }); });
    return classes;
    function parseNodeClassName(xml) {
        if (!xml)
            return null;
        var classes = [];
        var className = getClassNameById(xml.localName, xml.namespace);
        if (className)
            classes.push(className);
        var skinName = xml["$skinName"];
        if (skinName && skinName.toLowerCase().indexOf(".exml") != skinName.length - 5)
            classes.push(skinName);
        if (classes.length)
            return classes;
        return null;
    }
}
function parseUsedEXML(xml) {
    var files = [];
    visitNodes(xml, function (node) { return parseEXMLPathInAttributes(node); }, function (path) { return files.push(path); });
    return files;
    function parseEXMLPathInAttributes(xml) {
        if (!xml)
            return null;
        var skinName = xml["$skinName"];
        if (skinName && skinName.toLowerCase().indexOf(".exml") == skinName.length - 5)
            return skinName;
        return null;
    }
}
function visitNodes(xml, condition, callback) {
    if (!xml)
        return;
    var result = condition(xml);
    if (result)
        callback(result);
    if (!xml.children || xml.children.length < 1)
        return;
    xml.children.forEach(function (node) {
        visitNodes(node, condition, callback);
    });
}
/**
 * @private
 * 根据类的短名ID和命名空间获取完整类名(以"."分隔)
 * @param id 类的短名ID
 * @param ns 命名空间
 */
function getClassNameById(id, ns) {
    if (id == "Object" && ns == exports.NS_S) {
    }
    var name = "";
    if (basicTypes.indexOf(id) != -1) {
    }
    if (ns == exports.NS_W) {
    }
    else if (!ns || ns == exports.NS_S) {
    }
    else {
        name = ns.substring(0, ns.length - 1) + id;
    }
    return name;
}

//# sourceMappingURL=../../lib/eui/EXML.js.map


text:
import smbus
import yaml
from i2c_register import I2CRegister

class BitfieldReg(I2CRegister):

    def __init__(self, bus, addr, conf):
        I2CRegister.__init__(self, bus, addr, conf)
        if 'writemask' in self.config.keys():
            self.mask = self.config['writemask']
        else:
            self.mask = 0xff

        self.map_bit_names()

    def map_bit_names(self):
        """ Build reverse map names of bits and remap each bit's value dict """
        self.bits = self.config['bits']
        self.bit_names = {}
        for bitnum,bit in self.bits.items():
            # create a name -> bitnum mapping
            if 'name' in bit.keys():
                self.bit_names[bit['name']] = bitnum
            # reverse map a subfields possible bit values when provided with names
            if 'values' in bit.keys():
                bit['value_names'] = {}
                for value_num,val_name in bit['values'].items():
                    bit['value_names'][val_name] = value_num

    def read(self,bit):
        """ Read bit at postion bit, or position defined by named bit """
        if type(bit) is str:
            bit = self.bit_names[bit]
        length = self.bits[bit]['length']
        #print "Reading at bit", bit, "(length = %d)" % length
        byte = self.read_byte()
        #print "Raw byte:", bin(byte)
        lowbit = bit-length+1
        value = (byte>>lowbit) & ((1<<length)-1)
        return value

    def write(self, bit, value, merge=True):
        """
        Write value starting at position bit (high to low)

        When merge is set, first read the current value so that only the
        specified bits will be changed.

        """
        if type(bit) is str:
            bit = self.bit_names[bit]
        if type(value) is str:
            value = self.bits[bit]['value_names'][value]
        length = self.bits[bit]['length']
        lowbit = bit-length+1
        #print "Writing {:08b} on bits {} to {})".format(value, bit, lowbit)
        new = value << lowbit
        # merge the new with the old
        if merge:
            old = self.read_byte()
            mergemask = ((1<<length)-1) << lowbit
            #print "Merging {:08b} with {:08b} using mask {:08b}".format(new, old, mergemask)
            # clear bits in old and OR in the new ones
            new = (old & (0xff ^ mergemask)) | new
        new &= self.mask
        #print "Masked with {:08b} => {:08b}".format(self.mask, new)
        self.write_byte(new)


text:
package models

import (
	"errors"
	"log"
	"strings"

	"github.com/EaseApp/web-backend/src/lib"
	r "github.com/dancannon/gorethink"
	"github.com/satori/go.uuid"
)

// Application holds attributes for an Ease user's applications.
type Application struct {
	Name      string `gorethink:"name" json:"name"`
	AppToken  string `gorethink:"app_token" json:"app_token"`
	TableName string `gorethink:"table_name" json:"table_name"`
}

// appDoc is the type of each document in an application table.
type appDoc struct {
	ID   string      `gorethink:"id"`
	Name string      `gorethink:"name"`
	Data interface{} `gorethink:"data"`
}

// newApplication creates a new application with a token and the given name.
func newApplication(user *User, appName string) (*Application, error) {
	appToken, err := generateRandomString(30)
	if err != nil {
		log.Println("Error: Couldn't generate random API token.")
		log.Println(err)
		return nil, err
	}
	// Get a UUID for the table name.
	tableName := strings.Replace(uuid.NewV4().String(), "-", "_", -1)
	return &Application{
		Name:      appName,
		AppToken:  appToken,
		TableName: tableName,
	}, nil
}

// CreateApplication creates a new application on the given user.
func (querier *ModelQuerier) CreateApplication(user *User, appName string) (*Application, error) {
	app, err := newApplication(user, appName)
	if err != nil {
		return nil, err
	}

	// Create a table for the new application.
	err = r.DB("test").TableCreate(app.TableName).Exec(querier.session)
	if err != nil {
		return nil, err
	}

	user.Applications = append(user.Applications, *app)
	user, err = querier.Save(user)
	if err != nil {
		return nil, err
	}
	return app, nil
}

// DeleteApplication handles deleting an application and dropping its table.
func (querier *ModelQuerier) DeleteApplication(user *User, appName string) (*User, error) {

	// Search for the app to delete.
	var appToDelete Application
	var newApps []Application
	for i, app := range user.Applications {
		if app.Name == appName {
			newApps = append(user.Applications[:i], user.Applications[i+1:]...)
			appToDelete = app
		}
	}

	// If an app with that name does not exist.
	if newApps == nil {
		return nil, errors.New("Could not find application with that name")
	}

	// Drop the app's table.
	err := r.DB("test").TableDrop(appToDelete.TableName).Exec(querier.session)
	if err != nil {
		return nil, err
	}

	// Resave the user with the updated application list.
	user.Applications = newApps
	return querier.Save(user)
}

// AuthenticateApplication checks that the given username, app name, and
// app token are valid, and if so returns the given application.
func (querier *ModelQuerier) AuthenticateApplication(
	username, appName, appToken string) (*Application, error) {
	user := querier.FindUser(username)
	if user == nil {
		return nil, errors.New("Couldn't find user with that name")
	}

	for _, app := range user.Applications {
		if (app.Name == appName || app.TableName == appName) && app.AppToken == appToken {
			return &app, nil
		}
	}
	return nil, errors.New("Invalid application token")
}

// AuthenticateApplicationWithTableName checks that the given username, table name, and
// app token are valid, and if so returns the given application.
func (querier *ModelQuerier) AuthenticateApplicationWithTableName(
	username, application, appToken string) (*Application, error) {
	user := querier.FindUser(username)
	if user == nil {
		return nil, errors.New("Couldn't find user with that name")
	}

	for _, app := range user.Applications {
		if app.Name == application && app.AppToken == appToken {
			return &app, nil
		}
	}
	return nil, errors.New("Invalid application token")
}

// SaveApplicationData saves the given data to the application's table at the given path.
func (querier *ModelQuerier) SaveApplicationData(
	app *Application, path lib.Path, data interface{}) error {
	if path.IsRoot() {
		return errors.New("Cannot save data to application root")
	}
	res, err := r.Table(app.TableName).Filter(map[string]string{"name": path.TopLevelDocName}).Run(querier.session)
	defer res.Close()
	if err != nil {
		return err
	}

	// Find the ID of the top-level doc.
	var docID string

	// If the top-level doc for this query doesn't exist yet, it needs to be created.
	if res.IsNil() {
		insertRes, err := r.Table(app.TableName).Insert(
			map[string]interface{}{"name": path.TopLevelDocName, "data": nil}).RunWrite(querier.session)
		if err != nil {
			return err
		}
		docID = insertRes.GeneratedKeys[0]
	} else {
		var doc appDoc
		err = res.One(&doc)
		if err != nil {
			return err
		}
		docID = doc.ID
	}

	// Generate the nested data query.
	query := path.ToNestedQuery(data)

	// Upsert the given data at the nested path.
	err = r.Table(app.TableName).Get(docID).Update(query).Exec(querier.session)

	return err
}

// ReadApplicationData reads the application's data at the given path and returns it.
func (querier *ModelQuerier) ReadApplicationData(
	app *Application, path lib.Path) (interface{}, error) {
	// Send back all the documents if root.
	if path.IsRoot() {
		res, err := r.Table(app.TableName).Filter(map[string]string{}).Run(querier.session)
		defer res.Close()
		if err != nil {
			return nil, err
		}

		var docs []appDoc
		err = res.All(&docs)
		if err != nil {
			return nil, err
		}

		// Convert the documents to the pure user data.
		docsData := make(map[string]interface{})
		for _, doc := range docs {
			docsData[doc.Name] = doc.Data
		}
		return docsData, nil
	}

	res, err := r.Table(app.TableName).Filter(map[string]string{"name": path.TopLevelDocName}).Run(querier.session)
	defer res.Close()
	if err != nil {
		return nil, err
	}

	// If the top-level doc for this query doesn't exist, return nil.
	if res.IsNil() {
		return nil, nil
	}

	var doc appDoc
	err = res.One(&doc)
	if err != nil {
		return nil, err
	}

	// If nested data isn't requested, return all the doc's data.
	if len(path.RemainingSegments) == 0 {
		return doc.Data, nil
	}

	nextMapLevel, ok := doc.Data.(map[string]interface{})
	if !ok {
		return nil, nil
	}

	// Dive into the nested maps.
	for idx, segment := range path.RemainingSegments {
		// Try to get the next nested level for each remaining segment.
		_, ok = nextMapLevel[segment]
		if !ok {
			return nil, nil
		}

		// Return the final data if this is the last segment
		if idx == len(path.RemainingSegments)-1 {
			return nextMapLevel[segment], nil
		}

		nextMapLevel, ok = nextMapLevel[segment].(map[string]interface{})
		// The nest doesn't go any further, so return nil.
		if !ok {
			return nil, nil
		}
	}

	// This should never be reached.
	log.Println("ERROR: This should never be reached.")
	return nil, nil
}

// DeleteApplicationData deletes the application data at the given path.
func (querier *ModelQuerier) DeleteApplicationData(
	app *Application, path lib.Path) error {

	// Empty the table if the path is root.
	if path.IsRoot() {
		err := r.Table(app.TableName).Delete().Exec(querier.session)
		return err
	}

	// Delete the top-level doc if the path isn't nested.
	if len(path.RemainingSegments) == 0 {
		err := r.Table(app.TableName).Filter(map[string]string{
			"name": path.TopLevelDocName}).Delete().Exec(querier.session)
		return err
	}

	// If the path is nested, read the data, then delete the given entry from the map,
	// then resave.

	// The below code is partly taken from ReadApplicationData and can probably be refactored.
	res, err := r.Table(app.TableName).Filter(map[string]string{"name": path.TopLevelDocName}).Run(querier.session)
	defer res.Close()
	if err != nil {
		return err
	}

	// If the top-level doc for this query doesn't exist, return nil.
	if res.IsNil() {
		return nil
	}

	var doc appDoc
	err = res.One(&doc)
	if err != nil {
		return err
	}

	nextMapLevel, ok := doc.Data.(map[string]interface{})
	if !ok {
		return nil
	}

	// Dive into the nested maps.
	for idx, segment := range path.RemainingSegments {
		// Try to get the next nested level for each remaining segment.
		_, ok = nextMapLevel[segment]
		if !ok {
			return nil
		}

		// If this is the last segment, delete it from the map and replace in the db.
		if idx == len(path.RemainingSegments)-1 {
			delete(nextMapLevel, segment)
			err = r.Table(app.TableName).Get(doc.ID).Replace(doc).Exec(querier.session)
			return err
		}

		nextMapLevel, ok = nextMapLevel[segment].(map[string]interface{})
		// The nest doesn't go any further, so return nil.
		if !ok {
			return nil
		}
	}

	// This should never be reached.
	log.Println("ERROR: This should never be reached.")
	return nil
}


text:
if [ $GOAL = "FE" ]
then
    echo 'Starting FRONTEND'
    cd frontend && npm start
else
    echo 'Starting BACKEND'
    cd backend && npm run build && node dist/index.js
fi


text:
package org.mockito.internal;

import java.lang.annotation.Documented;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;

@Retention(RetentionPolicy.CLASS)
@Documented
public @interface SuppressSignatureCheck {}


text:
require 'rails_helper'

describe "admin/configuration/split_pane.html.erb" do

  before :each do
    allow(view).to receive(:config_view_path).and_return("config_view_path")
    allow(view).to receive(:config_update_path).and_return('config_update_path')
  end

  it "should render heading" do
    assign(:conflicted_config, GoConfig.new({"content" => 'conflicted-content', "md5" => 'conflict-md5', "location" => "path_to_config_xml"}))
    assign(:go_config, GoConfig.new({"content" => 'current-content', "md5" => 'current-md5', "location" => "path_to_config_xml"}))

    render

    Capybara.string(response.body).find('div.heading').tap do |div|
      expect(div).to have_selector("h2", :text => "Configuration File")
      expect(div).to have_selector("span", :text => "Configuration File Path:")
      expect(div).to have_selector("span", :text => "path_to_config_xml")
    end
  end

  it "should render view" do
    assign(:conflicted_config, GoConfig.new({"content" => 'conflicted-content', "md5" => 'conflict-md5', "location" => "path_to_config_xml"}))
    assign(:go_config, GoConfig.new({"content" => 'current-content', "md5" => 'current-md5', "location" => "path_to_config_xml"}))
    date = java.util.Date.new(1366866649)
    difference = "#{time_ago_in_words(date.to_string)} #{'ago'}"
    cruise_config_revision = double("cruise config revision")
    expect(cruise_config_revision).to receive(:getTime).and_return(date)
    expect(cruise_config_revision).to receive(:getUsername).and_return("Ali")
    assign(:go_config_revision, cruise_config_revision)

    render

    Capybara.string(response.body).find('div#admin-holder-for-admin-config-source-xml').tap do |div|
      div.find("div.conflicted_content").tap do |conflicted_content|
        expect(conflicted_content).to have_selector("h3", :text => "Your Changes")
        expect(conflicted_content).to have_selector("pre.wrap_pre", :text => "conflicted-content")

        expect(conflicted_content).not_to have_selector("input.hidden[name='configMd5'][value='conflict-md5']")
        expect(conflicted_content).not_to have_selector("input.hidden[name='config_md5'][value='conflict-md5']")
      end
      div.find("div.current_content").tap do |current_content|
        current_content.find("form#config_editor_form[method='post'][action='config_update_path']").tap do |config_editor|
          expect(config_editor).to have_selector("input[name='_method'][value='put']", visible: :hidden)
          current_content.find("div.form_heading").tap do |form_heading|
            expect(form_heading).to have_selector("div.config_change_timestamp", :text => "Last modified: #{difference} by Ali")
            expect(form_heading).to have_selector("div.config_change_timestamp[title='Last modified: #{difference} by Ali']")
            form_heading.find("div.buttons-group").tap do |buttons_group|
              expect(buttons_group).to have_selector("input#save_config[class='link_as_button primary'][type='submit'][value='SAVE'][disabled='disabled']")
              expect(buttons_group).to have_selector("a#cancel_edit[class='link_as_button'][href='config_view_path']", :text => "Cancel")
            end
          end
          expect(current_content).to have_selector("input[type='hidden'][name='go_config[md5]'][value='current-md5']", visible: :hidden)
          expect(current_content).to have_selector("textarea#content[name='go_config[content]'][data-config-url='/go/api/admin/config/current-md5.xml']")
        end
      end
    end
  end

  it "should not bomb when no time stamp for current revision exists" do
    assign(:conflicted_config, GoConfig.new({"content" => 'conflicted-content', "md5" => 'conflict-md5', "location" => "path_to_config_xml"}))
    assign(:go_config, GoConfig.new({"content" => 'current-content', "md5" => 'current-md5', "location" => "path_to_config_xml"}))
    assign(:go_config_revision, nil)

    render

    expect(response.body).to have_selector("div.config_change_timestamp", :text => "Last modified: Unknown by Unknown")
  end

  it "should show global errors in case of config save failure" do
    assign(:conflicted_config, GoConfig.new({"content" => 'conflicted-content', "md5" => 'conflict-md5', "location" => "path_to_config_xml"}))
    assign(:go_config, GoConfig.new({"content" => 'current-content', "md5" => 'current-md5', "location" => "path_to_config_xml"}))
    assign(:errors, ['some error that has happened', 'more lines'])

    render

    Capybara.string(response.body).find('div.form_submit_errors').tap do |div|
      div.find("div.errors").tap do |errors|
        expect(errors).to have_selector("h3", :text => "The following error(s) need to be resolved in order to perform this action:")
        errors.find("ul").tap do |ul|
          expect(ul).to have_selector("li.error", :text => "some error that has happened")
          expect(ul).to have_selector("li.error", :text => "more lines")
        end
      end
    end
  end

end


text:
// @flow
import {ReduceStore} from 'flux/utils'
import {fromJS}      from 'immutable'
import {Map}         from 'immutable'

import StringActionTypes from './StringActionTypes'
import StringsEN         from './StringsEN'
import StringsZH         from './StringsZH'
import AppDispatcher     from '../AppDispatcher'
import {langCode}        from '../I18NConstants'
import AppActionTypes    from '../app/AppActionTypes'

import {localStorageAvailable} from '../LocalStorage'
import {migrate}               from '../LocalStorage'
const localStorageKey:string = 'StringStore'

// We want to provide a migration capacity for the format of this store.  It's serialized
// into localStorage and there's no telling when old versions will be seen in the future.
const initialStates:Array<Object> = [Map({v:0, lang: langCode.zh})]

/**
 * This store differs from the others.
 *
 * In this store want to save the language choice to
 * localState and we _do not_ want to save the blizzard of strings.  But for the ordinary
 * operation of the app, we _do_ want the strings in the state.  We must therefore engage
 * in contortions to append and prune the strings from the state where applicable.
 *
 */
class StringStore extends ReduceStore {

    constructor() {super(AppDispatcher)}

    getInitialState():Object {
        if (localStorageAvailable) {
            const localStorageState = localStorage.getItem(localStorageKey)

            if(localStorageState) {
                let originalParse = migrate(fromJS(JSON.parse(localStorageState)), initialStates)
                if(originalParse.get('lang') === langCode.zh) originalParse = originalParse.set('strings', StringsZH)
                else if(originalParse.get('lang') === langCode.en) originalParse = originalParse.set('strings', StringsEN)
                // else max fubar error

                return originalParse
            }
        }

        return initialStates.slice(-1)[0].set('strings', StringsZH)
    }

    reduce(state:Object, action:Object):Object {

        let newState:Object = state

        switch (action.type) {

            case AppActionTypes.ON_CLICK_APP_RESET:
                newState = initialStates.slice(-1)[0].set('strings', StringsZH)
                break

            case StringActionTypes.ON_LANG_EN:
                newState = newState.set('lang', langCode.en)
                newState = newState.set('strings', StringsEN)
                break

            case StringActionTypes.ON_LANG_ZH:
                newState = newState.set('lang', langCode.zh)
                newState = newState.set('strings', StringsZH)
                break

            default:
                // do nothing, newState is already set to the existing state
        }

        // We don't need to save all these strings to localStorage but we do
        // want to save the language selection.
        if(localStorageAvailable)
            localStorage.setItem(localStorageKey, JSON.stringify(newState.delete('strings').toJSON()))

        return newState
    }
}

export default new StringStore()


text:
<?php

class Group_Controller extends Base_Kakadu_Controller {

    private $rules = array(
                            'name'          => 'required|min:5|max:100',
                            'description'   => 'required|min:50|max:500'
                        );

    /**
     * Shows all groups with pagination.
     *
     * On a ajax request just the list will be returned
     *
     * GET variables:
     * - sort: name, id, created_at (Sorting value)
     * - sort_dir: asc, desc (Sorting direction)
     * - per_page: number (20) (Items per page)
     * - page: number (Actuall page)
     */
    public function get_groups() {

        //Check permissions
        $permission = $this->checkPermissions(Const_Action::ALL);

        if($permission === Const_Permission::DENIED) {
            return View::make('general.permission');
        }

        //Set up the optins
        $append = array();

        if(Input::has('sort')) {
            $sort = Input::get('sort');
            $append['sort'] = $sort;
        } else {
            $sort = 'name';
        }

        if(Input::has('sort_dir')) {
            $sort_dir = Input::get('sort_dir');
            $append['sort_dir'] = $sort_dir;
        } else {
            $sort_dir = 'asc';
        }

        if(Input::has('per_page')) {
            $per_page = Input::get('per_page');
            $append['per_page'] = $per_page;
        } else {
            $per_page = 20;
        }

        //Create view
        $groups = Learngroup::order_by($sort, $sort_dir)->paginate($per_page);
        $tmp = array();

        foreach($groups->results as $group) {
            $tmp[] = $this->getGroupArray($group);
        }

        if(Request::ajax()) {
            $view = View::make('group.list');
        } else {
            $view = View::make('group.groups');
        }

        $view->groups = $tmp;
        $view->links = $groups->appends($append)->links();

        if(Request::ajax()) {
            return $view;
        } else {
            $this->layout->content = $view;
        }
    }

    /**
     * Shows a group.
     *
     * On an ajax request just the members table will be returned
     */
    public function get_group($id) {

        //Get group
        $this->group = Learngroup::find($id);

        if($this->group === NULL) {
            return Response::error('404');
        }

        //Check permissions
        $permission = $this->checkPermissions(Const_Action::SHOW);

        if($permission === Const_Permission::DENIED) {
            return View::make('general.permission');
        }

        //Admins and users
        $pivot = $this->group->users()->pivot()->get();
        $role_admin = Role::where('name', 'LIKE', 'admin')->first();
        $role_member = Role::where('name', 'LIKE', 'member')->first();

        $admins = array();
        $users = array();

        foreach($pivot as $allocation) {
            $user = Sentry::user((int)$allocation->user_id);

            $data = array(
                'email'         => $user->get('email'),
                'displayname'   => $user->get('metadata.displayname')
            );

            switch($allocation->role_id) {
                case $role_admin->id:
                    $admins[] = $data;
                    $users[] = $data;
                    break;

                case $role_member->id:
                    $users[] = $data;
                    break;

                default:
                    break;
            }
        }

        //Courses
        $result = $this->group->courses()->order_by('name', 'ASC')->get();
        $courses = array();

        foreach($result as $course) {
            $courses[] = array(
                    'id'            => $course->id,
                    'name'          => $course->name,
                    'description'   => $course->description,
                    'created_at'    => $course->created_at,
                    'updated_at'    => $course->updated_at
                );
        }

        //Create view
        if(Request::ajax()) {
            $view = View::make('group.members');
        } else {
            $view = View::make('group.group');
        }

        $view->group = $this->getGroupArray($this->group);
        $view->admins = $admins;
        $view->users = $users;
        $view->courses = $courses;

        //Check ajax request
        if(Request::ajax()) {
            return $view;
        }else{
            $this->layout->content = $view;
        }

    }

    /**
     * Shows the view to create a group
     */
    public function get_create() {

        //Check permissions
        $permission = $this->checkPermissions(Const_Action::CREATE);

        if($permission === Const_Permission::DENIED) {
            return View::make('general.permission');
        }

        //Create view
        $this->layout->content = View::make('group.create');
    }

    /**
     * Create a group
     */
    public function post_create() {

        $redirect_success = 'group';
        $redirect_error = 'group/create';

        //Validate input
        $response = $this->validateInput($this->rules);

        if ($response !== true) {
            return $this->redirectWithErrors($redirect_error, $response);
        }

        //Check permissions
        $permission = $this->checkPermissions(Const_Action::CREATE);

        if($permission === Const_Permission::DENIED) {
            return View::make('general.permission');
        }

        //Create the group
        $group = new Learngroup;
        $group->name = Input::get('name');
        $group->description = Input::get('description');
        $group->save();

        //Add group admin
        try {
            $user_sentry = Sentry::user();
            $user_kakadu = User::find($user_sentry->get('id'));
        } catch (Sentry\SentryException $e) {
            $messages = array($e->getMessage());
            return $this->redirectWithErrors($redirect_error, $messages);
        }

        $role = Role::where('name', 'LIKE', 'admin')->first();
        $group->users()->attach($user_kakadu, array('role_id' => $role->id));

        return Redirect::to_route($redirect_success, array($group->id));
    }

    /**
     * Shows the view to edit a group
     */
    public function get_edit($id) {

        //Get group
        $this->group = Learngroup::find($id);

        if($this->group === NULL) {
            return Response::error('404');
        }

        //Check permissions
        $permission = $this->checkPermissions(Const_Action::EDIT);

        if($permission === Const_Permission::DENIED) {
            return View::make('general.permission');
        }

        //Create view
        $view = View::make('group.edit');
        $this->layout->content = $view;
        $view->group = $this->getGroupArray($this->group);
    }

    /**
     * Edit a group
     */
    public function post_edit() {

        $redirect_success = 'group';
        $redirect_error = 'group/edit';

        //Validate input
        $this->rules['id'] = 'required|integer|min:0';
        $response = $this->validateInput($this->rules);

        if ($response !== true) {
            $parameters = array(Input::get('id'));
            return $this->redirectWithErrors($redirect_error, $response, $parameters);
        }

        //Get group
        $this->group = Learngroup::find(Input::get('id'));

        if($this->group === NULL) {
            return Response::error('404');
        }

        //Check permissions
        $permission = $this->checkPermissions(Const_Action::EDIT);

        if($permission === Const_Permission::DENIED) {
            return View::make('general.permission');
        }

        //Edit the group
        $this->group->name = Input::get('name');
        $this->group->description = Input::get('description');
        $this->group->save();

        return Redirect::to_route($redirect_success, array($this->group->id));
    }

    /**
     * Delete a group
     */
    public function get_delete($id) {

        $redirect_success = 'groups';
        $redirect_error = 'group';

        //Get the group
        $this->group = Learngroup::find($id);

        if($this->group === NULL) {
            return Response::error('404');
        }

        //Check permissions
        $permission = $this->checkPermissions(Const_Action::DELETE);

        if($permission === Const_Permission::DENIED) {
            return View::make('general.permission');
        }

        //Delete the group
        Helper_Group::deleteGroupAndCheckRelatedCourses($this->group);

        return Redirect::to_route($redirect_success);
    }

    /**
     * Show the view that the group was deleted
     */
    public function get_deleted() {
        $this->layout->content = View::make('group.deleted');
    }

    /**
     * Validate input with the given rules
     *
     * @return array|boolean Returns a error array when there is validation error or true on a valid validation
     */
    private function validateInput($rules) {
        $validation = Validator::make(Input::all(), $rules);

        if ($validation->fails()) {
            return $validation->errors->all();
        }

        return true;
    }

}


text:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">

    <data>

        <variable
            name="viewModel"
            type="de.fluchtwege.vocabulary.addlesson.AddLessonViewModel"/>
    </data>

    <RelativeLayout

        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <TextView
            android:id="@+id/save_lesson"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_alignParentBottom="true"
            android:background="@color/colorPrimary"
            android:clickable="true"
            android:foreground="?attr/selectableItemBackground"
            android:gravity="center"
            android:text="@string/save"
            android:textColor="@color/white"
            android:textSize="@dimen/text_large"/>

        <TextView
            android:id="@+id/enter_question"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_margin="@dimen/margin_large"
            android:clickable="true"
            android:text="@string/enter_question"
            android:textSize="@dimen/text_large"/>

        <EditText
            android:id="@+id/lesson_name"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_below="@id/enter_question"
            android:layout_margin="@dimen/margin_large"
            android:lines="1"
            android:imeOptions="actionNext"
            android:hint="@string/lesson_name"
            android:text="@={viewModel.lessonName}"/>

        <EditText
            android:id="@+id/lesson_description"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_margin="@dimen/margin_large"
            android:layout_below="@id/lesson_name"
            android:lines="1"
            android:imeOptions="actionDone"
            android:hint="@string/lesson_description"
            android:text="@={viewModel.description}"/>

    </RelativeLayout>
</layout>