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

    <item
        android:id="@+id/actionExplore"
        android:title="@string/explore"
        android:icon="@drawable/ic_explore_black"
        app:showAsAction="always"/>

    <item
        android:id="@+id/actionShare"
        android:title="@string/share"
        android:icon="@android:drawable/ic_menu_share"
        app:showAsAction="always"/>

</menu>


text:
package org.wso2.carbon.identity.authenticator.mepin;

public class MepinConstants {
    public static final String AUTHENTICATOR_NAME = "MePINAuthenticator";
    public static final String AUTHENTICATOR_FRIENDLY_NAME = "MePIN";

    public static final String MEPIN_GET_USER_INFO_URL = "https://api.mepin.com/simple_api/user_info";
    public static final String MEPIN_CREATE_TRANSACTION_URL = "https://api.mepin.com/transactions/create";
    public static final String MEPIN_GET_TRANSACTION_URL = "https://api.mepin.com/transactions/show";

    public static final String MEPIN_APPICATION_ID = "ApplicationId";
    public static final String MEPIN_USERNAME = "Username";
    public static final String MEPIN_PASSWORD = "Password";
    public static final String MEPIN_CALLBACK_URL = "callbackUrl";
    public static final String MEPIN_ACCESSTOKEN = "access_token";
    public static final String MEPIN_ID = "mepin_id";
    public static final String MEPIN_CLIENT_ID = "ClientId";
    public static final String MEPIN_SHORT_MESSAGE = "ShortMessage";
    public static final String MEPIN_MESSAGE = "Message";
    public static final String MEPIN_EXPIRY_TIME = "ExpiryTime";
    public static final String MEPIN_HEADER = "Header";
    public static final String MEPIN_CONFIRMATION_POLICY = "ConfirmationPolicy";
    public static final String MEPIN_QUERY = "identifier=%s&short_message=%s&header=%s&message=%s&client_id=%s&account=%s&expiry_time=%s&callback_url=%s&confirmation_policy=%s";
    public static final String MEPIN_ID_NOT_FOUND = "MePIN Id is not found. Authentication failed";
    public static final String MEPIN_TRANSACTION_ID = "transaction_id";
    public static final String MEPIN_TRANSACTION_STATUS = "transaction_status";
    public static final String MEPIN_ALLOW = "allow";
    public static final String MEPIN_COMPLETED = "completed";
    public static final String MEPIN_CANCELED = "canceled";
    public static final String MEPIN_EXPIRED = "expired";
    public static final String MEPIN_ERROR = "error";
    public static final String MEPIN_STATUS = "status";
    public static final String MEPIN_OK = "ok";
    public static final String MEPIN_LOGIN = "mepinLogin";
    public static final String LOGIN_PAGE = "authenticationendpoint/login.do";
    public static final String MEPIN_PAGE = "mepinauthenticationendpoint/mepin.jsp";

    public static final String HTTP_GET = "GET";
    public static final String HTTP_ACCEPT = "Accept";
    public static final String HTTP_AUTHORIZATION = "Authorization";
    public static final String HTTP_AUTHORIZATION_BASIC = "Basic ";
    public static final String HTTP_CONTENT_TYPE = "application/json";
    public static final String HTTP_POST_CONTENT_TYPE = "application/x-www-form-urlencoded;charset=UTF-8";
    public static final String CHARSET = "UTF-8";
    public static final String HTTP_ACCEPT_CHARSET = "Accept-Charset";
    public static final String USERNAME = "username";
    public static final String PASSWORD = "password";
    public static final String TRUE = "true";
    public static final String FAILED = "Failed";
    public static final String AUTH_HEADER = "authHeader";
    public static final String IS_SECOND_STEP = "isSecondStep";

}

redpajama_set_name: RedPajamaGithub


text:
package net.metanotion.rpc;

import java.io.IOException;
import java.io.Writer;

import net.metanotion.io.EOFException;
import net.metanotion.json.JsonObject;
import net.metanotion.util.ObjectOutputStream;
import net.metanotion.util.ObjectStreamClosedException;

public final class JSONWriterEncoder implements ObjectOutputStream<JsonObject> {
	private final Writer out;
	public JSONWriterEncoder(final Writer out) { this.out = out; }

	@Override public void write(final JsonObject o) throws ObjectStreamClosedException {
		try {
			out.write(o.toString());
		}
		catch (final java.io.EOFException eof) { throw new EOFException(eof); }
		catch (final java.nio.channels.ClosedChannelException closed) { throw new ObjectStreamClosedException(closed); }
		catch (final IOException ioe) { throw new RuntimeException(ioe); }
	}

	@Override public void close() {
		try {
			out.close();
		} catch (IOException ioe) { throw new RuntimeException(ioe); }
	}

	@Override public void flush() {
		try {
			this.out.flush();
		} catch (IOException ioe) { throw new RuntimeException(ioe); }
	}
}


text:
package com.byteperceptions.require.turn;

import com.byteperceptions.require.model.Player;

/**
 * @author Ryan Ylitalo
 *
 */
public class PlayerTurnThread implements Runnable
{

	private Player player;

	public PlayerTurnThread(Player player)
	{
		this.player = player;
	}

	@Override
	public void run()
	{
		try
		{
			Thread.sleep(700);
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		player.takeTurn();
	}

}


text:
namespace ppapi {
namespace proxy {

class PPAPI_PROXY_EXPORT CameraCapabilitiesResource
    : public Resource,
      public thunk::PPB_CameraCapabilities_API {
 public:
  CameraCapabilitiesResource(PP_Instance instance,
                             const std::vector<PP_VideoCaptureFormat>& formats);

  CameraCapabilitiesResource(const CameraCapabilitiesResource&) = delete;
  CameraCapabilitiesResource& operator=(const CameraCapabilitiesResource&) =
      delete;

  ~CameraCapabilitiesResource() override;

  // Resource overrides.
  thunk::PPB_CameraCapabilities_API* AsPPB_CameraCapabilities_API() override;

  // PPB_CameraCapabilities_API implementation.
  void GetSupportedVideoCaptureFormats(
      uint32_t* array_size,
      PP_VideoCaptureFormat** formats) override;

 private:
  size_t num_video_capture_formats_;
  std::unique_ptr<PP_VideoCaptureFormat[]> video_capture_formats_;
};

}  // namespace proxy
}  // namespace ppapi

#endif  // PPAPI_PROXY_CAMERA_CAPABILITIES_RESOURCE_H_


text:
"use strict";

const _ = require("lodash");
const addEmptyLineBefore = require("../../utils/addEmptyLineBefore");
const getPreviousNonSharedLineCommentNode = require("../../utils/getPreviousNonSharedLineCommentNode");
const hasEmptyLine = require("../../utils/hasEmptyLine");
const isAfterComment = require("../../utils/isAfterComment");
const isBlocklessAtRuleAfterBlocklessAtRule = require("../../utils/isBlocklessAtRuleAfterBlocklessAtRule");
const isBlocklessAtRuleAfterSameNameBlocklessAtRule = require("../../utils/isBlocklessAtRuleAfterSameNameBlocklessAtRule");
const isFirstNested = require("../../utils/isFirstNested");
const isFirstNodeOfRoot = require("../../utils/isFirstNodeOfRoot");
const optionsMatches = require("../../utils/optionsMatches");
const removeEmptyLinesBefore = require("../../utils/removeEmptyLinesBefore");
const report = require("../../utils/report");
const ruleMessages = require("../../utils/ruleMessages");
const validateOptions = require("../../utils/validateOptions");

const ruleName = "at-rule-empty-line-before";

const messages = ruleMessages(ruleName, {
  expected: "Expected empty line before at-rule",
  rejected: "Unexpected empty line before at-rule"
});

const rule = function(expectation, options, context) {
  return (root, result) => {
    const validOptions = validateOptions(
      result,
      ruleName,
      {
        actual: expectation,
        possible: ["always", "never"]
      },
      {
        actual: options,
        possible: {
          except: [
            "after-same-name",
            "inside-block",
            "blockless-after-same-name-blockless",
            "blockless-after-blockless",
            "first-nested"
          ],
          ignore: [
            "after-comment",
            "inside-block",
            "blockless-after-same-name-blockless",
            "blockless-after-blockless"
          ],
          ignoreAtRules: [_.isString]
        },
        optional: true
      }
    );
    if (!validOptions) {
      return;
    }

    root.walkAtRules(atRule => {
      const isNested = atRule.parent.type !== "root";
      // Ignore the first node
      if (isFirstNodeOfRoot(atRule)) {
        return;
      }

      // Return early if at-rule is to be ignored
      if (optionsMatches(options, "ignoreAtRules", atRule.name)) {
        return;
      }

      // Optionally ignore the expectation if the node is blockless
      if (
        optionsMatches(options, "ignore", "blockless-after-blockless") &&
        isBlocklessAtRuleAfterBlocklessAtRule(atRule)
      ) {
        return;
      }

      // Optionally ignore the expection if the node is blockless
      // and following another blockless at-rule with the same name
      if (
        optionsMatches(
          options,
          "ignore",
          "blockless-after-same-name-blockless"
        ) &&
        isBlocklessAtRuleAfterSameNameBlocklessAtRule(atRule)
      ) {
        return;
      }

      // Optionally ignore the expectation if the node is inside a block
      if (optionsMatches(options, "ignore", "inside-block") && isNested) {
        return;
      }

      // Optionally ignore the expectation if a comment precedes this node
      if (
        optionsMatches(options, "ignore", "after-comment") &&
        isAfterComment(atRule)
      ) {
        return;
      }

      const hasEmptyLineBefore = hasEmptyLine(atRule.raws.before);
      let expectEmptyLineBefore = expectation === "always" ? true : false;

      // Optionally reverse the expectation if any exceptions apply
      if (
        (optionsMatches(options, "except", "after-same-name") &&
          isAtRuleAfterSameNameAtRule(atRule)) ||
        (optionsMatches(options, "except", "inside-block") && isNested) ||
        (optionsMatches(options, "except", "first-nested") &&
          isFirstNested(atRule)) ||
        (optionsMatches(options, "except", "blockless-after-blockless") &&
          isBlocklessAtRuleAfterBlocklessAtRule(atRule)) ||
        (optionsMatches(
          options,
          "except",
          "blockless-after-same-name-blockless"
        ) &&
          isBlocklessAtRuleAfterSameNameBlocklessAtRule(atRule))
      ) {
        expectEmptyLineBefore = !expectEmptyLineBefore;
      }

      // Return if the expectation is met
      if (expectEmptyLineBefore === hasEmptyLineBefore) {
        return;
      }

      // Fix
      if (context.fix) {
        if (expectEmptyLineBefore) {
          addEmptyLineBefore(atRule, context.newline);
        } else {
          removeEmptyLinesBefore(atRule, context.newline);
        }

        return;
      }

      const message = expectEmptyLineBefore
        ? messages.expected
        : messages.rejected;

      report({ message, node: atRule, result, ruleName });
    });
  };
};

function isAtRuleAfterSameNameAtRule(atRule) {
  const previousNode = getPreviousNonSharedLineCommentNode(atRule);
  return (
    previousNode &&
    previousNode.type === "atrule" &&
    previousNode.name === atRule.name
  );
}

rule.ruleName = ruleName;
rule.messages = messages;
module.exports = rule;


text:
package barqsoft.footballscores.service;

import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

/**
 * Created by Krenare Rexhepi on 12/15/2015.
 */
public class ParseTeams {
    String data;
    public static ArrayList<FootballData> urls = null;
    private static final String FIX = "fixtures";
    private static String result = "result";
    private static String homeTeam = "";
    private static String awayTeam = "";
    private static String homeTeamgoals = "";
    private static String awayTeamgoals = "";
    private static String homeTeamName = "homeTeamName";
    private static String awayTeamName = "awayTeamName";
    private static String goalsAwayTeam = "goalsAwayTeam";
    private static String goalsHomeTeam = "goalsHomeTeam";
    private static String game_date = "date";
    private static String date = "";
    private static String imgHome = "";
    private static String imgAway="";

