text:
import os.path
from os import listdir
import re
from collections import OrderedDict, deque, Sequence
import logging
import warnings

try:
    from itertools import zip_longest
except ImportError:
    from itertools import izip_longest as zip_longest

default_tokenizer = re.compile(r'\S+\s*')

class ToolboxError(Exception): pass
class ToolboxInitError(ToolboxError): pass
class ToolboxAlignmentError(ToolboxError): pass
class ToolboxWarning(UserWarning): pass

def custom_formatwarning(msg, category, *args):
    return '{}: {}\n'.format(category.__name__, msg)

warnings.formatwarning = custom_formatwarning

def find_project_file(path):
    proj_path = None
    if os.path.isfile(path):
        if path.lower().endswith('.prj'):
            proj_path = path
    elif os.path.isdir(path):
        fns = [fn for fn in listdir(path) if fn.lower().endswith('.prj')]
        if len(fns) == 1:
            proj_path = fns[0]
    if proj_path is None:
        raise ToolboxInitError(
            'Toolbox project file not found at {}.'.format(path)
        )
    return proj_path

toolbox_line_re = re.compile(r'(?P<mkr>\\[^\s]+)( (?P<val>.*\n?))?$')

# inspired by the NLTK's implementation:
#   http://www.nltk.org/_modules/nltk/toolbox.html
def read_toolbox_file(f, strip=True):
    """
    Parse a Toolbox file and yield pairs of (marker, value). By default,
    no interpretation or normalization of the data is done besides
    stripping the trailing whitespace of each value (set the `strip`
    parameter to False to leave whitespace on).

    Args:
        f: An open file-like object.
        strip: If True, strip trailing whitespace from each value.
    Yields:
        Pairs of (marker, value)
    """
    def make_val(val_lines, strip):
        if val_lines == [None]:
            return None
        val = ''.join([s or '' for s in val_lines])  # first s might be None
        if strip:
            val = val.rstrip()
        return val
    mkr = None
    val_lines = []
    for line in f:
        mkr_match = toolbox_line_re.match(line)
        if mkr_match is not None:
            # first yield the current pair
            if mkr is not None:
                yield (mkr, make_val(val_lines, strip))
            mkr = mkr_match.group('mkr')
            val_lines = [mkr_match.group('val')]
        else:
            val_lines.append(line)
    # when we reach the end of the file, yield the final pair
    if mkr is not None:
        yield (mkr, make_val(val_lines, strip))

def iterparse(pairs, keys):
    """
    Yield pairs of (event, result) based on `keys` for the given
    `pairs`. Events and associated results are given below:

    =====  =============================================
    event                     result
    =====  =============================================
    key    the (key, value) pair for when \key was seen
    start  the (key, value) pair for when \+key was seen
    end    the (key, value) pair for when \-key was seen
    data   list of (marker, value) pairs between keys
    =====  =============================================

    Args:
        pairs: An iterable of (marker, value) pairs.
        keys: A container of markers that delimit blocks of associated
              data.
    Yields:
        Pairs of (event, result).
    """
    start_keys = set(re.sub(r'\\(.*)', r'\+\1', k) for k in keys)
    end_keys = set(re.sub(r'\\(.*)', r'\-\1', k) for k in keys)
    all_keys = set(keys).union(start_keys, end_keys)
    data = []
    for mkr, val in pairs:
        if mkr in all_keys:
            if len(data) > 0:
                yield ('data', data)
                data = []
            if mkr in keys:
                yield ('key', (mkr, val))
            elif mkr in start_keys:
                yield ('start', ('\\{}'.format(mkr[2:]), val))
            elif mkr in end_keys:
                yield ('end', ('\\{}'.format(mkr[2:]), val))
        else:
            data.append((mkr, val))
    # don't forget to yield the last one
    if len(data) > 0:
        yield ('data', data)

def records(pairs, record_marker, context_keys=None):
    """
    An alternative parsing function to iterparse(), which yields pairs
    of (context, data), where context is a dictionary mapping each key
    to the previously seen value, and data is the list of
    (marker, value) pairs delimited by the keys. The basic usage is:

        records(pairs, '\\ref')

    Where `'\\ref'` is the delimiter of records in `pairs`.

    Args:
        pairs: An iterable of (marker, value) pairs.
        record_marker: The marker(s) that delimits records. If the
            value is a string, it is considered the only record
            marker. Any other Sequence (list, tuple, etc.) become an
            ordered hierarchy of record delimiters. When a higher
            marker is encountered, it resets the value of the lower
            markers to None. For instance, if ['\\id', '\\ref'] is
            used, '\\ref' is reset to None whenever '\\id' is
            encountered.
        context_keys: A container of additional delimiters to include
            in the context, but unlike `record_marker`, these do not
            reset other markers. E.g. one might use \\page to group
            elements in a section that spans several pages.
    Yields:
        Pairs of (context, data)
    Raises:
        ToolboxError when block-start markers (\\+key) or block-end
        markers (\\-key) are seen, as they are considered invalid
        within records.
    """
    if isinstance(record_marker, str):
        record_marker = [record_marker]
    if not isinstance(record_marker, Sequence):
        raise ToolboxError('Record marker must be a string or a sequence.')
    keys = set(record_marker).union(context_keys or [])
    context = dict((key, None) for key in keys)
    for event, result in iterparse(pairs, keys):
        if event == 'key':
            mkr, val = result
            try:
                idx = record_marker.index(mkr)
                for m in record_marker[idx:]:
                    context[m] = None
            except ValueError:
                pass
            context[mkr] = val
        elif event == 'data':
            yield (context, result)
        else:
            raise ToolboxError('Illegal event in record: {}'
                               .format(event, result))

def field_groups(pairs, aligned_fields):
    """
    Yield lists of (marker, value) pairs where all pairs in the list
    are aligned. Unaligned fields will be returned as the only pair in
    the list, and repeating groups (e.g. where they are wrapped) will
    be returned separately.
    """
    group = []
    seen = set()
    for mkr, val in pairs:
        # unaligned or repeated fields start over grouping
        if mkr not in aligned_fields or mkr in seen:
            if group:
                yield group
            group = []
            seen = set()
            if mkr not in aligned_fields:
                yield [(mkr, val)]
                continue
        group.append((mkr, val))
        seen.add(mkr)
    # yield the last group if non-empty
    if group:
        yield group

