text:
<component name="ProjectDictionaryState">
  <dictionary name="Cody">
    <words>
      <w>rowlett</w>
    </words>
  </dictionary>
</component>

redpajama_set_name: RedPajamaGithub


text:
/* Javascript to track changes, and prompt the user for saving */

var ModificationTracker = Class.create({

    initialize: function(){
        if(AE.checkForModification){
        	this.form = $('command');

            if(this.form){
            	this.formElements =  this.form.select('textarea','input','select');
                AE.formFieldCount = this.formElements.size();

                //observe the change
                this.formElements.each(function(el){
                	el.observe('change',function(){
                		AE.formFieldModified=true;
                	});
                });

                //observe submit on the form
                this.form.observe('submit', function(){
                	AE.checkForModification=false;
                });

                window.onbeforeunload = this.checkForModificationsOnPage.bind(this);
            }

        }

    },

    //check if there is a form field change
    checkForModificationsOnPage: function(){
        if(AE.checkForModification){
           var curFormElementCount = this.form.select('textarea','input','select').size();
           if(AE.formFieldModified || (curFormElementCount != AE.formFieldCount) )
        	   return AE.UNSAVED_DATA_MESSAGE;
        }
    }

});

Event.observe(document, "dom:loaded", function(){
	new ModificationTracker();
});


text:
// coding: utf-8

// ----------------------------------------------------------------------------

// Inspired by: http://arduino.cc/en/Tutorial/DigitalReadSerial

#include "../../arduino_uno.hpp"

// create a device wrapper and a stream in oder to be able to send strings
xpcc::IODeviceWrapper< Uart0, xpcc::IOBuffer::BlockIfFull > serialDevice;
xpcc::IOStream serialStream(serialDevice);

// name pin2
typedef DigitalInput2 PushButton;

MAIN_FUNCTION
{
	// initialize the serial communication module
	DigitalInput0::connect(Uart0::Rx);
	DigitalOutput1::connect(Uart0::Tx);
	Uart0::initialize<clock, 9600>();

	PushButton::setInput();

	while (1)
	{
		// read the input pin
		bool buttonState = PushButton::read();
		// print button state
		serialStream << buttonState << xpcc::endl;
	}
}


text:
package org.japo.java.lib;

/**
 *
 * @author Adrián Martínez Gil 1dawm161715(at)gmail.com
 */
public class LibreriaTiempo {
    // Constantes

    private static final String SEPARADORES_FECHA = "-/";

    public static boolean comprobarFecha(int dia, int mes, int any) {
        return comprobarDia(dia, mes, any) && comprobarMes(mes);
    }

    public static boolean comprobarMes31(int mes) {
        return mes == 1 || mes == 3 || mes == 5 || mes == 7
                || mes == 8 || mes == 10 || mes == 12;
    }

    public static boolean comprobarMes30(int mes) {
        return mes == 4 || mes == 6 || mes == 9 || mes == 11;
    }

    public static boolean comprobarMes(int mes) {
        return mes >= 1 && mes <= 12;
    }

    public static boolean comprobarBisiesto(int any) {
        return any % 400 == 0 || any % 100 != 0 && any % 4 == 0;
    }

    public static int obtenerDiasFebrero(int any) {
        int dias;
        if (comprobarBisiesto(any)) {
            dias = 29;
        } else {
            dias = 28;
        }
        return dias;
    }

    public static boolean comprobarDia(int dia, int mes, int any) {
        return dia >= 1 && dia <= obtenerDiasMes(mes, any);
    }

    public static int obtenerDiasMes(int mes, int any) {
        int dias;
        if (comprobarMes31(mes)) {
            dias = 31;
        } else if (comprobarMes30(mes)) {
            dias = 30;
        } else {
            dias = obtenerDiasFebrero(any);
        }
        return dias;
    }

    public boolean validarFormatoFecha(String fecha) {
        String dia = fecha.substring(0, fecha.indexOf('/')-1);// <--------------
        boolean testFormato = false;
        if (formatoDia(fecha) && formatoMes(fecha) && formatoAnyo(fecha)) {
            testFormato = true;
        }
    return testFormato;
    }

    public static boolean formatoDia(String fecha) {
        boolean testFormato = false;
        for (int i = 0; i < fecha.length(); i++){
            if (fecha.charAt(i) >= '0' || fecha.charAt(i) <= '9'){
                testFormato = true;
            }
        }
        return testFormato;
    }

    public static boolean formatoMes(String fecha) {

    }

    public static boolean formatoAnyo(String fecha) {

    }

}


text:
import React from "react"
import { mount } from "enzyme"
import { assert } from "chai"

import FollowButton from "./FollowButton"
import LoginTooltip from "./LoginTooltip"
import Router from "../Router"

import { makePost } from "../factories/posts"
import * as utilFuncs from "../lib/util"
import IntegrationTestHelper from "../util/integration_test_helper"

describe("FollowButton", () => {
  let helper, toggleFollowPostStub, post

  beforeEach(() => {
    helper = new IntegrationTestHelper()
    toggleFollowPostStub = helper.sandbox.stub()
    post = makePost()
  })

  afterEach(() => {
    helper.cleanup()
  })

  const renderButton = () =>
    mount(
      <Router store={helper.store} history={helper.browserHistory}>
        <FollowButton post={post} toggleFollowPost={toggleFollowPostStub} />
      </Router>
    )

  it("should have a LoginTooltip", () => {
    const wrapper = renderButton()
    wrapper.find(LoginTooltip).exists()
  })

  //
  ;[
    [true, "Unfollow"],
    [false, "Follow"]
  ].forEach(([subscribed, buttonText]) => {
    it(`should include a ${buttonText} button when subscribed === ${subscribed.toString()}`, () => {
      helper.sandbox.stub(utilFuncs, "userIsAnonymous").returns(false)
      post.subscribed = subscribed
      const wrapper = renderButton()
      const button = wrapper.find(subscribed ? ".subscribed" : ".unsubscribed")
      assert.include(button.text(), buttonText)
      button.simulate("click")
      assert.ok(toggleFollowPostStub.calledOnce)
    })
  })
})


text:
namespace GRAPH
{
    class Event;
    class EventTouch;
    class EventCustom;
    class EventListenerCustom;

    class EventDispatcher : public HObject
    {
    public:
        void addEventListenerWithSceneGraphPriority(EventListener* listener, HObject* target);
        void addEventListenerWithFixedPriority(EventListener* listener, int fixedPriority);
        EventListenerCustom* addCustomEventListener(const std::string &eventName, const std::function<void(EventCustom*)>& callback);

        void removeEventListener(EventListener* listener);
        void removeEventListenersForType(EventListener::Type listenerType);
        void removeEventListenersForTarget(HObject* target, bool recursive = false);
        void removeCustomEventListeners(const std::string& customEventName);
        void removeAllEventListeners();

        void pauseEventListenersForTarget(HObject* target, bool recursive = false);
        void resumeEventListenersForTarget(HObject* target, bool recursive = false);

        void setPriority(EventListener* listener, int fixedPriority);
        void setEnabled(bool isEnabled);
        bool isEnabled() const;

        void dispatchEvent(Event* event);
        void dispatchCustomEvent(const std::string &eventName, void *optionalUserData = nullptr);

        EventDispatcher();
        ~EventDispatcher();

    protected:
        void setDirtyForNode(HObject* target);

        class EventListenerVector
        {
        public:
            EventListenerVector();
            ~EventListenerVector();
            uint64 size() const;
            bool empty() const;

            void push_back(EventListener* item);
            void clearSceneGraphListeners();
            void clearFixedListeners();
            void clear();

            inline std::vector<EventListener*>* getFixedPriorityListeners() const { return _fixedListeners; }
            inline std::vector<EventListener*>* getSceneGraphPriorityListeners() const { return _sceneGraphListeners; }
            inline uint64 getGt0Index() const { return _gt0Index; }
            inline void setGt0Index(uint64 index) { _gt0Index = index; }
        private:
            std::vector<EventListener*>* _fixedListeners;
            std::vector<EventListener*>* _sceneGraphListeners;
            uint64 _gt0Index;
        };

        void addEventListener(EventListener* listener);
        void forceAddEventListener(EventListener* listener);

        EventListenerVector* getListeners(const EventListener::ListenerID& listenerID);

        void updateDirtyFlagForSceneGraph();

        void removeEventListenersForListenerID(const EventListener::ListenerID& listenerID);

        void sortEventListeners(const EventListener::ListenerID& listenerID);
        void sortEventListenersOfSceneGraphPriority(const EventListener::ListenerID& listenerID, HObject* rootTarget);
        void sortEventListenersOfFixedPriority(const EventListener::ListenerID& listenerID);

        void updateListeners(Event* event);

        void dispatchTouchEvent(EventTouch* event);
        void dispatchEventToListeners(EventListenerVector* listeners, const std::function<bool(EventListener*)>& onEvent);
        void dispatchTouchEventToListeners(EventListenerVector* listeners, const std::function<bool(EventListener*)>& onEvent);

        void associateNodeAndEventListener(HObject* target, EventListener* listener);
        void dissociateNodeAndEventListener(HObject* target, EventListener* listener);

        enum class DirtyFlag
        {
            NONE = 0,
            FIXED_PRIORITY = 1 << 0,
            SCENE_GRAPH_PRIORITY = 1 << 1,
            ALL = FIXED_PRIORITY | SCENE_GRAPH_PRIORITY
        };

        void setDirty(const EventListener::ListenerID& listenerID, DirtyFlag flag);

        void visitTarget(HObject* target, bool isRootTarget);

    private:
        std::unordered_map<EventListener::ListenerID, EventListenerVector*> listenerMap_;
        std::unordered_map<EventListener::ListenerID, DirtyFlag> priorityDirtyFlagMap_;
        std::unordered_map<HObject*, std::vector<EventListener*>*> nodeListenersMap_;
        std::unordered_map<HObject*, int> nodePriorityMap_;
        std::unordered_map<float, std::vector<HObject*>> globalZOrderNodeMap_;
        std::vector<EventListener*> toAddedListeners_;
        std::set<HObject*> dirtyNodes_;
        int inDispatch_;
        bool isEnabled_;
        int nodePriorityIndex_;
        std::set<std::string> internalCustomListenerIDs_;

        friend class Node;
    };
}

#endif // EVENTDISPATCHER_H


text:
package mailbox;

import org.apache.commons.lang3.StringUtils;
import play.Configuration;

import javax.annotation.Nonnull;

/**
 * An email address whose detail part is parsed.
 */
public class EmailAddressWithDetail {
    @Nonnull
    private final String user;

    @Nonnull
    private String detail;

    @Nonnull
    private final String domain;

    public EmailAddressWithDetail(@Nonnull String address) {
        int plus = address.indexOf('+');
        int at = address.indexOf('@');

        if (plus < 0) {
            user = address.substring(0, at);
            detail = "";
        } else {
            user = address.substring(0, plus);
            detail = address.substring(plus + 1, at);
        }

        domain = address.substring(at + 1);
    }

    /**
     * @return  whether this email address is to Yobi
     */
    public boolean isToYobi() {
        Configuration imapConfig = Configuration.root().getConfig("imap");
        String yobiAddr = imapConfig.getString("address", imapConfig.getString("user"));
        return this.equalsExceptDetails(new EmailAddressWithDetail(yobiAddr));
    }

    @Nonnull
    public String getUser() {
        return user;
    }

    @Nonnull
    public String getDetail() {
        return detail;
    }

    @Nonnull
    public String getDomain() {
        return domain;
    }

    /**
     * Set the detail part.
     *
     * @param detail
     */
    public void setDetail(@Nonnull String detail) {
        if (detail == null) {
            throw new IllegalArgumentException("detail must not be null");
        }
        this.detail = detail;
    }

    /**
     * @param that
     * @return  whether the given address has the same detail with this
     */
    public boolean equalsExceptDetails(@Nonnull EmailAddressWithDetail that) {
        return this.getUser().equals(that.getUser())
            && this.getDomain().equals(that.getDomain());
    }