    public ParseTeams(String data) {
        this.data = data;
    }

    public ArrayList<FootballData> parseTeams() {
        ArrayList<FootballData> allUrl = new ArrayList<>();

        try {
            JSONObject jsonObject = new JSONObject(data);
            JSONArray originalTitleArray = jsonObject.getJSONArray(FIX);

            for (int i = 0; i < originalTitleArray.length(); i++) {
                JSONObject movieresults = originalTitleArray.getJSONObject(i);
                homeTeam = movieresults.getString(homeTeamName);
                awayTeam = movieresults.getString(awayTeamName);
                date = movieresults.getString(game_date);
                JSONObject results = movieresults.getJSONObject(result);
                homeTeamgoals = results.getString(goalsHomeTeam);
                awayTeamgoals = results.getString(goalsAwayTeam);
                JSONObject links = movieresults.getJSONObject("_links").getJSONObject("homeTeam");
                imgHome = links.getString("href");
                JSONObject links_away = movieresults.getJSONObject("_links").getJSONObject("awayTeam");
                imgAway = links_away.getString("href");
                FootballData footballData = new FootballData(
                        homeTeam,
                        awayTeam,
                        date,
                        homeTeamgoals,
                        awayTeamgoals,
                        imgHome,
                        imgAway);
                allUrl.add(footballData);

            }

        } catch (JSONException e) {
            Log.e("", e.getMessage().toString());
        }

        urls = allUrl;
        return allUrl;
    }

    public ArrayList<FootballData> parseData() {
        ArrayList<FootballData> allUrl = new ArrayList<>();

        try {
            JSONObject jsonObject = new JSONObject(data);
            String crestUrl = jsonObject.getString("crestUrl");
            String name = jsonObject.getString("name");

            FootballData footballData = new FootballData(name, crestUrl);
            allUrl.add(footballData);

        } catch (JSONException e) {
            Log.e("", e.getMessage().toString());
        }

        urls = allUrl;
        return allUrl;
    }
}


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Infestation.Suplements
{
    public abstract class Suplement : ISupplement
    {
        public Suplement()
        {

        }
        public virtual int AggressionEffect
        {
            get; protected set;
        }

        public virtual int HealthEffect
        {
            get; protected set;
        }

        public virtual int PowerEffect
        {
            get; protected set;

        }

        public virtual void ReactTo(ISupplement otherSupplement)
        {

            // TODO : •	Edit: The ReactTo method needs to be implemented specifically
            // for ONLY two of the above tasks – most supplements don't need to react (at least in this task)
            throw new NotImplementedException();
        }
    }
}


text:
import { BrowserWindow, nativeTheme } from 'electron';
import { isWindows, isMacintosh } from 'vs/base/common/platform';
import { IStateMainService } from 'vs/platform/state/electron-main/state';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { IPartsSplash } from 'vs/platform/windows/common/windows';

const DEFAULT_BG_LIGHT = '#FFFFFF';
const DEFAULT_BG_DARK = '#1E1E1E';
const DEFAULT_BG_HC_BLACK = '#000000';

const THEME_STORAGE_KEY = 'theme';
const THEME_BG_STORAGE_KEY = 'themeBackground';
const THEME_WINDOW_SPLASH = 'windowSplash';

export const IThemeMainService = createDecorator<IThemeMainService>('themeMainService');

export interface IThemeMainService {

	readonly _serviceBrand: undefined;

	getBackgroundColor(): string;

	saveWindowSplash(windowId: number | undefined, splash: IPartsSplash): void;
	getWindowSplash(): IPartsSplash | undefined;
}

export class ThemeMainService implements IThemeMainService {

	declare readonly _serviceBrand: undefined;

	constructor(@IStateMainService private stateMainService: IStateMainService) { }

	getBackgroundColor(): string {
		if ((isWindows || isMacintosh) && nativeTheme.shouldUseInvertedColorScheme) {
			return DEFAULT_BG_HC_BLACK;
		}

		let background = this.stateMainService.getItem<string | null>(THEME_BG_STORAGE_KEY, null);
		if (!background) {
			let baseTheme: string;
			if ((isWindows || isMacintosh) && nativeTheme.shouldUseInvertedColorScheme) {
				baseTheme = 'hc-black';
			} else {
				baseTheme = this.stateMainService.getItem<string>(THEME_STORAGE_KEY, 'vs-dark').split(' ')[0];
			}

			background = (baseTheme === 'hc-black') ? DEFAULT_BG_HC_BLACK : (baseTheme === 'vs' ? DEFAULT_BG_LIGHT : DEFAULT_BG_DARK);
		}

		if (isMacintosh && background.toUpperCase() === DEFAULT_BG_DARK) {
			background = '#171717'; // https://github.com/electron/electron/issues/5150
		}

		return background;
	}

	saveWindowSplash(windowId: number | undefined, splash: IPartsSplash): void {

		// Update in storage
		this.stateMainService.setItems([
			{ key: THEME_STORAGE_KEY, data: splash.baseTheme },
			{ key: THEME_BG_STORAGE_KEY, data: splash.colorInfo.background },
			{ key: THEME_WINDOW_SPLASH, data: splash }
		]);

		// Update in opened windows
		if (typeof windowId === 'number') {
			this.updateBackgroundColor(windowId, splash);
		}
	}

	private updateBackgroundColor(windowId: number, splash: IPartsSplash): void {
		for (const window of BrowserWindow.getAllWindows()) {
			if (window.id === windowId) {
				window.setBackgroundColor(splash.colorInfo.background);
				break;
			}
		}
	}

	getWindowSplash(): IPartsSplash | undefined {
		return this.stateMainService.getItem<IPartsSplash>(THEME_WINDOW_SPLASH);
	}
}


text:
package esidev

/*
last_week object */
type GetFwLeaderboardsCorporationsLastWeekLastWeek1 struct {
	/*
	 Amount of victory points */
	Amount int32 `json:"amount,omitempty"`
	/*
	 corporation_id integer */
	CorporationId int32 `json:"corporation_id,omitempty"`
}


text:
package com.github.sociallabel.service;

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

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Tuple;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.JoinType;
import javax.persistence.criteria.Root;
import javax.persistence.criteria.SetJoin;

import org.springframework.data.querydsl.QPageRequest;
import org.springframework.stereotype.Repository;

import com.github.sociallabel.entity.Tag;
import com.github.sociallabel.entity.Tag_;
import com.github.sociallabel.entity.UserTag;

@Repository("tupleRepository")
public class TupleRepository {

	@PersistenceContext(unitName="persistenceUnit")
	EntityManager em;

	public List<Tuple> findAllRecommendedUser(Set<String> idsNotIn, QPageRequest pageable) {
		// TODO Auto-generated method stub
		if(idsNotIn == null) idsNotIn = Collections.emptySet();
		CriteriaBuilder cb = em.getCriteriaBuilder();
		CriteriaQuery<Tuple> cq = cb.createTupleQuery();
		Root<Tag> tag = cq.from(Tag.class);
		SetJoin<Tag, UserTag> userTags = tag.join(Tag_.userTags, JoinType.LEFT);
		cq.select(cb.tuple(tag, cb.count(userTags)));

//		Predicate notin = cb.not(tag.get(Tag_.id).in(idsNotIn));
//
//		cq.where(notin);
		cq.groupBy(tag.get(Tag_.id));
		cq.orderBy(cb.desc(cb.count(userTags)));

		TypedQuery<Tuple> query = em.createQuery(cq);

		query.setFirstResult(pageable.getOffset());
		query.setMaxResults(pageable.getPageSize());

		return query.getResultList();
	}

}


text:
namespace core{
namespace random{

template<class Generator>
class RandomWrapper{
friend class RandomInterface;
private:
    Generator gen;

    RandomWrapper(unsigned long seedVal):
	gen(seedVal * 12345){}

    void reSeed(unsigned long seedVal){
	gen.seed(seedVal * 12345);
    }

    const unsigned long get(){
	return gen();
    }

    const bool getBool(){
	return gen() % 2 == 1;
    }

    const std::vector<unsigned long> getN(const size_t n){
	std::vector<unsigned long> values(n);
	for(int i = 0; i < n; i++){
	    values[i] = get();
	}

	return values;
    }

    const signed long getRange(const int min, const int max){
	std::uniform_int_distribution<int> distribution(min, max);
	return distribution(gen);
    }

    const std::vector<signed long> getRangeN(const size_t n, const int min, const int max){
	std::vector<signed long> values(n);

	for(int i = 0; i < n; i++){
	    values[n] = getRange(min, max);
	}
	return values;
    }

    const signed long getBellCurve(const int min_, const int max_){
	const int min = std::min(min_, max_);
	const int max = std::max(min_, max_);
	const int range = max - min;

	const int numberOfRandNumbersNeeded = range / sizeof(unsigned long);
	const int extras = range % sizeof(unsigned long);

	signed long acc = 0;
	for(int i = 0; i < numberOfRandNumbersNeeded; i++){
	    acc += std::bitset<sizeof(unsigned long)>(get()).count();
	}
	unsigned int lastRandValue = get();
	for(int i = 0; i < extras; i++){
	    acc += (lastRandValue & 1);
	    lastRandValue = lastRandValue >> 1;
	}

	return min + acc;
    }

    const std::vector<signed long> getNBellCurve(const size_t n,
						    const int min_,
						    const int max_){
	std::vector<signed long> values(n);
	for(int i = 0; i < n; i++){
	    values[i] = getBellCurve(min_, max_);
	}

	return values;
    }
};

} // namespace random
} // namespace core


text:
/*
  Free Code Camp Challenge  - Mutations
  https://www.freecodecamp.com/challenges/mutations
*/

function mutation(arr) {
  var firstElement = arr[0].toLowerCase();
  var secondElement = arr[1].toLowerCase();
  var contains = 0;

  for (var i = 0; i < secondElement.length; i++) {
    contains = firstElement.indexOf(secondElement[i]);

    if (contains !== - 1) {
      return true;
    }
  }

  return false;
}

mutation(["hello", "hey"]);


text:
require 'dnsruby/packet_sender'
require 'dnsruby/recursor'

module Dnsruby
  #  == Description
  #  Dnsruby::Resolver is a DNS stub resolver.
  #  This class performs queries with retries across multiple nameservers.
  #  The system configured resolvers are used by default.
  #
  #  The retry policy is a combination of the Net::DNS and dnsjava approach, and has the option of :
  #  * A total timeout for the query (defaults to 0, meaning "no total timeout")
  #  * A retransmission system that targets the namervers concurrently once the first query round is
  #   complete, but in which the total time per query round is split between the number of nameservers
  #   targetted for the first round. and total time for query round is doubled for each query round
  #
  #  Note that, if a total timeout is specified, then that will apply regardless of the retry policy
  #  (i.e. it may cut retries short).
  #
  #  Note also that these timeouts are distinct from the SingleResolver's packet_timeout
  #
  #  Timeouts apply to the initial query and response. If DNSSEC validation is to
  #  be performed, then additional queries may be required (these are performed automatically
  #  by Dnsruby). Each additional query will be performed with its own timeouts.
  #  So, even with a query_timeout of 5 seconds, a response which required extensive
  #  validation may take several times that long.
  #  (Future versions of Dnsruby may expose finer-grained events for client tracking of
  #  responses and validation)
  #
  #  == Methods
  #
  #  === Synchronous
  #  These methods raise an exception or return a response message with rcode==NOERROR
  #
  #  *  Dnsruby::Resolver#send_message(msg)
  #  *  Dnsruby::Resolver#query(name [, type [, klass]])
  #
  #    There are "!" versions of these two methods that return an array [response, error]
  #    instead of raising an error on failure.  They can be called as follows:
  #
  #    response, error = resolver.send_message!(...)
  #    response, error = resolver.query!(...)
  #
  #    If the request succeeds, response will contain the Dnsruby::Message response
  #    and error will be nil.
  #
  #    If the request fails, response will be nil and error will contain the error raised.
  #
  #  === Asynchronous
  #  These methods use a response queue to return the response and the error
  #
  #  *  Dnsruby::Resolver#send_async(msg, response_queue, query_id)
  #
  #  == Event Loop
  #  Dnsruby runs a pure Ruby event loop to handle I/O in a single thread.
  #  Support for EventMachine has been deprecated.
  class Resolver
    DefaultQueryTimeout = 0
    DefaultPacketTimeout = 5
    DefaultRetryTimes = 1
    DefaultRetryDelay = 5
    DefaultPipeLiningMaxQueries = 5
    DefaultPort = 53
    DefaultDnssec = false
    AbsoluteMinDnssecUdpSize = 1220
    MinDnssecUdpSize = 4096
    DefaultUDPSize = MinDnssecUdpSize