def normalize_record(pairs, aligned_fields, strip=True):
    """
    Return a list of pairs of (marker, value) from `pairs`, where values
    with the same marker are recombined (i.e. unwrapped). If the marker
    is in `aligned_fields`, spacing will also be normalized (taking the
    length of the longest token) so that the tokens still align visually
    in columns.

    Args:
        pairs: An iterable of (marker, value) pairs.
        aligned_fields: A container of markers that are aligned.
    Return:
        The list of pairs with aligned fields normalized.

    Example:

    >>> data = [
    ...     ('\\t', 'inu=ga   ippiki'),
    ...     ('\\m', 'inu =ga  ichi -hiki'),
    ...     ('\\g', 'dog =NOM one  -CLF.ANIMAL'),
    ...     ('\\t', 'hoeru'),
    ...     ('\\m', 'hoe  -ru'),
    ...     ('\\g', 'bark -IPFV'),
    ...     ('\\f', 'One dog barks.')
    ... ]
    >>> for (mkr, val) in normalize_record(data, set(['\\t', \\g', '\\m'])):
    ...     print(mkr, val)
    \t inu=ga   ippiki           hoeru
    \m inu =ga  ichi -hiki       hoe  -ru
    \g dog =NOM one  -CLF.ANIMAL bark -IPFV
    \f One dog barks.
    """
    field_data = OrderedDict()
    # gather lines with the same marker, and keep track of the longest
    # aligned fields at each position
    maxlens = {}
    for mkr, val in pairs:
        if mkr not in field_data:
            field_data[mkr] = []
        if val is None:
            continue
        field_data[mkr].append(val)
        i = len(field_data[mkr]) - 1
        # this string length counts unicode combining characters, so
        # the lengths may appear off when printed
        if mkr in aligned_fields and len(val) > maxlens.get(i, -1):
            maxlens[i] = len(val)
    # join and normalize spacing (use longest length for each position)
    mkrs = list(field_data.keys())
    for mkr in mkrs:
        data = field_data[mkr]
        if data == []:
            joined = None
        elif mkr in aligned_fields:
            joined = ' '.join(s.ljust(maxlens[i]) for i, s in enumerate(data))
        else:
            joined = ' '.join(data)
        if strip and joined is not None:
            joined = joined.rstrip()
        field_data[mkr] = joined
    return list(field_data.items())

def align_fields(pairs, alignments=None, tokenizers=None, errors='strict'):
    """
    Align source to target tokens for each line in `pairs` using
    alignment mappings given in `alignments`. Line values are tokenized
    by whitespace by default, but can be handled specially by giving a
    custom tokenizer in `tokenizers`.

    Args:
        pairs: An iterable of (marker, value) pairs
        alignments: A dictionary of {marker1: marker2} alignments, where
            marker1 is aligned to marker2. If `alignments` is None, each
            value will still be put in a list as the only item with an
            alignment target of None.
        tokenizers: A dictionary of {marker: regex}, where the compiled
            regular expression `regex` is used to find sub-parts of the
            original value of the field. If `tokenizers` is None or a
            tokenizer regex is not given for a marker, and the marker is
            the source or target of an alignment, the values will be
            split by whitespace.
        errors: If 'strict', errors during alignment will be raised.
            Otherwise they will be ignored.

    Returns:
        A list of alignment pairs. Each alignment pair is a structure
        (marker, [(target_token, [source_tokens])]). That is, for each
        target token, a list of source tokens is aligned to it. For
        unaligned lines, the target token is None and the source tokens
        has the original line as the only list item. Lines that are a
        target but not source of any alignment have their own
        untokenized line as the target token. If the value of a line is
        None (e.g. there was a marker but no content), then both the
        target_token and the source_tokens will be None, even if the
        line should have been aligned to something.

    Example:

    >>> data = [
    ...     ('\\t', 'inu=ga   ippiki           hoeru     '),
    ...     ('\\m', 'inu =ga  ichi -hiki       hoe  -ru  '),
    ...     ('\\g', 'dog =NOM one  -CLF.ANIMAL bark -IPFV'),
    ...     ('\\f', 'One dog barks.'),
    ...     ('\\x', None)
    ... ]
    >>> align_fields(data, alignments={'\\m': '\\t', '\\g': '\\m'})
    [('\\t', [('inu=ga   ippiki           hoeru     ',
               ['inu=ga', 'ippiki', 'hoeru'])]),
     ('\\m', [('inu=ga', ['inu', '=ga']),
              ('ippiki', ['ichi', '-hiki']),
              ('hoeru', ['hoe', '-ru'])]),
     ('\\g', [('inu', ['dog']),
              ('=ga', ['=NOM']),
              ('ichi', ['one']),
              ('-hiki' ['-CLF.ANIMAL']),
              ('hoe', ['bark']),
              ('-ru', ['-IPFV'])]),
     ('\\f', [(None, ['One dog barks.'])]),
     ('\\x', [(None, None)])
    ]
    """
    aligned_fields = set(alignments.keys()).union(alignments.values())
    alignments = dict(alignments or [])
    tokenizers = dict(tokenizers or [])
    prev = {}  # previous tokenization matches used for alignment
    aligned_pairs = []
    for mkr, val in pairs:
        tokenizer = tokenizers.get(mkr, default_tokenizer)
        # empty content
        if val is None:
            aligned_pairs.append((mkr, [(None, None)]))
        # unaligned fields; don't do any tokenization
        elif mkr not in aligned_fields:
            aligned_pairs.append((mkr, [(None, [val])]))
        else:
            toks = list(tokenizer.finditer(val))
            prev[mkr] = toks
            # target, but not source, of alignments; just tokenize
            if mkr not in alignments:
                aligned_pairs.append(
                    (mkr, [(val, [t.group(0).rstrip() for t in toks])])
                )
            # source of an alignment; tokenize and align
            else:
                tgt_toks = prev.get(alignments[mkr])
                if tgt_toks is None:
                    logging.warning(
                        'Alignment target {} must precede source {}.'
                        .format(alignments[mkr], mkr)
                    )
                    continue
                aligned = _align_tokens(
                    toks, tgt_toks, errors=errors
                )
                aligned_pairs.append((mkr, aligned))
    return aligned_pairs

def _align_tokens(src, tgt, errors='strict'):
    # make a deque so we can efficiently pop from the front; also this
    # makes a copy of src so we don't affect the original
    _src = deque(src)
    _tgt = deque(tgt)
    #last_tgt_idx = len(_tgt) - 1
    #last_end = -1  # the end pos of the last source token
    aligned = []
    while _tgt:
        t = _tgt.popleft()
        next_t = _tgt[0] if _tgt else None  # None indicates end of deque
        try:
            grp = _collect_aligned_tokens(
                _src, t, next_t, errors=errors
            )
        except ToolboxAlignmentError as e:
            if errors == 'reanalyze':
                _src, _tgt = _reanalyze_tokens(src, tgt)
                aligned = []
                errors = 'reanalyze_1'  # change this to avoid a cycle
                continue
            else:
                raise
        aligned.append((t.group(0).rstrip(), grp))
    return aligned