    public String toString() {
        return StringUtils.join(new String[]{user, detail}, "+") + "@" + domain;
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<!--

    Copyright 2004 The Apache Software Foundation

    Licensed under the Apache License, Version 2.0 (the "License");
    you may not use this file except in compliance with the License.
    You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing, software
    distributed under the License is distributed on an "AS IS" BASIS,
    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    See the License for the specific language governing permissions and
    limitations under the License.
-->

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
    <description>Test Web Deployment</description>
    <resource-env-ref>
        <resource-env-ref-name>fake-resource-env-ref</resource-env-ref-name>
        <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
    </resource-env-ref>
    <resource-ref>
        <res-ref-name>fake-resource-ref</res-ref-name>
        <res-type>javax.sql.DataSource</res-type>
        <res-auth>Container</res-auth>
        <res-sharing-scope>Shareable</res-sharing-scope>
    </resource-ref>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>Admin Role</web-resource-name>
            <url-pattern>/protected/*</url-pattern>
        </web-resource-collection>
        <auth-constraint>
            <role-name>content-administrator</role-name>
        </auth-constraint>
    </security-constraint>

    <security-constraint>
        <web-resource-collection>
            <web-resource-name>NO ACCESS</web-resource-name>
            <url-pattern>/auth/logon.html</url-pattern>
        </web-resource-collection>
        <auth-constraint/>
    </security-constraint>

    <login-config>
        <auth-method>FORM</auth-method>
        <realm-name>Test JAAS Realm</realm-name>
        <form-login-config>
            <form-login-page>/auth/logon.html?param=test</form-login-page>
            <form-error-page>/auth/logonError.html?param=test</form-error-page>
        </form-login-config>
    </login-config>

    <security-role>
        <role-name>content-administrator</role-name>
    </security-role>

    <ejb-ref>
        <ejb-ref-name>fake-ejb-ref</ejb-ref-name>
        <ejb-ref-type>Entity</ejb-ref-type>
        <home>some.package.FakeHome</home>
        <remote>some.package.Fake</remote>
    </ejb-ref>
    <ejb-ref>
        <ejb-ref-name>another-ejb-ref</ejb-ref-name>
        <ejb-ref-type>Entity</ejb-ref-type>
        <home>some.package.FakeHome</home>
        <remote>some.package.Fake</remote>
    </ejb-ref>
    <ejb-local-ref>
        <ejb-ref-name>fake-ejb-local-ref</ejb-ref-name>
        <ejb-ref-type>Entity</ejb-ref-type>
        <local-home>some.package.FakeLocalHome</local-home>
        <local>some.package.FakeLocal</local>
    </ejb-local-ref>
    <ejb-local-ref>
        <ejb-ref-name>another-ejb-local-ref</ejb-ref-name>
        <ejb-ref-type>Entity</ejb-ref-type>
        <local-home>some.package.FakeLocalHome</local-home>
        <local>some.package.FakeLocal</local>
    </ejb-local-ref>

</web-app>


text:
package pl.warsjawa.android2.model.gmapsapi.nearby;

import java.util.List;

public class NearbyPlacesList {

    private List<NearbyPlace> results;

    public List<NearbyPlace> getResults() {
        return results;
    }
}


text:
package io.rsocket.client;

import io.rsocket.Payload;
import io.rsocket.RSocket;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.BiFunction;
import java.util.function.Function;
import org.reactivestreams.Publisher;
import org.reactivestreams.Subscriber;
import org.reactivestreams.Subscription;
import reactor.core.publisher.*;

public class TestingRSocket implements RSocket {

  private final AtomicInteger count;
  private final MonoProcessor<Void> onClose = MonoProcessor.create();
  private final BiFunction<Subscriber<? super Payload>, Payload, Boolean> eachPayloadHandler;

  public TestingRSocket(Function<Payload, Payload> responder) {
    this(
        (subscriber, payload) -> {
          subscriber.onNext(responder.apply(payload));
          return true;
        });
  }

  public TestingRSocket(
      BiFunction<Subscriber<? super Payload>, Payload, Boolean> eachPayloadHandler) {
    this.eachPayloadHandler = eachPayloadHandler;
    this.count = new AtomicInteger(0);
  }

  public int countMessageReceived() {
    return count.get();
  }

  @Override
  public Mono<Void> fireAndForget(Payload payload) {
    return Mono.empty();
  }

  @Override
  public Mono<Payload> requestResponse(Payload payload) {
    return Mono.from(
        subscriber ->
            subscriber.onSubscribe(
                new Subscription() {
                  boolean cancelled;

                  @Override
                  public void request(long n) {
                    if (cancelled) {
                      return;
                    }
                    try {
                      count.incrementAndGet();
                      if (eachPayloadHandler.apply(subscriber, payload)) {
                        subscriber.onComplete();
                      }
                    } catch (Throwable t) {
                      subscriber.onError(t);
                    }
                  }

                  @Override
                  public void cancel() {}
                }));
  }

  @Override
  public Flux<Payload> requestStream(Payload payload) {
    return requestResponse(payload).flux();
  }

  @Override
  public Flux<Payload> requestChannel(Publisher<Payload> inputs) {
    return Flux.from(
        subscriber ->
            inputs.subscribe(
                new Subscriber<Payload>() {
                  @Override
                  public void onSubscribe(Subscription s) {
                    subscriber.onSubscribe(s);
                  }

                  @Override
                  public void onNext(Payload input) {
                    eachPayloadHandler.apply(subscriber, input);
                  }

                  @Override
                  public void onError(Throwable t) {
                    subscriber.onError(t);
                  }

                  @Override
                  public void onComplete() {
                    subscriber.onComplete();
                  }
                }));
  }

  @Override
  public Mono<Void> metadataPush(Payload payload) {
    return fireAndForget(payload);
  }

  @Override
  public double availability() {
    return 1.0;
  }

  @Override
  public void dispose() {
    onClose.onComplete();
  }

  @Override
  public boolean isDisposed() {
    return onClose.isDisposed();
  }

  @Override
  public Mono<Void> onClose() {
    return onClose;
  }
}


text:
#region MIT License

#endregion

#if UseDouble
using Scalar = System.Double;
#else
using Scalar = System.Single;
#endif

using System;
using NUnit.Framework;

namespace AdvanceMath.UnitTest
{

    [TestFixture]
    public class Vector3DTest
    {
        static Random rand = new Random();
        const Scalar Value = 600;
        Vector3D op1;
        Vector3D op2;
        [SetUp]
        public void Init()
        {
            op1 = new Vector3D(Value, -Value, Value);
            op2 = new Vector3D(-Value, Value, -Value);
        }
        [Test]
        public void Equals()
        {
            Assert.IsTrue(Vector3D.Zero != Vector3D.YAxis);
            Assert.IsFalse(Vector3D.Zero == Vector3D.YAxis);
            Assert.AreEqual(Vector3D.Zero, Vector3D.Zero);
            Assert.AreNotEqual(Vector3D.Zero, Vector3D.YAxis);
        }
        [Test]
        public void Addition()
        {
            Assert.AreEqual(Vector3D.Zero, op1 + op2, "Operator");
            Assert.AreEqual(Vector3D.Zero, Vector3D.Add(op1, op2), "Method");
            UnitHelper.RefOperationTester<Vector3D>(op1, op2, Vector3D.Zero, Vector3D.Add, "Addition");
        }
        [Test]
        public void Subtraction()
        {
            Assert.AreEqual(op1 - op1, Vector3D.Zero, "Operator");
            Assert.AreEqual(Vector3D.Zero, Vector3D.Subtract(op1, op1), "Method");
            UnitHelper.RefOperationTester<Vector3D>(op1, op2, op1 - op2, Vector3D.Subtract,"Subtraction");
        }
        [Test]
        public void Dot()
        {
            Scalar expected = -(Value * Value * 3);
            UnitHelper.RefOperationTester<Vector3D, Vector3D, Scalar>(op1, op2, expected, Vector3D.Dot,"Dot");
            Assert.AreEqual(expected,op1 * op2,"Operator" );
            Assert.AreEqual(expected,Vector3D.Dot(op1, op2),"Method" );
        }
        [Test]
        public void Magnitude()
        {
            Scalar expected = MathHelper.Sqrt(Value * Value * 3);
            Assert.AreEqual(expected, op1.Magnitude, UnitHelper.Tolerance, "magnitude 1");
            Vector3D test = op1;
            expected = 6;
            test = Vector3D.SetMagnitude(test, expected);
            Assert.AreEqual(expected, test.Magnitude, UnitHelper.Tolerance, "magnitude 2");
            expected = 1;
            Vector3D.Normalize(ref test, out test);
            Assert.AreEqual(expected, test.Magnitude, UnitHelper.Tolerance, "magnitude 3");
        }
        [Test]
        public void Transform()
        {
            Assert.Fail("Not Implimented");
        }
        [Test]
        public void Min()
        {
            Assert.AreEqual(new Vector3D(-Value, -Value, -Value), Vector3D.Min(op1, op2), "1");
            UnitHelper.RefOperationTester<Vector3D>(op1, op2, new Vector3D(-Value, -Value, -Value), Vector3D.Min, "2");
        }
        [Test]
        public void Max()
        {
            Assert.AreEqual(new Vector3D(Value, Value, Value), Vector3D.Max(op1, op2), "1");
            UnitHelper.RefOperationTester<Vector3D>(op1, op2, new Vector3D(Value, Value, Value), Vector3D.Max, "2");
        }

        [Test]
        public void Multiplication()
        {
            Vector3D expected = op1;
            expected.X *= 2;
            expected.Y *= 2;
            expected.Z *= 2;
            UnitHelper.RefOperationTesterLeftSame<Scalar, Vector3D>(op1, 2, expected, Vector3D.Multiply, "1");
            UnitHelper.RefOperationTesterRightSame<Scalar, Vector3D>(2, op1, expected, Vector3D.Multiply, "2");
            Assert.AreEqual(expected, Vector3D.Multiply(2, op1), "3");
            Assert.AreEqual(expected, Vector3D.Multiply(op1, 2), "4");
            Assert.AreEqual(expected, 2 * op1, "5");
            Assert.AreEqual(expected, op1 * 2, "6");
        }
    }
}


text:
import fileinput as fi
import linecache as lc
import numpy     as np

# ----------------------------------------------------------------------- #
def getAuto( argRun ):
# ----------------------------------------------------------------------- #

	inputFileName = raw_input(' Enter name of input information: ')

	temp = fi.input( inputFileName )
	lineno = np.zeros(9, dtype = int)

	for line in temp:
		if line.find('# Name of interaction file') !=-1:
			lineno[0] = fi.lineno() + 1
		elif line.find('# Number of nuclides to run in [n] ') !=-1:
			lineno[1] = fi.lineno() + 1
		elif line.find('# Number of states to keep') !=-1:
			lineno[2] = fi.lineno() + 1
		elif line.find('# Max number of iterations') !=-1:
			lineno[3] = fi.lineno() + 1
		elif line.find('# Number of parameters') !=-1:
			lineno[4] = fi.lineno() + 1
		elif line.find('# Name of .sps file (w/out extension)') !=-1:
			lineno[5] = fi.lineno() + 1
		elif line.find('# Number of isotopes') !=-1:
			lineno[6] = fi.lineno() + 1
		elif line.find('# General output name') !=-1:
			lineno[7] = fi.lineno() + 1
		elif line.find('# Number MILCOM') !=-1:
			lineno[8] = fi.lineno() + 1
		else:
			continue

	intName    = str(lc.getline( inputFileName, int(lineno[0]) ).split()[0])
	nuclideNum = int(lc.getline( inputFileName, int(lineno[1]) ).split()[0])
	numStates  = int(lc.getline( inputFileName, int(lineno[2]) ).split()[0])
	numIter    = int(lc.getline( inputFileName, int(lineno[3]) ).split()[0])
	numParams  = int(lc.getline( inputFileName, int(lineno[4]) ).split()[0])
	spsName    = str(lc.getline( inputFileName, int(lineno[5]) ).split()[0])
	isotopeNum = int(lc.getline( inputFileName, int(lineno[6]) ).split()[0])
	mkdirName  = str(lc.getline( inputFileName, int(lineno[7]) ).split()[0])
	outputName = str(lc.getline( inputFileName, int(lineno[7]) ).split()[0])

	# Create arrays to contain nuclide information
	nuclideName = []
	nuclideA    = []
	valProNuc   = []
	valNeutNuc  = []
	jzSysNuc    = []
	# Create arrays to contain isotope information
	isotopes    = []
	valProIso   = []
	valNeutIso  = []
	jzSysIso    = []

	for i in range( nuclideNum ):
		nuclideName.append( str( lc.getline (inputFileName, lineno[1] + 1 + 5*i ).split()[0]) )
		nuclideA.append(    int( lc.getline (inputFileName, lineno[1] + 2 + 5*i ).split()[0]) )
		valProNuc.append(   int( lc.getline (inputFileName, lineno[1] + 3 + 5*i ).split()[0]) )
		valNeutNuc.append(  int( lc.getline (inputFileName, lineno[1] + 4 + 5*i ).split()[0]) )
		jzSysNuc.append(    int( lc.getline (inputFileName, lineno[1] + 5 + 5*i ).split()[0]) )

	for i in range( isotopeNum ):
		isotopes.append(   str( lc.getline (inputFileName, lineno[6] + 1 + 4*i ).split()[0]) )
		valProIso.append(  int( lc.getline (inputFileName, lineno[6] + 2 + 4*i ).split()[0]) )
		valNeutIso.append( int( lc.getline (inputFileName, lineno[6] + 3 + 4*i ).split()[0]) )
		jzSysIso.append(   int( lc.getline (inputFileName, lineno[6] + 4 + 4*i ).split()[0]) )

	return ( intName, nuclideNum, numStates, numIter, numParams, spsName,
					 isotopeNum, mkdirName, outputName, nuclideName, nuclideA, valProNuc,
					 valNeutNuc, jzSysNuc, isotopes, valProIso, valNeutIso, jzSysIso )


text:
namespace oxygine
{
    void OAL_CHECK();

    SoundSystemOAL* SoundHandleOAL::ss()
    {
        return (SoundSystemOAL*)SoundSystem::get();
    }

    SoundHandleOAL::SoundHandleOAL() : _alSource(0), _pos(0)//, _stream(0)
    {
    }

    void SoundHandleOAL::_init()
    {

    }

    void SoundHandleOAL::_restore()
    {
        alSourcef(_alSource, AL_GAIN, _volume);
        OAL_CHECK();

        alSourcef(_alSource, AL_PITCH, _pitch);
        OAL_CHECK();
    }

    void SoundHandleOAL::_play()
    {
        if (_alSource)
            _stop();

        _alSource = ss()->getSource();
        _restore();

        _xplay();

        alSourcei(_alSource, AL_BYTE_OFFSET, _pos);
        OAL_CHECK();

        alSourcePlay(_alSource);
        OAL_CHECK();
    }

    void SoundHandleOAL::_resume()
    {
        if (_alSource)
            return;

        _alSource = ss()->getSource();

        _restore();

        _xresume();

        alSourcei(_alSource, AL_BYTE_OFFSET, _pos);
        OAL_CHECK();

        alSourcePlay(_alSource);
        OAL_CHECK();
    }

    void SoundHandleOAL::_pause()
    {
        if (!_alSource)
            return;

        alGetSourcei(_alSource, AL_BYTE_OFFSET, &_pos);

#ifdef __APPLE__
        //crash ios workaround?
        _pos = 0;
#endif

        OAL_CHECK();

        _xpause();

        //_stream->pause(this);

        ss()->freeSource(_alSource);
        _alSource = 0;
        _state = paused;
    }

    void SoundHandleOAL::_stop()
    {
        if (_alSource)
        {
            _xstop();

            ss()->freeSource(_alSource);
        }

        _alSource = 0;
        _state = stopped;
        _pos = 0;
    }

    void SoundHandleOAL::_update()
    {
        if (!_alSource)
            return;

        _xupdate();

        //_stream->update(this);
    }

    void SoundHandleOAL::_updateVolume()
    {
        if (!_alSource)
            return;
        alSourcef(_alSource, AL_GAIN, _volume);
    }

    void SoundHandleOAL::_updatePitch()
    {
        if (!_alSource)
            return;
        alSourcef(_alSource, AL_PITCH, _pitch);
    }

    void SoundHandleOAL::_updateLoop()
    {
        if (!_alSource)
            return;
        _xupdateLoop();
    }

    void SoundHandleOAL::_setPosition(int tm)
    {
        _xsetPosition(tm);
    }

    void SoundHandleOAL::_ended()
    {

        _state = ended;
        ss()->freeSource(_alSource);
        _alSource = 0;
    }

    SoundHandleOAL* SoundHandleOAL::create(Sound* snd_)
    {
        SoundOAL* snd = (SoundOAL*)snd_;

        SoundHandleOAL* s = 0;
        switch (snd->getType())
        {
            case SoundOAL::Buffer:
                s = new StaticSoundHandleOAL(snd->getAlBuffer());
                break;
            case SoundOAL::Ogg:
                s = new StreamingOggSoundHandleOAL(snd);
                break;
            case SoundOAL::Wav:
                s = new StreamingWavSoundHandleOAL(snd);
                break;
            default:
                return 0;
        }

        s->_duration = snd->getDuration();

        return s;
    }
}


text:
package main

import (
	"encoding/json"
	"fmt"
	"github.com/jcelliott/lumber"
	"io/ioutil"
	"net/http"
	"strings"
)

func FetchCharInfo(d3 *career, i int) {

	fmt.Printf("Fetching details of %s - Level %.f %s\n", d3.Heroes[i].Name, d3.Heroes[i].Level, d3.Heroes[i].Class)

}

func FetchBattleTag() string {

	var battletag string
	fmt.Println("Enter your battletag?")
	fmt.Scanf("%s", &battletag)
	return battletag
}

func DoRequest(url string) ([]byte, error) {
	res, err := http.Get(url)

	if err != nil {
		panic(err.Error())
	}
	body, err := ioutil.ReadAll(res.Body)
	return body, err

}

func main() {

	var (
		i         int
		battletag string
		url       string
		career    career
		body      []byte
		err       error
	)

	log := lumber.NewConsoleLogger(lumber.WARN)
	log.Prefix("D3CD")

	battletag = FetchBattleTag()
	url = API_BASE + strings.Replace(battletag, "#", "-", 1) + "/"
	log.Debug("URL to fetch is url %s", url)
	body, err = DoRequest(url)

	err = json.Unmarshal(body, &career)

	if err != nil {
		panic(err.Error())
	}

	fmt.Println("Fetching char info")
	log.Debug("Fetched battleg %s", career.BattleTag)
	fmt.Println("Which Hero would you like to find info about?")
	for index := range career.Heroes {
		fmt.Printf("\t %d %s of %s class\n", index, career.Heroes[index].Name, career.Heroes[index].Class)
	}

	fmt.Scan(&i)
	FetchCharInfo(&career, i)

}


text:
<?php

namespace Mmi\BackBundle;

use Symfony\Component\HttpKernel\Bundle\Bundle;

class MmiBackBundle extends Bundle
{
}


text: An ANTLR4 grammar for [RFC3080](https://tools.ietf.org/html/rfc3080) BEEP frames.


text:
package com.google.android.apps.iosched.provider;

import com.google.android.apps.iosched.provider.ScheduleContract.Announcements;
import com.google.android.apps.iosched.provider.ScheduleContract.Blocks;
import com.google.android.apps.iosched.provider.ScheduleContract.Rooms;
import com.google.android.apps.iosched.provider.ScheduleContract.SearchSuggest;
import com.google.android.apps.iosched.provider.ScheduleContract.Sessions;
import com.google.android.apps.iosched.provider.ScheduleContract.Speakers;
import com.google.android.apps.iosched.provider.ScheduleContract.Tracks;
import com.google.android.apps.iosched.provider.ScheduleContract.Vendors;
import com.google.android.apps.iosched.provider.ScheduleDatabase.SessionsSearchColumns;
import com.google.android.apps.iosched.provider.ScheduleDatabase.SessionsSpeakers;
import com.google.android.apps.iosched.provider.ScheduleDatabase.SessionsTracks;
import com.google.android.apps.iosched.provider.ScheduleDatabase.Tables;
import com.google.android.apps.iosched.util.SelectionBuilder;

import android.app.Activity;
import android.app.SearchManager;
import android.content.ContentProvider;
import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentValues;
import android.content.Context;
import android.content.OperationApplicationException;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.provider.BaseColumns;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static com.google.android.apps.iosched.util.LogUtils.LOGV;
import static com.google.android.apps.iosched.util.LogUtils.LOGE;
import static com.google.android.apps.iosched.util.LogUtils.makeLogTag;

/**
 * Provider that stores {@link ScheduleContract} data. Data is usually inserted
 * by {@link com.google.android.apps.iosched.sync.SyncHelper}, and queried by various
 * {@link Activity} instances.
 */
public class ScheduleProvider extends ContentProvider {
    private static final String TAG = makeLogTag(ScheduleProvider.class);

    private ScheduleDatabase mOpenHelper;

    private static final UriMatcher sUriMatcher = buildUriMatcher();

    private static final int BLOCKS = 100;
    private static final int BLOCKS_BETWEEN = 101;
    private static final int BLOCKS_ID = 102;
    private static final int BLOCKS_ID_SESSIONS = 103;
    private static final int BLOCKS_ID_SESSIONS_STARRED = 104;

    private static final int TRACKS = 200;
    private static final int TRACKS_ID = 201;
    private static final int TRACKS_ID_SESSIONS = 202;
    private static final int TRACKS_ID_VENDORS = 203;

    private static final int ROOMS = 300;
    private static final int ROOMS_ID = 301;
    private static final int ROOMS_ID_SESSIONS = 302;

    private static final int SESSIONS = 400;
    private static final int SESSIONS_STARRED = 401;
    private static final int SESSIONS_WITH_TRACK = 402;
    private static final int SESSIONS_SEARCH = 403;
    private static final int SESSIONS_AT = 404;
    private static final int SESSIONS_ID = 405;
    private static final int SESSIONS_ID_SPEAKERS = 406;
    private static final int SESSIONS_ID_TRACKS = 407;
    private static final int SESSIONS_ID_WITH_TRACK = 408;

    private static final int SPEAKERS = 500;
    private static final int SPEAKERS_ID = 501;
    private static final int SPEAKERS_ID_SESSIONS = 502;

    private static final int VENDORS = 600;
    private static final int VENDORS_STARRED = 601;
    private static final int VENDORS_SEARCH = 603;
    private static final int VENDORS_ID = 604;

    private static final int ANNOUNCEMENTS = 700;
    private static final int ANNOUNCEMENTS_ID = 701;

    private static final int SEARCH_SUGGEST = 800;

    private static final String MIME_XML = "text/xml";

    /**
     * Build and return a {@link UriMatcher} that catches all {@link Uri}
     * variations supported by this {@link ContentProvider}.
     */
    private static UriMatcher buildUriMatcher() {
        final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
        final String authority = ScheduleContract.CONTENT_AUTHORITY;

        matcher.addURI(authority, "blocks", BLOCKS);
        matcher.addURI(authority, "blocks/between/*/*", BLOCKS_BETWEEN);
        matcher.addURI(authority, "blocks/*", BLOCKS_ID);
        matcher.addURI(authority, "blocks/*/sessions", BLOCKS_ID_SESSIONS);
        matcher.addURI(authority, "blocks/*/sessions/starred", BLOCKS_ID_SESSIONS_STARRED);

        matcher.addURI(authority, "tracks", TRACKS);
        matcher.addURI(authority, "tracks/*", TRACKS_ID);
        matcher.addURI(authority, "tracks/*/sessions", TRACKS_ID_SESSIONS);
        matcher.addURI(authority, "tracks/*/vendors", TRACKS_ID_VENDORS);

        matcher.addURI(authority, "rooms", ROOMS);
        matcher.addURI(authority, "rooms/*", ROOMS_ID);
        matcher.addURI(authority, "rooms/*/sessions", ROOMS_ID_SESSIONS);

        matcher.addURI(authority, "sessions", SESSIONS);
        matcher.addURI(authority, "sessions/starred", SESSIONS_STARRED);
        matcher.addURI(authority, "sessions/with_track", SESSIONS_WITH_TRACK);
        matcher.addURI(authority, "sessions/search/*", SESSIONS_SEARCH);
        matcher.addURI(authority, "sessions/at/*", SESSIONS_AT);
        matcher.addURI(authority, "sessions/*", SESSIONS_ID);
        matcher.addURI(authority, "sessions/*/speakers", SESSIONS_ID_SPEAKERS);
        matcher.addURI(authority, "sessions/*/tracks", SESSIONS_ID_TRACKS);
        matcher.addURI(authority, "sessions/*/with_track", SESSIONS_ID_WITH_TRACK);

        matcher.addURI(authority, "speakers", SPEAKERS);
        matcher.addURI(authority, "speakers/*", SPEAKERS_ID);
        matcher.addURI(authority, "speakers/*/sessions", SPEAKERS_ID_SESSIONS);

        matcher.addURI(authority, "vendors", VENDORS);
        matcher.addURI(authority, "vendors/starred", VENDORS_STARRED);
        matcher.addURI(authority, "vendors/search/*", VENDORS_SEARCH);
        matcher.addURI(authority, "vendors/*", VENDORS_ID);

        matcher.addURI(authority, "announcements", ANNOUNCEMENTS);
        matcher.addURI(authority, "announcements/*", ANNOUNCEMENTS_ID);

        matcher.addURI(authority, "search_suggest_query", SEARCH_SUGGEST);

        return matcher;
    }

    @Override
    public boolean onCreate() {
        mOpenHelper = new ScheduleDatabase(getContext());
        return true;
    }

    private void deleteDatabase() {
        // TODO: wait for content provider operations to finish, then tear down
        mOpenHelper.close();
        Context context = getContext();
        ScheduleDatabase.deleteDatabase(context);
        mOpenHelper = new ScheduleDatabase(getContext());
    }

    /** {@inheritDoc} */
    @Override
    public String getType(Uri uri) {
        final int match = sUriMatcher.match(uri);
        switch (match) {
            case BLOCKS:
                return Blocks.CONTENT_TYPE;
            case BLOCKS_BETWEEN:
                return Blocks.CONTENT_TYPE;
            case BLOCKS_ID:
                return Blocks.CONTENT_ITEM_TYPE;
            case BLOCKS_ID_SESSIONS:
                return Sessions.CONTENT_TYPE;
            case BLOCKS_ID_SESSIONS_STARRED:
                return Sessions.CONTENT_TYPE;
            case TRACKS:
                return Tracks.CONTENT_TYPE;
            case TRACKS_ID:
                return Tracks.CONTENT_ITEM_TYPE;
            case TRACKS_ID_SESSIONS:
                return Sessions.CONTENT_TYPE;
            case TRACKS_ID_VENDORS:
                return Vendors.CONTENT_TYPE;
            case ROOMS:
                return Rooms.CONTENT_TYPE;
            case ROOMS_ID:
                return Rooms.CONTENT_ITEM_TYPE;
            case ROOMS_ID_SESSIONS:
                return Sessions.CONTENT_TYPE;
            case SESSIONS:
                return Sessions.CONTENT_TYPE;
            case SESSIONS_STARRED:
                return Sessions.CONTENT_TYPE;
            case SESSIONS_WITH_TRACK:
                return Sessions.CONTENT_TYPE;
            case SESSIONS_SEARCH:
                return Sessions.CONTENT_TYPE;
            case SESSIONS_AT:
                return Sessions.CONTENT_TYPE;
            case SESSIONS_ID:
                return Sessions.CONTENT_ITEM_TYPE;
            case SESSIONS_ID_SPEAKERS:
                return Speakers.CONTENT_TYPE;
            case SESSIONS_ID_TRACKS:
                return Tracks.CONTENT_TYPE;
            case SESSIONS_ID_WITH_TRACK:
                return Sessions.CONTENT_TYPE;
            case SPEAKERS:
                return Speakers.CONTENT_TYPE;
            case SPEAKERS_ID:
                return Speakers.CONTENT_ITEM_TYPE;
            case SPEAKERS_ID_SESSIONS:
                return Sessions.CONTENT_TYPE;
            case VENDORS:
                return Vendors.CONTENT_TYPE;
            case VENDORS_STARRED:
                return Vendors.CONTENT_TYPE;
            case VENDORS_SEARCH:
                return Vendors.CONTENT_TYPE;
            case VENDORS_ID:
                return Vendors.CONTENT_ITEM_TYPE;
            case ANNOUNCEMENTS:
                return Announcements.CONTENT_TYPE;
            case ANNOUNCEMENTS_ID:
                return Announcements.CONTENT_ITEM_TYPE;
            default:
                throw new UnsupportedOperationException("Unknown uri: " + uri);
        }
    }

    /** {@inheritDoc} */
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
            String sortOrder) {
        LOGV(TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")");
//        LOGE(TAG, "query(uri=" + uri + ", proj=" + Arrays.toString(projection) + ")");

        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();

        final int match = sUriMatcher.match(uri);
        switch (match) {
            default: {
                // Most cases are handled with simple SelectionBuilder
                final SelectionBuilder builder = buildExpandedSelection(uri, match);
                return builder.where(selection, selectionArgs).query(db, projection, sortOrder);
            }
            case SEARCH_SUGGEST: {
                final SelectionBuilder builder = new SelectionBuilder();

                // Adjust incoming query to become SQL text match
                selectionArgs[0] = selectionArgs[0] + "%";
                builder.table(Tables.SEARCH_SUGGEST);
                builder.where(selection, selectionArgs);
                builder.map(SearchManager.SUGGEST_COLUMN_QUERY,
                        SearchManager.SUGGEST_COLUMN_TEXT_1);

                projection = new String[] {
                        BaseColumns._ID,
                        SearchManager.SUGGEST_COLUMN_TEXT_1,
                        SearchManager.SUGGEST_COLUMN_QUERY
                };

                final String limit = uri.getQueryParameter(SearchManager.SUGGEST_PARAMETER_LIMIT);
                return builder.query(db, projection, null, null, SearchSuggest.DEFAULT_SORT, limit);
            }
        }
    }

    /** {@inheritDoc} */
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        LOGV(TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")");
//        LOGE(TAG, "insert(uri=" + uri + ", values=" + values.toString() + ")");

        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        final int match = sUriMatcher.match(uri);
        boolean syncToNetwork = !ScheduleContract.hasCallerIsSyncAdapterParameter(uri);
        switch (match) {
            case BLOCKS: {
                db.insertOrThrow(Tables.BLOCKS, null, values);
                getContext().getContentResolver().notifyChange(uri, null, syncToNetwork);
                return Blocks.buildBlockUri(values.getAsString(Blocks.BLOCK_ID));
            }
            case TRACKS: {
                db.insertOrThrow(Tables.TRACKS, null, values);
                getContext().getContentResolver().notifyChange(uri, null, syncToNetwork);
                return Tracks.buildTrackUri(values.getAsString(Tracks.TRACK_ID));
            }
            case ROOMS: {
                db.insertOrThrow(Tables.ROOMS, null, values);
                getContext().getContentResolver().notifyChange(uri, null, syncToNetwork);
                return Rooms.buildRoomUri(values.getAsString(Rooms.ROOM_ID));
            }
            case SESSIONS: {
                db.insertOrThrow(Tables.SESSIONS, null, values);
                getContext().getContentResolver().notifyChange(uri, null, syncToNetwork);
                return Sessions.buildSessionUri(values.getAsString(Sessions.SESSION_ID));
            }
            case SESSIONS_ID_SPEAKERS: {
                db.insertOrThrow(Tables.SESSIONS_SPEAKERS, null, values);
                getContext().getContentResolver().notifyChange(uri, null, syncToNetwork);
                return Speakers.buildSpeakerUri(values.getAsString(SessionsSpeakers.SPEAKER_ID));
            }
            case SESSIONS_ID_TRACKS: {
                db.insertOrThrow(Tables.SESSIONS_TRACKS, null, values);
                getContext().getContentResolver().notifyChange(uri, null, syncToNetwork);
                return Tracks.buildTrackUri(values.getAsString(SessionsTracks.TRACK_ID));
            }
            case SPEAKERS: {
                db.insertOrThrow(Tables.SPEAKERS, null, values);
                getContext().getContentResolver().notifyChange(uri, null, syncToNetwork);
                return Speakers.buildSpeakerUri(values.getAsString(Speakers.SPEAKER_ID));
            }
            case VENDORS: {
                db.insertOrThrow(Tables.VENDORS, null, values);
                getContext().getContentResolver().notifyChange(uri, null, syncToNetwork);
                return Vendors.buildVendorUri(values.getAsString(Vendors.VENDOR_ID));
            }
            case ANNOUNCEMENTS: {
                db.insertOrThrow(Tables.ANNOUNCEMENTS, null, values);
                getContext().getContentResolver().notifyChange(uri, null, syncToNetwork);
                return Announcements.buildAnnouncementUri(values
                        .getAsString(Announcements.ANNOUNCEMENT_ID));
            }
            case SEARCH_SUGGEST: {
                db.insertOrThrow(Tables.SEARCH_SUGGEST, null, values);
                getContext().getContentResolver().notifyChange(uri, null, syncToNetwork);
                return SearchSuggest.CONTENT_URI;
            }
            default: {
                throw new UnsupportedOperationException("Unknown uri: " + uri);
            }
        }
    }