    class EventType
      RECEIVED = 0
      VALIDATED = 1 # @TODO@ Should be COMPLETE?
      ERROR = 2
    end

    #  The port to send queries to on the resolver
    attr_reader :port

    #  Should TCP be used as a transport rather than UDP?
    #  If use_tcp==true, then ONLY TCP will be used as a transport.
    attr_reader :use_tcp

    #  If tcp_pipelining==true, then we reuse the TCP connection
    attr_reader :tcp_pipelining

    # How many times (number of messages) to reuse the pipelining connection
    # before closing, :infinite for infinite number of requests per connection
    attr_reader :tcp_pipelining_max_queries

    #  If no_tcp==true, then ONLY UDP will be used as a transport.
    #  This should not generally be used, but is provided as a debugging aid.
    attr_reader :no_tcp

    attr_reader :tsig

    #  Should truncation be ignored?
    #  i.e. the TC bit is ignored and thus the resolver will not requery over TCP if TC is set
    attr_reader :ignore_truncation

    #  The source address to send queries from for IPv4
    attr_reader :src_address

    #  The source address to send queries from for IPv6
    attr_reader :src_address6

    #  Should the Recursion Desired bit be set?
    attr_reader :recurse

    #  The maximum UDP size to be used
    attr_reader :udp_size

    #  The current Config
    attr_reader :config

    #  Does this Resolver cache answers, and attempt to retrieve answer from the cache?
    attr_reader :do_caching

    #  The array of SingleResolvers used for sending query messages
    #     attr_accessor :single_resolvers # :nodoc:
    def single_resolvers=(s) # :nodoc:
      @configured = true
      #       @single_res_mutex.synchronize {
      @single_resolvers = s
      #       }
    end
    def single_resolvers # :nodoc:
      unless @configured
        add_config_nameservers
      end
      @single_resolvers
    end

    #  The timeout for any individual packet. This is the timeout used by SingleResolver
    attr_reader :packet_timeout

    #  Note that this timeout represents the total time a query may run for - multiple packets
    #  can be sent to multiple nameservers in this time.
    #  This is distinct from the SingleResolver per-packet timeout
    #  The query_timeout is not required - it will default to 0, which means "do not use query_timeout".
    #  If this is the case then the timeout will be dictated by the retry_times and retry_delay attributes
    attr_accessor :query_timeout

    #  The query will be tried across nameservers retry_times times, with a delay of retry_delay seconds
    #  between each retry. The first time round, retry_delay will be divided by the number of nameservers
    #  being targetted, and a new nameserver will be queried with the resultant delay.
    attr_accessor :retry_times, :retry_delay

    #  Use DNSSEC for this Resolver
    attr_reader :dnssec

    #  Defines whether validation is performed by default on this Resolver when the
    #  query method is called.
    #  Note that send_message and send_async expect a
    #  Message object to be passed in, which is already configured to the callers
    #  requirements.
    attr_accessor :do_validation

    #  Defines whether we will cache responses, or pass every request to the
    #  upstream resolver.  This is only really useful when querying authoritative
    #  servers (as the upstream recursive resolver is likely to cache)
    attr_accessor :do_caching

    #  --
    #  @TODO@ add load_balance? i.e. Target nameservers in a random, rather than pre-determined, order?
    #  This is best done when configuring the Resolver, as it will re-order servers based on their response times.
    #
    #  ++

    #  Query for a name. If a valid Message is received, then it is returned
    #  to the caller. Otherwise an exception (a Dnsruby::ResolvError or Dnsruby::ResolvTimeout) is raised.
    #
    #    require 'dnsruby'
    #    res = Dnsruby::Resolver.new
    #    response = res.query('example.com') # defaults to Types.A, Classes.IN
    #    response = res.query('example.com', Types.MX)
    #    response = res.query('208.77.188.166') # IPv4 address so PTR query will be made
    #    response = res.query('208.77.188.166', Types.PTR)
    def query(name, type=Types.A, klass=Classes.IN, set_cd=@dnssec)
      msg = Message.new
      msg.do_caching = @do_caching
      msg.header.rd = 1
      msg.add_question(name, type, klass)
      msg.do_validation = @do_validation
      if @dnssec
        msg.header.cd = set_cd # We do our own validation by default
      end
      send_message(msg)
    end

    #  Like query, but does not raise an error when an error occurs.
    #  Instead, it returns it.
    #  @return a 2 element array: [response, error]
    def query!(name, type=Types.A, klass=Classes.IN, set_cd=@dnssec)
      response = nil; error = nil
      begin
        response = query(name, type, klass, set_cd)
      rescue => e
        error = e
      end
      [response, error]
    end

    def query_no_validation_or_recursion(name, type=Types.A, klass=Classes.IN) # :nodoc: all
      msg = Message.new
      msg.do_caching = @do_caching
      msg.header.rd = false
      msg.do_validation = false
      msg.add_question(name, type, klass)
      if @dnssec
        msg.header.cd = true # We do our own validation by default
      end
      send_message(msg)
    end

    #  Send a message, and wait for the response. If a valid Message is received, then it is returned
    #  to the caller. Otherwise an exception (a Dnsruby::ResolvError or Dnsruby::ResolvTimeout) is raised.
    #
    #  send_async is called internally.
    #
    #  example :
    #
    #    require 'dnsruby'
    #    include Dnsruby
    #    res = Dnsruby::Resolver.new
    #    begin
    #    response = res.send_message(Message.new('example.com', Types.MX))
    #    rescue ResolvError
    #      # ...
    #    rescue ResolvTimeout
    #      # ...
    #    end
    def send_message(message)
      Dnsruby.log.debug{'Resolver : sending message'}
      q = Queue.new
      send_async(message, q)

      _id, result, error = q.pop

      if error
        error.response = result if error.is_a?(ResolvError)
        raise error
      else
        result
      end
    end

    #  Like send_message, but does not raise an error when an error occurs.
    #  Instead, it returns it.
    #  @return a 2 element array: [response, error]
    def send_message!(message)
      response = nil; error = nil
      begin
        response = send_message(message)
      rescue => e
        error = e
      end
      [response, error]
    end

    # Sends a message with send_plain_message.
    # Effectively a wrapper around send_plain_message, but adds
    # the ability to configure whether an error will be raised
    # or returned if it occurs.
    #
    # @param message the message to send to the DNS server
    # @param error_strategy :return to return [response, error] (default),
    #                       :raise to return response only, or raise an error if one occurs
    def query_raw(message, error_strategy = :return)

      unless [:return, :raise].include?(error_strategy)
        raise ArgumentError.new('error_strategy should be one of [:return, :raise].')
      end

      response, error = send_plain_message(message)

      if error_strategy == :return
        [response, error]
      else
        raise error if error
        response
      end
    end

    #  This method takes a Message (supplied by the client), and sends it to
    #  the configured nameservers. No changes are made to the Message before it
    #  is sent (TSIG signatures will be applied if configured on the Resolver).
    #  Retries are handled as the Resolver is configured to do.
    #  Incoming responses to the query are not cached or validated (although TCP
    #  fallback will be performed if the TC bit is set and the (Single)Resolver has
    #  ignore_truncation set to false).
    #  Note that the Message is left untouched - this means that no OPT records are
    #  added, even if the UDP transport for the server is specified at more than 512
    #  bytes. If it is desired to use EDNS for this packet, then you should call
    #  the Dnsruby::PacketSender#prepare_for_dnssec(msg), or
    #  Dnsruby::PacketSender#add_opt_rr(msg)
    #  The return value from this method is the [response, error] tuple. Either of
    #  these values may be nil - it is up to the client to check.
    #
    #  example :
    #
    #    require 'dnsruby'
    #    include Dnsruby
    #    res = Dnsruby::Resolver.new
    #    response, error = res.send_plain_message(Message.new('example.com', Types.MX))
    #    if error
    #      print "Error returned : #{error}\n"
    #    else
    #      process_response(response)
    #    end
    def send_plain_message(message)
      Dnsruby::TheLog.debug('Resolver : send_plain_message')
      message.do_caching = false
      message.do_validation = false
      message.send_raw = true
      q = Queue.new
      send_async(message, q)
      _id, result, error = q.pop
      error.response = result if !error.nil? && error.is_a?(ResolvError)
      [result, error]
    end

    #  Asynchronously send a Message to the server. The send can be done using just
    #  Dnsruby. Support for EventMachine has been deprecated.
    #
    #  == Dnsruby pure Ruby event loop :
    #
    #  A client_queue is supplied by the client,
    #  along with an optional client_query_id to identify the response. The client_query_id
    #  is generated, if not supplied, and returned to the client.
    #  When the response is known,
    #  a tuple of (query_id, response_message, exception) will be added to the client_queue.
    #
    #  The query is sent synchronously in the caller's thread. The select thread is then used to
    #  listen for and process the response (up to pushing it to the client_queue). The client thread
    #  is then used to retrieve the response and deal with it.
    #
    #  Takes :
    #
    #  * msg - the message to send
    #  * client_queue - a Queue to push the response to, when it arrives
    #  * client_query_id - an optional ID to identify the query to the client
    #  * use_tcp - whether to use only TCP (defaults to SingleResolver.use_tcp)
    #
    #  Returns :
    #
    #  * client_query_id - to identify the query response to the client. This ID is
    #  generated if it is not passed in by the client
    #
    #  === Example invocations :
    #
    #     id = res.send_async(msg, queue)
    #     NOT SUPPORTED : id = res.send_async(msg, queue, use_tcp)
    #     id = res.send_async(msg, queue, id)
    #     id = res.send_async(msg, queue, id, use_tcp)
    #
    #  === Example code :
    #
    #    require 'dnsruby'
    #    res = Dnsruby::Resolver.newsend
    #    query_id = 10 # can be any object you like
    #    query_queue = Queue.new
    #    res.send_async(Message.new('example.com', Types.MX),  query_queue, query_id)
    #    query_id_2 = res.send_async(Message.new('example.com', Types.A), query_queue)
    #    # ...do a load of other stuff here...
    #    2.times do
    #      response_id, response, exception = query_queue.pop
    #      # You can check the ID to see which query has been answered
    #      if exception == nil
    #          # deal with good response
    #      else
    #          # deal with problem
    #      end
    #    end
    #
    def send_async(msg, client_queue, client_query_id = nil)
      unless @configured
        add_config_nameservers
      end
      #       @single_res_mutex.synchronize {
      unless @resolver_ruby # @TODO@ Synchronize this?
        @resolver_ruby = ResolverRuby.new(self)
      end
      #       }
      client_query_id = @resolver_ruby.send_async(msg, client_queue, client_query_id)
      if @single_resolvers.length == 0
        Thread.start {
          sleep(@query_timeout == 0 ? 1 : @query_timeout)
          client_queue.push([client_query_id, nil, ResolvTimeout.new('Query timed out - no nameservers configured')])
        }
      end
      client_query_id
    end