def _collect_aligned_tokens(src, t, next_t, errors='strict'):
    grp = []
    while src:
        s = src[0]  # don't pop just yet
        s_tok = s.group(0).rstrip()

        if next_t is not None:

            # basic case; reached next column
            if s.start() >= next_t.start():
                break

            # exceptional case; overlapping columns
            s_end = s.start() + len(s_tok)
            if s_end >= next_t.start():
                msg = 'Possible misalignment at position {} ({}).'.format(
                    next_t.start(), s_tok
                )
                # recover in some way, but still warn the user
                warnings.warn(msg, ToolboxWarning)
                if errors == 'ratio':
                    ratio = float(s_end - next_t.start()) / len(s_tok)
                    if ratio >= 0.5:
                        break
                else:  # errors == 'strict' or otherwise
                    raise ToolboxAlignmentError(msg)

        # we're good to go. pop the token and continue
        src.popleft()  # no need to store it again
        grp.append(s_tok)
    return grp

def _reanalyze_tokens(src, tgt):
    # get joined strings
    src = ' '.join(x.group(0) for x in src)
    tgt = ' '.join(x.group(0) for x in tgt)
    # normalize spacing
    src = re.sub(r'\s+', ' ', src.strip())
    tgt = re.sub(r'\s+', ' ', tgt.strip())
    # put them in lists of tokens (initially just the strings)
    src = [src]
    tgt = [tgt]
    # iteratively find deeper alignments if possible
    level_delims = [  # the order is reversed, so pop() can be used
        r'([\.])',  # dot-delimiter for glosses
        r'\s+|((?<!\s)[-=~](?!\s))',  # space or (delim not next to a space)
        r'(?<=[^-=~\s])\s+(?=[^-=~\s])'  # space not adjacent to a delimiter
    ]
    while level_delims:
        delim = level_delims.pop()
        assert len(src) == len(tgt)
        # tokenize each token in src and tgt (and filter '' and None)
        _src = list(map(lambda x: list(filter(bool, re.split(delim, x))), src))
        _tgt = list(map(lambda x: list(filter(bool, re.split(delim, x))), tgt))
        pairs = zip_longest(_src, _tgt, fillvalue=[])
        if all(len(s) == len(t) for s, t in pairs):
            # same # tokens on each; reassign and continue
            src = [tok for toks in _src for tok in toks]
            tgt = [tok for toks in _tgt for tok in toks]
        else:
            # reshape src and break
            _src = list(map(lambda xs: ' '.join(xs), _src))
            src, tgt = zip(*map(lambda st: _ljust_pair(*st), zip(_src, tgt)))
            break
    # finally return re matches with the default tokenizer
    src = deque(default_tokenizer.finditer(' '.join(src)))
    tgt = deque(default_tokenizer.finditer(' '.join(tgt)))
    return src, tgt

def _ljust_pair(s, t):
    maxlen = max(len(s or ''), len(t or ''))
    return ((s or '').ljust(maxlen), (t or '').ljust(maxlen))

class ToolboxProject(object):
    def __init__(self, path):
        self.path = find_project_file(path)
        self.alignments = {}
        self.initialize()

    def initialize(self):
        pass


text:
/*
 * aaline.h
 *
 *	Structure definitions, function prototypes, and
 *	so forth for the antialiased line drawing sample code.
 *
 *	This code assumes integers are 32 bits.
 */

#include <stdio.h>
#include <stdlib.h>

/* Definitions used in this code */
#define WinWidth	640
#define WinHeight	480

/* Blend modes */
#define BLEND_ARBITRARY	1	/* Blend to arbitrary background color */
#define BLEND_CONSTANT	2	/* Blend to constant background color */
#define ADD_TO_BACKGROUND 3	/* Add to background color */

/* Frame Buffer Data Structure */

typedef struct fb fb;

struct fb {
    int fb_width;		/* Number of  horizontal pixels */
    int fb_height;		/* Number of vertical pixels */
    unsigned long *fbptr;	/* Pointer to frame buffer memory */
};

/* Data used when setting up a line.  Should be in a context structure */

/* Convert from floating-point to internal fixed-point formats */
#define ONE_XY			(long int) 0x00100000
#define FIX_XY_SHIFT		(long int) 20
#define ONEHALF_XY		(long int) 0x00080000
#define ONE_Z			(long int) 0x40000000
#define ONE_RGB			(long int) 0x40000000
#define ONE_16			(long int) 0x4000

#define FLOAT_TO_FIX_XY(x)	((long int) ((x) * (float) ONE_XY))

#define FLOAT_TO_FIX_Z(x)	((long int) ((x) * (float) ONE_Z))
#define FLOAT_TO_FIX_RGB(x)	((long int) ((x) * (float) ONE_RGB))
#define FLOAT_TO_FIX_16(x)	((long int) ((x) * (float) ONE_16))
#define FIX_TO_INT_XY(x)	((x) >> FIX_XY_SHIFT)
#define FIX_16_TO_FLOAT(x)	((float) (x) / (float) ONE_16)
#define FIX_TO_FLOAT_XY(x)	((float) (x) / (float) ONE_XY)
#define FIX_TO_FLOAT_Z(x)	((float) (x) / (float) ONE_Z)
#define FIX_TO_FLOAT_RGB(x)	((float) (x) / (float) ONE_RGB)

/* Get fractional part, next lowest integer part */
#define FRACT_XY(x)		((x) & (long int) 0x000fffff)
#define FLOOR_XY(x)		((x) & (long int) 0xfff00000)
#define FIX_XY_TO_INT(x)	((long int) (x) >> (long int) FIX_XY_SHIFT)

/* Sizes for tables in Draw */
#define FILTER_WIDTH	0.75	/* Line filter width adjustment */
#define F_TABLE_SIZE	64	/* Filter table size */
#define SC_TABLE_SIZE	32	/* Slope correction table size */
#define SRT_INT		5	/* Sqrt table index integer bits */
#define SRT_FRACT	4	/* ...fraction bits */
#define SR_INT		3	/* Square root result integer bits */
#define SR_FRACT	5	/* ...fraction bits */
#define SR_TABLE_SIZE	(1 << (SRT_INT + SRT_FRACT))

#define EP_MASK		(long int) 0x000f0000u	/* AA line end-point filter mask */
#define EP_SHIFT	13u	/* Number of bits to shift end-point */

