text:
package org.openchain.certification.dbdao;

import static org.junit.Assert.*;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.openchain.certification.TestHelper;
import org.openchain.certification.model.Question;
import org.openchain.certification.model.QuestionException;
import org.openchain.certification.model.Section;
import org.openchain.certification.model.SubQuestion;
import org.openchain.certification.model.Survey;
import org.openchain.certification.model.SurveyResponseException;
import org.openchain.certification.model.User;
import org.openchain.certification.model.YesNoNotApplicableQuestion;
import org.openchain.certification.model.YesNoQuestion;
import org.openchain.certification.model.YesNoQuestion.YesNo;
import org.openchain.certification.model.YesNoQuestionWithEvidence;

public class TestSurveyDbDao {

	private Connection con;

	@Before
	public void setUp() throws Exception {
		con = TestHelper.getConnection();
		TestHelper.truncateDatabase(con);
	}

	@After
	public void tearDown() throws Exception {
		con.close();
	}

	@Test
	public void testGetSurveyString() throws QuestionException, SQLException, SurveyResponseException {
		String specVersion = "test-spec-version";
		String language = "abc";
		Survey survey = new Survey(specVersion, language);
		List<Section> sections = new ArrayList<Section>();
		Section section1 = new Section(language);
		String section1Name = "section1Name";
		section1.setName(section1Name);
		String section1Title = "section1Title";
		section1.setTitle(section1Title);
		List<Question> section1Questions = new ArrayList<Question>();
		String s1q1Question="s1q1question";
		String s1q1Number = "1.a";
		YesNo s1q1Answer = YesNo.Yes;
		String[] s1q1SpecRef = new String[] {"s1q1SpecRef"};
		Question s1q1 = new YesNoQuestion(s1q1Question,
				section1Name, s1q1Number, specVersion, s1q1SpecRef, language, s1q1Answer);

		section1Questions.add(s1q1);
		String s1q2Question="s1q2question";
		String s1q2Number = "1.b";
		YesNo s1q2Answer = YesNo.NotApplicable;
		String s1q2Prompt = "s1q2prompt";
		String[] s1q2SpecRef = new String[] {"s1q2SpecRef"};
		Question s1q2 = new YesNoNotApplicableQuestion(s1q2Question,
				section1Name, s1q2Number, specVersion, s1q2SpecRef, language, s1q2Answer, s1q2Prompt);
		section1Questions.add(s1q2);
		section1.setQuestions(section1Questions);
		sections.add(section1);
		Section section2 = new Section(language);
		String section2Name = "section2Name";
		section2.setName(section2Name);
		String section2Title = "section2Title";
		section2.setTitle(section2Title);
		List<Question> section2Questions = new ArrayList<Question>();
		String s2q1Question="s2q1question";
		String s2q1Number = "2.b";
		int s2q1MinCorrect = 4;
		String[] s2q1SpecRef = new String[] {"s2q1SpecRef"};
		Question s2q1 = new SubQuestion(s2q1Question,
				section2Name, s2q1Number, specVersion, s2q1SpecRef, language, s2q1MinCorrect);
		section2Questions.add(s2q1);
		String s2q2Question="s2q2question";
		String s2q2Number = "2.b.ii";
		YesNo s2q2Answer = YesNo.No;
		String s2q2Prompt = "s2q2prompt";
		String s2q2validate = "dd";
		String[] s2q2SpecRef = new String[] {"s2q2SpecRef"};
		Question s2q2 = new YesNoQuestionWithEvidence(s2q2Question,
				section2Name, s2q2Number, specVersion, s2q2SpecRef, language, s2q2Answer, s2q2Prompt, Pattern.compile(s2q2validate));
		s2q2.setSubQuestionOfNumber(s2q1Number);
		section2Questions.add(s2q2);
		String s2q3Question="s2q3question";
		String s2q3Number = "1.b.iii";
		YesNo s2q3Answer = YesNo.NotAnswered;
		String[] s2q3SpecRef = new String[] {"s2q3SpecRef"};
		Question s2q3 = new YesNoQuestion(s2q3Question,
				section2Name, s2q3Number, specVersion, s2q3SpecRef, language, s2q3Answer);
		s2q3.setSubQuestionOfNumber(s2q1Number);
		section2Questions.add(s2q3);
		section2.setQuestions(section2Questions);
		sections.add(section2);
		survey.setSections(sections);
		SurveyDbDao dao = new SurveyDbDao(con);
		dao.addSurvey(survey);
		Survey result = dao.getSurvey(specVersion, language);
		assertEquals(specVersion, result.getSpecVersion());
		for (Section rs:result.getSections()) {
			if (rs.getName().equals(section1Name)) {
				assertEquals(section1Title, rs.getTitle());
				assertEquals(language, rs.getLanguage());
				for (Question rq:rs.getQuestions()) {
					if (rq.getNumber().equals(s1q1Number)) {
						YesNoQuestion yn = (YesNoQuestion)rq;
						assertEquals(s1q1Question, yn.getQuestion());
						assertEquals(s1q1Answer, yn.getCorrectAnswer());
						assertEquals(section1Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s1q1SpecRef), Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertTrue(yn.getSubQuestionOfNumber() == null);
						assertEquals(language, yn.getLanguage());
					} else if (rq.getNumber().equals(s1q2Number)) {
						YesNoNotApplicableQuestion yn = (YesNoNotApplicableQuestion)rq;
						assertEquals(s1q2Question, yn.getQuestion());
						assertEquals(s1q2Answer, yn.getCorrectAnswer());
						assertEquals(section1Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s1q2SpecRef), Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertTrue(yn.getSubQuestionOfNumber() == null);
						assertEquals(language, yn.getLanguage());
					} else {
						fail("no matching question numbers");
					}
				}
			} else if (rs.getName().equals(section2Name)) {
				assertEquals(section2Title, rs.getTitle());
				assertEquals(language, rs.getLanguage());
				for (Question rq:rs.getQuestions()) {
					assertEquals(language, rq.getLanguage());
					if (rq.getNumber().equals(s2q1Number)) {
						SubQuestion yn = (SubQuestion)rq;
						assertEquals(s2q1Question, yn.getQuestion());
						assertEquals(s2q1MinCorrect, yn.getMinNumberValidatedAnswers());
						assertEquals(section2Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s2q1SpecRef), Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertTrue(yn.getSubQuestionOfNumber() == null);
					} else if (rq.getNumber().equals(s2q2Number)) {
						YesNoQuestionWithEvidence yn = (YesNoQuestionWithEvidence)rq;
						assertEquals(s2q2Question, yn.getQuestion());
						assertEquals(s2q2Answer, yn.getCorrectAnswer());
						assertEquals(section2Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s2q2SpecRef), Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertEquals(s2q2Prompt, yn.getEvidencePrompt());
						assertEquals(s2q2validate, yn.getEvidenceValidation().toString());
						assertEquals(s2q1Number, yn.getSubQuestionOfNumber());
					} else if (rq.getNumber().equals(s2q3Number)) {
						YesNoQuestion yn = (YesNoQuestion)rq;
						assertEquals(s2q3Question, yn.getQuestion());
						assertEquals(s2q3Answer, yn.getCorrectAnswer());
						assertEquals(section2Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s2q3SpecRef), Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertEquals(s2q1Number, yn.getSubQuestionOfNumber());
					} else {
						fail("no matching question numbers");
					}
				}
			} else {
				fail("No matching section names");
			}
		}
	}