    #  Close the Resolver. Unfinished queries are terminated with OtherResolvError.
    def close
      @resolver_ruby.close if @resolver_ruby
    end

    #  Create a new Resolver object. If no parameters are passed in, then the default
    #  system configuration will be used. Otherwise, a Hash may be passed in with the
    #  following optional elements :
    #
    #
    #  * :port
    #  * :use_tcp
    #  * :tsig
    #  * :ignore_truncation
    #  * :src_address
    #  * :src_address6
    #  * :src_port
    #  * :recurse
    #  * :udp_size
    #  * :config_info - see Config
    #  * :nameserver - can be either a String or an array of Strings
    #  * :packet_timeout
    #  * :query_timeout
    #  * :retry_times
    #  * :retry_delay
    #  * :do_caching
    #  * :tcp_pipelining
    #  * :tcp_pipelining_max_queries - can be a number or :infinite symbol
    def initialize(*args)
      #  @TODO@ Should we allow :namesver to be an RRSet of NS records? Would then need to randomly order them?
      @resolver_ruby = nil
      @src_address = nil
      @src_address6 = nil
      @single_res_mutex = Mutex.new
      @configured = false
      @do_caching = true
      @config = Config.new()
      reset_attributes

      #  Process args
      if args.length == 1
        if args[0].class == Hash
          args[0].keys.each do |key|
            begin
              if key == :config_info
                @config.set_config_info(args[0][:config_info])
              elsif key == :nameserver
                set_config_nameserver(args[0][:nameserver])
              elsif key == :nameservers
                set_config_nameserver(args[0][:nameservers])
              else
                send(key.to_s + '=', args[0][key])
              end
            rescue Exception => e
              Dnsruby.log.error{"Argument #{key} not valid : #{e}\n"}
            end
          end
        elsif args[0].class == String
          set_config_nameserver(args[0])
        elsif args[0].class == Config
          #  also accepts a Config object from Dnsruby::Resolv
          @config = args[0]
        end
      else
        #  Anything to do?
      end
      update
    end

    def add_config_nameservers # :nodoc: all
      unless @configured
        @config.get_ready
      end
      @configured = true
      @single_res_mutex.synchronize {
        #  Add the Config nameservers
        @config.nameserver.each do |ns|
          res = PacketSender.new({
              server:             ns,
              port:               @port,
              dnssec:             @dnssec,
              use_tcp:            @use_tcp,
              no_tcp:             @no_tcp,
              tcp_pipelining:     @tcp_pipelining,
              tcp_pipelining_max_queries: @tcp_pipelining_max_queries,
              packet_timeout:     @packet_timeout,
              tsig:               @tsig,
              ignore_truncation:  @ignore_truncation,
              src_address:        @src_address,
              src_address6:       @src_address6,
              src_port:           @src_port,
              recurse:            @recurse,
              udp_size:           @udp_size})
          @single_resolvers.push(res) if res
        end
      }
    end

    def set_config_nameserver(n)
      #  @TODO@ Should we allow NS RRSet here? If so, then .sort_by {rand}
      @config.get_ready unless @configured
      @configured = true

      @config.nameserver = n.kind_of?(String) ? [n] : n
      add_config_nameservers
    end

    def reset_attributes # :nodoc: all
      @resolver_ruby.reset_attributes if @resolver_ruby

      #  Attributes

      #  do_validation tells the Resolver whether to try to validate the response
      #  with DNSSEC. This should work for NSEC-signed domains, but NSEC3
      #  validation is not currently supported. This attribute now defaults to
      #  false. Please let me know if you require NSEC3 validation.
      @do_validation = false
      @query_timeout = DefaultQueryTimeout
      @retry_delay = DefaultRetryDelay
      @retry_times = DefaultRetryTimes
      @packet_timeout = DefaultPacketTimeout
      @port = DefaultPort
      @udp_size = DefaultUDPSize
      @dnssec = DefaultDnssec
      @do_caching= true
      @use_tcp = false
      @no_tcp = false
      @tcp_pipelining = false
      @tcp_pipelining_max_queries = DefaultPipeLiningMaxQueries
      @tsig = nil
      @ignore_truncation = false
      @config = Config.new()
      @src_address = nil
      @src_address6 = nil
      @src_port = [0]
      @recurse = true
      @single_res_mutex.synchronize {
        @single_resolvers=[]
      }
      @configured = false
    end

    def update # :nodoc: all
      #  Update any resolvers we have with the latest config
      @single_res_mutex.synchronize do
        @single_resolvers.delete(nil) # Just in case...
        @single_resolvers.each { |res| update_internal_res(res) }
      end
    end

    #     # Add a new SingleResolver to the list of resolvers this Resolver object will
    #     # query.
    #     def add_resolver(internal) # :nodoc:
    #       # @TODO@ Make a new PacketSender from this SingleResolver!!
    #       @single_resolvers.push(internal)
    #     end

    def add_server(server)# :nodoc:
      @configured = true
      res = PacketSender.new(server)
      log_and_raise("Can't create server #{server}", ArgumentError) unless res
      update_internal_res(res)
      @single_res_mutex.synchronize { @single_resolvers.push(res) }
    end

    def update_internal_res(res)
      [:port, :use_tcp, :no_tcp, :tcp_pipelining, :tcp_pipelining_max_queries, :tsig, :ignore_truncation, :packet_timeout,
        :src_address, :src_address6, :src_port, :recurse,
        :udp_size, :dnssec].each do |param|

        res.send(param.to_s + '=', instance_variable_get('@' + param.to_s))
      end
    end

    def nameservers=(ns)
      self.nameserver=(ns)
    end

    def nameserver=(n)
      @configured = true
      @single_res_mutex.synchronize { @single_resolvers=[] }
      set_config_nameserver(n)
      add_config_nameservers
    end

    #  --
    #  @TODO@ Should really auto-generate these methods.
    #  Also, any way to tie them up with SingleResolver RDoc?
    #  ++

    def packet_timeout=(t)
      @packet_timeout = t
      update
    end

    #  The source port to send queries from
    #  Returns either a single Integer or an Array
    #  e.g. '0', or '[60001, 60002, 60007]'
    #
    #  Defaults to 0 - random port
    def src_port
      @src_port.length == 1 ? @src_port[0] : @src_port
    end

    #  Can be a single Integer or a Range or an Array
    #  If an invalid port is selected (one reserved by
    #  IANA), then an ArgumentError will be raised.
    #
    #         res.src_port=0
    #         res.src_port=[60001,60005,60010]
    #         res.src_port=60015..60115
    #
    def src_port=(p)
      if Resolver.check_port(p)
        @src_port = Resolver.get_ports_from(p)
        update
      end
    end

    #  Can be a single Integer or a Range or an Array
    #  If an invalid port is selected (one reserved by
    #  IANA), then an ArgumentError will be raised.
    #  "0" means "any valid port" - this is only a viable
    #  option if it is the only port in the list.
    #  An ArgumentError will be raised if "0" is added to
    #  an existing set of source ports.
    #
    #         res.add_src_port(60000)
    #         res.add_src_port([60001,60005,60010])
    #         res.add_src_port(60015..60115)
    #
    def add_src_port(p)
      if Resolver.check_port(p, @src_port)
        a = Resolver.get_ports_from(p)
        a.each do |x|
          if (@src_port.length > 0) && (x == 0)
            log_and_raise("src_port of 0 only allowed as only src_port value (currently #{@src_port.length} values",
                ArgumentError)
          end
          @src_port.push(x)
        end
      end
      update
    end

    def Resolver.check_port(p, src_port=[])
      unless p.is_a?(Integer)
        tmp_src_ports = Array.new(src_port)
        p.each do |x|
          unless Resolver.check_port(x, tmp_src_ports)
            return false
          end
          tmp_src_ports.push(x)
        end
        return true
      end
      if Resolver.port_in_range(p)
        return ! ((p == 0) && (src_port.length > 0))
      else
        Dnsruby.log.error("Illegal port (#{p})")
        log_and_raise("Illegal port #{p}", ArgumentError)
      end
    end

    def Resolver.port_in_range(p)
      (p == 0) || ((p >= 50000) && (p <= 65535))
    end

    def Resolver.get_ports_from(p)
      a = []
      if p.is_a?(Integer)
        a = [p]
      else
        p.each do |x|
          a.push(x)
        end
      end
      a
    end

    def tcp_pipelining=(on)
      @tcp_pipelining = on
      update
    end

    def tcp_pipelining_max_queries=(max)
      @tcp_pipelining_max_queries = max
      update
    end

    def use_tcp=(on)
      @use_tcp = on
      update
    end

    def no_tcp=(on)
      @no_tcp=on
      update
    end

    #  Sets the TSIG to sign outgoing messages with.
    #  Pass in either a Dnsruby::RR::TSIG, or a key_name and key (or just a key)
    #  Pass in nil to stop tsig signing.
    #  * res.tsig=(tsig_rr)
    #  * res.tsig=(key_name, key) # defaults to hmac-md5
    #  * res.tsig=(key_name, key, alg) # e.g. alg = 'hmac-sha1'
    #  * res.tsig=nil # Stop the resolver from signing
    def tsig=(t)
      @tsig = t
      update
    end

    protected
    def Resolver.create_tsig_options(name, key, algorithm = nil)
        options = {
          type:  Types.TSIG,
          klass: Classes.ANY,
          name:  name,
          key:   key
      }
      options[:algorithm] = algorithm if algorithm
      options
    end

    public
    def Resolver.get_tsig(args)

      tsig = nil

      if args.length == 1
        if args[0]
          if args[0].instance_of?(RR::TSIG)
            tsig = args[0]
          elsif args[0].instance_of?(Array)
            tsig = RR.new_from_hash(create_tsig_options(*args[0]))
          end
        else
          #           Dnsruby.log.debug{'TSIG signing switched off'}
          return nil
        end
      else
        tsig = RR.new_from_hash(create_tsig_options(args))
      end
      Dnsruby.log.info{"TSIG signing now using #{tsig.name}, key=#{tsig.key}"}
      tsig
    end

    def ignore_truncation=(on)
      @ignore_truncation = on
      update
    end

    def src_address=(a)
      @src_address = a
      update
    end

    def src_address6=(a)
      @src_address6 = a
      update
    end

    def port=(a)
      @port = a
      update
    end

    def persistent_tcp=(on)
      @persistent_tcp = on
      update
    end