typedef long int fix_xy;	/* S11.20 */
typedef long int fix_z;		/* S1.30 */
typedef long int fix_rgb;	/* S1.30 */

/* One vertex at any of the various stages of the pipeline */
typedef struct aa_vertex aa_vertex;
struct aa_vertex {
    unsigned header;
    float x, y, z, w;
    float r, g, b, a;
};

/* All values needed to draw one line */
typedef struct aa_setup_line aa_setup_line;
struct aa_setup_line {
    int x_major;
    int negative;

    fix_xy vs;			/* Starting point */
    fix_xy us;
    fix_xy ue;			/* End (along major axis) */
    fix_xy dvdu;		/* Delta for minor axis step */

    fix_z zs;			/* Starting Z and color */
    fix_rgb rs;
    fix_rgb gs;
    fix_rgb bs;
    fix_rgb as;

    fix_z dzdu;			/* Delta for Z and color */
    fix_rgb drdu;
    fix_rgb dgdu;
    fix_rgb dbdu;
    fix_rgb dadu;
};

/* Global variables */
extern int antialiased;		/* Antialiased lines, not jaggy */
extern int capline;		/* Draw last pixel of jaggy lines */
extern int blendmode;		/* Which blend mode to use */
extern int background;		/* Black */

/* Function prototypes */
void init_screen(int background);
void draw_pixel(long int x, long int y, short r, short g, short b);
void close_screen(void);
void init_tables(void);

void setup_line(aa_vertex *v1, aa_vertex *v2);
void draw_line(aa_setup_line *line);
void draw_aa_hspan(fix_xy x, fix_xy y, fix_z z,
    fix_rgb r, fix_rgb g, fix_rgb b, long int ep_corr, long int slope);
void draw_aa_vspan(fix_xy x, fix_xy y, fix_z z,
    fix_rgb r, fix_rgb g, fix_rgb b, long int ep_corr, long int slope);
long int fix_xy_mult(long int a, fix_xy b);
long int clamp_rgb(long int x);
long int clamp_z(long int x);
long int float_to_fix(float x, long int one);

void process_pixel(unsigned x, unsigned y, unsigned long z, unsigned long color);

/* End of aaline.h */

redpajama_set_name: RedPajamaGithub