	@Test
	public void testUpdateQuestions() throws QuestionException, SQLException, SurveyResponseException {
		String specVersion = "test-spec-version";
		String language = "fra";
		Survey survey = new Survey(specVersion, language);
		List<Section> sections = new ArrayList<Section>();
		Section section1 = new Section(language);
		String section1Name = "section1Name";
		section1.setName(section1Name);
		String section1Title = "section1Title";
		section1.setTitle(section1Title);
		List<Question> section1Questions = new ArrayList<Question>();
		String s1q1Question="s1q1question";
		String s1q1Number = "1.a";
		YesNo s1q1Answer = YesNo.Yes;
		String[]  s1q1SpecRef = new String[] {"s1q1SpecRef"};
		Question s1q1 = new YesNoQuestion(s1q1Question,
				section1Name, s1q1Number, specVersion, s1q1SpecRef, language, s1q1Answer);
		section1Questions.add(s1q1);
		String s1q2Question="s1q2question";
		String s1q2Number = "1.b";
		YesNo s1q2Answer = YesNo.NotApplicable;
		String s1q2Prompt = "s1q2prompt";
		String[] s1q2SpecRef = new String[] {"s1q2SpecRef"};
		Question s1q2 = new YesNoNotApplicableQuestion(s1q2Question,
				section1Name, s1q2Number, specVersion, s1q2SpecRef, language, s1q2Answer, s1q2Prompt);
		section1Questions.add(s1q2);
		section1.setQuestions(section1Questions);
		sections.add(section1);
		Section section2 = new Section(language);
		String section2Name = "section2Name";
		section2.setName(section2Name);
		String section2Title = "section2Title";
		section2.setTitle(section2Title);
		List<Question> section2Questions = new ArrayList<Question>();
		String s2q1Question="s2q1question";
		String s2q1Number = "2.b";
		int s2q1MinCorrect = 4;
		String[] s2q1SpecRef = new String[] {"s2q1SpecRef"};
		Question s2q1 = new SubQuestion(s2q1Question,
				section2Name, s2q1Number, specVersion, s2q1SpecRef, language, s2q1MinCorrect);
		section2Questions.add(s2q1);
		String s2q2Question="s2q2question";
		String s2q2Number = "2.b.ii";
		YesNo s2q2Answer = YesNo.No;
		String s2q2Prompt = "s2q2prompt";
		String s2q2validate = "dd";
		String[] s2q2SpecRef = new String[] {"s2q2SpecRef"};
		Question s2q2 = new YesNoQuestionWithEvidence(s2q2Question,
				section2Name, s2q2Number, specVersion, s2q2SpecRef, language,
				s2q2Answer, s2q2Prompt, Pattern.compile(s2q2validate));
		s2q2.setSubQuestionOfNumber(s2q1Number);
		section2Questions.add(s2q2);
		String s2q3Question="s2q3question";
		String s2q3Number = "1.b.iii";
		YesNo s2q3Answer = YesNo.NotAnswered;
		String[] s2q3SpecRef = new String[] {"s2q3SpecRef"};
		Question s2q3 = new YesNoQuestion(s2q3Question,
				section2Name, s2q3Number, specVersion, s2q3SpecRef, language, s2q3Answer);
		s2q3.setSubQuestionOfNumber(s2q1Number);
		section2Questions.add(s2q3);
		section2.setQuestions(section2Questions);
		sections.add(section2);
		survey.setSections(sections);
		SurveyDbDao dao = new SurveyDbDao(con);
		dao.addSurvey(survey);

		// make updates
		String us1q2Question = "Updated s1q2Question";
		YesNo updates1q2Answer = YesNo.Any;
		String us1q2Prompt = "Updated "+s1q2Prompt;
		String us1q2valid = "abc";
		String[] us1q2specRef = new String[] {"UpdatedRef"};
		Question Updateds1q2 = new YesNoQuestionWithEvidence(us1q2Question,
				section1Name, s1q2Number, specVersion, us1q2specRef, language,
				updates1q2Answer, us1q2Prompt, Pattern.compile(us1q2valid));

		String us2q3Question = "Updated " +s2q3Question;
		String[] us2q3SpecRef = new String[] {"us2q3SpecRef"};
		Question updateds2q3 = new YesNoQuestion(us2q3Question,
				section2Name, s2q3Number, specVersion, us2q3SpecRef, language, s2q3Answer);
		updateds2q3.setSubQuestionOfNumber(s2q1Number);
		List<Question> questionsToUpdate = new ArrayList<Question>();
		questionsToUpdate.add(Updateds1q2);
		questionsToUpdate.add(updateds2q3);
		dao.updateQuestions(questionsToUpdate);
		Survey result = dao.getSurvey(specVersion, language);
		assertEquals(specVersion, result.getSpecVersion());
		for (Section rs:result.getSections()) {
			assertEquals(language, rs.getLanguage());
			if (rs.getName().equals(section1Name)) {
				assertEquals(section1Title, rs.getTitle());
				for (Question rq:rs.getQuestions()) {
					assertEquals(language, rq.getLanguage());
					if (rq.getNumber().equals(s1q1Number)) {
						YesNoQuestion yn = (YesNoQuestion)rq;
						assertEquals(s1q1Question, yn.getQuestion());
						assertEquals(s1q1Answer, yn.getCorrectAnswer());
						assertEquals(section1Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s1q1SpecRef),
								Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertTrue(yn.getSubQuestionOfNumber() == null);
					} else if (rq.getNumber().equals(s1q2Number)) {
						YesNoQuestionWithEvidence yn = (YesNoQuestionWithEvidence)rq;
						assertEquals(us1q2Question, yn.getQuestion());
						assertEquals(updates1q2Answer, yn.getCorrectAnswer());
						assertEquals(section1Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(us1q2specRef),
								Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertEquals(us1q2Prompt, yn.getEvidencePrompt());
						assertEquals(us1q2valid, yn.getEvidenceValidation().toString());
						assertTrue(yn.getSubQuestionOfNumber() == null);
					} else {
						fail("no matching question numbers");
					}
				}
			} else if (rs.getName().equals(section2Name)) {
				assertEquals(section2Title, rs.getTitle());
				for (Question rq:rs.getQuestions()) {
					assertEquals(language, rq.getLanguage());
					if (rq.getNumber().equals(s2q1Number)) {
						SubQuestion yn = (SubQuestion)rq;
						assertEquals(s2q1Question, yn.getQuestion());
						assertEquals(s2q1MinCorrect, yn.getMinNumberValidatedAnswers());
						assertEquals(section2Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s2q1SpecRef),
								Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertTrue(yn.getSubQuestionOfNumber() == null);
					} else if (rq.getNumber().equals(s2q2Number)) {
						YesNoQuestionWithEvidence yn = (YesNoQuestionWithEvidence)rq;
						assertEquals(s2q2Question, yn.getQuestion());
						assertEquals(s2q2Answer, yn.getCorrectAnswer());
						assertEquals(section2Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s2q2SpecRef),
								Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertEquals(s2q2Prompt, yn.getEvidencePrompt());
						assertEquals(s2q2validate, yn.getEvidenceValidation().toString());
						assertEquals(s2q1Number, yn.getSubQuestionOfNumber());
					} else if (rq.getNumber().equals(s2q3Number)) {
						YesNoQuestion yn = (YesNoQuestion)rq;
						assertEquals(us2q3Question, yn.getQuestion());
						assertEquals(s2q3Answer, yn.getCorrectAnswer());
						assertEquals(section2Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(us2q3SpecRef),
								Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertEquals(s2q1Number, yn.getSubQuestionOfNumber());
					} else {
						fail("no matching question numbers");
					}
				}
			} else {
				fail("No matching section names");
			}
		}
	}

	@Test
	public void testAddQuestions() throws SQLException, SurveyResponseException, QuestionException {
		String specVersion = "test-spec-version";
		String language = "ang";
		Survey survey = new Survey(specVersion, language);
		List<Section> sections = new ArrayList<Section>();
		Section section1 = new Section(language);
		String section1Name = "section1Name";
		section1.setName(section1Name);
		String section1Title = "section1Title";
		section1.setTitle(section1Title);
		List<Question> section1Questions = new ArrayList<Question>();
		String s1q1Question="s1q1question";
		String s1q1Number = "1.a";
		YesNo s1q1Answer = YesNo.Yes;
		String[] s1q1SpecRef = new String[] {"s1q1SpecRef"};
		Question s1q1 = new YesNoQuestion(s1q1Question,
				section1Name, s1q1Number, specVersion, s1q1SpecRef, language, s1q1Answer);
		section1Questions.add(s1q1);
		String s1q2Question="s1q2question";
		String s1q2Number = "1.b";
		YesNo s1q2Answer = YesNo.NotApplicable;
		String s1q2Prompt = "s1q2prompt";
		String[] s1q2SpecRef = new String[] {"s1q2SpecRef"};
		Question s1q2 = new YesNoNotApplicableQuestion(s1q2Question,
				section1Name, s1q2Number, specVersion, s1q2SpecRef, language, s1q2Answer, s1q2Prompt);
		section1Questions.add(s1q2);
		section1.setQuestions(section1Questions);
		sections.add(section1);
		Section section2 = new Section(language);
		String section2Name = "section2Name";
		section2.setName(section2Name);
		String section2Title = "section2Title";
		section2.setTitle(section2Title);
		List<Question> section2Questions = new ArrayList<Question>();
		String s2q1Question="s2q1question";
		String s2q1Number = "2.b";
		int s2q1MinCorrect = 4;
		String[] s2q1SpecRef = new String[] {"s2q1SpecRef"};
		Question s2q1 = new SubQuestion(s2q1Question,
				section2Name, s2q1Number, specVersion, s2q1SpecRef, language, s2q1MinCorrect);
		section2Questions.add(s2q1);
		String s2q2Question="s2q2question";
		String s2q2Number = "2.b.ii";
		YesNo s2q2Answer = YesNo.No;
		String s2q2Prompt = "s2q2prompt";
		String s2q2validate = "dd";
		String[] s2q2SpecRef = new String[] {"s2q2SpecRef"};
		Question s2q2 = new YesNoQuestionWithEvidence(s2q2Question,
				section2Name, s2q2Number, specVersion, s2q2SpecRef, language,
				s2q2Answer, s2q2Prompt, Pattern.compile(s2q2validate));
		s2q2.setSubQuestionOfNumber(s2q1Number);
		section2Questions.add(s2q2);
		String s2q3Question="s2q3question";
		String s2q3Number = "1.b.iii";
		YesNo s2q3Answer = YesNo.NotAnswered;
		String[] s2q3SpecRef = new String[] {"s2q3SpecRef"};
		Question s2q3 = new YesNoQuestion(s2q3Question,
				section2Name, s2q3Number, specVersion, s2q3SpecRef, language, s2q3Answer);
		s2q3.setSubQuestionOfNumber(s2q1Number);
		section2Questions.add(s2q3);
		section2.setQuestions(section2Questions);
		sections.add(section2);
		survey.setSections(sections);
		SurveyDbDao dao = new SurveyDbDao(con);
		dao.addSurvey(survey);

		// Add questions

		String s2q4Question="s2q4question";
		String s2q4Number = "1.b.ix";
		YesNo s2q4Answer = YesNo.No;
		String[] s2q4SpecRef = new String[] {"s2q4SpecRef"};
		Question s2q4 = new YesNoQuestion(s2q4Question,
				section2Name, s2q4Number, specVersion, s2q4SpecRef, language, s2q4Answer);
		s2q4.setSubQuestionOfNumber(s2q1Number);

		String s2q5Question="s2q5question";
		String s2q5Number = "1.c";
		YesNo s2q5Answer = YesNo.Yes;
		String[] s2q5SpecRef = new String[] {"s2q5SpecRef"};
		Question s2q5 = new YesNoQuestion(s2q5Question,
				section2Name, s2q5Number, specVersion, s2q5SpecRef, language, s2q5Answer);

		List<Question> added = new ArrayList<Question>();
		added.add(s2q4);
		added.add(s2q5);
		dao.addQuestions(added);

		Survey result = dao.getSurvey(specVersion, language);
		assertEquals(specVersion, result.getSpecVersion());
		for (Section rs:result.getSections()) {
			assertEquals(language, rs.getLanguage());
			if (rs.getName().equals(section1Name)) {
				assertEquals(section1Title, rs.getTitle());
				for (Question rq:rs.getQuestions()) {
					assertEquals(language, rq.getLanguage());
					if (rq.getNumber().equals(s1q1Number)) {
						YesNoQuestion yn = (YesNoQuestion)rq;
						assertEquals(s1q1Question, yn.getQuestion());
						assertEquals(s1q1Answer, yn.getCorrectAnswer());
						assertEquals(section1Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s1q1SpecRef),
								Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertTrue(yn.getSubQuestionOfNumber() == null);
					} else if (rq.getNumber().equals(s1q2Number)) {
						YesNoNotApplicableQuestion yn = (YesNoNotApplicableQuestion)rq;
						assertEquals(s1q2Question, yn.getQuestion());
						assertEquals(s1q2Answer, yn.getCorrectAnswer());
						assertEquals(section1Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s1q2SpecRef),
								Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertTrue(yn.getSubQuestionOfNumber() == null);
					} else {
						fail("no matching question numbers");
					}
				}
			} else if (rs.getName().equals(section2Name)) {
				assertEquals(section2Title, rs.getTitle());
				for (Question rq:rs.getQuestions()) {
					assertEquals(language, rq.getLanguage());
					if (rq.getNumber().equals(s2q1Number)) {
						SubQuestion yn = (SubQuestion)rq;
						assertEquals(s2q1Question, yn.getQuestion());
						assertEquals(s2q1MinCorrect, yn.getMinNumberValidatedAnswers());
						assertEquals(section2Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s2q1SpecRef),
								Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertTrue(yn.getSubQuestionOfNumber() == null);
					} else if (rq.getNumber().equals(s2q2Number)) {
						YesNoQuestionWithEvidence yn = (YesNoQuestionWithEvidence)rq;
						assertEquals(s2q2Question, yn.getQuestion());
						assertEquals(s2q2Answer, yn.getCorrectAnswer());
						assertEquals(section2Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s2q2SpecRef),
								Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertEquals(s2q2Prompt, yn.getEvidencePrompt());
						assertEquals(s2q2validate, yn.getEvidenceValidation().toString());
						assertEquals(s2q1Number, yn.getSubQuestionOfNumber());
					} else if (rq.getNumber().equals(s2q3Number)) {
						YesNoQuestion yn = (YesNoQuestion)rq;
						assertEquals(s2q3Question, yn.getQuestion());
						assertEquals(s2q3Answer, yn.getCorrectAnswer());
						assertEquals(section2Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s2q3SpecRef),
								Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertEquals(s2q1Number, yn.getSubQuestionOfNumber());
					} else if (rq.getNumber().equals(s2q4Number)) {
						YesNoQuestion yn = (YesNoQuestion)rq;
						assertEquals(s2q4Question, yn.getQuestion());
						assertEquals(s2q4Answer, yn.getCorrectAnswer());
						assertEquals(section2Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s2q4SpecRef),
								Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertEquals(s2q1Number, yn.getSubQuestionOfNumber());
					} else if (rq.getNumber().equals(s2q5Number)) {
						YesNoQuestion yn = (YesNoQuestion)rq;
						assertEquals(s2q5Question, yn.getQuestion());
						assertEquals(s2q5Answer, yn.getCorrectAnswer());
						assertEquals(section2Name, yn.getSectionName());
						assertEquals(specVersion, yn.getSpecVersion());
						assertEquals(Question.specReferenceArrayToStr(s2q5SpecRef),
								Question.specReferenceArrayToStr(yn.getSpecReference()));
						assertTrue(yn.getSubQuestionOfNumber() == null);
					} else {
						fail("no matching question numbers");
					}
				}
			} else {
				fail("No matching section names");
			}
		}
	}

	@Test
	public void testSubNumberErrorHandling() throws QuestionException, SQLException, SurveyResponseException {
		String specVersion = "test-spec-version";
		String language = "alr";
		Survey survey = new Survey(specVersion, language);
		List<Section> sections = new ArrayList<Section>();
		Section section1 = new Section(language);
		String section1Name = "section1Name";
		section1.setName(section1Name);
		String section1Title = "section1Title";
		section1.setTitle(section1Title);
		List<Question> section1Questions = new ArrayList<Question>();
		String s1q1Question="s1q1question";
		String s1q1Number = "1.a";
		YesNo s1q1Answer = YesNo.Yes;
		String[] s1q1SpecRef = new String[] {"s1q1SpecRef"};
		Question s1q1 = new YesNoQuestion(s1q1Question,
				section1Name, s1q1Number, specVersion, s1q1SpecRef, language, s1q1Answer);
		section1Questions.add(s1q1);
		String s1q2Question="s1q2question";
		String s1q2Number = "1.b";
		YesNo s1q2Answer = YesNo.NotApplicable;
		String s1q2Prompt = "s1q2prompt";
		String[] s1q2SpecRef = new String[] {"s1q2SpecRef"};
		Question s1q2 = new YesNoNotApplicableQuestion(s1q2Question,
				section1Name, s1q2Number, specVersion, s1q2SpecRef, language, s1q2Answer, s1q2Prompt);
		section1Questions.add(s1q2);
		section1.setQuestions(section1Questions);
		sections.add(section1);
		Section section2 = new Section(language);
		String section2Name = "section2Name";
		section2.setName(section2Name);
		String section2Title = "section2Title";
		section2.setTitle(section2Title);
		List<Question> section2Questions = new ArrayList<Question>();
		String s2q1Question="s2q1question";
		String s2q1Number = "2.b";
		int s2q1MinCorrect = 4;
		String[] s2q1SpecRef = new String[] {"s2q1SpecRef"};
		Question s2q1 = new SubQuestion(s2q1Question,
				section2Name, s2q1Number, specVersion, s2q1SpecRef, language, s2q1MinCorrect);
		section2Questions.add(s2q1);
		String s2q2Question="s2q2question";
		String s2q2Number = "2.b.ii";
		YesNo s2q2Answer = YesNo.No;
		String s2q2Prompt = "s2q2prompt";
		String s2q2validate = "dd";
		String[] s2q2SpecRef = new String[] {"s2q2SpecRef"};
		Question s2q2 = new YesNoQuestionWithEvidence(s2q2Question,
				section2Name, s2q2Number, specVersion, s2q2SpecRef, language,
				s2q2Answer, s2q2Prompt, Pattern.compile(s2q2validate));
		s2q2.setSubQuestionOfNumber("3.a");	// this should cause an exception
		section2Questions.add(s2q2);
		String s2q3Question="s2q3question";
		String s2q3Number = "1.b.iii";
		YesNo s2q3Answer = YesNo.NotAnswered;
		String[] s2q3SpecRef = new String[] {"s2q3SpecRef"};
		Question s2q3 = new YesNoQuestion(s2q3Question,
				section2Name, s2q3Number, specVersion, s2q3SpecRef, language, s2q3Answer);
		s2q3.setSubQuestionOfNumber(s2q1Number);
		section2Questions.add(s2q3);
		section2.setQuestions(section2Questions);
		sections.add(section2);
		survey.setSections(sections);
		SurveyDbDao dao = new SurveyDbDao(con);
		try {
			dao.addSurvey(survey);
			fail("This should have failed");
		} catch (QuestionException ex) {
			// expected
			assertTrue(ex.getMessage().contains("umber"));
		}
	}

	@Test
	public void testGetSurveyVersions() throws SQLException, SurveyResponseException, QuestionException {
		SurveyDbDao dao = new SurveyDbDao(con);
		String language = "asd";

		List<Section> sections = new ArrayList<Section>();
		Section section1 = new Section(language);
		String section1Name = "section1Name";
		section1.setName(section1Name);
		String section1Title = "section1Title";
		section1.setTitle(section1Title);
		List<Question> section1Questions = new ArrayList<Question>();
		String s1q1Question="s1q1question";
		String s1q1Number = "1.a";
		YesNo s1q1Answer = YesNo.Yes;
		String[] s1q1SpecRef = new String[] {"s1q1SpecRef"};
		Question s1q1 = new YesNoQuestion(s1q1Question,
				section1Name, s1q1Number, "v", s1q1SpecRef, language, s1q1Answer);
		section1Questions.add(s1q1);
		String s1q2Question="s1q2question";
		String s1q2Number = "1.b";
		YesNo s1q2Answer = YesNo.NotApplicable;
		String s1q2Prompt = "s1q2prompt";
		String[] s1q2SpecRef = new String[] {"s1q2SpecRef"};
		Question s1q2 = new YesNoNotApplicableQuestion(s1q2Question,
				section1Name, s1q2Number, "v", s1q2SpecRef, language, s1q2Answer, s1q2Prompt);
		section1Questions.add(s1q2);
		section1.setQuestions(section1Questions);
		sections.add(section1);
		String v1 = "1.0.0";
		String v2 = "1.0.1";
		String v3 = "2.1.1";
		String v4 = "2.2.2";
		Survey surveyV1 = new Survey(v1, language);
		surveyV1.setSections(sections);
		Survey surveyV2 = new Survey(v2, language);
		surveyV2.setSections(sections);
		Survey surveyV3 = new Survey(v3, language);
		surveyV3.setSections(sections);
		Survey surveyV4 = new Survey(v4, language);
		surveyV4.setSections(sections);
		dao.addSurvey(surveyV1);
		dao.addSurvey(surveyV3);
		dao.addSurvey(surveyV2);
		dao.addSurvey(surveyV4);
		List<String> result = dao.getSurveyVesions();
		assertEquals(4, result.size());
		assertEquals(v1, result.get(0));
		assertEquals(v2, result.get(1));
		assertEquals(v3, result.get(2));
		assertEquals(v4, result.get(3));
	}

	@Test
	public void testGetSurveyLanguages() throws SQLException, SurveyResponseException, QuestionException {
		SurveyDbDao dao = new SurveyDbDao(con);
		String language1 = "lang1";
		String language2 = "lang2";
		String language3 = "lang3";

		List<Section> sections = new ArrayList<Section>();
		Section section1 = new Section(language1);
		String section1Name = "section1Name";
		section1.setName(section1Name);
		String section1Title = "section1Title";
		section1.setTitle(section1Title);
		List<Question> section1Questions = new ArrayList<Question>();
		String s1q1Question="s1q1question";
		String s1q1Number = "1.a";
		YesNo s1q1Answer = YesNo.Yes;
		String[] s1q1SpecRef = new String[] {"s1q1SpecRef"};
		Question s1q1 = new YesNoQuestion(s1q1Question,
				section1Name, s1q1Number, "v", s1q1SpecRef, language1, s1q1Answer);
		section1Questions.add(s1q1);
		String s1q2Question="s1q2question";
		String s1q2Number = "1.b";
		YesNo s1q2Answer = YesNo.NotApplicable;
		String s1q2Prompt = "s1q2prompt";
		String[] s1q2SpecRef = new String[] {"s1q2SpecRef"};
		Question s1q2 = new YesNoNotApplicableQuestion(s1q2Question,
				section1Name, s1q2Number, "v", s1q2SpecRef, language1, s1q2Answer, s1q2Prompt);
		section1Questions.add(s1q2);
		section1.setQuestions(section1Questions);
		sections.add(section1);
		String version = "1.0.0";

		// test no languages
		assertEquals(0, dao.getSurveyLanguages(version).size());
		Survey survey1 = new Survey(version, language1);
		survey1.setSections(sections);
		dao.addSurvey(survey1);
		List<String> result = dao.getSurveyLanguages(version);
		assertEquals(1, result.size());
		assertEquals(language1, result.get(0));

		Survey survey2 = new Survey(version, language2);
		for (Section section:sections) {
			section.setLanguage(language2);
		}
		survey2.setSections(sections);
		dao.addSurvey(survey2);
		result = dao.getSurveyLanguages(version);
		assertEquals(2, result.size());
		assertTrue(result.contains(language1));
		assertTrue(result.contains(language2));

		Survey survey3 = new Survey(version, language3);
		for (Section section:sections) {
			section.setLanguage(language3);
		}
		survey3.setSections(sections);
		dao.addSurvey(survey3);
		result = dao.getSurveyLanguages(version);
		assertEquals(3, result.size());
		assertTrue(result.contains(language1));
		assertTrue(result.contains(language2));
		assertTrue(result.contains(language3));
	}

	@Test
	public void testLanguage()  throws SQLException, SurveyResponseException, QuestionException {
		String specVersion = "test-spec-version";
		String language1 = "abc";
		Survey survey1 = new Survey(specVersion, language1);
		List<Section> sections1 = new ArrayList<Section>();
		Section section1_1 = new Section(language1);
		String section1Name = "section1Name";
		section1_1.setName(section1Name);
		String section1Title = "section1Title";
		section1_1.setTitle(section1Title);
		List<Question> section1_1Questions = new ArrayList<Question>();
		String s1q1_1Question="s1q1question";
		String s1q1Number = "1.a";
		YesNo s1q1Answer = YesNo.Yes;
		Question s1q1_1 = new YesNoQuestion(s1q1_1Question,
				section1Name, s1q1Number, specVersion, new String[0], language1, s1q1Answer);
		section1_1Questions.add(s1q1_1);
		section1_1.setQuestions(section1_1Questions);
		sections1.add(section1_1);
		survey1.setSections(sections1);
		SurveyDbDao dao = new SurveyDbDao(con);
		dao.addSurvey(survey1);

		String language2 = "def";
		Survey survey2 = new Survey(specVersion, language2);
		List<Section> sections2 = new ArrayList<Section>();
		Section section1_2 = new Section(language2);
		String section2Name = "section2Name";
		section1_2.setName(section2Name);
		section1_2.setTitle(section1Title);
		List<Question> section1_2Questions = new ArrayList<Question>();
		String s1q1_2Question="s1q1-2question";
		Question s1q1_2 = new YesNoQuestion(s1q1_2Question,
				section2Name, s1q1Number, specVersion, new String[0], language2, s1q1Answer);
		section1_2Questions.add(s1q1_2);
		section1_2.setQuestions(section1_2Questions);
		sections2.add(section1_2);
		survey2.setSections(sections2);
		dao.addSurvey(survey2);

		Survey result = dao.getSurvey(specVersion, language1);
		assertEquals(language1, result.getLanguage());
		assertEquals(language1, result.getSections().get(0).getLanguage());
		assertEquals(section1Name, result.getSections().get(0).getName());
		assertEquals(language1, result.getSections().get(0).getQuestions().get(0).getLanguage());
		assertEquals(s1q1_1Question, result.getSections().get(0).getQuestions().get(0).getQuestion());

		result = dao.getSurvey(specVersion, language2);
		assertEquals(language2, result.getLanguage());
		assertEquals(language2, result.getSections().get(0).getLanguage());
		assertEquals(section2Name, result.getSections().get(0).getName());
		assertEquals(language2, result.getSections().get(0).getQuestions().get(0).getLanguage());
		assertEquals(s1q1_2Question, result.getSections().get(0).getQuestions().get(0).getQuestion());
	}

	@Test
	public void testGetSpecVersion() throws SQLException, SurveyResponseException, QuestionException {
		List<Section> sections = new ArrayList<Section>();
		Section section1 = new Section("abc");
		String section1Name = "section1Name";
		section1.setName(section1Name);
		String section1Title = "section1Title";
		section1.setTitle(section1Title);
		List<Question> section1Questions = new ArrayList<Question>();
		String s1q1Question="s1q1question";
		String s1q1Number = "1.a";
		YesNo s1q1Answer = YesNo.Yes;
		Question s1q1 = new YesNoQuestion(s1q1Question,
				section1Name, s1q1Number, "X", new String[0], "abc", s1q1Answer);
		String[] s1q1SpecRef = new String[] {"s1q1SpecRef"};
		s1q1.setSpecReference(s1q1SpecRef);
		section1Questions.add(s1q1);

		String version1 = "0.1.2";
		String lang1 = "fra";
		String version2 = "1.1.1";
		String lang2 = "abc";
		String lang3 = "ejk";
		Survey survey1 = new Survey(version1, lang1);
		survey1.setSections(sections);
		Survey survey2 = new Survey(version1, User.DEFAULT_LANGUAGE);
		survey2.setSections(sections);
		Survey survey3 = new Survey(version1, lang2);
		survey3.setSections(sections);
		Survey survey4 = new Survey(version2, null);
		survey4.setSections(sections);
		Survey survey5 = new Survey(version2, lang1);
		survey5.setSections(sections);
		SurveyDbDao dao = new SurveyDbDao(con);
		dao.addSurvey(survey1);
		dao.addSurvey(survey2);
		dao.addSurvey(survey3);
		dao.addSurvey(survey4);
		dao.addSurvey(survey5);
		// Test exact version language
		long lang1v1result = SurveyDbDao.getSpecId(con, version1, lang1, true);
		assertTrue(lang1v1result > 0);
		long defaultLangv1result = SurveyDbDao.getSpecId(con, version1, User.DEFAULT_LANGUAGE, true);
		assertTrue(defaultLangv1result > 0);
		assertTrue(defaultLangv1result != lang1v1result);
		long lang2v1result = SurveyDbDao.getSpecId(con, version1, lang2, true);
		assertTrue(lang2v1result > 0);
		assertTrue(lang2v1result != lang1v1result);
		assertTrue(lang2v1result != defaultLangv1result);
		long lang1v2result = SurveyDbDao.getSpecId(con, version2, lang1, true);
		assertTrue(lang1v2result > 0);
		assertTrue(lang1v2result != lang1v1result);
		assertTrue(lang1v2result != defaultLangv1result);
		// Test default language
		long defV1result = SurveyDbDao.getSpecId(con, version1, lang3, true);
		assertEquals(defaultLangv1result, defV1result);
		// Test no default
		long nullV2result = SurveyDbDao.getSpecId(con, version2, lang3, true);
		assertTrue(nullV2result > 0);
		assertTrue(nullV2result != lang1v1result);
		assertTrue(nullV2result != defaultLangv1result);
	}

	@Test
	public void testUpdateSectionTitle() throws QuestionException, SQLException, SurveyResponseException {
		String specVersion = "test-spec-version";
		String language = "abc";
		Survey survey = new Survey(specVersion, language);
		List<Section> sections = new ArrayList<Section>();
		Section section1 = new Section(language);
		String section1Name = "section1Name";
		section1.setName(section1Name);
		String section1Title = "section1Title";
		section1.setTitle(section1Title);
		List<Question> section1Questions = new ArrayList<Question>();
		String s1q1Question="s1q1question";
		String s1q1Number = "1.a";
		YesNo s1q1Answer = YesNo.Yes;
		String[] s1q1SpecRef = new String[] {"s1q1SpecRef"};
		Question s1q1 = new YesNoQuestion(s1q1Question,
				section1Name, s1q1Number, specVersion, s1q1SpecRef, language, s1q1Answer);

		section1Questions.add(s1q1);
		String s1q2Question="s1q2question";
		String s1q2Number = "1.b";
		YesNo s1q2Answer = YesNo.NotApplicable;
		String s1q2Prompt = "s1q2prompt";
		String[] s1q2SpecRef = new String[] {"s1q2SpecRef"};
		Question s1q2 = new YesNoNotApplicableQuestion(s1q2Question,
				section1Name, s1q2Number, specVersion, s1q2SpecRef, language, s1q2Answer, s1q2Prompt);
		section1Questions.add(s1q2);
		section1.setQuestions(section1Questions);
		sections.add(section1);
		Section section2 = new Section(language);
		String section2Name = "section2Name";
		section2.setName(section2Name);
		String section2Title = "section2Title";
		section2.setTitle(section2Title);
		List<Question> section2Questions = new ArrayList<Question>();
		String s2q1Question="s2q1question";
		String s2q1Number = "2.b";
		int s2q1MinCorrect = 4;
		String[] s2q1SpecRef = new String[] {"s2q1SpecRef"};
		Question s2q1 = new SubQuestion(s2q1Question,
				section2Name, s2q1Number, specVersion, s2q1SpecRef, language, s2q1MinCorrect);
		section2Questions.add(s2q1);
		String s2q2Question="s2q2question";
		String s2q2Number = "2.b.ii";
		YesNo s2q2Answer = YesNo.No;
		String s2q2Prompt = "s2q2prompt";
		String s2q2validate = "dd";
		String[] s2q2SpecRef = new String[] {"s2q2SpecRef"};
		Question s2q2 = new YesNoQuestionWithEvidence(s2q2Question,
				section2Name, s2q2Number, specVersion, s2q2SpecRef, language, s2q2Answer, s2q2Prompt, Pattern.compile(s2q2validate));
		s2q2.setSubQuestionOfNumber(s2q1Number);
		section2Questions.add(s2q2);
		String s2q3Question="s2q3question";
		String s2q3Number = "1.b.iii";
		YesNo s2q3Answer = YesNo.NotAnswered;
		String[] s2q3SpecRef = new String[] {"s2q3SpecRef"};
		Question s2q3 = new YesNoQuestion(s2q3Question,
				section2Name, s2q3Number, specVersion, s2q3SpecRef, language, s2q3Answer);
		s2q3.setSubQuestionOfNumber(s2q1Number);
		section2Questions.add(s2q3);
		section2.setQuestions(section2Questions);
		sections.add(section2);
		survey.setSections(sections);
		SurveyDbDao dao = new SurveyDbDao(con);
		dao.addSurvey(survey);
		Survey result = dao.getSurvey(specVersion, language);
		assertEquals(specVersion, result.getSpecVersion());
		for (Section rs:result.getSections()) {
			if (rs.getName().equals(section1Name)) {
				assertEquals(section1Title, rs.getTitle());
				assertEquals(language, rs.getLanguage());
			} else if (rs.getName().equals(section2Name)) {
				assertEquals(section2Title, rs.getTitle());
				assertEquals(language, rs.getLanguage());
			} else {
				fail("No matching section names");
			}
		}
		String newSection1Title = "newOneTitle";
		dao.updateSectionTitle(specVersion, language, section1Name, newSection1Title);
		result = dao.getSurvey(specVersion, language);
		for (Section rs:result.getSections()) {
			if (rs.getName().equals(section1Name)) {
				assertEquals(newSection1Title, rs.getTitle());
				assertEquals(language, rs.getLanguage());
			} else if (rs.getName().equals(section2Name)) {
				assertEquals(section2Title, rs.getTitle());
				assertEquals(language, rs.getLanguage());
			} else {
				fail("No matching section names");
			}
		}
	}
}


text:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading.Tasks;

namespace Moe.Lib
{
    /// <summary>
    ///     Extension methods for <see cref="System.Collections.Generic.IEnumerable{T}" />
    /// </summary>
    public static class EnumerableExtensions
    {
        /// <summary>
        ///     Performs an action on each value of the sequence
        /// </summary>
        /// <typeparam name="T">Sequence element type.</typeparam>
        /// <param name="sequence">Sequence on which to perform action</param>
        /// <param name="action">Action to perform on every item</param>
        /// <exception cref="System.ArgumentNullException">Thrown when given null <paramref name="sequence" /> or <paramref name="action" /></exception>
        public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
        {
            IList<T> values = sequence as IList<T> ?? sequence.ToList();
            if (sequence == null)
            {
                throw new ArgumentNullException(nameof(sequence));
            }

            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            foreach (T value in values)
            {
                action(value);
            }
        }

        /// <summary>
        ///     Performs an action on each value of the sequence
        /// </summary>
        /// <typeparam name="T">Sequence element type.</typeparam>
        /// <typeparam name="TResult">Result element type.</typeparam>
        /// <param name="sequence">Sequence on which to perform action</param>
        /// <param name="action">Action to perform on every item</param>
        /// <returns>IEnumerable<TR>.</returns>
        /// <exception cref="ArgumentNullException">
        /// </exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static IEnumerable<TResult> ForEach<T, TResult>(this IEnumerable<T> sequence, Func<T, TResult> action)
        {
            IList<T> values = sequence as IList<T> ?? sequence.ToList();

            if (sequence == null)
            {
                throw new ArgumentNullException(nameof(sequence));
            }

            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            return values.Select(value => action(value)).ToList();
        }

        /// <summary>
        ///     Performs an action on each value of the sequence
        /// </summary>
        /// <typeparam name="T">Sequence element type.</typeparam>
        /// <param name="sequence">Sequence on which to perform action.</param>
        /// <param name="action">Action to perform on every item</param>
        /// <returns>IEnumerable<V>.</returns>
        /// <exception cref="ArgumentNullException">
        /// </exception>
        /// <exception cref="System.ArgumentNullException"></exception>
        public static Task ForEach<T>(this IEnumerable<T> sequence, Func<T, Task> action)
        {
            IList<T> values = sequence as IList<T> ?? sequence.ToList();

            if (sequence == null)
            {
                throw new ArgumentNullException(nameof(sequence));
            }

            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            IEnumerable<Task> tasks = values.Select(value => action(value));
            return Task.WhenAll(tasks);
        }

        /// <summary>
        ///     Performs an action on each value of the sequence
        /// </summary>
        /// <typeparam name="T">Sequence element type.</typeparam>
        /// <typeparam name="TResult">Result element type.</typeparam>
        /// <param name="sequence">Sequence on which to perform action</param>
        /// <param name="action">Action to perform on every item</param>
        /// <returns>IEnumerable<V>.</returns>
        /// <exception cref="ArgumentNullException">
        /// </exception>
        /// <exception cref="ArgumentNullException"></exception>
        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures")]
        public static async Task<IEnumerable<TResult>> ForEach<T, TResult>(this IEnumerable<T> sequence, Func<T, Task<TResult>> action)
        {
            IList<T> values = sequence as IList<T> ?? sequence.ToList();
            IList<TResult> results = new List<TResult>();

            if (sequence == null)
            {
                throw new ArgumentNullException(nameof(sequence));
            }

            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            foreach (T value in values)
            {
                results.Add(await action(value));
            }
            return results;
        }

        /// <summary>
        ///     Gets the length of the enumerable sequence.
        ///     When the value is a null reference, it is considered to have 0 elements.
        /// </summary>
        /// <param name="sequence">The sequence.</param>
        /// <returns>System.Int32.</returns>
        public static int GetLength(this IEnumerable sequence)
        {
            // When the given enumerable is an ICollection, we can do a simple interface call to determine
            // it's size.
            if (sequence == null)
            {
                return 0;
            }

            ICollection collection = sequence as ICollection;

            if (collection != null)
            {
                return collection.Count;
            }

            // When we get at this point, we'll have to iterate over the enumerable to find out the size.
            IEnumerator enumerator = sequence.GetEnumerator();
            try
            {
                int count = 0;

                while (enumerator.MoveNext())
                {
                    count++;
                }

                return count;
            }
            finally
            {
                IDisposable disposable = enumerator as IDisposable;
                disposable?.Dispose();
            }
        }

        /// <summary>
        ///     Convenience method for retrieving a specific page of items within a collection.
        /// </summary>
        /// <typeparam name="T">Element type</typeparam>
        /// <param name="sequence">Sequence on which to perform action</param>
        /// <param name="pageIndex">The index of the page to get.</param>
        /// <param name="pageSize">The size of the pages.</param>
        public static IEnumerable<T> GetPage<T>(this IEnumerable<T> sequence, int pageIndex, int pageSize)
        {
            IList<T> values = sequence as IList<T> ?? sequence.ToList();
            if (pageIndex < 0)
            {
                pageIndex = 0;
            }

            if (pageSize < 0)
            {
                pageSize = 0;
            }

            return values.Skip(pageIndex * pageSize).Take(pageSize);
        }

        /// <summary>
        ///     Validates that the <paramref name="enumerable" /> is not null and contains items.
        /// </summary>
        /// <typeparam name="TSource">The type of the t source.</typeparam>
        /// <param name="enumerable">The enumerable.</param>
        /// <returns>System.Boolean.</returns>
        public static bool IsNotNullOrEmpty<TSource>(this IEnumerable<TSource> enumerable)
        {
            return enumerable != null && enumerable.Any();
        }

        /// <summary>
        ///     Determines whether [is null or empty] [the specified sequence].
        /// </summary>
        /// <typeparam name="TSource">The type of the t source.</typeparam>
        /// <param name="sequence">The sequence.</param>
        /// <returns>System.Boolean.</returns>
        public static bool IsNullOrEmpty<TSource>(this IEnumerable<TSource> sequence)
        {
            if (sequence == null)
            {
                return true;
            }

            ICollection<TSource> collection = sequence as ICollection<TSource>;

            if (collection != null)
            {
                // We expect this to be the normal flow.
                return collection.Count == 0;
            }

            // We expect this to be the exceptional flow, because most collections implement
            // ICollection<T>.
            return sequence.IsSequenceNullOrEmpty();
        }

        /// <summary>
        ///     Determines whether [is null or empty] [the specified sequence].
        /// </summary>
        /// <param name="sequence">The sequence.</param>
        /// <returns>System.Boolean.</returns>
        public static bool IsNullOrEmpty(this IEnumerable sequence)
        {
            return sequence == null || sequence.IsSequenceNullOrEmpty();
        }

        /// <summary>
        ///     Concatenates the members of a collection, using the specified separator between each member.
        /// </summary>
        /// <returns>A string that consists of the members of <paramref name="values" /> delimited by the <paramref name="separator" /> string. If values has no members, the method returns null.</returns>
        public static string Join<T>(this IEnumerable<T> values, string separator = ",")
        {
            separator = separator ?? ",";
            return values == null ? null : string.Join(separator, values);
        }

        /// <summary>
        ///     Converts an sequence into a readonly collection
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="enumerable">The enumerable.</param>
        /// <returns>System.Collections.Generic.IEnumerable<T>.</returns>
        public static IEnumerable<T> ToReadOnlyCollection<T>(this IEnumerable<T> enumerable)
        {
            return new ReadOnlyCollection<T>(enumerable.ToList());
        }

        private static bool IsEnumerableEmpty(IEnumerable sequence)
        {
            IEnumerator enumerator = sequence.GetEnumerator();

            try
            {
                return !enumerator.MoveNext();
            }
            finally
            {
                IDisposable disposable = enumerator as IDisposable;
                disposable?.Dispose();
            }
        }

        /// <summary>
        ///     Determines whether [is null or empty] [the specified sequence].
        /// </summary>
        /// <param name="sequence">The sequence.</param>
        /// <returns>System.Boolean.</returns>
        private static bool IsSequenceNullOrEmpty(this IEnumerable sequence)
        {
            if (sequence == null)
            {
                return true;
            }

            ICollection collection = sequence as ICollection;

            if (collection != null)
            {
                // We expect this to be the normal flow.
                return collection.Count == 0;
            }

            // We expect this to be the exceptional flow, because most collections implement ICollection.
            return IsEnumerableEmpty(sequence);
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
#ifndef QUATERNION_H_INCLUDED
#define QUATERNION_H_INCLUDED

#ifdef __cplusplus
extern "C" {
#endif

#include "platform/CCPlatformMacros.h"
#include "utility.h"

struct kmMat4;
struct kmMat3;
struct kmVec3;

typedef struct kmQuaternion {
    kmScalar x;
    kmScalar y;
    kmScalar z;
    kmScalar w;
} kmQuaternion;

CC_DLL kmQuaternion* const kmQuaternionConjugate(kmQuaternion* pOut, const kmQuaternion* pIn); ///< Returns pOut, sets pOut to the conjugate of pIn

CC_DLL const kmScalar     kmQuaternionDot(const kmQuaternion* q1, const kmQuaternion* q2); ///< Returns the dot product of the 2 quaternions

CC_DLL kmQuaternion* kmQuaternionExp(kmQuaternion* pOut, const kmQuaternion* pIn); ///< Returns the exponential of the quaternion

///< Makes the passed quaternion an identity quaternion

CC_DLL kmQuaternion* kmQuaternionIdentity(kmQuaternion* pOut);

///< Returns the inverse of the passed Quaternion

CC_DLL kmQuaternion* kmQuaternionInverse(kmQuaternion* pOut,
                                            const kmQuaternion* pIn);

///< Returns true if the quaternion is an identity quaternion

CC_DLL int kmQuaternionIsIdentity(const kmQuaternion* pIn);

///< Returns the length of the quaternion

CC_DLL kmScalar kmQuaternionLength(const kmQuaternion* pIn);

///< Returns the length of the quaternion squared (prevents a sqrt)

CC_DLL kmScalar kmQuaternionLengthSq(const kmQuaternion* pIn);

///< Returns the natural logarithm

CC_DLL kmQuaternion* kmQuaternionLn(kmQuaternion* pOut, const kmQuaternion* pIn);

///< Multiplies 2 quaternions together

CC_DLL kmQuaternion* kmQuaternionMultiply(kmQuaternion* pOut, const kmQuaternion* q1, const kmQuaternion* q2);

///< Normalizes a quaternion

CC_DLL kmQuaternion* kmQuaternionNormalize(kmQuaternion* pOut, const kmQuaternion* pIn);

///< Rotates a quaternion around an axis

CC_DLL kmQuaternion* kmQuaternionRotationAxis(kmQuaternion* pOut, const struct kmVec3* pV, kmScalar angle);

///< Creates a quaternion from a rotation matrix

CC_DLL kmQuaternion* kmQuaternionRotationMatrix(kmQuaternion* pOut, const struct kmMat3* pIn);

///< Create a quaternion from yaw, pitch and roll

CC_DLL kmQuaternion* kmQuaternionRotationYawPitchRoll(kmQuaternion* pOut, kmScalar yaw, kmScalar pitch, kmScalar roll);
///< Interpolate between 2 quaternions
CC_DLL kmQuaternion* kmQuaternionSlerp(kmQuaternion* pOut, const kmQuaternion* q1, const kmQuaternion* q2, kmScalar t);

///< Get the axis and angle of rotation from a quaternion
CC_DLL void kmQuaternionToAxisAngle(const kmQuaternion* pIn, struct kmVec3* pVector, kmScalar* pAngle);

///< Scale a quaternion
CC_DLL kmQuaternion* kmQuaternionScale(kmQuaternion* pOut, const kmQuaternion* pIn, kmScalar s);
CC_DLL kmQuaternion* kmQuaternionAssign(kmQuaternion* pOut, const kmQuaternion* pIn);
CC_DLL kmQuaternion* kmQuaternionAdd(kmQuaternion* pOut, const kmQuaternion* pQ1, const kmQuaternion* pQ2);
CC_DLL kmQuaternion* kmQuaternionRotationBetweenVec3(kmQuaternion* pOut, const struct kmVec3* vec1, const struct kmVec3* vec2, const struct kmVec3* fallback);
CC_DLL struct kmVec3* kmQuaternionMultiplyVec3(struct kmVec3* pOut, const kmQuaternion* q, const struct kmVec3* v);

#ifdef __cplusplus
}
#endif

#endif


text:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

<title>Packet24TeamAssign</title>
<meta name="date" content="2015-10-14">
<link rel="stylesheet" type="text/css" href="../../../stylesheet.css" title="Style">

JavaScript is disabled on your browser.

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method

game.control.packets

Class Packet24TeamAssign

java.lang.Object

game.control.packets.Packet

game.control.packets.Packet24TeamAssign

public class Packet24TeamAssign
extends Packet

This packet is sent when players are assigned teams.

Author:

Cameron Bryers 300326848 MMXV

         TEAM_ASSIGN = 24 + String username + int team(0:1)

Nested Class Summary

Nested classes/interfaces inherited from class game.control.packets.Packet

Packet.PacketType

Field Summary

Fields inherited from class game.control.packets.Packet

packetID

Constructor Summary

Constructors

Constructor and Description

Packet24TeamAssign(byte[] data)

Constructor intended for sending data

Packet24TeamAssign(java.lang.String[] players,
                  java.lang.String[] teams)

Constructor intended for receiving data.

Method Summary

All Methods Instance Methods Concrete Methods

Modifier and Type
Method and Description

byte[]
getData()

Return a byte representation of the packet

java.lang.String[]
getPlayers()

Gets the all of the players usernames on the server

java.lang.String[]
getTeams()

Gets the teams that the players on the server are assigned to

void
writeData(GameClient client)

Write data to a specific client

void
writeData(GameServer server)

Write data to all the clients on this server

Methods inherited from class game.control.packets.Packet

lookupPacket, lookupPacket, readData

Methods inherited from class java.lang.Object

equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait

Constructor Detail

Packet24TeamAssign

public Packet24TeamAssign(byte[] data)

Constructor intended for sending data

Parameters:

data - - message to be sent

Packet24TeamAssign

public Packet24TeamAssign(java.lang.String[] players,
                          java.lang.String[] teams)

Constructor intended for receiving data.

Parameters:

players - - array of player usernames

teamseam - allocation
            - team allocation GUARD "0" SPY "1"

Method Detail

writeData

public void writeData(GameClient client)

Description copied from class: Packet

Write data to a specific client

Specified by:

writeData in class Packet

Parameters:

client - - client to be written to

writeData

public void writeData(GameServer server)

Description copied from class: Packet

Write data to all the clients on this server

Specified by:

writeData in class Packet

Parameters:

server - - server to be written to

getData

public byte[] getData()

Description copied from class: Packet

Return a byte representation of the packet

Specified by:

getData in class Packet

Returns:

packet message as a byte array

getPlayers

public final java.lang.String[] getPlayers()

Gets the all of the players usernames on the server

Returns:

player usernames in an array

getTeams

public final java.lang.String[] getTeams()

Gets the teams that the players on the server are assigned to

Returns:

team allocation GUARD "0" SPY "1"

Skip navigation links

Overview

Package

Class

Use

Tree

Deprecated

Index

Help

Prev Class

Next Class

Frames

No Frames

All Classes

Summary:

Nested |

Field |

Constr |

Method

Detail:

Field |

Constr |

Method


text:
<!doctype html>

		<meta charset="utf-8">
		<title>reveal.js - The HTML Presentation Framework</title>
		<meta name="description" content="A framework for easily creating beautiful presentations using HTML">
		<meta name="author" content="Hakim El Hattab">
		<meta name="apple-mobile-web-app-capable" content="yes" />
		<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
		<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no, minimal-ui">
		<link rel="stylesheet" href="css/reveal.css">
		<link rel="stylesheet" href="css/theme/black.css" id="theme">

		<link rel="stylesheet" href="lib/css/zenburn.css">

Introduction to cryptography

						Jesse van Bekkum

History

Letter substitution

ROT-Thirteen

Ceasar Cypher

Enigma Machine

Confidentiality

Integrity

Availability

Non repudiation

Symmetric & Asymmetric

Symmetric

Asymmetric

Practice

Symmetric algorithms

Block ciphers and stream ciphers

 AES

						Advanced Encryption Standard

DES and Triple-DES

Asymmetric algorithms

 RSA

						Invented by Ron Rivest, Adi Shamir and Leonard Adleman

 RSA

Easy:

						$$p \times q \rightarrow pq$$

Difficult:

							$$p q \rightarrow p \times q$$

Others

Diffie-Hellman

ElGamal

Elliptic Curve

Hashing

Collisions

						$$ xebia \rightarrow aad3fcfa3352b57afd6aee013ccd69cb $$
						$$ Xebia \rightarrow 13f6a4bf6b2198a589dae92526c4b93a $$

Demo

						md5 = e06723d4961a0a3f950e7786f3766338

						From http://natmchugh.blogspot.nl/2014/10/how-i-created-two-images-with-same-md5.html

Files

Passwords

Files

<s>MD5</s>

<s>SHA-1</s>

SHA-256

Passwords

BCRYPT

PBKDF2

 Password-Based Key Derivation Function 2

Salt

Solution: Make each password unique

							$$hash(secret + o4wj) \neq hash(secret + re9g)$$

							For encryption: Nonce

Random number generators

Secure

Unpredictable

Based on external signals (network, mouse, keyboard)

Unsecure / Unblocking

Fast

Based on predictable seed, such as timestamp (in Java)

Implementation

Implementing cryptograpy protocols is DIFFICULT

Transport Layer Security & Secure Socket Layer

Never implement your own encryption

Use BCrypt

Use SHA-256

Use SecureRandom

					https://www.coursera.org/course/crypto

					Started 31 July

					Six weeks

Used images:

"Australian Made CMI H2D Home Safe" by Binarysequence

							Own work. Licensed under CC BY-SA 4.0 via Wikimedia Commons

							https://commons.wikimedia.org/wiki/File:Australian_Made_CMI_H2D_Home_Safe.JPG

"Padlock klódka ubt".
Licensed under CC BY-SA 3.0 via Wikimedia Commons
https://commons.wikimedia.org/wiki/File:Padlock_kl%C3%B3dka_ubt.JPG

By Hein waschefort (Own work) [CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons

By Diacritica (Own work)
[CC BY-SA 3.0 (http://creativecommons.org/licenses/by-sa/3.0)], via Wikimedia Commons

By Dubravko Sorić SoraZG on Flickr
[CC BY 2.0 (http://creativecommons.org/licenses/by/2.0)], via Wikimedia Commons

By Frettie (Own work)
[GFDL (http://www.gnu.org/copyleft/fdl.html) or CC BY 3.0 (http://creativecommons.org/licenses/by/3.0)], via Wikimedia Commons

By Bananenfalter (Own work) [CC0], via Wikimedia Commons

By Alan Turing Created in vector format by Scewing (RR Auctions) [Public domain], via Wikimedia Commons


text:
package drive.change.services;

import com.google.api.services.drive.model.Change;
import com.google.inject.Inject;
import database.repository.FileRepository;
import drive.change.model.CustomChange;
import org.neo4j.graphdb.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Created by david on 2016-05-04.
 */
public class ConverterService {
    private FileRepository fileRepository;
    private Node fileNode;
    private Change change;

    private static Logger logger = LoggerFactory.getLogger(ConverterService.class);

    @Inject
    public ConverterService(FileRepository fileRepository){
        this.fileRepository = fileRepository;
    }

    public CustomChange execute(Change change){

        CustomChange customChange = new CustomChange();

        customChange.setChange(change);

        fileNode = fileRepository.getNodeById(change.getFileId());
        customChange.setFileNode(fileNode);

        //Case new file
        if(fileNode == null){
            customChange.setNew(true);
            Node parentNode = fileRepository.getNodeById(change.getFile().getParents().get(0));
            customChange.setNewParentNode(parentNode);
            customChange.setOldParentNode(parentNode);

            customChange.setOldName(change.getFile().getName());
            customChange.setNewName(change.getFile().getName());

            return customChange;
        }

        //Case deletion
        customChange.setDeleted(change.getRemoved());

        if(change.getRemoved()) {
            Node parentNode = fileRepository.getParent(change.getFileId());
            customChange.setNewParentNode(parentNode);
            customChange.setOldParentNode(parentNode);
            String name = fileRepository.getName(fileNode);
            customChange.setOldName(name);
            customChange.setNewName(name);
            return customChange;
        }

        //Case trashed
        if (getTrashed(change)){
            customChange.setTrashed(true);
        }

        //Case untrashed
        if(fileRepository.getTrashed(fileNode) && ! getTrashed(change)) {
            customChange.setUnTrashed(true);
        }

        Node newParentNode = fileRepository.getNodeById(change.getFile().getParents().get(0));
        Node oldParentNode = fileRepository.getParent(change.getFileId());

        customChange.setNewParentNode(newParentNode);
        customChange.setOldParentNode(oldParentNode);

        customChange.setOldName(fileRepository.getName(fileNode));
        customChange.setNewName(change.getFile().getName());

        return customChange;
    }

    /**
     * Get trashed label value if available
     *
     * @param change Change
     *
     * @return boolean
     */
    public boolean getTrashed(Change change) {
        return (change.getFile() != null
                && change.getFile().getExplicitlyTrashed() != null
                && change.getFile().getExplicitlyTrashed())
                || (change.getFile() != null
                && change.getFile().getTrashed() != null
                && change.getFile().getTrashed());
    }
}


text:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns='http://www.blackboard.com/bb-manifest'>
    <plugin>
        <name value="BbRest"/>
        <handle value="bbrest"/>
        <version value="1.0.0"/>
        <vendor>
            <id value="gray"/>
            <name value="Paul Gray"/>
            <url value="http://www.paulgray.net"/>
        </vendor>
        <requires>
            <bbversion value="9.1"/>
        </requires>
        <http-actions>
            <config value="static/config.html"/>
        </http-actions>
        <application-defs>
            <application handle="bbrest-manager" name="BbRest Configuration" type="system">
                <links>
                    <link>
                        <name value="BbRest Configuration"/>
                        <url value="static/config.html"/>
                        <type value="system_tool"/>
                    </link>
                </links>
            </application>
        </application-defs>
        <permissions>
            <permission type="java.io.FilePermission" name="/usr/local/blackboard/content/vi/bb_bb60/plugins/gray-lmsrest/config/-" actions="read,write,delete" />
            <permission type="java.io.FilePermission" name="/usr/local/blackboard/logs/-" actions="write" />
            <permission type="java.io.FilePermission" name="/usr/local/blackboard/apps/tomcat/temp/-" actions="read,write,delete" />
            <permission type="java.security.SecurityPermission" name="*" />
            <permission type="java.lang.RuntimePermission" name="*" />
            <permission type="java.net.SocketPermission" name="*" actions="connect,resolve" />
            <permission type="java.lang.reflect.ReflectPermission" name="suppressAccessChecks" />
            <permission type="java.util.PropertyPermission" name="*" actions="read,write" />
            <permission type="blackboard.data.AttributePermission" name="user.personalinfo" actions="get" />
            <permission type="blackboard.data.AttributePermission" name="user.authinfo" actions="get" />
            <permission type="java.lang.RuntimePermission" name="createClassLoader" />
            <permission type="java.lang.RuntimePermission" name="setContextClassLoader" />
            <permission type="java.lang.RuntimePermission" name="getProtectionDomain" />

            <permission type="blackboard.persist.PersistPermission" name="message" actions="create,modify"/>

        </permissions>
    </plugin>
</manifest>


text:
package mesosphere.marathon
package core.leadership.impl

import akka.actor.ActorRef
import akka.pattern.ask
import akka.util.Timeout
import mesosphere.marathon.core.leadership.LeadershipCoordinator
import mesosphere.marathon.core.leadership.PreparationMessages.PrepareForStart
import mesosphere.marathon.core.leadership.impl.WhenLeaderActor.Stop

import scala.concurrent.Future
import scala.concurrent.duration._

private[leadership] class LeadershipCoordinatorDelegate(actorRef: ActorRef) extends LeadershipCoordinator {
  override def prepareForStart(): Future[Unit] = {
    import scala.concurrent.ExecutionContext.Implicits.global
    implicit val timeout: Timeout = 10.seconds
    (actorRef ? PrepareForStart).map(_ => ())
  }

  override def stop(): Unit = actorRef ! Stop
}


text:
update {prefix}settings set name = 'site_slogan' where name = 'motto';
update {prefix}settings set name = 'site_slogan_de' where name = 'motto_de';
update {prefix}settings set name = 'site_slogan_en' where name = 'motto_en';


text:
<?php

namespace litepubl\update;

use litepubl\tag\Cats;
use litepubl\tag\Common;
use litepubl\tag\Tags;

function update707()
{
    updateCats(Cats::i());
    updateCats(Tags::i());
}

function updateCats(Common $cats)
{
    $db = $cats->getDb('posts');
    $idPosts = $db->res2id($db->query("select id from $db->posts where $cats->postpropname  like '% %'"));
    //$cats->itemsposts->updatePosts($items, 'categories');
    foreach ($idPosts as $idPost) {
        $items = $cats->itemsposts->getItems($idPost);
        $db->table = 'posts';
        $db->setValue($idPost, $cats->postpropname, implode(',', $items));
    }
}


text:
package com.javadude.template2withstrategy;

import com.javadude.tms.BinaryTreeNode;

// STRATEGY
public interface NodeStrategy {
	// HOOK METHOD
	void dealWithMe(BinaryTreeNode node);
}


text:
from django.contrib.staticfiles.storage import CachedFilesMixin, ManifestFilesMixin

from pipeline.storage import PipelineMixin

from storages.backends.s3boto import S3BotoStorage

class S3PipelineManifestStorage(PipelineMixin, ManifestFilesMixin, S3BotoStorage):
    pass

class S3PipelineCachedStorage(PipelineMixin, CachedFilesMixin, S3BotoStorage):
    pass


text:
<!DOCTYPE html>

        <meta charset="UTF-8">
        <title>Components: buttons | Pati Montero's design system </title>
        <meta name="description" content="A button is a distinct visual element where users can click or tap to trigger an action.">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <link rel="stylesheet" href="css/styles.css">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link href="https://fonts.googleapis.com/css?family=Raleway:700&display=swap" rel="stylesheet">
        <link rel="icon" href="../images/pati-favicon.png" type="image/png">
        <meta name="google-site-verification" content="3DZHbv83s9zAmGpNLDUsum7EZakdUf_r_DeuB01UdHo" />

        Skip to content

                            <svg aria-label="Pati Montero" class="logo" width="122" hight="75" viewbox="0 0 122 75" xmlns="http://www.w3.org/2000/svg">
                                <g><path d="M112.1 45V18.8l-.8-.3-13.2 4.4V24c2 0 2 2.5 2 4.4v16.8c0 1.4.9 2.8 1.2 4.1-2.7 2.3-8.2 1.6-8.2-4.3V15.6c1-1.5 4.6-6.4 6.8-6.4 0 3.2 3.1 6.2 6.7 6.2 3.9 0 7-3.1 7-7.1 0-3.9-3-7.1-7-7.1-7.6 0-11.5 8.2-13.5 10.6V.9h-6c0 4-9 12.5-12 12.5v1.5h5v30.2c0 2 0 3.9.6 5.5-1.2.6-6.6 3-6.6-3.3V29.9c0-2.1.5-11.8-14.5-11.8 0 0-15.1-.9-15.1 8.6 0 4.6 3.5 5.5 5.7 5.5 1.8 0 5.4-1.1 5.4-5.5 0-2.9-1.7-4.2-1.7-4.2s1.3-2.2 4.5-2.2 4.7 1.8 4.7 5.2V35s-19.7-1.6-19.7 11.4c0 5.4 4.1 9.7 9.9 9.7 7.3 0 10.8-4.6 10.8-4.6s1.7 4.6 8 4.6c4.5 0 8.5-3.1 9.8-4.2 1.5 2.5 4.1 4.2 8 4.2 5.7 0 10.6-3.8 12.2-5.2 1.2 3.1 3.7 5.2 8.1 5.2 6.9 0 11.7-6 11.7-6l-.8-1c-2.6 2.8-9 1.9-9-4.1zm-49 5.2s-7.7 4.1-7.7-4.9c0-8.5 7.7-7.8 7.7-7.8v12.7zM27.8 18.2c-7.3 0-11.9 6.8-11.9 6.8h.2v-7h-.7L.1 22.5l.6.8c1.6 0 3.4 2.2 3.4 5v46.6h12v-19s2.4.9 7.1.9c14.7 0 18.3-11.3 18.3-21.1-.1-9.7-6.3-17.5-13.7-17.5zm-5.7 36c-4.5 0-6-5.2-6-8.1V27.6s2-1.9 5.1-1.9c2.5 0 8.1 2.5 8.1 12.6s-2.7 15.9-7.2 15.9z"/></g>
                            </svg>

Brand

Style

Components

Components: buttons

A wee design system's library

<time datetime="2020-05-20">Last updated on May 20, 2020—5 min read</time>

Accordions

Buttons

Cards—In progress

Links

Navigation

Texts

Buttons #

A button is a distinct visual element where users can click or tap to trigger an action.

Guidelines

Use a <button> for actions, such as copy, expand, collapse or send. If the need is a change of location, use a link <a>. The proper use of their meaning as HTML elements results in a more inclusive experience. It also eases the maintenance and scaling of this design system.

Deliver every button with a precise text that states its purpose. In most cases, it should be a verb that incites action. You'll know it works when the user can predict the outcome before triggering the button.

Keep its content below four words to prevent text wrapping.

Use sentence case for the texts, which means that only the first word starts with a capital letter. Don't use a period in the end.

A primary button conveys the most prominent choice that the user can take in a section. For this reason, there should be only one per page. For supporting actions, pick a secondary button instead.

A button's colour changes depending on its surroundings. It may be any of the four shades picked from the colour palette, as long as it yields an accessible contrast. The shades are dark-accent, accent, light and dark:

#dd2808

#f96c53

#f8f8f8

#2f2f2f

                    Code snippets
                    <button class="btn" data-expandall="">Expand all</button>

Primary button

                        <button data-expands="btn-primary-content" aria-label="open section" aria-describedby="btn-primary" aria-expanded="false">
                            <svg focusable="false" height="20mm" width="20mm" viewBox="0 0 70 70">
                                <g transform="translate(0 -981.5)">
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="60" width="9.8985" y="987.36" x="30.051" class="up-strut"></rect>
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="10" width="60" y="1012.4" x="5"></rect>
                                </g>
                            </svg>
                        </button>

Light text (#f8f8f8) over a dark-accent box area (#dd2808), this is the default style for all buttons. It can only perform accessibly over a light-coloured background or contrasting image.

Here are a few examples of proper usage:

<button class="btn">This is a button</button>

                            <button class="btn">This is a button</button>

                            <button class="btn">This is a button</button>

These are its code snippets:

                                    HTML
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#html-btn-primary">Copy HTML</button>

<button class="btn">This is a button</button>

                                    CSS
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#css-btn-primary">Copy CSS</button>

.btn {
    background-color: #dd2808;
    border: 2px solid transparent;
    border-radius: 3px;
    color: #f8f8f8;
    cursor: pointer;
    font: 700 1rem/1.2 'Raleway', Helvetica, sans-serif;
    padding: .5rem .75rem;
    text-decoration: none;
}

.btn:hover {
    background-color: #a71e06;
}

Primary accent button

                        <button data-expands="btn-primary-accent-content" aria-label="open section" aria-describedby="btn-primary-accent" aria-expanded="false">
                            <svg focusable="false" height="20mm" width="20mm" viewBox="0 0 70 70">
                                <g transform="translate(0 -981.5)">
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="60" width="9.8985" y="987.36" x="30.051" class="up-strut"></rect>
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="10" width="60" y="1012.4" x="5"></rect>
                                </g>
                            </svg>
                        </button>

Dark text (#2f2f2f) over an accent box (#f96c53), this is an alternative style. It should only appear over a dark-coloured background or contrasting image.

Here are a few examples of proper usage:

<button class="btn bg--accent">This is a button</button>

                            <button class="btn bg--accent">This is a button</button>

                            <button class="btn bg--accent">This is a button</button>

These are its code snippets:

                                    HTML
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#html-btn-primary-accent">Copy HTML</button>

<button class="btn bg--accent">This is a button</button>

                                    CSS
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#css-btn-primary-accent">Copy CSS</button>

.btn {
    background-color: #dd2808;
    border: 2px solid transparent;
    border-radius: 3px;
    color: #f8f8f8;
    cursor: pointer;
    font: 700 1rem/1.2 'Raleway', Helvetica, sans-serif;
    padding: .5rem .75rem;
    text-decoration: none;
}

.btn:hover {
    background-color: #a71e06;
}

.bg--accent {
    background-color: #f96c53;
    color: #2f2f2f;
}

button.bg--accent:hover {
    background-color: #fba798;
}

Primary dark button

                        <button data-expands="btn-primary-dark-content" aria-label="open section" aria-describedby="btn-primary-dark" aria-expanded="false">
                            <svg focusable="false" height="20mm" width="20mm" viewBox="0 0 70 70">
                                <g transform="translate(0 -981.5)">
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="60" width="9.8985" y="987.36" x="30.051" class="up-strut"></rect>
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="10" width="60" y="1012.4" x="5"></rect>
                                </g>
                            </svg>
                        </button>

Light text (#f8f8f8) over a dark box area (#2f2f2f), this is an alternative style. It should appear over a light or accent coloured background or contrasting image.

Here are a few examples of proper usage:

<button class="btn bg--dark">This is a button</button>

<button class="btn bg--dark">This is a button</button>

                            <button class="btn bg--dark">This is a button</button>

These are its code snippets:

                                    HTML
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#html-btn-primary-dark">Copy HTML</button>

<button class="btn bg--dark">This is a button</button>

                                    CSS
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#css-btn-primary-dark">Copy CSS</button>

.btn {
    background-color: #dd2808;
    border: 2px solid transparent;
    border-radius: 3px;
    color: #f8f8f8;
    cursor: pointer;
    font: 700 1rem/1.2 'Raleway', Helvetica, sans-serif;
    padding: .5rem .75rem;
    text-decoration: none;
}

.btn:hover {
    background-color: #a71e06;
}

.bg--dark {
    background-color: #2f2f2f;
    color: #f8f8f8;
}

Primary light button

                        <button data-expands="btn-primary-light-content" aria-label="open section" aria-describedby="btn-primary-light" aria-expanded="false">
                            <svg focusable="false" height="20mm" width="20mm" viewBox="0 0 70 70">
                                <g transform="translate(0 -981.5)">
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="60" width="9.8985" y="987.36" x="30.051" class="up-strut"></rect>
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="10" width="60" y="1012.4" x="5"></rect>
                                </g>
                            </svg>
                        </button>

Dark text (#2f2f2f) over a light box area (#f8f8f8), this is an alternative style. It should only appear over a dark-coloured background or contrasting image.

Here are a few examples of proper usage:

<button class="btn bg--light">This is a button</button>

<button class="btn bg--light">This is a button</button>

                            <button class="btn bg--light">This is a button</button>

These are its code snippets:

                                    HTML
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#html-btn-primary-light">Copy HTML</button>

<button class="btn bg--light">This is a button</button>

                                    CSS
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#css-btn-primary-light">Copy CSS</button>

.btn {
    background-color: #dd2808;
    border: 2px solid transparent;
    border-radius: 3px;
    color: #f8f8f8;
    cursor: pointer;
    font: 700 1rem/1.2 'Raleway', Helvetica, sans-serif;
    padding: .5rem .75rem;
    text-decoration: none;
}

.btn:hover {
    background-color: #a71e06;
}

.bg--light {
    background-color: #f8f8f8;
    color: #2f2f2f;
}

button.bg--light:hover {
    background-color: #fcdad4;
}

Secondary button

                        <button data-expands="btn-secondary-content" aria-label="open section" aria-describedby="btn-secondary" aria-expanded="false">
                            <svg focusable="false" height="20mm" width="20mm" viewBox="0 0 70 70">
                                <g transform="translate(0 -981.5)">
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="60" width="9.8985" y="987.36" x="30.051" class="up-strut"></rect>
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="10" width="60" y="1012.4" x="5"></rect>
                                </g>
                            </svg>
                        </button>

A light box area (#f8f8f8) with dark-accent border and text (#dd2808), this is the main style for secondary buttons. It works better over a light-coloured background or contrasting image.

Here are a few examples of proper usage:

<button class="btn-sec">This is a button</button>

                            <button class="btn-sec">This is a button</button>

                            <button class="btn-sec">This is a button</button>

These are its code snippets:

                                    HTML
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#html-btn-secondary">Copy HTML</button>

<button class="btn-sec">This is a button</button>

                                    CSS
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#css-btn-secondary">Copy CSS</button>

.btn-sec {
    background-color: #f8f8f8;
    border: 2px solid #dd2808;
    border-radius: 3px;
    color: #dd2808;
    cursor: pointer;
    font: 700 1rem/1.2 'Raleway', Helvetica, sans-serif;
    padding: .5rem .75rem;
    text-decoration: none;
}

.btn-sec:hover {
    background-color: #ffffff;
}

Secondary accent button

                        <button data-expands="btn-secondary-accent-content" aria-label="open section" aria-describedby="btn-secondary-accent" aria-expanded="false">
                            <svg focusable="false" height="20mm" width="20mm" viewBox="0 0 70 70">
                                <g transform="translate(0 -981.5)">
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="60" width="9.8985" y="987.36" x="30.051" class="up-strut"></rect>
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="10" width="60" y="1012.4" x="5"></rect>
                                </g>
                            </svg>
                        </button>

A dark box area (#2f2f2f) with accent border and text (#f96c53), this is an alternative style. It can work over a dark or light coloured background.

Here are a few examples of proper usage:

<button class="btn-sec bd--accent">This is a button</button>

                            <button class="btn-sec bd--accent">This is a button</button>

                            <button class="btn-sec bd--accent">This is a button</button>

These are its code snippets:

                                    HTML
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#html-btn-secondary-accent">Copy HTML</button>

<button class="btn-sec bd--accent">This is a button</button>

                                    CSS
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#css-btn-secondary-accent">Copy CSS</button>

.btn-sec {
    background-color: #f8f8f8;
    border: 2px solid #dd2808;
    border-radius: 3px;
    color: #dd2808;
    cursor: pointer;
    font: 700 1rem/1.2 'Raleway', Helvetica, sans-serif;
    padding: .5rem .75rem;
    text-decoration: none;
}

.btn-sec:hover {
    background-color: #ffffff;
}

.bd--accent {
    background-color: #2f2f2f;
    border: 2px solid #f96c53;
    color: #f96c53;
}

button.bd--accent:hover {
    background-color: #1f1f1f;
}

Secondary dark button

                        <button data-expands="btn-secondary-dark-content" aria-label="open section" aria-describedby="btn-secondary-dark" aria-expanded="false">
                            <svg focusable="false" height="20mm" width="20mm" viewBox="0 0 70 70">
                                <g transform="translate(0 -981.5)">
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="60" width="9.8985" y="987.36" x="30.051" class="up-strut"></rect>
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="10" width="60" y="1012.4" x="5"></rect>
                                </g>
                            </svg>
                        </button>

A light box area (#f8f8f8) with dark border and text (#2f2f2f), this is an alternative style. It can work over a dark or light background or contrasting image.

Here are a few examples of proper usage:

<button class="btn-sec bd--dark">This is a button</button>

<button class="btn-sec bd--dark">This is a button</button>

                            <button class="btn-sec bd--dark">This is a button</button>

These are its code snippets:

                                    HTML
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#html-btn-secondary-dark">Copy HTML</button>

<button class="btn-sec bd--dark">This is a button</button>

                                    CSS
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#css-btn-secondary-dark">Copy CSS</button>

.btn-sec {
    background-color: #f0f0f0;
    border: 2px solid #dd2808;
    border-radius: 3px;
    color: #dd2808;
    cursor: pointer;
    font: 700 1rem/1.2 'Raleway', Helvetica, sans-serif;
    padding: .5rem .75rem;
    text-decoration: none;
}

.btn-sec:hover {
    background-color: #ffffff;
}

.bd--dark {
    border: 2px solid #2f2f2f;
    color: #2f2f2f;
}

Secondary light button

                        <button data-expands="btn-secondary-light-content" aria-label="open section" aria-describedby="btn-secondary-light" aria-expanded="false">
                            <svg focusable="false" height="20mm" width="20mm" viewBox="0 0 70 70">
                                <g transform="translate(0 -981.5)">
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="60" width="9.8985" y="987.36" x="30.051" class="up-strut"></rect>
                                    <rect style="stroke-width:0;fill:#2f2f2f" ry="4" height="10" width="60" y="1012.4" x="5"></rect>
                                </g>
                            </svg>
                        </button>

A dark box area (#2f2f2f) with light border and text (#f8f8f8), this is an alternative style. It can work over a dark background or contrasting image.

Here are a few examples of proper usage:

<button class="btn-sec bd--light">This is a button</button>

<button class="btn-sec bd--light">This is a button</button>

                            <button class="btn-sec bd--light">This is a button</button>

These are its code snippets:

                                    HTML
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#html-btn-secondary-light">Copy HTML</button>

<button class="btn-sec bd--light">This is a button</button>

                                    CSS
                                    <button class="btn-sec" aria-label="copy to clipboard"  data-clipboard-target="#css-btn-secondary-light">Copy CSS</button>

.btn-sec {
    background-color: #f8f8f8;
    border: 2px solid #dd2808;
    border-radius: 3px;
    color: #dd2808;
    cursor: pointer;
    font: 700 1rem/1.2 'Raleway', Helvetica, sans-serif;
    padding: .5rem .75rem;
    text-decoration: none;
}

.btn-sec:hover {
    background-color: #ffffff;
}

.bd--light {
    background-color: #2f2f2f;
    border: 2px solid #f8f8f8;
    color: #f8f8f8;
}

button.bd--light:hover {
    background-color: #1f1f1f;
}

Sources of inspiration

A Complete Guide to Links and Buttons—CSS-Tricks

Atomic Design—Brad Frost

Buttons—Material Design

Buttons—PatternFly Design System

Buttons—Polaris Design System

Buttons in Design Systems—Nathan Curtis

                See cards as a component

© 2019-2020 Pati Montero   ❧   Privacy policy

Github and Netlify host this website ♥


text:
title: Scala 2.7.6.final
start: 10 September 2009
layout: downloadpage
release_version: 2.7.6.final
release_date: "September 10, 2009"
show_resources: "true"
permalink: /download/2.7.6.final.html
requirements: "This Scala software distribution can be installed on any Unix-like or Windows system. It requires the Java runtime version 1.6 or later, which can be downloaded here."
resources: [
  ["-main-unixsys", "scala-2.7.6.final.tgz",                "/files/archive/scala-2.7.6.final.tgz",                   "Max OS X, Unix, Cygwin",  "16 MB"],
  ["-main-windows", "scala-2.7.6.final.zip",                "/files/archive/scala-2.7.6.final.zip",                   "Windows",                 "16 MB"]
]
---