    def persistent_udp=(on)
      @persistent_udp = on
      update
    end

    def do_caching=(on)
      @do_caching=on
      update
    end

    def recurse=(a)
      @recurse = a
      update
    end

    def dnssec=(d)
      @dnssec = d
      if d
        #  Set the UDP size (RFC 4035 section 4.1)
        if @udp_size < MinDnssecUdpSize
          self.udp_size = MinDnssecUdpSize
        end
      end
      update
    end

    def udp_size=(s)
      @udp_size = s
      update
    end

    def single_res_mutex # :nodoc: all
      @single_res_mutex
    end

    def generate_timeouts(base=0) # :nodoc: all
      #  These should be be pegged to the single_resolver they are targetting :
      #   e.g. timeouts[timeout1]=nameserver
      timeouts = {}
      retry_delay = @retry_delay
      #       @single_res_mutex.synchronize {
      @retry_times.times do |retry_count|
        if retry_count > 0
          retry_delay *= 2
        end

        @single_resolvers.delete(nil) # Just in case...
        @single_resolvers.each_index do |i|
          res = @single_resolvers[i]
          offset = (i * @retry_delay.to_f / @single_resolvers.length)
          if retry_count == 0
            timeouts[base + offset]=[res, retry_count]
          else
            if timeouts.has_key?(base + retry_delay + offset)
              log_and_raise('Duplicate timeout key!')
            end
            timeouts[base + retry_delay + offset]=[res, retry_count]
          end
        end
      end
      #       }
      timeouts
    end
  end

  #  This class implements the I/O using pure Ruby, with no dependencies.
  #  Support for EventMachine has been deprecated.
  class ResolverRuby # :nodoc: all
    def initialize(parent)
      reset_attributes
      @parent=parent
    end
    def reset_attributes # :nodoc: all
      #  data structures
      #       @mutex=Mutex.new
      @query_list = {}
      @timeouts = {}
    end
    def send_async(msg, client_queue, client_query_id=nil)
      #  This is the whole point of the Resolver class.
      #  We want to use multiple SingleResolvers to run a query.
      #  So we kick off a system with select_thread where we send
      #  a query with a queue, but log ourselves as observers for that
      #  queue. When a new response is pushed on to the queue, then the
      #  select thread will call this class' handler method IN THAT THREAD.
      #  When the final response is known, this class then sticks it in
      #  to the client queue.

      q = Queue.new
      if client_query_id.nil?
        client_query_id = Time.now + rand(10000)
      end

      unless client_queue.kind_of?(Queue)
        log_and_raise('Wrong type for client_queue in Resolver# send_async')
        #  @TODO@ Handle different queue tuples - push this to generic send_error method
        client_queue.push([client_query_id, ArgumentError.new('Wrong type of client_queue passed to Dnsruby::Resolver# send_async - should have been Queue, was #{client_queue.class}')])
        return
      end

      unless msg.kind_of?Message
        Dnsruby.log.error{'Wrong type for msg in Resolver# send_async'}
        #  @TODO@ Handle different queue tuples - push this to generic send_error method
        client_queue.push([client_query_id, ArgumentError.new("Wrong type of msg passed to Dnsruby::Resolver# send_async - should have been Message, was #{msg.class}")])
        return
      end

      begin
        msg.encode
      rescue EncodeError => err
        Dnsruby.log.error { "Can't encode " + msg.to_s + " : #{err}" }
        client_queue.push([client_query_id, err])
        return
      end

      tick_needed = false
      #  add to our data structures
      #       @mutex.synchronize{
      @parent.single_res_mutex.synchronize {
        tick_needed = true if @query_list.empty?
        if @query_list.has_key?(client_query_id)
          Dnsruby.log.error("Duplicate query id requested (#{client_query_id}")
          #  @TODO@ Handle different queue tuples - push this to generic send_error method
          client_queue.push([client_query_id, ArgumentError.new('Client query ID already in use')])
          return
        end
        outstanding = []
        @query_list[client_query_id]=[msg, client_queue, q, outstanding]

        query_timeout = Time.now + @parent.query_timeout
        if @parent.query_timeout == 0
          query_timeout = Time.now + 31536000 # a year from now
        end
        @timeouts[client_query_id] = [query_timeout, generate_timeouts]
      }

      #  Now do querying stuff using SingleResolver
      #  All this will be handled by the tick method (if we have 0 as the first timeout)
      st = SelectThread.instance
      st.add_observer(q, self)
      tick if tick_needed
      client_query_id
    end

    def generate_timeouts # :nodoc: all
      #  Create the timeouts for the query from the retry_times and retry_delay attributes.
      #  These are created at the same time in case the parameters change during the life of the query.
      #
      #  These should be absolute, rather than relative
      #  The first value should be Time.now[
      @parent.generate_timeouts(Time.now)
    end

    #  Close the Resolver. Unfinished queries are terminated with OtherResolvError.
    def close
      #       @mutex.synchronize {
      @parent.single_res_mutex.synchronize {
        @query_list.each do |client_query_id, values|
         _msg, client_queue, q, _outstanding = values
          send_result_and_stop_querying(client_queue, client_query_id, q, nil,
              OtherResolvError.new('Resolver closing!'))
        end
      }
    end

    #  MUST BE CALLED IN A SYNCHRONIZED BLOCK!
    #
    #  Send the result back to the client, and close the socket for that query by removing
    #  the query from the select thread.
    def send_result_and_stop_querying(client_queue, client_query_id, select_queue, msg, error) # :nodoc: all
      stop_querying(client_query_id)
      send_result(client_queue, client_query_id, select_queue, msg, error)
    end

    #  MUST BE CALLED IN A SYNCHRONIZED BLOCK!
    #
    #  Stops send any more packets for a client-level query
    def stop_querying(client_query_id) # :nodoc: all
      @timeouts.delete(client_query_id)
    end

    #  MUST BE CALLED IN A SYNCHRONIZED BLOCK!
    #
    #  Sends the result to the client's queue, and removes the queue observer from the select thread
    def send_result(client_queue, client_query_id, select_queue, msg, error) # :nodoc: all
      stop_querying(client_query_id)  # @TODO@ !
      #  We might still get some callbacks, which we should ignore
      st = SelectThread.instance
      st.remove_observer(select_queue, self)
      #       @mutex.synchronize{
      #  Remove the query from all of the data structures
      @query_list.delete(client_query_id)
      #       }
      #  Return the response to the client
      client_queue.push([client_query_id, msg, error])
    end

    #  This method is called twice a second from the select loop, in the select thread.
    #  It should arguably be called from another worker thread... (which also handles the queue)
    #  Each tick, we check if any timeouts have occurred. If so, we take the appropriate action :
    #  Return a timeout to the client, or send a new query
    def tick # :nodoc: all
      #  Handle the tick
      #  Do we have any retries due to be sent yet?
      #       @mutex.synchronize{
      @parent.single_res_mutex.synchronize {
        time_now = Time.now
        @timeouts.keys.each do |client_query_id|
          msg, client_queue, select_queue, outstanding = @query_list[client_query_id]
          query_timeout, timeouts = @timeouts[client_query_id]
          if query_timeout < Time.now
            #  Time the query out
            send_result_and_stop_querying(client_queue, client_query_id, select_queue, nil,
                ResolvTimeout.new('Query timed out'))
            next
          end
          timeouts_done = []
          timeouts.keys.sort.each do |timeout|
            if timeout < time_now
              #  Send the next query
              res, retry_count = timeouts[timeout]
              id = [res, msg, client_query_id, retry_count]
              Dnsruby.log.debug("Sending msg to #{res.server}")
              #  We should keep a list of the queries which are outstanding
              outstanding.push(id)
              timeouts_done.push(timeout)
              timeouts.delete(timeout)

              #  Pick a new QID here @TODO@ !!!
              #               msg.header.id = rand(65535);
              #               print "New query : #{new_msg}\n"
              res.send_async(msg, select_queue, id)
            else
              break
            end
          end
          timeouts_done.each { |t| timeouts.delete(t) }
        end
      }
    end

    #  This method is called by the SelectThread (in the select thread) when the queue has a new item on it.
    #  The queue interface is used to separate producer/consumer threads, but we're using it here in one thread.
    #  It's probably a good idea to create a new "worker thread" to take items from the select thread queue and
    #  call this method in the worker thread.
    #
    def handle_queue_event(queue, id) # :nodoc: all
      #  Time to process a new queue event.
      #  If we get a callback for an ID we don't know about, don't worry -
      #  just ignore it. It may be for a query we've already completed.
      #
      #  So, get the next response from the queue (presuming there is one!)
      #
      #  @TODO@ Tick could poll the queue and then call this method if needed - no need for observer interface.
      #  @TODO@ Currently, tick and handle_queue_event called from select_thread - could have thread chuck events in to tick_queue. But then, clients would have to call in on other thread!
      #
      #  So - two types of response :
      #  1) we've got a coherent response (or error) - stop sending more packets for that query!
      #  2) we've validated the response - it's ready to be sent to the client
      #
      #  so need two more methods :
      #   handleValidationResponse : basically calls send_result_and_stop_querying and
      #   handleValidationError : does the same as handleValidationResponse, but for errors
      #  can leave handleError alone
      #  but need to change handleResponse to stop sending, rather than send_result_and_stop_querying.
      #
      #  @TODO@ Also, we could really do with a MaxValidationTimeout - if validation not OK within
      #  this time, then raise Timeout (and stop validation)?
      #
      #  @TODO@ Also, should there be some facility to stop validator following same chain
      #  concurrently?
      #
      #  @TODO@ Also, should have option to speak only to configured resolvers (not follow authoritative chain)
      #
      if queue.empty?
        log_and_raise('Severe internal error - Queue empty in handle_queue_event')
      end
      event_id, event_type, response, error = queue.pop
      #  We should remove this packet from the list of outstanding packets for this query
      _resolver, _msg, client_query_id, _retry_count = id
      if id != event_id
        log_and_raise("Serious internal error!! #{id} expected, #{event_id} received")
      end
      #       @mutex.synchronize{
      @parent.single_res_mutex.synchronize {
        if @query_list[client_query_id] == nil
          #           print "Dead query response - ignoring\n"
          Dnsruby.log.debug{'Ignoring response for dead query'}
          return
        end
        _msg, _client_queue, _select_queue, outstanding = @query_list[client_query_id]
        if event_type == Resolver::EventType::RECEIVED ||
              event_type == Resolver::EventType::ERROR
          unless outstanding.include?(id)
            log_and_raise("Query id not on outstanding list! #{outstanding.length} items. #{id} not on #{outstanding}")
          end
          outstanding.delete(id)
        end
        #       }
        if event_type == Resolver::EventType::RECEIVED
          #       if (event.kind_of?(Exception))
          if error
            handle_error_response(queue, event_id, error, response)
          else # if event.kind_of?(Message)
            handle_response(queue, event_id, response)
            #       else
            #         Dnsruby.log.error('Random object #{event.class} returned through queue to Resolver')
          end
        elsif event_type == Resolver::EventType::VALIDATED
          if error
            handle_validation_error(queue, event_id, error, response)
          else
            handle_validation_response(queue, event_id, response)
          end
        elsif event_type == Resolver::EventType::ERROR
          handle_error_response(queue, event_id, error, response)
        else
          #           print "ERROR - UNKNOWN EVENT TYPE IN RESOLVER : #{event_type}\n"
          TheLog.error("ERROR - UNKNOWN EVENT TYPE IN RESOLVER : #{event_type}")
        end
      }
    end