    /** {@inheritDoc} */
    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        LOGV(TAG, "update(uri=" + uri + ", values=" + values.toString() + ")");
//        LOGE(TAG, "update(uri=" + uri + ", values=" + values.toString() + ")");

        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        final SelectionBuilder builder = buildSimpleSelection(uri);
        int retVal = builder.where(selection, selectionArgs).update(db, values);
        boolean syncToNetwork = !ScheduleContract.hasCallerIsSyncAdapterParameter(uri);
        getContext().getContentResolver().notifyChange(uri, null, syncToNetwork);
        return retVal;
    }

    /** {@inheritDoc} */
    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        LOGV(TAG, "delete(uri=" + uri + ")");
        if (uri == ScheduleContract.BASE_CONTENT_URI) {
            // Handle whole database deletes (e.g. when signing out)
            deleteDatabase();
            getContext().getContentResolver().notifyChange(uri, null, false);
            return 1;
        }
        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        final SelectionBuilder builder = buildSimpleSelection(uri);
        int retVal = builder.where(selection, selectionArgs).delete(db);
        getContext().getContentResolver().notifyChange(uri, null,
                !ScheduleContract.hasCallerIsSyncAdapterParameter(uri));
        return retVal;
    }

    /**
     * Apply the given set of {@link ContentProviderOperation}, executing inside
     * a {@link SQLiteDatabase} transaction. All changes will be rolled back if
     * any single one fails.
     */
    @Override
    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
            throws OperationApplicationException {
        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
        db.beginTransaction();
        try {
            final int numOperations = operations.size();
            final ContentProviderResult[] results = new ContentProviderResult[numOperations];
            for (int i = 0; i < numOperations; i++) {
                results[i] = operations.get(i).apply(this, results, i);
            }
            db.setTransactionSuccessful();
            return results;
        } finally {
            db.endTransaction();
        }
    }

    /**
     * Build a simple {@link SelectionBuilder} to match the requested
     * {@link Uri}. This is usually enough to support {@link #insert},
     * {@link #update}, and {@link #delete} operations.
     */
    private SelectionBuilder buildSimpleSelection(Uri uri) {
        final SelectionBuilder builder = new SelectionBuilder();
        final int match = sUriMatcher.match(uri);
        switch (match) {
            case BLOCKS: {
                return builder.table(Tables.BLOCKS);
            }
            case BLOCKS_ID: {
                final String blockId = Blocks.getBlockId(uri);
                return builder.table(Tables.BLOCKS)
                        .where(Blocks.BLOCK_ID + "=?", blockId);
            }
            case TRACKS: {
                return builder.table(Tables.TRACKS);
            }
            case TRACKS_ID: {
                final String trackId = Tracks.getTrackId(uri);
                return builder.table(Tables.TRACKS)
                        .where(Tracks.TRACK_ID + "=?", trackId);
            }
            case ROOMS: {
                return builder.table(Tables.ROOMS);
            }
            case ROOMS_ID: {
                final String roomId = Rooms.getRoomId(uri);
                return builder.table(Tables.ROOMS)
                        .where(Rooms.ROOM_ID + "=?", roomId);
            }
            case SESSIONS: {
                return builder.table(Tables.SESSIONS);
            }
            case SESSIONS_ID: {
                final String sessionId = Sessions.getSessionId(uri);
                return builder.table(Tables.SESSIONS)
                        .where(Sessions.SESSION_ID + "=?", sessionId);
            }
            case SESSIONS_ID_SPEAKERS: {
                final String sessionId = Sessions.getSessionId(uri);
                return builder.table(Tables.SESSIONS_SPEAKERS)
                        .where(Sessions.SESSION_ID + "=?", sessionId);
            }
            case SESSIONS_ID_TRACKS: {
                final String sessionId = Sessions.getSessionId(uri);
                return builder.table(Tables.SESSIONS_TRACKS)
                        .where(Sessions.SESSION_ID + "=?", sessionId);
            }
            case SPEAKERS: {
                return builder.table(Tables.SPEAKERS);
            }
            case SPEAKERS_ID: {
                final String speakerId = Speakers.getSpeakerId(uri);
                return builder.table(Tables.SPEAKERS)
                        .where(Speakers.SPEAKER_ID + "=?", speakerId);
            }
            case VENDORS: {
                return builder.table(Tables.VENDORS);
            }
            case VENDORS_ID: {
                final String vendorId = Vendors.getVendorId(uri);
                return builder.table(Tables.VENDORS)
                        .where(Vendors.VENDOR_ID + "=?", vendorId);
            }
            case ANNOUNCEMENTS: {
                return builder.table(Tables.ANNOUNCEMENTS);
            }
            case ANNOUNCEMENTS_ID: {
                final String announcementId = Announcements.getAnnouncementId(uri);
                return builder.table(Tables.ANNOUNCEMENTS)
                        .where(Announcements.ANNOUNCEMENT_ID + "=?", announcementId);
            }
            case SEARCH_SUGGEST: {
                return builder.table(Tables.SEARCH_SUGGEST);
            }
            default: {
                throw new UnsupportedOperationException("Unknown uri: " + uri);
            }
        }
    }

    /**
     * Build an advanced {@link SelectionBuilder} to match the requested
     * {@link Uri}. This is usually only used by {@link #query}, since it
     * performs table joins useful for {@link Cursor} data.
     */
    private SelectionBuilder buildExpandedSelection(Uri uri, int match) {
        final SelectionBuilder builder = new SelectionBuilder();
        switch (match) {
            case BLOCKS: {
                return builder
                        .table(Tables.BLOCKS)
                        .map(Blocks.SESSIONS_COUNT, Subquery.BLOCK_SESSIONS_COUNT)
                        .map(Blocks.NUM_STARRED_SESSIONS, Subquery.BLOCK_NUM_STARRED_SESSIONS)
                        .map(Blocks.STARRED_SESSION_ID, Subquery.BLOCK_STARRED_SESSION_ID)
                        .map(Blocks.STARRED_SESSION_TITLE, Subquery.BLOCK_STARRED_SESSION_TITLE)
                        .map(Blocks.STARRED_SESSION_HASHTAGS,
                                Subquery.BLOCK_STARRED_SESSION_HASHTAGS)
                        .map(Blocks.STARRED_SESSION_URL, Subquery.BLOCK_STARRED_SESSION_URL)
                        .map(Blocks.STARRED_SESSION_LIVESTREAM_URL,
                                Subquery.BLOCK_STARRED_SESSION_LIVESTREAM_URL)
                        .map(Blocks.STARRED_SESSION_ROOM_NAME,
                                Subquery.BLOCK_STARRED_SESSION_ROOM_NAME)
                        .map(Blocks.STARRED_SESSION_ROOM_ID, Subquery.BLOCK_STARRED_SESSION_ROOM_ID);
            }
            case BLOCKS_BETWEEN: {
                final List<String> segments = uri.getPathSegments();
                final String startTime = segments.get(2);
                final String endTime = segments.get(3);
                return builder.table(Tables.BLOCKS)
                        .map(Blocks.SESSIONS_COUNT, Subquery.BLOCK_SESSIONS_COUNT)
                        .map(Blocks.NUM_STARRED_SESSIONS, Subquery.BLOCK_NUM_STARRED_SESSIONS)
                        .where(Blocks.BLOCK_START + ">=?", startTime)
                        .where(Blocks.BLOCK_START + "<=?", endTime);
            }
            case BLOCKS_ID: {
                final String blockId = Blocks.getBlockId(uri);
                return builder.table(Tables.BLOCKS)
                        .map(Blocks.SESSIONS_COUNT, Subquery.BLOCK_SESSIONS_COUNT)
                        .map(Blocks.NUM_STARRED_SESSIONS, Subquery.BLOCK_NUM_STARRED_SESSIONS)
                        .where(Blocks.BLOCK_ID + "=?", blockId);
            }
            case BLOCKS_ID_SESSIONS: {
                final String blockId = Blocks.getBlockId(uri);
                return builder.table(Tables.SESSIONS_JOIN_BLOCKS_ROOMS)
                        .map(Blocks.SESSIONS_COUNT, Subquery.BLOCK_SESSIONS_COUNT)
                        .map(Blocks.NUM_STARRED_SESSIONS, Subquery.BLOCK_NUM_STARRED_SESSIONS)
                        .mapToTable(Sessions._ID, Tables.SESSIONS)
                        .mapToTable(Sessions.SESSION_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.BLOCK_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.ROOM_ID, Tables.SESSIONS)
                        .where(Qualified.SESSIONS_BLOCK_ID + "=?", blockId);
            }
            case BLOCKS_ID_SESSIONS_STARRED: {
                final String blockId = Blocks.getBlockId(uri);
                return builder.table(Tables.SESSIONS_JOIN_BLOCKS_ROOMS)
                        .map(Blocks.SESSIONS_COUNT, Subquery.BLOCK_SESSIONS_COUNT)
                        .map(Blocks.NUM_STARRED_SESSIONS, Subquery.BLOCK_NUM_STARRED_SESSIONS)
                        .mapToTable(Sessions._ID, Tables.SESSIONS)
                        .mapToTable(Sessions.SESSION_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.BLOCK_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.ROOM_ID, Tables.SESSIONS)
                        .where(Qualified.SESSIONS_BLOCK_ID + "=?", blockId)
                        .where(Qualified.SESSIONS_STARRED + "=1");
            }
            case TRACKS: {
                return builder.table(Tables.TRACKS)
                        .map(Tracks.SESSIONS_COUNT, Subquery.TRACK_SESSIONS_COUNT)
                        .map(Tracks.VENDORS_COUNT, Subquery.TRACK_VENDORS_COUNT);
            }
            case TRACKS_ID: {
                final String trackId = Tracks.getTrackId(uri);
                return builder.table(Tables.TRACKS)
                        .where(Tracks.TRACK_ID + "=?", trackId);
            }
            case TRACKS_ID_SESSIONS: {
                final String trackId = Tracks.getTrackId(uri);
                return builder.table(Tables.SESSIONS_TRACKS_JOIN_SESSIONS_BLOCKS_ROOMS)
                        .mapToTable(Sessions._ID, Tables.SESSIONS)
                        .mapToTable(Sessions.SESSION_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.BLOCK_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.ROOM_ID, Tables.SESSIONS)
                        .where(Qualified.SESSIONS_TRACKS_TRACK_ID + "=?", trackId);
            }
            case TRACKS_ID_VENDORS: {
                final String trackId = Tracks.getTrackId(uri);
                return builder.table(Tables.VENDORS_JOIN_TRACKS)
                        .mapToTable(Vendors._ID, Tables.VENDORS)
                        .mapToTable(Vendors.TRACK_ID, Tables.VENDORS)
                        .where(Qualified.VENDORS_TRACK_ID + "=?", trackId);
            }
            case ROOMS: {
                return builder.table(Tables.ROOMS);
            }
            case ROOMS_ID: {
                final String roomId = Rooms.getRoomId(uri);
                return builder.table(Tables.ROOMS)
                        .where(Rooms.ROOM_ID + "=?", roomId);
            }
            case ROOMS_ID_SESSIONS: {
                final String roomId = Rooms.getRoomId(uri);
                return builder.table(Tables.SESSIONS_JOIN_BLOCKS_ROOMS)
                        .mapToTable(Sessions._ID, Tables.SESSIONS)
                        .mapToTable(Sessions.BLOCK_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.ROOM_ID, Tables.SESSIONS)
                        .where(Qualified.SESSIONS_ROOM_ID + "=?", roomId);
            }
            case SESSIONS: {
                return builder.table(Tables.SESSIONS_JOIN_BLOCKS_ROOMS)
                        .mapToTable(Sessions._ID, Tables.SESSIONS)
                        .mapToTable(Sessions.BLOCK_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.ROOM_ID, Tables.SESSIONS);
            }
            case SESSIONS_STARRED: {
                return builder.table(Tables.SESSIONS_JOIN_BLOCKS_ROOMS)
                        .mapToTable(Sessions._ID, Tables.SESSIONS)
                        .mapToTable(Sessions.BLOCK_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.ROOM_ID, Tables.SESSIONS)
                        .where(Sessions.SESSION_STARRED + "=1");
            }
            case SESSIONS_WITH_TRACK: {
                return builder.table(Tables.SESSIONS_JOIN_TRACKS_JOIN_BLOCKS)
                        .mapToTable(Sessions._ID, Tables.SESSIONS)
                        .mapToTable(Sessions.SESSION_ID, Tables.SESSIONS)
                        .mapToTable(Tracks.TRACK_ID, Tables.TRACKS)
                        .mapToTable(Tracks.TRACK_NAME, Tables.TRACKS)
                        .mapToTable(Blocks.BLOCK_ID, Tables.BLOCKS);
            }
            case SESSIONS_ID_WITH_TRACK: {
                final String sessionId = Sessions.getSessionId(uri);
                return builder.table(Tables.SESSIONS_JOIN_TRACKS_JOIN_BLOCKS)
                        .mapToTable(Sessions._ID, Tables.SESSIONS)
                        .mapToTable(Sessions.SESSION_ID, Tables.SESSIONS)
                        .mapToTable(Tracks.TRACK_ID, Tables.TRACKS)
                        .mapToTable(Tracks.TRACK_NAME, Tables.TRACKS)
                        .mapToTable(Blocks.BLOCK_ID, Tables.BLOCKS)
                        .where(Qualified.SESSIONS_SESSION_ID + "=?", sessionId);
            }
            case SESSIONS_SEARCH: {
                final String query = Sessions.getSearchQuery(uri);
                return builder.table(Tables.SESSIONS_SEARCH_JOIN_SESSIONS_BLOCKS_ROOMS)
                        .map(Sessions.SEARCH_SNIPPET, Subquery.SESSIONS_SNIPPET)
                        .mapToTable(Sessions._ID, Tables.SESSIONS)
                        .mapToTable(Sessions.SESSION_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.BLOCK_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.ROOM_ID, Tables.SESSIONS)
                        .where(SessionsSearchColumns.BODY + " MATCH ?", query);
            }
            case SESSIONS_AT: {
                final List<String> segments = uri.getPathSegments();
                final String time = segments.get(2);
                return builder.table(Tables.SESSIONS_JOIN_BLOCKS_ROOMS)
                        .mapToTable(Sessions._ID, Tables.SESSIONS)
                        .mapToTable(Sessions.BLOCK_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.ROOM_ID, Tables.SESSIONS)
                        .where(Sessions.BLOCK_START + "<=?", time)
                        .where(Sessions.BLOCK_END + ">=?", time);
            }
            case SESSIONS_ID: {
                final String sessionId = Sessions.getSessionId(uri);
                return builder.table(Tables.SESSIONS_JOIN_BLOCKS_ROOMS)
                        .mapToTable(Sessions._ID, Tables.SESSIONS)
                        .mapToTable(Sessions.BLOCK_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.ROOM_ID, Tables.SESSIONS)
                        .where(Qualified.SESSIONS_SESSION_ID + "=?", sessionId);
            }
            case SESSIONS_ID_SPEAKERS: {
                final String sessionId = Sessions.getSessionId(uri);
                return builder.table(Tables.SESSIONS_SPEAKERS_JOIN_SPEAKERS)
                        .mapToTable(Speakers._ID, Tables.SPEAKERS)
                        .mapToTable(Speakers.SPEAKER_ID, Tables.SPEAKERS)
                        .where(Qualified.SESSIONS_SPEAKERS_SESSION_ID + "=?", sessionId);
            }
            case SESSIONS_ID_TRACKS: {
                final String sessionId = Sessions.getSessionId(uri);
                return builder.table(Tables.SESSIONS_TRACKS_JOIN_TRACKS)
                        .mapToTable(Tracks._ID, Tables.TRACKS)
                        .mapToTable(Tracks.TRACK_ID, Tables.TRACKS)
                        .where(Qualified.SESSIONS_TRACKS_SESSION_ID + "=?", sessionId);
            }
            case SPEAKERS: {
                return builder.table(Tables.SPEAKERS);
            }
            case SPEAKERS_ID: {
                final String speakerId = Speakers.getSpeakerId(uri);
                return builder.table(Tables.SPEAKERS)
                        .where(Speakers.SPEAKER_ID + "=?", speakerId);
            }
            case SPEAKERS_ID_SESSIONS: {
                final String speakerId = Speakers.getSpeakerId(uri);
                return builder.table(Tables.SESSIONS_SPEAKERS_JOIN_SESSIONS_BLOCKS_ROOMS)
                        .mapToTable(Sessions._ID, Tables.SESSIONS)
                        .mapToTable(Sessions.SESSION_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.BLOCK_ID, Tables.SESSIONS)
                        .mapToTable(Sessions.ROOM_ID, Tables.SESSIONS)
                        .where(Qualified.SESSIONS_SPEAKERS_SPEAKER_ID + "=?", speakerId);
            }
            case VENDORS: {
                return builder.table(Tables.VENDORS_JOIN_TRACKS)
                        .mapToTable(Vendors._ID, Tables.VENDORS)
                        .mapToTable(Vendors.TRACK_ID, Tables.VENDORS);
            }
            case VENDORS_STARRED: {
                return builder.table(Tables.VENDORS_JOIN_TRACKS)
                        .mapToTable(Vendors._ID, Tables.VENDORS)
                        .mapToTable(Vendors.TRACK_ID, Tables.VENDORS)
                        .where(Vendors.VENDOR_STARRED + "=1");
            }
            case VENDORS_ID: {
                final String vendorId = Vendors.getVendorId(uri);
                return builder.table(Tables.VENDORS_JOIN_TRACKS)
                        .mapToTable(Vendors._ID, Tables.VENDORS)
                        .mapToTable(Vendors.TRACK_ID, Tables.VENDORS)
                        .where(Vendors.VENDOR_ID + "=?", vendorId);
            }
            case ANNOUNCEMENTS: {
                return builder.table(Tables.ANNOUNCEMENTS);
            }
            case ANNOUNCEMENTS_ID: {
                final String announcementId = Announcements.getAnnouncementId(uri);
                return builder.table(Tables.ANNOUNCEMENTS)
                        .where(Announcements.ANNOUNCEMENT_ID + "=?", announcementId);
            }
            default: {
                throw new UnsupportedOperationException("Unknown uri: " + uri);
            }
        }
    }

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        final int match = sUriMatcher.match(uri);
        switch (match) {
            default: {
                throw new UnsupportedOperationException("Unknown uri: " + uri);
            }
        }
    }

    private interface Subquery {
        String BLOCK_SESSIONS_COUNT = "(SELECT COUNT(" + Qualified.SESSIONS_SESSION_ID + ") FROM "
                + Tables.SESSIONS + " WHERE " + Qualified.SESSIONS_BLOCK_ID + "="
                + Qualified.BLOCKS_BLOCK_ID + ")";

        String BLOCK_NUM_STARRED_SESSIONS = "(SELECT COUNT(1) FROM "
                + Tables.SESSIONS + " WHERE " + Qualified.SESSIONS_BLOCK_ID + "="
                + Qualified.BLOCKS_BLOCK_ID + " AND " + Qualified.SESSIONS_STARRED + "=1)";

        String BLOCK_STARRED_SESSION_ID = "(SELECT " + Qualified.SESSIONS_SESSION_ID + " FROM "
                + Tables.SESSIONS + " WHERE " + Qualified.SESSIONS_BLOCK_ID + "="
                + Qualified.BLOCKS_BLOCK_ID + " AND " + Qualified.SESSIONS_STARRED + "=1 "
                + "ORDER BY " + Qualified.SESSIONS_TITLE + ")";

        String BLOCK_STARRED_SESSION_TITLE = "(SELECT " + Qualified.SESSIONS_TITLE + " FROM "
                + Tables.SESSIONS + " WHERE " + Qualified.SESSIONS_BLOCK_ID + "="
                + Qualified.BLOCKS_BLOCK_ID + " AND " + Qualified.SESSIONS_STARRED + "=1 "
                + "ORDER BY " + Qualified.SESSIONS_TITLE + ")";

        String BLOCK_STARRED_SESSION_HASHTAGS = "(SELECT " + Qualified.SESSIONS_HASHTAGS + " FROM "
                + Tables.SESSIONS + " WHERE " + Qualified.SESSIONS_BLOCK_ID + "="
                + Qualified.BLOCKS_BLOCK_ID + " AND " + Qualified.SESSIONS_STARRED + "=1 "
                + "ORDER BY " + Qualified.SESSIONS_TITLE + ")";

        String BLOCK_STARRED_SESSION_URL = "(SELECT " + Qualified.SESSIONS_URL + " FROM "
                + Tables.SESSIONS + " WHERE " + Qualified.SESSIONS_BLOCK_ID + "="
                + Qualified.BLOCKS_BLOCK_ID + " AND " + Qualified.SESSIONS_STARRED + "=1 "
                + "ORDER BY " + Qualified.SESSIONS_TITLE + ")";

        String BLOCK_STARRED_SESSION_LIVESTREAM_URL = "(SELECT "
                + Qualified.SESSIONS_LIVESTREAM_URL
                + " FROM "
                + Tables.SESSIONS + " WHERE " + Qualified.SESSIONS_BLOCK_ID + "="
                + Qualified.BLOCKS_BLOCK_ID + " AND " + Qualified.SESSIONS_STARRED + "=1 "
                + "ORDER BY " + Qualified.SESSIONS_TITLE + ")";

        String BLOCK_STARRED_SESSION_ROOM_NAME = "(SELECT " + Qualified.ROOMS_ROOM_NAME + " FROM "
                + Tables.SESSIONS_JOIN_ROOMS + " WHERE " + Qualified.SESSIONS_BLOCK_ID + "="
                + Qualified.BLOCKS_BLOCK_ID + " AND " + Qualified.SESSIONS_STARRED + "=1 "
                + "ORDER BY " + Qualified.SESSIONS_TITLE + ")";

        String BLOCK_STARRED_SESSION_ROOM_ID = "(SELECT " + Qualified.ROOMS_ROOM_ID + " FROM "
                + Tables.SESSIONS_JOIN_ROOMS + " WHERE " + Qualified.SESSIONS_BLOCK_ID + "="
                + Qualified.BLOCKS_BLOCK_ID + " AND " + Qualified.SESSIONS_STARRED + "=1 "
                + "ORDER BY " + Qualified.SESSIONS_TITLE + ")";

        String TRACK_SESSIONS_COUNT = "(SELECT COUNT(" + Qualified.SESSIONS_TRACKS_SESSION_ID
                + ") FROM " + Tables.SESSIONS_TRACKS + " WHERE "
                + Qualified.SESSIONS_TRACKS_TRACK_ID + "=" + Qualified.TRACKS_TRACK_ID + ")";

        String TRACK_VENDORS_COUNT = "(SELECT COUNT(" + Qualified.VENDORS_VENDOR_ID + ") FROM "
                + Tables.VENDORS + " WHERE " + Qualified.VENDORS_TRACK_ID + "="
                + Qualified.TRACKS_TRACK_ID + ")";

        String SESSIONS_SNIPPET = "snippet(" + Tables.SESSIONS_SEARCH + ",'{','}','\u2026')";
    }

    /**
     * {@link ScheduleContract} fields that are fully qualified with a specific
     * parent {@link Tables}. Used when needed to work around SQL ambiguity.
     */
    private interface Qualified {
        String SESSIONS_SESSION_ID = Tables.SESSIONS + "." + Sessions.SESSION_ID;
        String SESSIONS_BLOCK_ID = Tables.SESSIONS + "." + Sessions.BLOCK_ID;
        String SESSIONS_ROOM_ID = Tables.SESSIONS + "." + Sessions.ROOM_ID;

        String SESSIONS_TRACKS_SESSION_ID = Tables.SESSIONS_TRACKS + "."
                + SessionsTracks.SESSION_ID;
        String SESSIONS_TRACKS_TRACK_ID = Tables.SESSIONS_TRACKS + "."
                + SessionsTracks.TRACK_ID;

        String SESSIONS_SPEAKERS_SESSION_ID = Tables.SESSIONS_SPEAKERS + "."
                + SessionsSpeakers.SESSION_ID;
        String SESSIONS_SPEAKERS_SPEAKER_ID = Tables.SESSIONS_SPEAKERS + "."
                + SessionsSpeakers.SPEAKER_ID;

        String VENDORS_VENDOR_ID = Tables.VENDORS + "." + Vendors.VENDOR_ID;
        String VENDORS_TRACK_ID = Tables.VENDORS + "." + Vendors.TRACK_ID;

        String SESSIONS_STARRED = Tables.SESSIONS + "." + Sessions.SESSION_STARRED;
        String SESSIONS_TITLE = Tables.SESSIONS + "." + Sessions.SESSION_TITLE;
        String SESSIONS_HASHTAGS = Tables.SESSIONS + "." + Sessions.SESSION_HASHTAGS;
        String SESSIONS_URL = Tables.SESSIONS + "." + Sessions.SESSION_URL;

        String SESSIONS_LIVESTREAM_URL = Tables.SESSIONS + "." + Sessions.SESSION_LIVESTREAM_URL;

        String ROOMS_ROOM_NAME = Tables.ROOMS + "." + Rooms.ROOM_NAME;
        String ROOMS_ROOM_ID = Tables.ROOMS + "." + Rooms.ROOM_ID;

        String TRACKS_TRACK_ID = Tables.TRACKS + "." + Tracks.TRACK_ID;
        String BLOCKS_BLOCK_ID = Tables.BLOCKS + "." + Blocks.BLOCK_ID;
    }
}