text:
/*
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.skife.jdbi.v2;

class DerivedBean extends SampleBean {
    private Long blongField;

    public Long getBlongField() {
        return blongField;
    }

    public void setBlongField(Long blongField) {
        this.blongField = blongField;
    }
}


text:
require File.expand_path('../../test_helper', __FILE__)
require File.expand_path('../../fixtures/test_fork_jobs', __FILE__)
require File.expand_path('../../fixtures/test_queue_settings', __FILE__)

describe "Backburner::Workers::ThreadsOnFork module" do

  before do
    Backburner.default_queues.clear
    @worker_class = Backburner::Workers::ThreadsOnFork
    @worker_class.shutdown = false
    @worker_class.is_child = false
    @worker_class.threads_number = 1
    @worker_class.garbage_after = 1
    @ignore_forks = false
  end

  after do
    Backburner.configure { |config| config.max_job_retries = 0; config.retry_delay = 5; config.logger = nil }
    unless @ignore_forks
      cpids = @worker_class.instance_variable_get("@child_pids")
      if cpids && cpids.length > 0
        raise "Why is there forks alive?"
      end
    end
  end

  describe "for process_tube_names method" do
    it "should interpreter the job_name:threads_limit:garbage_after:retries format" do
      worker = @worker_class.new(["foo:1:2:3"])
      assert_equal ["foo"], worker.tube_names
    end

    it "should interpreter event if is missing values" do
      tubes = %W(foo1:1:2:3 foo2:4:5 foo3:6 foo4 foo5::7:8 foo6:::9 foo7::10)
      worker = @worker_class.new(tubes)
      assert_equal %W(foo1 foo2 foo3 foo4 foo5 foo6 foo7), worker.tube_names
    end

    it "should store interpreted values correctly" do
      tubes = %W(foo1:1:2:3 foo2:4:5 foo3:6 foo4 foo5::7:8 foo6:::9 foo7::10)
      worker = @worker_class.new(tubes)
      assert_equal({
        "demo.test.foo1" => { :threads => 1,   :garbage => 2,   :retries => 3   },
        "demo.test.foo2" => { :threads => 4,   :garbage => 5,   :retries => nil },
        "demo.test.foo3" => { :threads => 6,   :garbage => nil, :retries => nil },
        "demo.test.foo4" => { :threads => nil, :garbage => nil, :retries => nil },
        "demo.test.foo5" => { :threads => nil, :garbage => 7,   :retries => 8   },
        "demo.test.foo6" => { :threads => nil, :garbage => nil, :retries => 9   },
        "demo.test.foo7" => { :threads => nil, :garbage => 10,  :retries => nil }
      }, worker.instance_variable_get("@tubes_data"))
    end
  end

  describe "for process_tube_settings" do
    it "should set the settings specified by queue name in class" do
      worker = @worker_class.new
      assert_equal(worker.instance_variable_get("@tubes_data")['demo.test.job-settings'],  { :threads => 5,   :garbage => 10,   :retries => 6 })
    end

    it 'should override the tube settings if they are specified directly at class level' do
      worker = @worker_class.new
      assert_equal(worker.instance_variable_get("@tubes_data")['demo.test.job-settings-override'], { :threads => 10,   :garbage => 1000,   :retries => 2 })
    end
  end

  describe "for prepare method" do
    before do
      Backburner.configure { |config| config.logger = false }
    end

    it "should watch specified tubes" do
      worker = @worker_class.new(["foo", "bar"])
      out = capture_stdout { worker.prepare }
      assert_equal ["demo.test.foo", "demo.test.bar"], worker.tube_names
      assert_match /demo\.test\.foo/, out
    end # multiple

    it "should watch single tube" do
      worker = @worker_class.new("foo")
      out = capture_stdout { worker.prepare }
      assert_equal ["demo.test.foo"], worker.tube_names
      assert_match /demo\.test\.foo/, out
    end # single

    it "should respect default_queues settings" do
      Backburner.default_queues.concat(["foo", "bar"])
      worker = @worker_class.new
      out = capture_stdout { worker.prepare }
      assert_equal ["demo.test.foo", "demo.test.bar"], worker.tube_names
      assert_match /demo\.test\.foo/, out
    end

    it "should assign based on all tubes" do
      @worker_class.any_instance.expects(:all_existing_queues).once.returns("bar")
      worker = @worker_class.new
      out = capture_stdout { worker.prepare }
      assert_equal ["demo.test.bar"], worker.tube_names
      assert_match /demo\.test\.bar/, out
    end # all assign

    it "should properly retrieve all tubes" do
      worker = @worker_class.new
      out = capture_stdout { worker.prepare }
      assert_contains worker.tube_names, "demo.test.test-job-fork"
      assert_match /demo\.test\.test-job-fork/, out
    end # all read
  end # prepare

  describe "forking and threading" do

    it "start should call fork_and_watch for each tube" do
      worker = @worker_class.new(%W(foo bar))
      worker.expects(:fork_and_watch).with("demo.test.foo").once
      worker.expects(:fork_and_watch).with("demo.test.bar").once
      silenced { worker.start(false) }
    end

    it "fork_and_watch should create a thread to fork and watch" do
      worker = @worker_class.new(%(foo))
      worker.expects(:create_thread).once.with("demo.test.foo")
      silenced { worker.start(false) }
    end

    it "fork_and_watch thread should wait with wait_for_process" do
      process_exit = stub('process_exit')
      process_exit.expects(:exitstatus).returns(99)
      worker = @worker_class.new(%(foo))
      worker.expects(:wait_for_process).with(12).returns([nil, process_exit])

      wc = @worker_class
      # TODO: Is there a best way do do this?
      worker.define_singleton_method :fork_it do
        wc.shutdown = true
        12
      end
      def worker.create_thread(*args, &block); block.call(*args) end

      out = silenced(2) { worker.start(false) }
      refute_match /Catastrophic failure/, out
    end

    it "fork_and_watch thread should log an error if exitstatus is != 99" do
      process_exit = stub('process_exit')
      process_exit.expects(:exitstatus).twice.returns(0)
      worker = @worker_class.new(%(foo))
      worker.expects(:wait_for_process).with(12).returns([nil, process_exit])

      wc = @worker_class
      # TODO: Is there a best way do do this?
      worker.define_singleton_method :fork_it do
        wc.shutdown = true
        12
      end
      def worker.create_thread(*args, &block); block.call(*args) end
      out = silenced(2) { worker.start(false) }
      assert_match /Catastrophic failure: tube demo\.test\.foo exited with code 0\./, out
    end

    describe "fork_inner" do

      before do
        @worker_class.any_instance.expects(:coolest_exit).once
      end

      it "should watch just the channel it receive as argument" do
        worker = @worker_class.new(%(foo))
        @worker_class.expects(:threads_number).returns(1)
        worker.expects(:run_while_can).once
        silenced do
          worker.prepare
          worker.fork_inner('demo.test.bar')
        end
        assert_same_elements %W(demo.test.bar), @worker_class.connection.tubes.watched.map(&:name)
      end

      it "should not create threads if the number of threads is 1" do
        worker = @worker_class.new(%(foo))
        @worker_class.expects(:threads_number).returns(1)
        worker.expects(:run_while_can).once
        worker.expects(:create_thread).never
        silenced do
          worker.prepare
          worker.fork_inner('demo.test.foo')
        end
      end

      it "should create threads if the number of threads is > 1" do
        worker = @worker_class.new(%(foo))
        @worker_class.expects(:threads_number).returns(5)
        worker.expects(:create_thread).times(5)
        silenced do
          worker.prepare
          worker.fork_inner('demo.test.foo')
        end
      end

      it "should create threads that call run_while_can" do
        worker = @worker_class.new(%(foo))
        @worker_class.expects(:threads_number).returns(5)
        worker.expects(:run_while_can).times(5)
        # TODO
        def worker.create_thread(*args, &block); block.call(*args) end
        silenced do
          worker.prepare
          worker.fork_inner('demo.test.foo')
        end
      end

      it "should create a connection for each thread" do
        name = 'demo.test.foo'
        num_threads = 3

        worker = @worker_class.new(%(foo))
        @worker_class.expects(:threads_number).returns(num_threads)
        invocations = Array(1..num_threads).map { |i|
          conn = OpenStruct.new(:num => i)
          conn.expects(:close)
          conn
        }
        Backburner::Connection.expects(:new).times(num_threads).returns(*invocations)

        # ensure each invocation of run_while_can is with a different connection
        num_conns = states('num_conns').starts_as(0)
        invocations.each do |conn|
          worker.expects(:run_while_can).with(name, conn).when(num_conns.is(conn.num-1)).then(num_conns.is(conn.num))
        end

        def worker.create_thread(*args, &block); block.call(*args) end
        silenced do
          worker.prepare
          worker.fork_inner(name)
        end
        assert_equal(num_threads, num_conns.current_state)
      end

      it "should set @garbage_after, @threads_number and set retries if needed" do
        worker = @worker_class.new(%W(foo1 foo2:10 foo3:20:30 foo4:40:50:60))
        default_threads = 1
        default_garbage = 5
        default_retries = 100
        @worker_class.expects(:threads_number).times(1).returns(default_threads)
        @worker_class.expects(:garbage_after).times(2).returns(default_garbage)
        @worker_class.any_instance.expects(:coolest_exit).times(3)
        Backburner.configuration.max_job_retries = default_retries

        worker.expects(:create_thread).times(70)
        worker.expects(:run_while_can).once

        silenced do
          worker.prepare
          worker.fork_inner('demo.test.foo1')
        end

        assert_equal worker.instance_variable_get("@threads_number"), default_threads
        assert_equal worker.instance_variable_get("@garbage_after"), default_garbage
        assert_equal Backburner.configuration.max_job_retries, default_retries

        silenced do
          worker.fork_inner('demo.test.foo2')
        end

        assert_equal worker.instance_variable_get("@threads_number"), 10
        assert_equal worker.instance_variable_get("@garbage_after"), default_garbage
        assert_equal Backburner.configuration.max_job_retries, default_retries

        silenced do
          worker.fork_inner('demo.test.foo3')
        end

        assert_equal worker.instance_variable_get("@threads_number"), 20
        assert_equal worker.instance_variable_get("@garbage_after"), 30
        assert_equal Backburner.configuration.max_job_retries, default_retries

        silenced do
          worker.fork_inner('demo.test.foo4')
        end

        assert_equal worker.instance_variable_get("@threads_number"), 40
        assert_equal worker.instance_variable_get("@garbage_after"), 50
        assert_equal Backburner.configuration.max_job_retries, 60
      end

    end

    describe "cleanup on parent" do

      it "child_pids should return a list of alive children pids" do
        worker = @worker_class.new(%W(foo))
        Kernel.expects(:fork).once.returns(12345)
        Process.expects(:kill).with(0, 12345).once
        Process.expects(:pid).once.returns(12346)
        assert_equal [], @worker_class.child_pids
        worker.fork_it {}
        child_pids = @worker_class.child_pids
        assert_equal [12345], child_pids
        child_pids.clear
      end

      it "child_pids should return an empty array if is_child" do
        Process.expects(:pid).never
        @worker_class.is_child = true
        @worker_class.child_pids << 12345
        assert_equal [], @worker_class.child_pids
      end

      it "stop_forks should send a SIGTERM for every child" do
        Process.expects(:pid).returns(12346).at_least(1)
        Process.expects(:kill).with(0, 12345).at_least(1)
        Process.expects(:kill).with(0, 12347).at_least(1)
        Process.expects(:kill).with("SIGTERM", 12345)
        Process.expects(:kill).with("SIGTERM", 12347)
        @worker_class.child_pids << 12345
        @worker_class.child_pids << 12347
        assert_equal [12345, 12347], @worker_class.child_pids
        @worker_class.stop_forks
        @worker_class.child_pids.clear
      end

      it "kill_forks should send a SIGKILL for every child" do
        Process.expects(:pid).returns(12346).at_least(1)
        Process.expects(:kill).with(0, 12345).at_least(1)
        Process.expects(:kill).with(0, 12347).at_least(1)
        Process.expects(:kill).with("SIGKILL", 12345)
        Process.expects(:kill).with("SIGKILL", 12347)
        @worker_class.child_pids << 12345
        @worker_class.child_pids << 12347
        assert_equal [12345, 12347], @worker_class.child_pids
        @worker_class.kill_forks
        @worker_class.child_pids.clear
      end

      it "finish_forks should call stop_forks, kill_forks and Process.waitall" do
        Process.expects(:pid).returns(12346).at_least(1)
        Process.expects(:kill).with(0, 12345).at_least(1)
        Process.expects(:kill).with(0, 12347).at_least(1)
        Process.expects(:kill).with("SIGTERM", 12345)
        Process.expects(:kill).with("SIGTERM", 12347)
        Process.expects(:kill).with("SIGKILL", 12345)
        Process.expects(:kill).with("SIGKILL", 12347)
        Kernel.expects(:sleep).with(1)
        Process.expects(:waitall)
        @worker_class.child_pids << 12345
        @worker_class.child_pids << 12347
        assert_equal [12345, 12347], @worker_class.child_pids
        silenced do
          @worker_class.finish_forks
        end
        @worker_class.child_pids.clear
      end

      it "finish_forks should not do anything if is_child" do
        @worker_class.expects(:stop_forks).never
        @worker_class.is_child = true
        @worker_class.child_pids << 12345
        silenced do
          @worker_class.finish_forks
        end
      end

    end # cleanup on parent

    describe "practical tests" do

      before do
        @templogger = Templogger.new('/tmp')
        Backburner.configure { |config| config.logger = @templogger.logger }
        $worker_test_count = 0
        $worker_success = false
        $worker_raise   = false
        clear_jobs!('response')
        clear_jobs!('foo.bar.1', 'foo.bar.2', 'foo.bar.3', 'foo.bar.4', 'foo.bar.5', 'foo.bar.6')
        @worker_class.threads_number = 1
        @worker_class.garbage_after  = 10
        silenced do
          @response_worker = @worker_class.new('response')
          @response_worker.watch_tube('demo.test.response')
        end
        @ignore_forks = true
      end

      after do
        @templogger.close
        clear_jobs!('response')
        clear_jobs!('foo.bar.1', 'foo.bar.2', 'foo.bar.3', 'foo.bar.4', 'foo.bar.5', 'foo.bar.6')
        @worker_class.threads_number = 1
        @worker_class.shutdown = true
        silenced do
          @worker_class.stop_forks
          Timeout::timeout(2) { sleep 0.1 while @worker_class.child_pids.length > 0 }
          @worker_class.kill_forks
          Timeout::timeout(2) { sleep 0.1 while @worker_class.child_pids.length > 0 }
        end
      end

      it "should work an enqueued job" do
        @worker = @worker_class.new('foo.bar.1')
        @worker.start(false)
        @worker_class.enqueue TestJobFork, [1, 2], :queue => "foo.bar.1"
        silenced(2) do
          @templogger.wait_for_match(/Completed TestJobFork/m)
          @response_worker.work_one_job
        end
        assert_equal 3, $worker_test_count
      end # enqueue

      it "should work for an async job" do
        @worker = @worker_class.new('foo.bar.2')
        @worker.start(false)
        TestAsyncJobFork.async(:queue => 'foo.bar.2').foo(3, 5)
        silenced(2) do
          @templogger.wait_for_match(/Completed TestAsyncJobFork/m)
          @response_worker.work_one_job
        end
        assert_equal 15, $worker_test_count
      end # async

      it "should fail quietly if there's an argument error" do
        @worker = @worker_class.new('foo.bar.3')
        @worker.start(false)
        @worker_class.enqueue TestJobFork, ["bam", "foo", "bar"], :queue => "foo.bar.3"
        silenced(5) do
          @templogger.wait_for_match(/Finished TestJobFork.*attempt 1 of 1/m)
        end
        assert_match(/Exception ArgumentError/, @templogger.body)
        assert_equal 0, $worker_test_count
      end # fail, argument

      it "should support retrying jobs and burying" do
        Backburner.configure { |config| config.max_job_retries = 1; config.retry_delay = 0 }
        @worker = @worker_class.new('foo.bar.4')
        @worker.start(false)
        @worker_class.enqueue TestRetryJobFork, ["bam", "foo"], :queue => 'foo.bar.4'
        silenced(2) do
          @templogger.wait_for_match(/Finished TestRetryJobFork.*attempt 2 of 2/m)
          2.times { @response_worker.work_one_job }
        end
        assert_equal 2, $worker_test_count
        assert_equal false, $worker_success
      end # retry, bury

      it "should support retrying jobs and succeeds" do
        Backburner.configure { |config| config.max_job_retries = 2; config.retry_delay = 0 }
        @worker = @worker_class.new('foo.bar.5')
        @worker.start(false)
        @worker_class.enqueue TestRetryJobFork, ["bam", "foo"], :queue => 'foo.bar.5'
        silenced(2) do
          @templogger.wait_for_match(/Completed TestRetryJobFork/m)
          3.times { @response_worker.work_one_job }
        end
        assert_equal 3, $worker_test_count
        assert_equal true, $worker_success
      end # retrying, succeeds

      it "should support a multithreaded worker without deadlocks" do
        num_threads = 5
        num_jobs = 8
        num_jobs.times do
          @worker_class.enqueue TestJobFork, [6,2], :queue => 'foo.bar.6'
        end
        @worker_class.threads_number = num_threads
        @worker = @worker_class.new('foo.bar.6')
        @worker.start(false)
        silenced(2) do
          @templogger.wait_for_match(/Completed TestJobFork/m)
          num_jobs.times { @response_worker.work_one_job }
        end
        assert_equal num_jobs, $worker_test_count
      end # multithreaded

    end # practical tests

  end # forking and threading

end # Backburner::Workers::ThreadsOnFork module


text:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Serilog;
using System.IO;
using XSharpModel;
using System.ComponentModel;
using Community.VisualStudio.Toolkit;
using Microsoft.VisualStudio.Shell;
using System.Diagnostics;

namespace XSharp.Project
{
    internal static class Logger
    {
        static bool log2debugger = false;
        static bool log2file = false;

        private static string singleline = new string('-', 80);
        private static string doubleline = new string('=', 80);

        static bool active = false;
        internal static bool Active => active;
        internal static void Start()
        {
            if (!active ||
                log2debugger  != XSettings.EnableDebugLogging ||
                log2file != XSettings.EnableFileLogging)
            {
                if (active)
                {
                    Stop();
                }
                var config = new LoggerConfiguration()
                        .MinimumLevel.Debug();
                log2debugger = false;
                log2file = false;
                if (XSettings.EnableDebugLogging)
                {
                    config = config.WriteTo.Debug();
                    log2debugger = true;
                }
                if (XSettings.EnableFileLogging)
                {
                    var temp = Path.GetTempPath();
                    temp = Path.Combine(temp, "XSharp.Intellisense");
                    if (!Directory.Exists(temp))
                    {
                        Directory.CreateDirectory(temp);
                    }
#pragma warning disable CS0618 // Type or member is obsolete
                    int threadid = AppDomain.GetCurrentThreadId();
#pragma warning restore CS0618 // Type or member is obsolete
                    string strId = threadid.ToString("X");
                    var log = Path.Combine(temp, "Project_"+strId+"_.log");
                    config = config.WriteTo.File(log,
                        rollingInterval: RollingInterval.Day,
                        rollOnFileSizeLimit: true,
                        flushToDiskInterval: TimeSpan.FromSeconds(15),
                        retainedFileCountLimit: 5);
                    log2file = true;
                }

                Log.Logger = config.CreateLogger();

                Log.Information(doubleline);
                Log.Information("Started Logging");
                string version="";
                ThreadHelper.JoinableTaskFactory.Run(async delegate
                {
                    var ver = await VS.Shell.GetVsVersionAsync();
                    version = ver.ToString();
                });
                Log.Information("Visual Studio Exe     : " + Process.GetCurrentProcess().MainModule.FileName);
                Log.Information("Visual Studio version : " + version);
                Log.Information("XSharp Project System : " + Constants.FileVersion);

                Log.Information(doubleline);
                var sol = VS.Solutions.GetCurrentSolution();
                if (sol != null)
                {
                    Log.Information(singleline);
                    Log.Information("Current solution: " + sol.FullPath);

                    var children = EnumChildren(sol);
                    foreach (var child in children)
                    {
                        if (child.Type == SolutionItemType.Project)
                        {
                            Log.Information("Project " + child.FullPath);
                        }
                    }
                    Log.Information(singleline);

                }

                AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;
                //AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;
                active = true;
            }
            // Force all Logging options to be enabled
            XSettings.EnableBraceMatchLog = true;
            XSettings.EnableCodeCompletionLog = true;
            XSettings.EnableDatabaseLog = true;
            XSettings.EnableParameterLog = true;
            XSettings.EnableParseLog = true;
            XSettings.EnableQuickInfoLog = true;
            XSettings.EnableReferenceInfoLog = true;
            XSettings.EnableTypelookupLog = true;
        }

        static IList<SolutionItem> EnumChildren(SolutionItem item)
        {
            var items = new List<SolutionItem>();
            foreach (var child in item.Children)
            {
                items.Add(child);
                try
                {
                    items.AddRange(EnumChildren(child));
                }
                catch (Exception e)
                {
                    Exception(e, "EnumChildren");
                }
            }
            return items;
        }

        private static void CurrentDomain_FirstChanceException(object sender, System.Runtime.ExceptionServices.FirstChanceExceptionEventArgs e)
        {

            if (active)
            {
                if (e.Exception is OperationCanceledException)
                {
                    ; // do nothing
                }
                else if (e.Exception is Win32Exception)
                {
                    ; // do nothing
                }
                else
                {
                    Log.Error(e.Exception, formatMessage("FirstChanceException"));
                }
            }
        }

        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            if (active)
            {
                if (e.ExceptionObject is Exception ex)
                    Log.Fatal(ex, formatMessage("UnhandledException"));
            }
        }

        internal static void Stop()
        {
            if (active)
            {
                Log.Information(doubleline);
                Log.Information("Stopped logging");
                Log.Information(doubleline);

                Log.CloseAndFlush();
                active = false;
                AppDomain.CurrentDomain.UnhandledException -= CurrentDomain_UnhandledException;
                //AppDomain.CurrentDomain.FirstChanceException -= CurrentDomain_FirstChanceException;
            }
        }

        internal static void Debug(string message)
        {
            if (active)
            {
                Log.Debug(formatMessage(message));
            }

        }
        internal static void Information(string message)
        {
            if (active)
            {
                Log.Information(formatMessage(message));
            }
        }

        internal static void Exception(Exception e, string message)
        {
            if (active)
            {
                Log.Error(e, formatMessage(message));
            }
        }
        internal static void SingleLine()
        {
            Information(singleline);
        }
        internal static void DoubleLine()
        {
            Information(doubleline);
        }

        private static string formatMessage(string message)
        {
            return string.Format("{0:X4} {1}", System.Threading.Thread.CurrentThread.ManagedThreadId, message);
        }

    }
}


text:
% !TEX TS-program = pdflatex
% !TEX encoding = UTF-8 Unicode

\documentclass[a4paper]{article}

\usepackage[english]{babel}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}
\usepackage[pdftex]{graphicx}
\usepackage{float}
\usepackage{fancyhdr}
\usepackage[toc,page]{appendix}
\usepackage{listings}
\usepackage{booktabs} % for much better looking tables
\usepackage{array} % for better arrays (eg matrices) in maths
\usepackage{paralist} % very flexible & customizable lists (eg. enumerate/itemize, etc.)
\usepackage{verbatim} % adds environment for commenting out blocks of text & for better verbatim
\usepackage{subfig} % make it possible to include more than one captioned figure/table in a single float
\usepackage[margin=2.5cm]{geometry}

\usepackage[stable]{footmisc} % footnotes in section tags
\usepackage{natbib} % automatic short-hand citations

\setlength{\parindent}{0pt}

%%% HEADERS & FOOTERS
\author{Niclas Olofsson}
\pagestyle{fancy} % options: empty , plain , fancy
\renewcommand{\headrulewidth}{1pt} % customise the layout...
\fancyhead[LO,LE]{Niclas Olofsson\\Planning report}
\lfoot{}\cfoot{\thepage}\rfoot{}

%%%% SECTION TITLE APPEARANCE
%\usepackage{sectsty}
%\allsectionsfont{\sffamily\mdseries\upshape} % (See the fntguide.pdf for font help)
%% (This matches ConTeXt defaults)
%
%%%% ToC (table of contents) APPEARANCE
%\usepackage[nottoc,notlof,notlot]{tocbibind} % Put the bibliography in the ToC
%\usepackage[titles,subfigure]{tocloft} % Alter the style of the Table of Contents
%\renewcommand{\cftsecfont}{\rmfamily\mdseries\upshape}
%\renewcommand{\cftsecpagefont}{\rmfamily\mdseries\upshape} % No bold!

%%% END Article customizations

%%% The "real" document content comes below...

\title{Planning rapport for final thesis at IDA}
%\date{} % Activate to display a given date or no date (if empty),
         % otherwise the current date is printed

\begin{document}
\maketitle

\section{Author}
Niclas Olofsson, Civilingenjörsutbildning i Datateknik

\section{Working title}
Automated testing in web applications

\section{Problem formulation}
\input{problem_formulation.tex}

\section{Initial approach}
\input{initial_approach.tex}

\section{Literature basis}
\input{litterature_basis.tex}

\section{Time schedule}
\input{time_schedule.tex}

%\bibliographystyle{plain}
\bibliographystyle{plainnat}
\bibliography{references}

\end{document}


text:
package c5db;

import c5db.interfaces.C5Module;
import c5db.interfaces.ModuleInformationProvider;
import c5db.messages.generated.ModuleType;
import c5db.util.FiberOnly;
import com.google.common.collect.ImmutableMap;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.Service;
import com.google.common.util.concurrent.SettableFuture;
import org.jetlang.channels.Channel;
import org.jetlang.channels.MemoryChannel;
import org.jetlang.channels.Subscriber;
import org.jetlang.fibers.Fiber;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;

/**
 * A basic ModuleInformationProvider that enables one to register and start C5Modules,
 * after which their life cycle is tracked using a SimpleC5ModuleListener.
 */