    def handle_error_response(select_queue, query_id, error, response) # :nodoc: all
      #  Handle an error
      #       @mutex.synchronize{
      Dnsruby.log.debug{"handling error #{error.class}, #{error}"}
      #  Check what sort of error it was :
      resolver, _msg, client_query_id, _retry_count = query_id
      _msg, client_queue, select_queue, outstanding = @query_list[client_query_id]
      if error.kind_of?(ResolvTimeout)
        #    - if it was a timeout, then check which number it was, and how many retries are expected on that server
        #        - if it was the last retry, on the last server, then return a timeout to the client (and clean up)
        #        - otherwise, continue
        #  Do we have any more packets to send to this resolver?

        decrement_resolver_priority(resolver)
        timeouts = @timeouts[client_query_id]
        if outstanding.empty? && timeouts && timeouts[1].values.empty?
          Dnsruby.log.debug{'Sending timeout to client'}
          send_result_and_stop_querying(client_queue, client_query_id, select_queue, response, error)
        end
      elsif error.kind_of?(NXDomain)
        #    - if it was an NXDomain, then return that to the client, and stop all new queries (and clean up)
        #         send_result_and_stop_querying(client_queue, client_query_id, select_queue, response, error)
        increment_resolver_priority(resolver) unless response.cached
        stop_querying(client_query_id)
        #  @TODO@ Does the client want notified at this point?
      elsif error.kind_of?(EncodeError)
        Dnsruby.log.debug{'Encode error - sending to client'}
        send_result_and_stop_querying(client_queue, client_query_id, select_queue, response, error)
      else
        #    - if it was any other error, then remove that server from the list for that query
        #    If a Too Many Open Files error, then don't remove, but let retry work.
        timeouts = @timeouts[client_query_id]
        unless error.to_s =~ /Errno::EMFILE/
          Dnsruby.log.debug{"Removing #{resolver.server} from resolver list for this query"}
          if timeouts
            timeouts[1].each do |key, value|
              res = value[0]
              if res == resolver
                timeouts[1].delete(key)
              end
            end
          end
          #  Also stick it to the back of the list for future queries
          demote_resolver(resolver)
        else
          Dnsruby.log.debug("NOT Removing #{resolver.server} due to Errno::EMFILE")
        end
        #         - if it was the last server, then return an error to the client (and clean up)
        if outstanding.empty? && ((!timeouts) || (timeouts && timeouts[1].values.empty?))
          #           if outstanding.empty?
          Dnsruby.log.debug{'Sending error to client'}
          send_result_and_stop_querying(client_queue, client_query_id, select_queue, response, error)
        end
      end
      #  @TODO@ If we're still sending packets for this query, but none are outstanding, then
      #  jumpstart the next query?
      #       }
    end

    #  TO BE CALLED IN A SYNCHRONIZED BLOCK
    def increment_resolver_priority(res)
      TheLog.debug("Incrementing resolver priority for #{res.server}\n")
      #       @parent.single_res_mutex.synchronize {
      index = @parent.single_resolvers.index(res)
      if index > 0
        @parent.single_resolvers.delete(res)
        @parent.single_resolvers.insert(index-1,res)
      end
      #       }
    end

    #  TO BE CALLED IN A SYNCHRONIZED BLOCK
    def decrement_resolver_priority(res)
      TheLog.debug("Decrementing resolver priority for #{res.server}\n")
      #       @parent.single_res_mutex.synchronize {
      index = @parent.single_resolvers.index(res)
      if index < @parent.single_resolvers.length
        @parent.single_resolvers.delete(res)
        @parent.single_resolvers.insert(index+1,res)
      end
      #       }
    end

    #  TO BE CALLED IN A SYNCHRONIZED BLOCK
    def demote_resolver(res)
      TheLog.debug("Demoting resolver priority for #{res.server} to bottom\n")
      #       @parent.single_res_mutex.synchronize {
      @parent.single_resolvers.delete(res)
      @parent.single_resolvers.push(res)
      #       }
    end

    def handle_response(select_queue, query_id, response) # :nodoc: all
      #  Handle a good response
      #  Should also stick resolver more to the front of the list for future queries
      Dnsruby.log.debug('Handling good response')
      resolver, _msg, client_query_id, _retry_count = query_id
      increment_resolver_priority(resolver) unless response.cached
      #       @mutex.synchronize{
      _query, _client_queue, s_queue, _outstanding = @query_list[client_query_id]
      if s_queue != select_queue
        log_and_raise("Serious internal error : expected select queue #{s_queue}, got #{select_queue}")
      end
      stop_querying(client_query_id)
      #  @TODO@ Does the client want notified at this point?
      #         client_queue.push([client_query_id, Resolver::EventType::RECEIVED, msg, nil])
      #       }
    end

    def handle_validation_response(select_queue, query_id, response) # :nodoc: all
      _resolver, _msg, client_query_id, _retry_count = query_id
      #       @mutex.synchronize {
      _query, client_queue, s_queue, _outstanding = @query_list[client_query_id]
      if s_queue != select_queue
        log_and_raise("Serious internal error : expected select queue #{s_queue}, got #{select_queue}")
      end
      if response.rcode == RCode.NXDOMAIN
        send_result(client_queue, client_query_id, select_queue, response, NXDomain.new)
      else
        #  @TODO@ Was there an error validating? Should we raise an exception for certain security levels?
        #  This should be configurable by the client.
        send_result(client_queue, client_query_id, select_queue, response, nil)
        #       }
      end
    end

    def handle_validation_error(select_queue, query_id, error, response)
      _resolver, _msg, client_query_id, _retry_count = query_id
      _query, client_queue, s_queue, _outstanding = @query_list[client_query_id]
      if s_queue != select_queue
        log_and_raise("Serious internal error : expected select queue #{s_queue}, got #{select_queue}")
      end
      #       For some errors, we immediately send result. For others, should we retry?
      #       Either :
      #                 handle_error_response(queue, event_id, error, response)
      #                 Or:
      send_result(client_queue, client_query_id, select_queue, response, error)
      #
      #
    end
  end
end
require 'dnsruby/single_resolver'


text:
/**
 * CalculationsOnParticles.java
 *
 * Author  : Christopher K. Allen
 * Since   : Nov 14, 2013
 */
package xal.tools.beam.calc;

import xal.model.probe.traj.ParticleProbeState;
import xal.model.probe.traj.ProbeState;
import xal.model.probe.traj.Trajectory;
import xal.tools.beam.PhaseMatrix;
import xal.tools.beam.PhaseVector;
import xal.tools.beam.Twiss;
import xal.tools.beam.calc.ISimulationResults.ISimLocResults;
import xal.tools.math.r3.R3;
import xal.tools.math.r6.R6;

/**
 *

 * Provides processing functions appropriate for single particle simulation data.
 *

 *

 * Additional class methods provide access to computed quantities used by the
 * class for the above processing, such as the "periodic fixed orbit", "periodic
 * betatron phase advance", and "period matched Twiss parameter".  These parameters
 * make not make sense here, as we make the very broad assumption that the particle
 * is in a periodic system and the simulation data is taken about n periods,
 * but they are available.
 *

 *
 * @author Christopher K. Allen
 * @since  Nov 14, 2013
 * @version Sep 25, 2014
 */
public class CalculationsOnParticles extends CalculationEngine implements ISimLocResults<ParticleProbeState> {

    /*
     * Local Attributes
     */

    /** The trajectory around one turn of the ring */
    private final Trajectory<ParticleProbeState>        trjSimul;

    /** The final envelope probe state (at the end of the simulation ) */
    private final ParticleProbeState        staFinal;

    /** The response matrix for the linac (between initial state and final state) */
    private final PhaseMatrix               matResp;

    /** The betatron phase advances at the at the exit of the linac */
    private final R3                        vecPhsAdv;

    /** The fixed orbit position at the entrance of the Linac */
    private final PhaseVector               vecFxdPt;

    /** The matched beam Twiss parameters at the start of the ring */
    private final Twiss[]                   arrTwsMch;

    /**
     * Constructor for CalculationsOnParticles. Creates a new
     * CalculationsOnParticles object for process the simulation
     * data contained in the given particle trajectory object.
     *
     * @param   datSim     simulation data for a particle
     *
     * @author Christopher K. Allen
     * @since  Nov 14, 2013
     */

    public CalculationsOnParticles(Trajectory<ParticleProbeState> datSim) {
        ParticleProbeState  pstFinal = datSim.finalState();

        this.trjSimul  = datSim;
        this.staFinal  = pstFinal;
        this.matResp   = this.staFinal.getResponseMatrix();

        this.vecPhsAdv = super.calculatePhaseAdvPerCell(this.matResp);
        this.vecFxdPt  = super.calculateFixedPoint(this.matResp);
        this.arrTwsMch = super.calculateMatchedTwiss(this.matResp);
	}

    /*
     * Attributes and Properties
     */

	/**
     * Returns the simulation trajectory from which all the machine properties are
     * computed.
     *
     * @return      simulation trajectory from which this object was initialized
     *
     * @author Christopher K. Allen
     * @since  Nov 7, 2013
     */
    public Trajectory<ParticleProbeState>   getTrajectory() {
        return this.trjSimul;
    }

    /**
     * Returns the full response matrix Φ providing the sensitivity of the final particle
     * position z to the initial conditions z0.
     *
     * @return  the response matrix Φ = ∂z/∂z0
     *
     * @author Christopher K. Allen
     * @since  Nov 7, 2013
     */
    public PhaseMatrix  getFullResponseMatrix() {
        return this.matResp;
    }

    /**
     *

     * Returns the betatron phase advances from the simulation beginning to end
     * (which are computed at instantiation).  The results are value for trajectories
     * near the simulation trajectory associated with this computation engine.  The fact
     * being from the use of the response matrix in the calculations.
     *

     *

     * The returned value is the calculation
     * {@link #calculatePhaseAdvPerCell(PhaseMatrix)} of the super class,
     * and thus assumes simulation trajectory is that for at least one period of
     * a periodic structure.
     *

     *
NOTES:

     *

     * · The betatron phase advances are given in the range [0,2&pi];.
     *

     *

     *
     * @return  vector particle betatron phase advances (in radians)
     *
     * @author Christopher K. Allen
     * @since  Oct 30, 2013
     */
    public R3   periodBetatronPhaseAdvance() {
        return this.vecPhsAdv;
    }

    /**
     *

     * Returns the phase space location of the fixed point at the simulation start
     * (which is computed at instantiation) assuming the simulation is that for
     * at least one period of a periodic accelerating or transport section.   That is,
     * we assume the beamline is periodic and the returned value is an invariant particle
     * position under the action of the response matrix.
     *

     *

     * The returned value z is the result of the
     * calculation {@link #calculateFixedPoint(PhaseMatrix)} given the
     * full response matrix Φ at the simulation exit (see {@link #getFullResponseMatrix()}).
     * It is invariant under
     * the action of Φ, that is, Φz = z.
     *

     *
NOTES:

     *

     * · The entrance and exit of the beamline should have the same fixed point
     * value.
     *

     *
     * @return
     *
     * @author Christopher K. Allen
     * @since  Oct 30, 2013
     */
    public PhaseVector  periodFixedOrbitPt() {
        return this.vecFxdPt;
    }