text:
@interface TWTCompoundValidatorTests : TWTRandomizedTestCase

- (void)testInit;
- (void)testCopy;
- (void)testHashAndIsEqual;

- (void)testValidateValueErrorForNotWithPassingValidator;
- (void)testValidateValueErrorForNotWithFailingValidator;

- (void)testValidateValueErrorForAndWithNoValidators;
- (void)testValidateValueErrorForAndWithOnePassingValidator;
- (void)testValidateValueErrorForAndWithMultiplePassingValidators;
- (void)testValidateValueErrorForAndWithOneFailingValidator;
- (void)testValidateValueErrorForAndWithMultipleFailingValidators;

- (void)testValidateValueErrorForOrWithNoValidators;
- (void)testValidateValueErrorForOrWithOnePassingValidator;
- (void)testValidateValueErrorForOrWithMultiplePassingValidators;
- (void)testValidateValueErrorForOrWithOneFailingValidator;
- (void)testValidateValueErrorForOrWithMultipleFailingValidators;

- (void)testValidateValueErrorForMutualExclusionWithNoValidators;
- (void)testValidateValueErrorForMutualExclusionWithOnePassingValidator;
- (void)testValidateValueErrorForMutualExclusionWithMultiplePassingValidators;
- (void)testValidateValueErrorForMutualExclusionWithOneFailingValidator;
- (void)testValidateValueErrorForMutualExclusionWithMultipleFailingValidators;