public class SimpleModuleInformationProvider implements ModuleInformationProvider {
  private final Fiber fiber;
  private final Consumer<Throwable> failureHandler;
  private final Map<ModuleType, C5Module> modules = new HashMap<>();
  private final Map<ModuleType, Integer> onlineModuleToPortMap = new HashMap<>();
  private final Channel<ImmutableMap<ModuleType, Integer>> moduleChangeChannel = new MemoryChannel<>();

  public SimpleModuleInformationProvider(Fiber fiber, Consumer<Throwable> failureHandler) {
    this.fiber = fiber;
    this.failureHandler = failureHandler;
  }

  public ListenableFuture<Service.State> startModule(C5Module module) {
    SettableFuture<Service.State> startedFuture = SettableFuture.create();
    Service.Listener stateChangeListener = new SimpleC5ModuleListener(
        module,
        () -> {
          addRunningModule(module);
          startedFuture.set(null);
        },
        () -> removeModule(module),
        failureHandler);

    module.addListener(stateChangeListener, fiber);
    modules.put(module.getModuleType(), module);
    module.start();

    return startedFuture;
  }

  @Override
  public ListenableFuture<C5Module> getModule(ModuleType moduleType) {
    SettableFuture<C5Module> moduleFuture = SettableFuture.create();
    fiber.execute(() -> moduleFuture.set(modules.get(moduleType)));
    return moduleFuture;
  }