    /**
     *

     * Returns the matched Courant-Snyder parameters at the entrance of the simulation
     * assuming the simulation is at least one period of a periodic structure. These
     * are the "envelopes" taken from the "closed envelope" solution under the assume
     * the linac is a periodic transport.
     *

     *

     * Note that emittance ε is the parameter used to describe the extend of
     * the actual beam (rather than the normalized size β), or "acceptance".  Thus it
     * cannot be computed here and NaN is returned instead.
     *

     *
NOTES:

     *

     * · The entrance of the simulation is assumed to be the location of the
     * first and last states of the solution trajectory.
     *

     *
     * @return  array of Twiss parameter sets (α, β, NaN)
     *
     * @author Christopher K. Allen
     * @since  Oct 30, 2013
     */
    public Twiss[]  periodMatchedTwiss() {
        return this.arrTwsMch;
    }

    /*
     * ISumLocationResults<ParticleProbeState> Interface
     */

    /**
     * Simply returns the location of the simulated particle at the location of
     * the give state.  No real computation necessary.
     *
     * @see xal.tools.beam.calc.ISimEnvResults#computeCoordinatePosition(xal.model.probe.traj.ProbeState)
     *
     * @author Christopher K. Allen
     * @since  Nov 14, 2013
     */
    @Override
    public PhaseVector computeCoordinatePosition(ParticleProbeState state) {
        PhaseVector     vecPos = state.getPhaseCoordinates();

        return vecPos;
    }

    /**
     *
IMPORTANT NOTE

     *

     * This method has been modified so it returns exactly the same value as
     * {@link #computeCoordinatePosition(ParticleProbeState)}.  This modification is
     * maintain compatibility with the previous use of computeFixedOrbit()
     * presented by the trajectory classes for particles, beam envelopes, etc.  They
     * responded differently depending upon whether the structure producing the simulation
     * data was from a ring or a linear transport/accelerator structure.
     *

     *

     * Thus, ignore all commenting below!
     *

     *
     *

     * Consider first the point in phase space that is invariant under repeated application
     * of the response matrix Φ for the entire beamline or ring.  This is under
     * the condition that we decompose Φ into its homogeneous and non-homogeneous
     * components.  A particle entering the linac at that location exits at the same location.
     *

     *

     * To compute this linac fixed point, recall that the homogeneous response
     * matrix Φ for the beamline (or full-turn matrix for a ring)
     * has final row that represents the translation Δ of the particle
     * under the action of Φ.  The 6×6 sub-matrix of Φ represents
     * the (linear) action of the bending magnetics and quadrupoles and corresponds to the
     * matrix T ∈ R6×6 (here T is linear).
     * Thus, we can write the linear operator Φ
     * as the augmented system
     *

     *

     *

     *     Φ = |T Δ |,   z ≡ |p| ,
     *         |0 1 |        |1|
     *

     * where p is the projection of z into the embedded phase space
     * R6 (without homogeneous coordinate).
     * coordinates).
     *

     *

     * Putting this together we get
     *

     *

     *     Φz = Tp + Δ = p ,
     *

     *

     * to which the solution is
     *

     *

     *     p = -(T - I)-1Δ
     *

     *

     * assuming it exists.  The question of solution existence falls upon the
     * resolvent R ≡ (T - I)-1 of T.
     * By inspection we can see that p is defined so long as the eigenvalues
     * of T are located away from 1.
     * In this case the returned value is the augmented vector
     * (p 1)T ∈ R6 × {1}.
     *

     *

     * When the set of eigenvectors does contain 1, we attempt to find the solution for the
     * transverse phase space.  That is, we take vector p ∈ R4
     * and T ∈ R4×4 where
     * T = proj4×4 Φ.  The solution value is then
     * z = (p 0 0 1)T.
     *

     *

     * Once we have the fixed point z0 for the linac we compute the trajectory
     * of the fixed point at the location of the given probe state.  To do so, we multiply
     * z0 by the response matrix Φn for the given
     * probe state.  That is, we propagate the fixed point of the linac from the linac entrance
     * to the location of the given phase state.
     *

     *
     * @return  The quantity Φn⋅z0, the linac
     *          fixed point z0 propagated to the state location sn
     *
     * @see xal.tools.beam.calc.ISimEnvResults#computeFixedOrbit(xal.model.probe.traj.ProbeState)
     *
     * @author Christopher K. Allen
     * @since  Nov 14, 2013
     */
    @Override
    public PhaseVector computeFixedOrbit(ParticleProbeState state) {
//        PhaseMatrix matRespLoc = state.getResponseMatrix();
//        PhaseVector vecFxdLoc  = matRespLoc.times( this.vecFxdPt );

        PhaseVector vecFxdOrb = this.computeCoordinatePosition(state);

        return vecFxdOrb;
    }

    /**
     * Computes the chromatic aberration for one pass of the particle around the ring
     * starting at the given state location,
     * or for a beamline the entrance of the line to this state position. The returned
     * vector is the displacement from the closed orbit caused
     * by a unit momentum offset (δp = 1).  See the documentation in
     * {@link ISimLocResults#computeChromAberration(ProbeState)} for a more detailed
     * exposition.
     *
     * @see xal.tools.beam.calc.ISimLocResults#computeChromAberration(xal.model.probe.traj.ProbeState)
     *
     * @author Christopher K. Allen
     * @since  Nov 14, 2013
     */
    @Override
    public PhaseVector computeChromAberration(ParticleProbeState state) {
        double      dblGamma = state.getGamma();
        PhaseMatrix matResp  = state.getResponseMatrix();
        R6          vecDel   = super.calculateAberration(matResp, dblGamma);

        return PhaseVector.embed(vecDel);
    }