@end

#pragma mark

@implementation TWTCompoundValidatorTests

- (TWTCompoundValidatorType)randomCompoundValidatorType
{
    TWTCompoundValidatorType types[3] = { TWTCompoundValidatorTypeAnd, TWTCompoundValidatorTypeOr, TWTCompoundValidatorTypeMutualExclusion };
    return types[random() % 3];
}

- (void)testInit
{
    TWTCompoundValidator *validator = [[TWTCompoundValidator alloc] init];
    XCTAssertNotNil(validator, @"returns nil");
    XCTAssertEqual(validator.compoundValidatorType, TWTCompoundValidatorTypeAnd, @"type is not TWTCompoundValidatorTypeAnd");
    XCTAssertNil(validator.subvalidators, @"subvalidators is non-nil");

    TWTCompoundValidatorType randomType = [self randomCompoundValidatorType];
    NSArray *randomSubvalidators = UMKGeneratedArrayWithElementCount(1 + random() % 5, ^id(NSUInteger index) {
        return [self randomValidator];
    });

    // Test all types but not
    validator = [[TWTCompoundValidator alloc] initWithType:randomType subvalidators:randomSubvalidators];
    XCTAssertNotNil(validator, @"returns nil");
    XCTAssertEqual(validator.compoundValidatorType, randomType, @"type set incorrectly");
    XCTAssertEqualObjects(validator.subvalidators, randomSubvalidators, @"subvalidators set incorrectly");

    // Test not type
    NSArray *notSubvalidators = @[ [self randomValidator] ];
    validator = [[TWTCompoundValidator alloc] initWithType:TWTCompoundValidatorTypeNot subvalidators:notSubvalidators];
    XCTAssertNotNil(validator, @"returns nil");
    XCTAssertEqual(validator.compoundValidatorType, TWTCompoundValidatorTypeNot, @"type set incorrectly");
    XCTAssertEqualObjects(validator.subvalidators, notSubvalidators, @"subvalidators set incorrectly");

    XCTAssertThrows([[TWTCompoundValidator alloc] initWithType:TWTCompoundValidatorTypeNot subvalidators:nil], @"does not throw with nil subvalidators");
    XCTAssertThrows([[TWTCompoundValidator alloc] initWithType:TWTCompoundValidatorTypeNot subvalidators:@[ ]], @"does not throw with empty subvalidators");

    notSubvalidators = UMKGeneratedArrayWithElementCount(random() % 5 + 2, ^id(NSUInteger index) {
        return [self randomValidator];
    });

    XCTAssertThrows([[TWTCompoundValidator alloc] initWithType:TWTCompoundValidatorTypeNot subvalidators:notSubvalidators],
                    @"does not throw with more than 1 subvalidators");

    // Test factory methods
    validator = [TWTCompoundValidator andValidatorWithSubvalidators:randomSubvalidators];
    XCTAssertNotNil(validator, @"returns nil");
    XCTAssertEqual(validator.compoundValidatorType, TWTCompoundValidatorTypeAnd, @"type is not TWTCompoundValidatorTypeAnd");
    XCTAssertEqualObjects(validator.subvalidators, randomSubvalidators, @"subvalidators set incorrectly");

    validator = [TWTCompoundValidator orValidatorWithSubvalidators:randomSubvalidators];
    XCTAssertNotNil(validator, @"returns nil");
    XCTAssertEqual(validator.compoundValidatorType, TWTCompoundValidatorTypeOr, @"type is not TWTCompoundValidatorTypeOr");
    XCTAssertEqualObjects(validator.subvalidators, randomSubvalidators, @"subvalidators set incorrectly");

    validator = [TWTCompoundValidator mutualExclusionValidatorWithSubvalidators:randomSubvalidators];
    XCTAssertNotNil(validator, @"returns nil");
    XCTAssertEqual(validator.compoundValidatorType, TWTCompoundValidatorTypeMutualExclusion, @"type is not TWTCompoundValidatorTypeMutualExclusion");
    XCTAssertEqualObjects(validator.subvalidators, randomSubvalidators, @"subvalidators set incorrectly");
}