  @Override
  public ListenableFuture<ImmutableMap<ModuleType, Integer>> getOnlineModules() {
    final SettableFuture<ImmutableMap<ModuleType, Integer>> future = SettableFuture.create();
    fiber.execute(() -> future.set(ImmutableMap.copyOf(onlineModuleToPortMap)));
    return future;
  }

  @Override
  public Subscriber<ImmutableMap<ModuleType, Integer>> moduleChangeChannel() {
    return moduleChangeChannel;
  }

  @Override
  public ImmutableMap<ModuleType, C5Module> getModules()
      throws ExecutionException, InterruptedException, TimeoutException {
    throw new UnsupportedOperationException();
  }

  @FiberOnly
  private void addRunningModule(C5Module module) {
    ModuleType type = module.getModuleType();
    if (modules.containsKey(type) && modules.get(type).equals(module)) {
      onlineModuleToPortMap.put(type, module.port());
      publishCurrentActivePorts();
    }
  }

  @FiberOnly
  private void removeModule(C5Module module) {
    ModuleType type = module.getModuleType();
    if (modules.containsKey(type) && modules.get(type).equals(module)) {
      modules.remove(type);
      onlineModuleToPortMap.remove(type);
      publishCurrentActivePorts();
    }
  }

  @FiberOnly
  private void publishCurrentActivePorts() {
    moduleChangeChannel.publish(ImmutableMap.copyOf(onlineModuleToPortMap));
  }
}