    /*
     * Support Methods
     */

}


text:
+++
title = "June 2018 Meetup"
date = "2018-06-25"
year = "2018"
draft = false
tags = ["golang", "user group", "meetup", "Edmonton", "YEG"]
description = "Community"
+++

Meetup [#50](https://github.com/edmontongo/presentations/issues/83). Please **RSVP** at [Meetup](https://www.meetup.com/startupedmonton/events/ddzwmnyxjbhc/).

We get started at 6:30 pm.

{{< mh2 "Sponsors" >}}

Venue provided by [Startup Edmonton](https://www.startupedmonton.com/).

{{< mh2 "Discussion" >}}

The Impact of Community by Cassandra Salisbury ([video](https://www.youtube.com/watch?v=fdIHODCbeRY))

Let's talk about the Go Community. The [Community Outreach Working Group](https://blog.golang.org/community-outreach-working-group) ([discussion](https://github.com/golang/cwg/issues)), Startup Week Community Event (Oct 15-19), Go adoption in Edmonton, and our meetup. ([slides](https://talks.godoc.org/github.com/edmontongo/presentations/2018-06/community/community.slide#1))

{{< mh2 "Jobs" >}}

- [Software Engineer at CenturyLink](https://www.linkedin.com/jobs/cap/view/717839856/?pathWildcard=717839856&trk=mcm)

{{< mh2 "Events" >}}

- [Monthly Hack Day](https://www.meetup.com/startupedmonton/events/qvnfrlyxkbkb/) - Jul 7
- [GopherCon UK](https://www.gophercon.co.uk/schedule/) - Aug 1-3 ([scholarships](https://www.gophercon.co.uk/scholarships/))
- [GopherCon](https://www.gophercon.com/) - Aug 27-30 ([scholarships](https://womenwhogo.org/scholarships.html))
- Edmonton Go Meetup - [July](/meetup/2018-07/)


text:
@implementation UIApplication (SSToolkitAdditions)

- (BOOL)isPirated {
	// This isn't bulletproof, but should catch a lot of cases. Thanks @marcoarment:
	// http://twitter.com/marcoarment/status/27965461020
	return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"SignerIdentity"] != nil;
}

- (void)setNetworkActivity:(BOOL)inProgress {
	// Ensure we're on the main thread
	if ([NSThread isMainThread] == NO) {
		[self performSelectorOnMainThread:@selector(_setNetworkActivityWithNumber:) withObject:[NSNumber numberWithBool:inProgress] waitUntilDone:NO];
		return;
	}

	[[self class] cancelPreviousPerformRequestsWithTarget:self selector:@selector(_setNetworkActivityIndicatorHidden) object:nil];

	if (inProgress == YES) {
		if (self.networkActivityIndicatorVisible == NO) {
			self.networkActivityIndicatorVisible = inProgress;
		}
	} else {
		[self performSelector:@selector(_setNetworkActivityIndicatorHidden) withObject:nil afterDelay:0.3];
	}
}

@end

@interface UIApplication (MSPrivateAdditions)
- (void)_setNetworkActivityWithNumber:(NSNumber *)number;
- (void)_setNetworkActivityIndicatorHidden;
@end

@implementation UIApplication (MSPrivateAdditions)

- (void)_setNetworkActivityWithNumber:(NSNumber *)number {
	[self setNetworkActivity:[number boolValue]];
}

- (void)_setNetworkActivityIndicatorHidden {
	self.networkActivityIndicatorVisible = NO;
}

@end


text:
You have found the chef-server self-contained development environment.
It aims to get you up and hacking on chef-server components in a
safe, pain-free manner.

In short it will create a simple Vagrant VM, while still allowing you to do
your development from the comfort of your own host. Changes to make are
loaded immediately into the running service (for erlang projects with
sync support) or otherwise made available on the guest VM.

## Quick Start

This assumes familiarity with the components of chef-server and that you
want to run oc\_erchef off of your local machine.

Requirements:

* VirtualBox 4.3+
* Vagrant 1.7+
* At least one recent Chef Server 12.0.9+ debian package download,
  which you can get using this command (if you have the most recent chefdk) `mixlib-install download chef-server -p ubuntu -a x86_64 -l 14`. dvm will then look for the package in either the Downloads dir
  on your machine or the omnibus/pkg directory under the chef-server repo
  where dvm is running. You can also set the INSTALLER environment variable
  to tell dvm where to find the package if it is not in one of those locations.
* A text editor on your machine.
* Any time you're doing something with 'dvm' on the VM, make sure
  you've acquired root by using `sudo -i`. Otherwise dvm won't be in your
  path.

First, add the following configuration to your `/etc/hosts` file:

    192.168.33.100 api.chef-server.dev manage.chef-server.dev
    192.168.33.150 database.chef-server.dev
    192.168.33.151 backend.chef-server.dev
    192.168.33.153 ldap.chef-server.dev
    192.168.33.155 reportingdb.chef-server.dev

Next, bring up the VMs!

    cd dev
    vagrant up
    ./sync

In a separate terminal session/pane/window:

    vagrant ssh
    sudo -i
    dvm quickstart oc_erchef

To use your running Chef Server through standard commands such as knife,
you'll need to create an organisation and a user, and then create a
knife config on your workstation.

    vagrant ssh
    sudo -i
    # create a user to access chef with
    chef-server-ctl user-create -f /tmp/admin.pem admin Admin User admin@example.com password
    # create an organization
    chef-server-ctl org-create -f /tmp/test-validator.pem test Test
    # associate the user with the organization
    chef-server-ctl org-user-add test admin

Now on your workstation, create `.chef/knife.rb` in the root of your
chef-server checkout, with the following:

    current_dir = File.dirname(__FILE__)
	log_level                :info
	log_location             STDOUT
	node_name                "admin"
	client_key               "#{current_dir}/admin.pem"
	chef_server_url          "https://api.chef-server.dev/organizations/test"

Then place `/tmp/admin.pem` from the vagrant node into the `.chef` directory.

### What can I do?

Start editing erchef files, pedant files, cookbooks, upgrade definitions,
and/or chef-server-ctl commands.

* Changes to erchef erlang files will be picked up and recompiled
  automatically shortly after you save them on the host.
* To test cookbook changes, load them with `dvm load omnibus private-chef-cookbooks`.
  Then run `chef-server-ctl reconfigure` in the VM to pick up the changes.
* upgrades and chef-server-ctl command changes/additions will be
  available very quickly after you save them on the host (< 5 seconds)
* To run pedant tests in the VM, use `dvm run oc-chef-pedant`.  You can also provide the
  usual flags, eg `dvm run oc-chef-pedant --focus-/skip-X`, `--smoke`, `--all`, etc.

`dvm` has support for many projects including bifrost and bookshelf.  Use `dvm list`
to see them all.

While all host changes are replicated to the dev vm only erlang projects support
automatic hot compile and reload of changed modules on the host. To whatever
extent supported by the language, we'll be adding the same for ruby service-based projects.

### Dependency Loading

If you find that you need to change an erlang project
dependency, dvm simplifies that too. For example, let's say we want to
modify `chef_authn` and pull it into the running erchef instance:

    # From in the vm. assumes sudo -i
    dvm load oc_erchef chef_authn

This will  clone `chef_authn` onto your host[1], where you can begin
editing it. It will link it into the project deps directory and hot-load
it into the running VM[2].  This is available for nearly all dependencies
declared in a project's rebar.config.

[1] NOTE: Presently this will clone into chef-server directory. We will be
 fixing this, it's a side effect of the recent project merge.
[2] There is currently a limitation here in that the owning project must
be running to pick up the changes. We will be fixing that shortly.

For a list of dependencies available for loading and their current
status, use `dvm list $PROJECTNAME`.  Any dependency that is not a
system library and declared in a project's app.src is typically
available.

Ruby project dependency loading support coming soon.

### Installing Chef Server Plugins

If you wish to install Chef Server plugins with pre-downloaded or pre-built
binaries, set the corresponding attribute in your `config.yml` to true and
make sure that you have the package in your install path, or you have set the
plugin environment variable (see below).

  * Chef Management Console - `MANAGE_PKG`
  * Push Jobs Server - `PUSH_JOBS_PKG`
  * Chef Reporting - `REPORTING_PKG`

### Configuring LDAP

If you wish to setup your Chef Server to use an external LDAP service, please set
`ldap start` to true in your config.yml. This LDAP server comes pre-configured
with two users: `child` and `douglas`. You can add more by adding more LDIF files
in the ldap-data directory of the provisioning cookbook.

_Note: The password should be the same as the username (for simplicity)_

### Setting up Chef Backend

If you wish to setup a development environment that is a 1 frontend, 1 backend
HA topology, set `chef-backend start` to true in your config.yml. _Warning: Chef Backend
is not compatible with the Push Jobs Server, Chef Reporting or LDAP DVM configurations._

### Installer Options

If you have a package at a non-default location (defaults are `../omnibus/pkg` and this directory),
you can specify it with the $INSTALLER variable. Also, you can automate the selection of which build
to use with $AUTOPACKAGE. So, to automatically select a custom package, set $INSTALLER to it's path
and $AUTOPACKAGE to 1.

### Coverage Analysis

Erlang has built-in support for code coverage analaysis which will
evaluate how often each line of code in erlang modules is hit.  To enable this
for a full project, use:

    dvm cover PROJECT enable

To enable it for a specific module, use:

    dvm cover PROJECT enable MODULE_NAME

To reset coverage stats for one or all modules:

    dvm cover PROJECT reset [MODULE_NAME]

To write coverage results to file (chef-server/testdata/coverage) use:

    dvm cover PROJECT report [MODULE_NAME]

And finally to disable coverage and re-enable automatic code sync:

    dvm cover PROJECT disable

Note that enabling cover will disable automatic compile and load of changed
modules, and disabling it will turn that back on.

## Troubleshooting

If you see something like the following, or ever have trouble with Vagrant while running `./sync`:

```
Files Transferred: 0
         Next Sync: 0 seconds...Bad port '-o'force_available_locales will default to true in the future. If you really want to skip validation of your locale you can set I18n.enforce_available_locales =rsync: connection unexpectedly closed (0 bytes received so far) [sender]
rsync error: error in rsync protocol data stream (code 12) at /SourceCache/rsync/rsync-45/rsync/io.c(453) [sender=2.6.9]

It appears that you've ran a newer version of Vagrant on this
computer. Unfortunately, newer versions of Vagrant change internal
directory layouts that cause older versions to break. This version
of Vagrant cannot properly run.

If you'd like to start from a clean state, please remove the
Vagrant state directory: /Users/tyler/.vagrant.d

Warning that this will remove all your boxes and potentially corrupt
existing Vagrant environments that were running based on the future
version.
```

It might be because ruby is picking up the ChefDK version of Vagrant instead of the one you normally use. For example:

```
which vagrant
/usr/local/bin/vagrant
++> irb
`irb(main):001:0> `which vagrant`
=> "/opt/chefdk/embedded/bin/vagrant\n"
```

You can tell `./sync` what Vagrant to use by setting `$VAGRANT_PATH` like so:

```
export VAGRANT_PATH=/usr/local/bin/vagrant
```

## Chef Mover

`chef-mover` does not currently support hot code loading. You can use it, but you have
to interact with it a bit differently. To start it, run:

```
dvm load chef-mover
dvm start chef-mover
```

This will start it up, but if you make any changes, you will need to reload the application, like:

```
dvm load chef-mover --force
dvm start chef-mover
```

Then the new code will be loaded.

## Not So Quick Start

TODO: details of components, terminology, etc. explore more dvm
commands?

## Test Data

[pending] If you want to load in test users, orgs, and nodes for testing outside
of pedant, you can:

`dvm populate`

TODO: Provide a canned set of test data in ec-backup form for more thorough tests?
##  dvm

At the heart of all this is the 'dvm' tool.  This tool
is used to manage the environment from within
the vm.  It must always be run as root, and to be sure that the
environment is correct, use `sudo -i` to become root to run it.

The intention here was to create a simple way to do all the
common activities:

* load a project
* run a test suite or subset thereof
* run a project and/or start a loaded service
* open a console to a running erlang app
* etop a running erlang app
* access the DB for a project

And a few other things.  You can just use `dvm` by itself and a list of
commands will be generated. You may also want to take a look in
defaults.yml, in which project definitions and other things are set up.

# Using external databases

To use an external database for Chef Server (and Reporting), create a `config.yml` file with the following contents:

```
vm:
  postgresql:
    start: true
    use-external: true
```

To use separate external databases for Chef Server and Chef Reporting, create a `config.yml` file with the following contents:

```
vm:
  postgresql:
    start: true
    use-external: true
  reporting_postgresql:
    start: true
    use-external: true
```


text:
package org.keycloak.login;

import java.net.URI;
import java.util.List;
import java.util.Map;

import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;

import org.keycloak.models.ClientModel;
import org.keycloak.models.ClientSessionModel;
import org.keycloak.models.ProtocolMapperModel;
import org.keycloak.models.RealmModel;
import org.keycloak.models.RoleModel;
import org.keycloak.models.UserModel;
import org.keycloak.models.utils.FormMessage;
import org.keycloak.provider.Provider;

/**
 * @author Stian Thorgersen
 */
public interface LoginFormsProvider extends Provider {

    /**
     * Adds a script to the html header
     *
     * @param scriptUrl
     */
    void addScript(String scriptUrl);

    public Response createResponse(UserModel.RequiredAction action);

    Response createForm(String form);

    public Response createLogin();

    public Response createPasswordReset();

    public Response createLoginTotp();

    public Response createRegistration();

    public Response createInfoPage();

    public Response createErrorPage();

    public Response createOAuthGrant(ClientSessionModel clientSessionModel);

    public Response createCode();

    public LoginFormsProvider setClientSessionCode(String accessCode);

    public LoginFormsProvider setAccessRequest(List<RoleModel> realmRolesRequested, MultivaluedMap<String,RoleModel> resourceRolesRequested, List<ProtocolMapperModel> protocolMappers);
    public LoginFormsProvider setAccessRequest(String message);

    /**
     * Set one global error message.
     *
     * @param message key of message
     * @param parameters to be formatted into message
     */
    public LoginFormsProvider setError(String message, Object ... parameters);

    /**
     * Set multiple error messages.
     *
     * @param messages to be set
     */
    public LoginFormsProvider setErrors(List<FormMessage> messages);

    LoginFormsProvider addError(FormMessage errorMessage);

    /**
     * Add a success message to the form
     *
     * @param errorMessage
     * @return
     */
    LoginFormsProvider addSuccess(FormMessage errorMessage);

    public LoginFormsProvider setSuccess(String message, Object ... parameters);

    public LoginFormsProvider setUser(UserModel user);

    public LoginFormsProvider setResponseHeader(String headerName, String headerValue);

    public LoginFormsProvider setFormData(MultivaluedMap<String, String> formData);

    LoginFormsProvider setAttribute(String name, Object value);

    public LoginFormsProvider setStatus(Response.Status status);

    LoginFormsProvider setActionUri(URI requestUri);
}


text:
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Reflection;
using JetBrains.Annotations;
using Microsoft.EntityFrameworkCore.Storage;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Microsoft.EntityFrameworkCore.Utilities;
using MongoDB.Bson;

namespace Blueshift.EntityFrameworkCore.MongoDB.Storage
{
    /// <inheritdoc cref="TypeMappingSource" />
    /// <inheritdoc cref="IMongoDbTypeMappingSource" />
    /// <summary>
    /// Determines whether a .NET type can be mapped to a MongoDB database type.
    /// </summary>
    public class MongoDbTypeMappingSource : TypeMappingSource, IMongoDbTypeMappingSource
    {
        private readonly ConcurrentDictionary<Type, CoreTypeMapping> _typeCache = new ConcurrentDictionary<Type, CoreTypeMapping>
        {
            [typeof(string)] = new PassThruTypeMapping(typeof(string)),
            [typeof(IEnumerable<string>)] = new PassThruTypeMapping(typeof(IEnumerable<string>)),
            [typeof(ObjectId)] = new PassThruTypeMapping(typeof(ObjectId)),
            [typeof(IEnumerable<ObjectId>)] = new PassThruTypeMapping(typeof(IEnumerable<ObjectId>)),
            [typeof(byte[])] = new PassThruTypeMapping(typeof(byte[])),
            [typeof(IEnumerable<byte[]>)] = new PassThruTypeMapping(typeof(IEnumerable<byte[]>))
        };

        /// <inheritdoc />
        public MongoDbTypeMappingSource([NotNull] TypeMappingSourceDependencies dependencies)
            : base(dependencies)
        {
        }

        /// <inheritdoc />
        protected override CoreTypeMapping FindMapping(in TypeMappingInfo mappingInfo)
            => _typeCache.GetOrAdd(
                   mappingInfo.ClrType,
                   clrType =>
                   {
                       TypeInfo typeInfo = (clrType.TryGetSequenceType() ?? clrType).UnwrapNullableType().GetTypeInfo();

                       return typeInfo.IsPrimitive
                              || typeInfo.IsValueType
                           ? new PassThruTypeMapping(clrType)
                           : null;
                   });

        private class PassThruTypeMapping : CoreTypeMapping
        {
            private PassThruTypeMapping(CoreTypeMappingParameters parameters)
                : base(parameters)
            {
            }

            public PassThruTypeMapping([NotNull] Type clrType)
                : base(new CoreTypeMappingParameters(clrType))
            {
            }

            public override CoreTypeMapping Clone(ValueConverter converter)
                => new PassThruTypeMapping(Parameters.WithComposedConverter(converter));
        }
    }
}