- (void)testCopy
{
    TWTCompoundValidatorType randomType = [self randomCompoundValidatorType];
    NSArray *randomSubvalidators = UMKGeneratedArrayWithElementCount(1 + random() % 5, ^id(NSUInteger index) {
        return [self randomValidator];
    });

    TWTCompoundValidator *validator = [[TWTCompoundValidator alloc] initWithType:randomType subvalidators:randomSubvalidators];
    TWTCompoundValidator *copy = [validator copy];
    XCTAssertEqual(copy, validator, @"copy returns different object");
    XCTAssertEqual(randomType, copy.compoundValidatorType, @"type is not set correctly");
    XCTAssertEqualObjects(randomSubvalidators, copy.subvalidators, @"subvalidators is not set correctly");
}

- (void)testHashAndIsEqual
{
    TWTCompoundValidatorType randomType1 = [self randomCompoundValidatorType];
    NSArray *randomSubvalidators1 = UMKGeneratedArrayWithElementCount(1 + random() % 5, ^id(NSUInteger index) {
        return [self randomValidator];
    });

    TWTCompoundValidatorType randomType2 = [self randomCompoundValidatorType];
    while (randomType2 == randomType1) {
        randomType2 = [self randomCompoundValidatorType];
    }

    NSArray *randomSubvalidators2 = UMKGeneratedArrayWithElementCount(1 + randomSubvalidators1.count, ^id(NSUInteger index) {
        return [self randomValidator];
    });

    TWTCompoundValidator *equalValidator1 = [[TWTCompoundValidator alloc] initWithType:randomType1 subvalidators:randomSubvalidators1];
    TWTCompoundValidator *equalValidator2 = [[TWTCompoundValidator alloc] initWithType:randomType1 subvalidators:randomSubvalidators1];
    TWTCompoundValidator *unequalValidator1 = [[TWTCompoundValidator alloc] initWithType:randomType2 subvalidators:randomSubvalidators1];
    TWTCompoundValidator *unequalValidator2 = [[TWTCompoundValidator alloc] initWithType:randomType1 subvalidators:randomSubvalidators2];

    XCTAssertEqual(equalValidator1.hash, equalValidator2.hash, @"hashes are different for equal objects");
    XCTAssertEqualObjects(equalValidator1, equalValidator2, @"equal objects are not equal");
    XCTAssertNotEqualObjects(equalValidator1, unequalValidator1, @"unequal objects are equal");
    XCTAssertNotEqualObjects(equalValidator1, unequalValidator2, @"unequal objects are equal");
}