text:
  // Forward Declarations
  class Matrix;

  typedef std::vector<double> DblVec;

  //! Enum that specifies the wanted model
enum model_type {id, jc, jck, jcss, wag, day, arve, jtt, mvr, lg};

  //! Gets the rate matrix for the specified model
  Matrix get_model_matrix(model_type model);
  //! Gets the equilibrium distribution for the specified model
  DblVec get_model_vec(model_type model);
  //! The Arvestad rate matrix
  Matrix get_arvestad();
  //! The Arvestad equilibrium distribution
  DblVec get_arve_eq();
  //! The JTT rate matrix
  Matrix get_jtt();
  //! The JTT equilibrium distribution
  DblVec get_jtt_eq();
  //! The Müller-Vingron rate matrix
  Matrix get_mvr();
  //! The Müller-Vingron equilibrium distribution
  DblVec get_mvr_eq();
  //! The Dayhoff rate matrix
  Matrix get_day();
  //! The Dayhoff equilibrium distribution
  DblVec get_day_eq();
  //! The WAG rate matrix
  Matrix get_wag();
  //! The WAG equilibrium distribution
  DblVec get_wag_eq();
  //! The LG rate matrix
  Matrix get_lg();
  //! The LG equilibrium distribution
  DblVec get_lg_eq();
#endif