#pragma mark - Not Validation Tests

- (void)testValidateValueErrorForNotWithPassingValidator
{
    TWTValidator *subvalidator = [self passingValidator];
    TWTCompoundValidator *validator = [TWTCompoundValidator notValidatorWithSubvalidator:subvalidator];
    XCTAssertFalse([validator validateValue:[self randomObject] error:NULL], @"passes with passing validator");

    NSError *error = nil;
    subvalidator = [self passingValidator];
    validator = [TWTCompoundValidator notValidatorWithSubvalidator:subvalidator];

    id value = [self randomObject];
    XCTAssertFalse([validator validateValue:value error:&error], @"passes with passing validator");
    XCTAssertNotNil(error, @"returns nil error");
    XCTAssertEqualObjects(error.domain, TWTValidationErrorDomain, @"incorrect error domain");
    XCTAssertEqual(error.code, TWTValidationErrorCodeCompoundValidatorError, @"incorrect error code");
    XCTAssertEqualObjects(error.twt_failingValidator, validator, @"incorrect failing validator");
    XCTAssertEqualObjects(error.twt_validatedValue, value, @"incorrect validated value");
}

- (void)testValidateValueErrorForNotWithFailingValidator
{
    TWTValidator *subvalidator = [self failingValidatorWithError:UMKRandomError()];
    TWTCompoundValidator *validator = [TWTCompoundValidator notValidatorWithSubvalidator:subvalidator];
    XCTAssertTrue([validator validateValue:[self randomObject] error:NULL], @"fails with passing validator");

    NSError *error = nil;
    subvalidator = [self failingValidatorWithError:UMKRandomError()];
    validator = [TWTCompoundValidator notValidatorWithSubvalidator:subvalidator];
    XCTAssertTrue([validator validateValue:[self randomObject] error:&error], @"fails with passing validator");
}

#pragma mark - And Validation Tests

- (void)testValidateValueErrorForAndWithNoValidators
{
    TWTCompoundValidator *validator = [TWTCompoundValidator andValidatorWithSubvalidators:nil];
    XCTAssertTrue([validator validateValue:[self randomObject] error:NULL], @"fails with nil validators");

    validator = [TWTCompoundValidator andValidatorWithSubvalidators:@[ ]];
    XCTAssertTrue([validator validateValue:[self randomObject] error:NULL], @"fails with no validators");
}

- (void)testValidateValueErrorForAndWithOnePassingValidator
{
    NSArray *subvalidators = @[ [self passingValidator] ];
    TWTCompoundValidator *validator = [TWTCompoundValidator andValidatorWithSubvalidators:subvalidators];
    XCTAssertTrue([validator validateValue:[self randomObject] error:NULL], @"fails with one passing validator");

    NSError *error = nil;
    validator = [TWTCompoundValidator andValidatorWithSubvalidators:subvalidators];
    XCTAssertTrue([validator validateValue:[self randomObject] error:&error], @"fails with one passing validator");
}

- (void)testValidateValueErrorForAndWithMultiplePassingValidators
{
    NSArray *subvalidators = UMKGeneratedArrayWithElementCount(2 + random() % 8, ^id(NSUInteger index) {
        return [self passingValidator];
    });

    TWTCompoundValidator *validator = [TWTCompoundValidator andValidatorWithSubvalidators:subvalidators];
    XCTAssertTrue([validator validateValue:[self randomObject] error:nil], @"fails with multiple passing validators");

    NSError *error = nil;
    validator = [TWTCompoundValidator andValidatorWithSubvalidators:subvalidators];
    XCTAssertTrue([validator validateValue:[self randomObject] error:&error], @"fails with multiple passing validators");
}

- (void)testValidateValueErrorForAndWithOneFailingValidator
{
    NSArray *subvalidators = @[ [self failingValidatorWithError:UMKRandomError()] ];
    TWTCompoundValidator *validator = [TWTCompoundValidator andValidatorWithSubvalidators:subvalidators];
    XCTAssertFalse([validator validateValue:[self randomObject] error:NULL]);

    NSError *error = nil;
    NSError *expectedError = UMKRandomError();
    subvalidators = @[ [self failingValidatorWithError:expectedError] ];
    validator = [TWTCompoundValidator andValidatorWithSubvalidators:subvalidators];

    id value = [self randomObject];
    XCTAssertFalse([validator validateValue:value error:&error], @"passes with one failing validator");
    XCTAssertNotNil(error, @"returns nil error");
    XCTAssertEqualObjects(error.domain, TWTValidationErrorDomain, @"incorrect error domain");
    XCTAssertEqual(error.code, TWTValidationErrorCodeCompoundValidatorError, @"incorrect error code");
    XCTAssertEqualObjects(error.twt_failingValidator, validator, @"incorrect failing validator");
    XCTAssertEqualObjects(error.twt_validatedValue, value, @"incorrect validated value");
    XCTAssertEqualObjects(error.twt_underlyingErrors, @[ expectedError ], @"incorrect underlying errors");

}

- (void)testValidateValueErrorForAndWithMultipleFailingValidators
{
    NSArray *subvalidators = UMKGeneratedArrayWithElementCount(4 + random() % 6, ^id(NSUInteger index) {
        return index % 2 == 0 ? [self passingValidator] : [self failingValidatorWithError:UMKRandomError()];
    });

    TWTCompoundValidator *validator = [TWTCompoundValidator andValidatorWithSubvalidators:subvalidators];
    XCTAssertFalse([validator validateValue:[self randomObject] error:NULL], @"passes with multiple failing validators");

    NSArray *expectedErrors = UMKGeneratedArrayWithElementCount(3, ^id(NSUInteger index) {
        return UMKRandomError();
    });

    subvalidators = @[ [self passingValidator],
                       [self failingValidatorWithError:expectedErrors[0]],
                       [self failingValidatorWithError:expectedErrors[1]],
                       [self passingValidator],
                       [self failingValidatorWithError:expectedErrors[2]],
                       [self passingValidator] ];

    NSError *error = nil;
    id value = [self randomObject];
    validator = [TWTCompoundValidator andValidatorWithSubvalidators:subvalidators];
    XCTAssertFalse([validator validateValue:value error:&error], @"passes with multiple failing validators");
    XCTAssertNotNil(error, @"returns nil error");
    XCTAssertEqualObjects(error.domain, TWTValidationErrorDomain, @"incorrect error domain");
    XCTAssertEqual(error.code, TWTValidationErrorCodeCompoundValidatorError, @"incorrect error code");
    XCTAssertEqualObjects(error.twt_failingValidator, validator, @"incorrect failing validator");
    XCTAssertEqualObjects(error.twt_validatedValue, value, @"incorrect validated value");
    XCTAssertEqualObjects(error.twt_underlyingErrors, expectedErrors, @"incorrect underlying errors");
}

#pragma mark - Or Validation Tests

- (void)testValidateValueErrorForOrWithNoValidators
{
    TWTCompoundValidator *validator = [TWTCompoundValidator orValidatorWithSubvalidators:nil];
    XCTAssertFalse([validator validateValue:[self randomObject] error:NULL], @"passes with nil validators");

    NSError *error = nil;
    id value = [self randomObject];
    XCTAssertFalse([validator validateValue:value error:&error], @"passes with nil validators");
    XCTAssertNotNil(error, @"returns nil error");
    XCTAssertEqualObjects(error.domain, TWTValidationErrorDomain, @"incorrect error domain");
    XCTAssertEqual(error.code, TWTValidationErrorCodeCompoundValidatorError, @"incorrect error code");
    XCTAssertEqualObjects(error.twt_failingValidator, validator, @"incorrect failing validator");
    XCTAssertEqualObjects(error.twt_validatedValue, value, @"incorrect validatedValue");
    XCTAssertNil(error.twt_underlyingErrors, @"non-nil underlying errors");

    validator = [TWTCompoundValidator orValidatorWithSubvalidators:@[ ]];
    XCTAssertFalse([validator validateValue:[self randomObject] error:NULL], @"passes with nil validators");

    error = nil;
    value = [self randomObject];
    XCTAssertFalse([validator validateValue:value error:&error], @"passes with nil validators");
    XCTAssertNotNil(error, @"returns nil error");
    XCTAssertEqualObjects(error.domain, TWTValidationErrorDomain, @"incorrect error domain");
    XCTAssertEqual(error.code, TWTValidationErrorCodeCompoundValidatorError, @"incorrect error code");
    XCTAssertEqualObjects(error.twt_failingValidator, validator, @"incorrect failing validator");
    XCTAssertEqualObjects(error.twt_validatedValue, value, @"incorrect validatedValue");
    XCTAssertNil(error.twt_underlyingErrors, @"non-nil underlying errors");
}

- (void)testValidateValueErrorForOrWithOnePassingValidator
{
    NSArray *subvalidators = @[ [self passingValidator] ];
    TWTCompoundValidator *validator = [TWTCompoundValidator orValidatorWithSubvalidators:subvalidators];
    XCTAssertTrue([validator validateValue:[self randomObject] error:NULL], @"fails with one passing validator");

    NSError *error = nil;
    validator = [TWTCompoundValidator orValidatorWithSubvalidators:subvalidators];
    XCTAssertTrue([validator validateValue:[self randomObject] error:&error], @"fails with one passing validator");
}

- (void)testValidateValueErrorForOrWithMultiplePassingValidators
{
    NSArray *subvalidators = UMKGeneratedArrayWithElementCount(2 + random() % 8, ^id(NSUInteger index) {
        return index % 2 == 0 ? [self passingValidator] : [self failingValidatorWithError:UMKRandomError()];
    });

    TWTCompoundValidator *validator = [TWTCompoundValidator orValidatorWithSubvalidators:subvalidators];
    XCTAssertTrue([validator validateValue:[self randomObject] error:NULL], @"fails with multiple passing validators");

    NSArray *expectedErrors = UMKGeneratedArrayWithElementCount(3, ^id(NSUInteger index) {
        return UMKRandomError();
    });

    NSError *error = nil;
    subvalidators = @[ [self passingValidator],
                       [self failingValidatorWithError:expectedErrors[0]],
                       [self failingValidatorWithError:expectedErrors[1]],
                       [self passingValidator],
                       [self failingValidatorWithError:expectedErrors[2]],
                       [self passingValidator] ];

    error = nil;
    validator = [TWTCompoundValidator orValidatorWithSubvalidators:subvalidators];
    XCTAssertTrue([validator validateValue:[self randomObject] error:&error], @"fails with multiple passing validators");
}

- (void)testValidateValueErrorForOrWithOneFailingValidator
{
    NSError *expectedError = UMKRandomError();
    NSArray *subvalidators = @[ [self failingValidatorWithError:expectedError] ];
    TWTCompoundValidator *validator = [TWTCompoundValidator orValidatorWithSubvalidators:subvalidators];
    XCTAssertFalse([validator validateValue:[self randomObject] error:NULL]);

    NSError *error = nil;
    id value = [self randomObject];
    XCTAssertFalse([validator validateValue:value error:&error], @"passes with one failing validator");
    XCTAssertNotNil(error, @"returns nil error");
    XCTAssertEqualObjects(error.domain, TWTValidationErrorDomain, @"incorrect error domain");
    XCTAssertEqual(error.code, TWTValidationErrorCodeCompoundValidatorError, @"incorrect error code");
    XCTAssertEqualObjects(error.twt_failingValidator, validator, @"incorrect failing validator");
    XCTAssertEqualObjects(error.twt_validatedValue, value, @"incorrect validatedValue");
    XCTAssertEqualObjects(error.twt_underlyingErrors, @[ expectedError ], @"incorrect underlying errors");
}

- (void)testValidateValueErrorForOrWithMultipleFailingValidators
{
    NSArray *subvalidators = UMKGeneratedArrayWithElementCount(2 + random() % 8, ^id(NSUInteger index) {
        return [self failingValidatorWithError:UMKRandomError()];
    });

    TWTCompoundValidator *validator = [TWTCompoundValidator orValidatorWithSubvalidators:subvalidators];
    XCTAssertFalse([validator validateValue:[self randomObject] error:nil], @"passes with multiple failing validators");

    NSArray *expectedErrors = UMKGeneratedArrayWithElementCount(3, ^id(NSUInteger index) {
        return UMKRandomError();
    });

    NSError *error = nil;
    subvalidators = @[ [self failingValidatorWithError:expectedErrors[0]],
                       [self failingValidatorWithError:expectedErrors[1]],
                       [self failingValidatorWithError:expectedErrors[2]] ];

    validator = [TWTCompoundValidator orValidatorWithSubvalidators:subvalidators];
    id value = [self randomObject];
    XCTAssertFalse([validator validateValue:value error:&error], @"passes with multiple failing validators");
    XCTAssertNotNil(error, @"returns nil error");
    XCTAssertEqualObjects(error.domain, TWTValidationErrorDomain, @"incorrect error domain");
    XCTAssertEqual(error.code, TWTValidationErrorCodeCompoundValidatorError, @"incorrect error code");
    XCTAssertEqualObjects(error.twt_failingValidator, validator, @"incorrect failing validator");
    XCTAssertEqualObjects(error.twt_validatedValue, value, @"incorrect validatedValue");
    XCTAssertEqualObjects(error.twt_underlyingErrors, expectedErrors, @"incorrect underlying errors");
}

#pragma mark - Mutual Exclusion Validation Tests

- (void)testValidateValueErrorForMutualExclusionWithNoValidators
{
    TWTCompoundValidator *validator = [TWTCompoundValidator mutualExclusionValidatorWithSubvalidators:nil];
    XCTAssertFalse([validator validateValue:[self randomObject] error:NULL], @"passes with nil validators");

    NSError *error = nil;
    id value = [self randomObject];
    XCTAssertFalse([validator validateValue:value error:&error], @"passes with nil validators");
    XCTAssertNotNil(error, @"returns nil error");
    XCTAssertEqualObjects(error.domain, TWTValidationErrorDomain, @"incorrect error domain");
    XCTAssertEqual(error.code, TWTValidationErrorCodeCompoundValidatorError, @"incorrect error code");
    XCTAssertEqualObjects(error.twt_failingValidator, validator, @"incorrect failing validator");
    XCTAssertEqualObjects(error.twt_validatedValue, value, @"incorrect validatedValue");
    XCTAssertNil(error.twt_underlyingErrors, @"non-nil underlying errors");

    validator = [TWTCompoundValidator mutualExclusionValidatorWithSubvalidators:@[ ]];
    XCTAssertFalse([validator validateValue:[self randomObject] error:NULL], @"passes with nil validators");

    error = nil;
    value = [self randomObject];
    XCTAssertFalse([validator validateValue:value error:&error], @"passes with nil validators");
    XCTAssertNotNil(error, @"returns nil error");
    XCTAssertEqualObjects(error.domain, TWTValidationErrorDomain, @"incorrect error domain");
    XCTAssertEqual(error.code, TWTValidationErrorCodeCompoundValidatorError, @"incorrect error code");
    XCTAssertEqualObjects(error.twt_failingValidator, validator, @"incorrect failing validator");
    XCTAssertEqualObjects(error.twt_validatedValue, value, @"incorrect validatedValue");
    XCTAssertNil(error.twt_underlyingErrors, @"non-nil underlying errors");
}

- (void)testValidateValueErrorForMutualExclusionWithOnePassingValidator
{
    NSArray *subvalidators = @[ [self passingValidator] ];
    TWTCompoundValidator *validator = [TWTCompoundValidator mutualExclusionValidatorWithSubvalidators:subvalidators];
    XCTAssertTrue([validator validateValue:[self randomObject] error:NULL], @"fails with one passing validator");

    NSError *error = nil;
    XCTAssertTrue([validator validateValue:[self randomObject] error:&error], @"fails with one passing validator");
}

- (void)testValidateValueErrorForMutualExclusionWithMultiplePassingValidators
{
    NSArray *subvalidators = UMKGeneratedArrayWithElementCount(3 + random() % 8, ^id(NSUInteger index) {
        return index % 2 == 0 ? [self passingValidator] : [self failingValidatorWithError:UMKRandomError()];
    });

    TWTCompoundValidator *validator = [TWTCompoundValidator mutualExclusionValidatorWithSubvalidators:subvalidators];
    XCTAssertFalse([validator validateValue:[self randomObject] error:NULL], @"passes with multiple passing validators");

    NSArray *expectedErrors = UMKGeneratedArrayWithElementCount(3, ^id(NSUInteger index) {
        return UMKRandomError();
    });

    NSError *error = nil;
    subvalidators = @[ [self passingValidator],
                       [self failingValidatorWithError:expectedErrors[0]],
                       [self failingValidatorWithError:expectedErrors[1]],
                       [self failingValidatorWithError:expectedErrors[2]],
                       [self passingValidator] ];

    error = nil;
    validator = [TWTCompoundValidator mutualExclusionValidatorWithSubvalidators:subvalidators];
    id value = [self randomObject];
    XCTAssertFalse([validator validateValue:value error:&error], @"passes with nil validators");
    XCTAssertNotNil(error, @"returns nil error");
    XCTAssertEqualObjects(error.domain, TWTValidationErrorDomain, @"incorrect error domain");
    XCTAssertEqual(error.code, TWTValidationErrorCodeCompoundValidatorError, @"incorrect error code");
    XCTAssertEqualObjects(error.twt_failingValidator, validator, @"incorrect failing validator");
    XCTAssertEqualObjects(error.twt_validatedValue, value, @"incorrect validatedValue");
    XCTAssertEqualObjects(error.twt_underlyingErrors, expectedErrors, @"incorrect underlying errors");
}

- (void)testValidateValueErrorForMutualExclusionWithOneFailingValidator
{
    NSError *expectedError = UMKRandomError();
    NSArray *subvalidators = @[ [self failingValidatorWithError:expectedError] ];
    TWTCompoundValidator *validator = [TWTCompoundValidator mutualExclusionValidatorWithSubvalidators:subvalidators];
    XCTAssertFalse([validator validateValue:[self randomObject] error:NULL]);

    NSError *error = nil;
    id value = [self randomObject];
    XCTAssertFalse([validator validateValue:value error:&error], @"passes with one failing validator");
    XCTAssertNotNil(error, @"returns nil error");
    XCTAssertEqualObjects(error.domain, TWTValidationErrorDomain, @"incorrect error domain");
    XCTAssertEqual(error.code, TWTValidationErrorCodeCompoundValidatorError, @"incorrect error code");
    XCTAssertEqualObjects(error.twt_failingValidator, validator, @"incorrect failing validator");
    XCTAssertEqualObjects(error.twt_validatedValue, value, @"incorrect validated value");
    XCTAssertEqualObjects(error.twt_underlyingErrors, @[ expectedError ], @"incorrect underlying errors");
}

- (void)testValidateValueErrorForMutualExclusionWithMultipleFailingValidators
{
    NSArray *subvalidators = UMKGeneratedArrayWithElementCount(2 + random() % 8, ^id(NSUInteger index) {
        return [self failingValidatorWithError:UMKRandomError()];
    });

    TWTCompoundValidator *validator = [TWTCompoundValidator orValidatorWithSubvalidators:subvalidators];
    XCTAssertFalse([validator validateValue:[self randomObject] error:nil], @"passes with multiple failing validators");

    NSArray *expectedErrors = UMKGeneratedArrayWithElementCount(3, ^id(NSUInteger index) {
        return UMKRandomError();
    });

    NSError *error = nil;
    subvalidators = @[ [self failingValidatorWithError:expectedErrors[0]],
                       [self failingValidatorWithError:expectedErrors[1]],
                       [self failingValidatorWithError:expectedErrors[2]] ];

    validator = [TWTCompoundValidator orValidatorWithSubvalidators:subvalidators];
    id value = [self randomObject];
    XCTAssertFalse([validator validateValue:value error:&error], @"passes with multiple failing validators");
    XCTAssertNotNil(error, @"returns nil error");
    XCTAssertEqualObjects(error.domain, TWTValidationErrorDomain, @"incorrect error domain");
    XCTAssertEqual(error.code, TWTValidationErrorCodeCompoundValidatorError, @"incorrect error code");
    XCTAssertEqualObjects(error.twt_failingValidator, validator, @"incorrect failing validator");
    XCTAssertEqualObjects(error.twt_validatedValue, value, @"incorrect validated value");
    XCTAssertEqualObjects(error.twt_underlyingErrors, expectedErrors, @"incorrect underlying errors");
}

@end


text:
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { HttpIntercaptorComponent } from './http-intercaptor/http-intercaptor.component';

@NgModule({
  imports: [
    CommonModule
  ],
  declarations: [HttpIntercaptorComponent],
  exports: [HttpIntercaptorComponent]
})
export class EscCommonModule { }