text:
%%% Definitions of styles and parameters

%% Settings for single-side (simplex) printing
% Margins: left 40mm, right 25mm, top and bottom 25mm
% (but beware, LaTeX adds 1in implicitly)
\documentclass[12pt,a4paper]{report}
\setlength\textwidth{145mm}
\setlength\textheight{247mm}
\setlength\oddsidemargin{15mm}
\setlength\evensidemargin{15mm}
\setlength\topmargin{0mm}
\setlength\headsep{0mm}
\setlength\headheight{0mm}
% makes the following text appear on a right-hand page
\let\openright=\clearpage

%% Settings for two-sided (duplex) printing
%\documentclass[12pt,a4paper,twoside,openright]{report}
%\setlength\textwidth{145mm}
%\setlength\textheight{247mm}
%\setlength\oddsidemargin{14.2mm}
%\setlength\evensidemargin{0mm}
%\setlength\topmargin{0mm}
%\setlength\headsep{0mm}
%\setlength\headheight{0mm}
%\let\openright=\cleardoublepage

%% Character encoding
\usepackage[utf8]{inputenc}

%% Packages
\usepackage{amsmath}        % extensions for typesetting of math
\usepackage{amsfonts}       % math fonts
\usepackage{amsthm}         % theorems, definitions, etc.
\usepackage{bbding}         % various symbols (squares, asterisks, scissors, ...)
\usepackage{bm}             % boldface symbols (\bm)
\usepackage{graphicx}       % embedding of pictures
\usepackage{fancyvrb}       % improved verbatim environment
\usepackage{natbib}         % citation style AUTHOR (YEAR), or AUTHOR [NUMBER]
\usepackage[nottoc]{tocbibind} % makes sure that bibliography and the lists
			                   % of figures/tables are included in the table
			                   % of contents
\usepackage{dcolumn}        % improved alignment of table columns
\usepackage{booktabs}       % improved horizontal lines in tables
\usepackage{paralist}       % improved enumerate and itemize
\usepackage[usenames]{xcolor}  % typesetting in color

%%% My own packages (not from the template)
\usepackage{adjustbox}
\usepackage{alltt}
% Attachments directory tree
\usepackage{dirtree}
\renewcommand*\DTstylecomment{\ttfamily\textcolor{gray}}
\setlength{\DTbaselineskip}{20pt}
\usepackage{textcomp}
% Footnotes always at bottom
\usepackage[bottom]{footmisc}

%%% Basic information on the thesis

% Thesis title in English
\def\ThesisTitle{Grammar to JetBrains MPS Convertor}

% Author of the thesis
\def\ThesisAuthor{Bc. Přemysl Vysoký}

% Year when the thesis is submitted
\def\YearSubmitted{2016}

% Name of the department or institute, where the work was officially assigned
\def\Department{Department of Distributed and Dependable Systems}

% Is it a department (katedra), or an institute (ústav)?
\def\DeptType{Department}

% Thesis supervisor: name, surname and titles
\def\Supervisor{RNDr. Pavel Parízek, Ph.D.}

% Supervisor's department (again according to Organizational structure of MFF)
\def\SupervisorsDepartment{Department of Distributed and Dependable Systems}

% Study programme and specialization
\def\StudyProgramme{Computer Science}
\def\StudyBranch{Software Systems}

\def\Abstract{%
JetBrains MPS is a language workbench focusing on domain-specific languages.
Unlike many other language workbenches and IDEs, it uses a projectional editor for code.
The developer directly manipulates the program in its tree form (AST) and not by editing a text source code.
This brings many advantages, but on the other hand requires time-consuming and complicated MPS language definition.
The thesis elaborates on the possibility of automating the process of creating MPS language definition from its grammar description.
It introduces the MPS editor, evaluates approaches of related projects and describes author's efforts to implement an MPS plugin that allows this import.
The chosen approach and the selection of tools used for implementation are justified in the thesis.
We point out important problems that any similar project might deal with and we introduce some possible solutions.
Furthermore, the thesis contains examples of imported languages, showing the potency of the chosen approach.
The thesis also aims to lay groundwork for future extensions and suggest possible improvements.
}

\def\Keywords{%
	{JetBrains MPS}, {grammar}, {convertor}, {import}, {programming language}, {projectional editor}
}

%% The hyperref package for clickable links in PDF and also for storing
%% metadata to PDF (including the table of contents).
\usepackage[pdftex,unicode]{hyperref}   % Must follow all other packages
\hypersetup{breaklinks=true}
\hypersetup{pdftitle={\ThesisTitle}}
\hypersetup{pdfauthor={\ThesisAuthor}}
\hypersetup{pdfkeywords=\Keywords}
\hypersetup{urlcolor=blue}


text:
#define _GNU_SOURCE
#include <stdlib.h>
#include <string.h>
#include <execinfo.h>

#include <dlfcn.h>

#include <glib.h>

#include <tinu/utils.h>
#include <tinu/backtrace.h>
#include <tinu/log.h>

//#include <config.h>

#ifdef ELFDEBUG_ENABLED
#include <tinu/dwarf.h>

static gboolean g_backtrace_init = FALSE;
static DwarfHandle *g_backtrace_dwarf;

extern const gchar *g_runtime_name;

gchar *(*g_demangler)(const gchar *function) = g_strdup;

static void
_backtrace_cleanup()
{
  dw_destroy(g_backtrace_dwarf);
}

static inline void
_backtrace_init()
{
  if (!g_backtrace_init)
    {
      g_backtrace_init = TRUE;
      g_backtrace_dwarf = dw_new(g_runtime_name);

      atexit(_backtrace_cleanup);
    }
}

static inline gboolean
_backtrace_get_lineinfo(const BacktraceEntry *entry, const gchar **file, guint32 *lineno)
{
  const DwarfEntry *dw_entry;

  if (!g_backtrace_dwarf)
    return FALSE;

  dw_entry = dw_lookup(g_backtrace_dwarf, entry->m_ptr, 0x30);

  if (!dw_entry)
    return FALSE;

  *file = g_quark_to_string(dw_entry->m_source);
  *lineno = dw_entry->m_lineno;
  return TRUE;
}
#else
#define _backtrace_init()
#define g_demangler g_strdup
#endif

#define MAX_BUF_SIZE      4096

struct _Backtrace
{
  gint                    m_refcnt;

  guint32                 m_length;
  gpointer               *m_symbols;
};

struct _DumpLogUserData
{
  gint                     m_priority;
  const gchar             *m_prefix;
};

static BacktraceEntry *
_backtrace_resolve_info(const gpointer addr)
{
  Dl_info info;
  BacktraceEntry *res = NULL;

  if (!addr)
    return NULL;

  if (dladdr(addr, &info) != 0);
    {
      res = g_new0(BacktraceEntry, 1);

      res->m_ptr = addr;
      res->m_offset = addr - info.dli_saddr;
      if (info.dli_sname)
        res->m_function = g_demangler(info.dli_sname);
      if (!res->m_function)
        res->m_function = g_strdup("<unknown>");
      res->m_file = g_strdup(info.dli_fname);
    }
  return res;
}

static void
_backtrace_dump_log_callback(const BacktraceEntry *entry, gpointer user_data)
{
  struct _DumpLogUserData *self = (struct _DumpLogUserData *)user_data;
  const gchar *src = NULL;
  guint32 line = 0;

  if (entry == BACKTRACE_ENTRY_INVALID)
    {
      log_format(self->m_priority, self->m_prefix,
                msg_tag_str("error", "invalid frame"), NULL);
      return;
    }

  backtrace_resolv_lines(entry, &src, &line);

  log_format(self->m_priority, self->m_prefix,
            msg_tag_str("function", entry->m_function),
            msg_tag_str("file", entry->m_file),
            msg_tag_hex("offset", entry->m_offset),
            msg_tag_ptr("ptr", entry->m_ptr),
            msg_tag_printf("location", "%s:%d", src, line), NULL);
}

struct _DumpFileUserData
{
  FILE                 *m_file;
  gint                  m_indent;
};

static void
_backtrace_dump_file_callback(const BacktraceEntry *entry, gpointer user_data)
{
  struct _DumpFileUserData *self = (struct _DumpFileUserData *)user_data;

  const gchar *src = NULL;
  guint32 line = 0;

  if (entry == BACKTRACE_ENTRY_INVALID)
    {
      fprintf(self->m_file, "%*c<invalid frame>\n", self->m_indent, ' ');
      return;
    }

  if (entry->m_function)
    fprintf(self->m_file, "%*c%s\n", self->m_indent, ' ', entry->m_function);
  else
    fprintf(self->m_file, "%*c<file: %s>\n", self->m_indent, ' ', entry->m_file);

  if (backtrace_resolv_lines(entry, &src, &line))
    fprintf(self->m_file, "\tlocation: %s:%d\n", src, line);
}

Backtrace *
backtrace_create(guint32 skip)
{
  return backtrace_create_depth(MAX_DEPTH, skip);
}

Backtrace *
backtrace_create_depth(guint32 depth, guint32 skip)
{
  gpointer buffer[MAX_DEPTH + 1];
  guint32 nptr;
  Backtrace *res;

  _backtrace_init();

  if (depth > MAX_DEPTH)
    {
      log_warn("Requested depth exceeded maximum depth",
                msg_tag_int("depth", depth),
                msg_tag_int("skip", skip), NULL);
    }

  if ((nptr = backtrace(buffer, MAX_DEPTH)) == -1)
    {
      log_error("Could not create backtrace object",
                msg_tag_int("depth", depth),
                msg_tag_int("skip", skip), NULL);
      return NULL;
    }

  if (nptr <= skip)
    {
      log_warn("Backtrace empty",
                msg_tag_int("depth", depth),
                msg_tag_int("skip", skip), NULL);

      res = t_new(Backtrace, 1);

      res->m_refcnt = 1;
      res->m_length = 0;
      res->m_symbols = NULL;
      return res;
    }

  res = t_new(Backtrace, 1);
  res->m_refcnt = 1;
  res->m_length = nptr - skip;
  res->m_symbols = g_new0(gpointer, nptr - skip);
  memcpy(res->m_symbols, buffer + skip, (nptr - skip) * sizeof(gpointer));

  return res;
}

Backtrace *
backtrace_reference(Backtrace *self)
{
  self->m_refcnt++;
  return self;
}

void
backtrace_unreference(Backtrace *self)
{
  if (!self)
    return;

  self->m_refcnt--;

  if (self->m_refcnt == 0)
    {
      t_free(self->m_symbols);
      t_free(self);
    }
}

guint32
backtrace_depth(const Backtrace *self)
{
  return self->m_length;
}

void
backtrace_dump_log(const Backtrace *self, const gchar *msg_prefix, gint priority)
{
  struct _DumpLogUserData ud = { priority, msg_prefix };
  backtrace_dump(self, &_backtrace_dump_log_callback, &ud);
}

void
backtrace_dump_file(const Backtrace *self, FILE *output, guint8 indent)
{
  struct _DumpFileUserData ud = { output, indent };
  backtrace_dump(self, &_backtrace_dump_file_callback, &ud);
}

void
backtrace_dump(const Backtrace *self, DumpCallback callback, void *user_data)
{
  BacktraceEntry *entry;
  guint32 i;

  for (i = 0; i < self->m_length; i++)
    {
      if (NULL != (entry = _backtrace_resolve_info(self->m_symbols[i])))
        {
          callback(entry, user_data);
          backtrace_entry_destroy(entry);
          t_free(entry);
        }
      else
        callback(BACKTRACE_ENTRY_INVALID, user_data);

    }
}

BacktraceEntry *
backtrace_line(const Backtrace *self, guint32 index)
{
  if (index >= self->m_length)
    return NULL;

  return _backtrace_resolve_info(self->m_symbols[index]);
}

gboolean
backtrace_resolv_lines(const BacktraceEntry *entry, const gchar **src, guint32 *line)
{
#ifdef ELFDEBUG_ENABLED
  return _backtrace_get_lineinfo(entry, src, line);
#else
  return FALSE;
#endif
}

void
backtrace_entry_destroy(BacktraceEntry *self)
{
  t_free(self->m_function);
  t_free(self->m_file);
}

MessageTag *
msg_tag_trace(const gchar *tag, const Backtrace *trace)
{
  MessageTag *res = t_new(MessageTag, 1);
  GString *str = g_string_new("");
  BacktraceEntry *entry;
  guint32 i;

  for (i = 0; i < trace->m_length; i++)
    {
      if ((NULL != (entry = _backtrace_resolve_info(trace->m_symbols[i]))) && entry->m_function)
        {
          g_string_append(str, entry->m_function);
          g_string_append(str, ", ");

          backtrace_entry_destroy(entry);
          t_free(entry);
        }
      else
        g_string_append(str, "???, ");
    }

  res->m_tag = strdup(tag);
  res->m_value = strndup(str->str, str->len - 2);

  g_string_free(str, TRUE);

  return res;
}

MessageTag *
msg_tag_trace_current(const gchar *tag, int skip)
{
  Backtrace *trace = backtrace_create(skip);
  MessageTag *res = msg_tag_trace(tag, trace);
  backtrace_unreference(trace);

  return res;
}

redpajama_set_name: RedPajamaGithub


text:
namespace google_apis {

DummyDriveService::DummyDriveService() {}

DummyDriveService::~DummyDriveService() {}

void DummyDriveService::Initialize(Profile* profile) {}

void DummyDriveService::AddObserver(DriveServiceObserver* observer) {}

void DummyDriveService::RemoveObserver(DriveServiceObserver* observer) {}

bool DummyDriveService::CanStartOperation() const { return true; }

void DummyDriveService::CancelAll() {}

bool DummyDriveService::CancelForFilePath(const base::FilePath& file_path) {
  return true;
}

OperationProgressStatusList DummyDriveService::GetProgressStatusList() const {
  return OperationProgressStatusList();
}

bool DummyDriveService::HasAccessToken() const { return true; }

bool DummyDriveService::HasRefreshToken() const { return true; }

void DummyDriveService::ClearAccessToken() { }

void DummyDriveService::ClearRefreshToken() { }

std::string DummyDriveService::GetRootResourceId() const {
  return "dummy_root";
}

void DummyDriveService::GetAllResourceList(
    const GetResourceListCallback& callback) {}

void DummyDriveService::GetResourceListInDirectory(
    const std::string& directory_resource_id,
    const GetResourceListCallback& callback) {}

void DummyDriveService::Search(
    const std::string& search_query,
    const GetResourceListCallback& callback) {}

void DummyDriveService::SearchInDirectory(
    const std::string& search_query,
    const std::string& directory_resource_id,
    const GetResourceListCallback& callback) {}

void DummyDriveService::GetChangeList(
    int64 start_changestamp,
    const GetResourceListCallback& callback) {}

void DummyDriveService::ContinueGetResourceList(
    const GURL& override_url,
    const GetResourceListCallback& callback) {}

void DummyDriveService::GetResourceEntry(
    const std::string& resource_id,
    const GetResourceEntryCallback& callback) {}

void DummyDriveService::GetAccountMetadata(
    const GetAccountMetadataCallback& callback) {}

void DummyDriveService::GetAboutResource(
    const GetAboutResourceCallback& callback) {}

void DummyDriveService::GetAppList(const GetAppListCallback& callback) {}

void DummyDriveService::DeleteResource(const std::string& resource_id,
                                       const std::string& etag,
                                       const EntryActionCallback& callback) {}

void DummyDriveService::DownloadFile(
    const base::FilePath& virtual_path,
    const base::FilePath& local_cache_path,
    const GURL& download_url,
    const DownloadActionCallback& download_action_callback,
    const GetContentCallback& get_content_callback,
    const ProgressCallback& progress_callback) {}

void DummyDriveService::CopyHostedDocument(
    const std::string& resource_id,
    const std::string& new_name,
    const GetResourceEntryCallback& callback) {}

void DummyDriveService::RenameResource(const std::string& resource_id,
                                       const std::string& new_name,
                                       const EntryActionCallback& callback) {}

void DummyDriveService::AddResourceToDirectory(
    const std::string& parent_resource_id,
    const std::string& resource_id,
    const EntryActionCallback& callback) {}

void DummyDriveService::RemoveResourceFromDirectory(
    const std::string& parent_resource_id,
    const std::string& resource_id,
    const EntryActionCallback& callback) {}

void DummyDriveService::AddNewDirectory(
    const std::string& parent_resource_id,
    const std::string& directory_name,
    const GetResourceEntryCallback& callback) {}

void DummyDriveService::InitiateUploadNewFile(
    const base::FilePath& drive_file_path,
    const std::string& content_type,
    int64 content_length,
    const std::string& parent_resource_id,
    const std::string& title,
    const InitiateUploadCallback& callback) {}

void DummyDriveService::InitiateUploadExistingFile(
    const base::FilePath& drive_file_path,
    const std::string& content_type,
    int64 content_length,
    const std::string& resource_id,
    const std::string& etag,
    const InitiateUploadCallback& callback) {}

void DummyDriveService::ResumeUpload(
    UploadMode upload_mode,
    const base::FilePath& drive_file_path,
    const GURL& upload_url,
    int64 start_position,
    int64 end_position,
    int64 content_length,
    const std::string& content_type,
    const scoped_refptr<net::IOBuffer>& buf,
    const UploadRangeCallback& callback,
    const ProgressCallback& progress_callback) {}

void DummyDriveService::GetUploadStatus(
    UploadMode upload_mode,
    const base::FilePath& drive_file_path,
    const GURL& upload_url,
    int64 content_length,
    const UploadRangeCallback& callback) {}

void DummyDriveService::AuthorizeApp(const std::string& resource_id,
                                     const std::string& app_id,
                                     const AuthorizeAppCallback& callback) {}

}  // namespace google_apis


text:
<?php
/*
 * Describe what it does to show you're not that dumb!
 *
 **/

/** @var $ctrl \bbn\Mvc\Controller */
$ctrl->action();


text:
namespace gpu {
namespace gles2 {

class Shader;
class ShaderTranslator;

// Program cache base class for caching linked gpu programs
class GPU_EXPORT ProgramCache {
 public:
  static const size_t kHashLength = base::kSHA1Length;

  typedef std::map<std::string, GLint> LocationMap;

  enum LinkedProgramStatus {
    LINK_UNKNOWN,
    LINK_SUCCEEDED
  };

  enum ProgramLoadResult {
    PROGRAM_LOAD_FAILURE,
    PROGRAM_LOAD_SUCCESS
  };

  ProgramCache();
  virtual ~ProgramCache();

  LinkedProgramStatus GetLinkedProgramStatus(
      const std::string& untranslated_shader_a,
      const ShaderTranslatorInterface* translator_a,
      const std::string& untranslated_shader_b,
      const ShaderTranslatorInterface* translator_b,
      const LocationMap* bind_attrib_location_map) const;

  // Loads the linked program from the cache.  If the program is not found or
  // there was an error, PROGRAM_LOAD_FAILURE should be returned.
  virtual ProgramLoadResult LoadLinkedProgram(
      GLuint program,
      Shader* shader_a,
      const ShaderTranslatorInterface* translator_a,
      Shader* shader_b,
      const ShaderTranslatorInterface* translator_b,
      const LocationMap* bind_attrib_location_map,
      const ShaderCacheCallback& shader_callback) = 0;

  // Saves the program into the cache.  If successful, the implementation should
  // call LinkedProgramCacheSuccess.
  virtual void SaveLinkedProgram(
      GLuint program,
      const Shader* shader_a,
      const ShaderTranslatorInterface* translator_a,
      const Shader* shader_b,
      const ShaderTranslatorInterface* translator_b,
      const LocationMap* bind_attrib_location_map,
      const ShaderCacheCallback& shader_callback) = 0;

  virtual void LoadProgram(const std::string& program) = 0;

  // clears the cache
  void Clear();

  // Only for testing
  void LinkedProgramCacheSuccess(const std::string& shader_a,
                                 const ShaderTranslatorInterface* translator_a,
                                 const std::string& shader_b,
                                 const ShaderTranslatorInterface* translator_b,
                                 const LocationMap* bind_attrib_location_map);

 protected:
  // called by implementing class after a shader was successfully cached
  void LinkedProgramCacheSuccess(const std::string& program_hash);

  // result is not null terminated
  void ComputeShaderHash(const std::string& shader,
                         const ShaderTranslatorInterface* translator,
                         char* result) const;

  // result is not null terminated.  hashed shaders are expected to be
  // kHashLength in length
  void ComputeProgramHash(
      const char* hashed_shader_0,
      const char* hashed_shader_1,
      const LocationMap* bind_attrib_location_map,
      char* result) const;

  void Evict(const std::string& program_hash);

 private:
  typedef base::hash_map<std::string,
                         LinkedProgramStatus> LinkStatusMap;

  // called to clear the backend cache
  virtual void ClearBackend() = 0;

  LinkStatusMap link_status_;

  DISALLOW_COPY_AND_ASSIGN(ProgramCache);
};

}  // namespace gles2
}  // namespace gpu

#endif  // GPU_COMMAND_BUFFER_SERVICE_PROGRAM_CACHE_H_


text:
<md-list>
    <md-list-item ng-repeat="track in tracks" ng-click="onPlay({uri: track.uri})">

{{ track.name }}

{{ track.artists[0].name }}

    </md-list-item>
</md-list>


text:
<!doctype html>
<?php
error_reporting(E_ALL - E_WARNING);
/*
 * SimpleXml y Xpath
 */

//Obtener xhtml
$html = file_get_contents('https://twitter.com/os_arz');

//Crear un Wrapper de DomDocument
$doc = new DOMDocument();
$doc->loadHTML($html);
$sxml = simplexml_import_dom($doc);

$tweets = $sxml->xpath('//p[@class="TweetTextSize TweetTextSize--16px js-tweet-text tweet-text"]');

?>

    <title>Semana 3 - SimpleXML Parser</title>
    <meta charset="utf-8">
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" rel="stylesheet">

SimpleXml & Xpath

                <?php foreach ($tweets as $tweet): ?>

                        <?php echo $tweet; ?>

                <?php endforeach; ?>


text:
'use strict';
/* jshint -W117 */

/**
 * @ngdoc service
 * @name tagrefineryGuiApp.socketio
 * @description
 * # socket
 * Factory in the tagrefineryGuiApp.
 */
angular.module('tagrefineryGuiApp')
  .factory('fetchData', ["socket", "$q", function (socket, $q) {
    return {
      get: function (events) {
        var totalCalls = [];

        // SocketIO call function with promise
        var calls = function (callback) {
          var deferred = $q.defer();

          socket.on(callback, function (data) {
            deferred.resolve(data);
          });

          return deferred.promise;
        };

        _.forEach(events, function(d) {
          // Send data and parameter requests
          socket.emit("get"+d, "");

          // Create promises array
          totalCalls.push(calls("is"+d));
        });

        // Build initial data object
        return $q.all(totalCalls)
          .then(function (results) {
            var data = {};
            var temp = [];

            _.forEach(events, function(d, key) {
              // Removes the socket listeners
              socket.removeAllListeners("is"+d);

              // Build return object
              data[d] = results[key];
            });

            // Returns the data
            return data;
          }, function () {
            console.log("No data.");

            _.forEach(events, function(d, key) {
              // Removes the socket listeners
              socket.removeAllListeners("is"+d);
            });
          });
      }
    }
  }]);


text:
/**
 * 1. Change the default font family in all browsers (opinionated).
 * 2. Prevent adjustments of font size after orientation changes in IE and iOS.
 */
html {
  -ms-text-size-adjust: 100%;
  /* 2 */
  -webkit-text-size-adjust: 100%;
  /* 2 */ }

/**
 * Remove the margin in all browsers (opinionated).
 */
body {
  margin: 0; }

/* HTML5 display definitions
   ========================================================================== */
/**
 * Add the correct display in IE 9-.
 * 1. Add the correct display in Edge, IE, and Firefox.
 * 2. Add the correct display in IE.
 */
article,
aside,
details,
figcaption,
figure,
footer,
header,
main,
menu,
nav,
section,
summary {
  /* 1 */
  display: block; }

/**
 * Add the correct display in IE 9-.
 */
audio,
canvas,
progress,
video {
  display: inline-block; }

/**
 * Add the correct display in iOS 4-7.
 */
audio:not([controls]) {
  display: none;
  height: 0; }

/**
 * Add the correct vertical alignment in Chrome, Firefox, and Opera.
 */
progress {
  vertical-align: baseline; }

/**
 * Add the correct display in IE 10-.
 * 1. Add the correct display in IE.
 */
template,
[hidden] {
  display: none; }

/* Links
   ========================================================================== */
/**
 * 1. Remove the gray background on active links in IE 10.
 * 2. Remove gaps in links underline in iOS 8+ and Safari 8+.
 */
a {
  background-color: transparent;
  /* 1 */
  -webkit-text-decoration-skip: objects;
  /* 2 */ }

/**
 * Remove the outline on focused links when they are also active or hovered
 * in all browsers (opinionated).
 */
a:active,
a:hover {
  outline-width: 0; }

/* Text-level semantics
   ========================================================================== */
/**
 * 1. Remove the bottom border in Firefox 39-.
 * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.
 */
abbr[title] {
  border-bottom: none;
  /* 1 */
  text-decoration: underline;
  /* 2 */
  text-decoration: underline dotted;
  /* 2 */ }

/**
 * Prevent the duplicate application of `bolder` by the next rule in Safari 6.
 */
b,
strong {
  font-weight: inherit; }

/**
 * Add the correct font weight in Chrome, Edge, and Safari.
 */
b,
strong {
  font-weight: 700; }

/* Embedded content
   ========================================================================== */
/**
 * Remove the border on images inside links in IE 10-.
 */
img {
  border-style: none; }

/**
 * Hide the overflow in IE.
 */
svg:not(:root) {
  overflow: hidden; }

/* Grouping content
   ========================================================================== */
/**
 * 1. Correct the inheritance and scaling of font size in all browsers.
 * 2. Correct the odd `em` font sizing in all browsers.
 */
code,
kbd,
pre,
samp {
  font-family: monospace, monospace;
  /* 1 */
  font-size: 1em;
  /* 2 */ }

/**
 * Add the correct margin in IE 8.
 */
figure {
  margin: 1em 40px; }

/**
 * 1. Add the correct box sizing in Firefox.
 * 2. Show the overflow in Edge and IE.
 */
hr {
  box-sizing: content-box;
  /* 1 */
  height: 0;
  /* 1 */
  overflow: visible;
  /* 2 */ }

/* Forms
   ========================================================================== */
/**
 * 1. Change font properties to `inherit` in all browsers (opinionated).
 * 2. Remove the margin in Firefox and Safari.
 */
button,
input,
select,
textarea {
  margin: 0;
  /* 2 */ }

/**
 * Restore the font weight unset by the previous rule.
 */
optgroup {
  font-weight: bold; }

/**
 * Show the overflow in IE.
 * 1. Show the overflow in Edge.
 */
button,
input {
  /* 1 */
  overflow: visible; }

/**
 * Remove the inheritance of text transform in Edge, Firefox, and IE.
 * 1. Remove the inheritance of text transform in Firefox.
 */
button,
select {
  /* 1 */
  text-transform: none; }

/**
 * 1. Prevent a WebKit bug where (2) destroys native `audio` and `video`
 *    controls in Android 4.
 * 2. Correct the inability to style clickable types in iOS and Safari.
 */
button,
html [type="button"],
[type="reset"],
[type="submit"] {
  -webkit-appearance: button;
  /* 2 */ }

/**
 * Remove the inner border and padding in Firefox.
 */
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
  border-style: none;
  padding: 0; }

/**
 * Restore the focus styles unset by the previous rule.
 */
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
  outline: 1px dotted ButtonText; }

/**
 * 1. Correct the text wrapping in Edge and IE.
 * 2. Correct the color inheritance from `fieldset` elements in IE.
 * 3. Remove the padding so developers are not caught out when they zero out
 *    `fieldset` elements in all browsers.
 */
legend {
  color: inherit;
  /* 2 */
  display: table;
  /* 1 */
  max-width: 100%;
  /* 1 */
  padding: 0;
  /* 3 */
  white-space: normal;
  /* 1 */ }

fieldset {
  margin: 0;
  padding: 0;
  border: none; }

/**
 * Remove the default vertical scrollbar in IE.
 */
textarea {
  overflow: auto; }

/**
 * 1. Add the correct box sizing in IE 10-.
 * 2. Remove the padding in IE 10-.
 */
[type="checkbox"],
[type="radio"] {
  width: auto;
  display: inline-block;
  vertical-align: middle;
  padding: 0;
  /* 2 */
  box-sizing: border-box;
  /* 1 */ }

/**
 * Correct the cursor style of increment and decrement buttons in Chrome.
 */
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
  height: auto; }

/**
 * 1. Correct the odd appearance in Chrome and Safari.
 * 2. Correct the outline style in Safari.
 */
[type="search"] {
  -webkit-appearance: textfield;
  /* 1 */
  outline-offset: -2px;
  /* 2 */ }

/**
 * Remove the inner padding and cancel buttons in Chrome and Safari on OS X.
 */
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
  -webkit-appearance: none; }

/**
 * Correct the text style of placeholders in Chrome, Edge, and Safari.
 */
::-webkit-input-placeholder {
  color: inherit; }

/**
 * 1. Correct the inability to style clickable types in iOS and Safari.
 * 2. Change font properties to `inherit` in Safari.
 */
::-webkit-file-upload-button {
  -webkit-appearance: button;
  /* 1 */
  font: inherit;
  /* 2 */ }

.u-align-left {
  text-align: left; }

.u-align-center {
  text-align: center; }

.u-align-right {
  text-align: right; }

.u-clearfix:before, .u-clearfix:after {
  content: " ";
  display: table; }

.u-clearfix:after {
  clear: both; }

.u-pull-left {
  float: left; }

.u-pull-right {
  float: right; }

a, .github-search, .github-submit {
  -webkit-transition: all 0.08s ease-in-out;
  transition: all 0.08s ease-in-out; }

a {
  color: #3c3c3c;
  outline: none;
  text-decoration: none; }
  a:hover {
    color: #4078c0;
    outline: none; }

strong {
  font-weight: 700; }

p {
  margin: 0; }

ul,
ol {
  margin: 0;
  padding: 0; }

li {
  list-style: none; }

button {
  outline: none; }

.pagination-button {
  padding: 7px 12px;
  margin-left: -1px;
  font-size: 13px;
  font-style: normal;
  font-weight: 600;
  color: #4078c0;
  cursor: pointer;
  white-space: nowrap;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  background: #fff;
  border: 1px solid #e5e5e5; }
  .pagination-button:first-child {
    margin-left: 0;
    border-bottom-left-radius: 3px;
    border-top-left-radius: 3px; }
  .pagination-button:last-child {
    border-bottom-right-radius: 3px;
    border-top-right-radius: 3px; }
  .pagination-button:hover {
    background-color: #e7e7e7;
    border-color: #e5e5e5; }
  .pagination-button:disabled, .pagination-button:disabled:hover {
    color: #d3d3d3;
    cursor: default;
    background-color: #fafafa; }
  @media only screen and (max-width: 740px) {
    .pagination-button {
      margin-top: 20px; } }

* {
  box-sizing: border-box; }
  *:before, *:after {
    box-sizing: border-box; }

body {
  position: relative;
  color: #3c3c3c;
  font-size: 16px;
  line-height: 24px;
  font-weight: 400;
  font-family: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol"', sans-serif;
  overflow-x: hidden;
  background-color: white;
  -webkit-font-smoothing: antialiased;
  -webkit-overflow-scrolling: touch; }

[ng\:cloak],
[ng-cloak],
[data-ng-cloak],
[x-ng-cloak],
.ng-cloak,
.x-ng-cloak {
  display: none; }

.github-wrapper {
  position: relative;
  margin: 60px auto 80px;
  max-width: 740px; }
  @media only screen and (max-width: 740px) {
    .github-wrapper {
      padding: 0 20px; } }

.github-header {
  text-align: center; }

.github-logo {
  color: #232323;
  width: 64px;
  height: 64px; }

.github-loading {
  display: inline-block; }

.github-form,
.github-repo-list-header,
.github-repo-stats {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: justify;
      -ms-flex-pack: justify;
          justify-content: space-between; }

.github-form {
  margin: 40px 0 0; }

.github-search {
  -webkit-box-flex: 1;
      -ms-flex: 1;
          flex: 1;
  margin: 0 4px 0 0;
  padding: 12px;
  font-size: 18px;
  color: #2d2d2d;
  background-color: white;
  border-radius: 3px;
  font-weight: 700;
  border: 1px solid #c2c2c2; }
  .github-search:focus {
    border-color: #4078c0;
    outline: none; }
  .github-search::-webkit-input-placeholder {
    color: #c2c2c2;
    font-weight: 400; }
  .github-search:-moz-placeholder {
    color: #c2c2c2;
    font-weight: 400; }
  .github-search::-moz-placeholder {
    color: #c2c2c2;
    font-weight: 400; }
  .github-search:-ms-input-placeholder {
    color: #c2c2c2;
    font-weight: 400; }

.github-submit {
  padding: 12px;
  font-weight: 700;
  font-size: 16px;
  cursor: pointer;
  color: #fff;
  text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.15);
  border-radius: 3px;
  border: 1px solid #5ca941;
  -webkit-user-select: none;
     -moz-user-select: none;
      -ms-user-select: none;
          user-select: none;
  background-image: -webkit-linear-gradient(#8add6d, #60b044);
  background-image: linear-gradient(#8add6d, #60b044);
  -webkit-appearance: none;
     -moz-appearance: none;
          appearance: none; }
  .github-submit:hover, .github-submit:focus {
    border-color: #4a993e;
    background-image: -webkit-linear-gradient(#79d858, #569e3d);
    background-image: linear-gradient(#79d858, #569e3d); }

.github-validation {
  margin-top: 10px;
  color: #8C1B1B; }

@media only screen and (max-width: 740px) {
  .github-repo-list-header {
    display: block;
    text-align: center; } }

.github-repo-list {
  margin-top: 50px; }
  .github-repo-list.loading {
    opacity: .4; }

.github-repo-title {
  margin: 0; }

.github-repo-item {
  margin: 60px 0; }

.github-repo-header {
  display: -webkit-box;
  display: -ms-flexbox;
  display: flex;
  -webkit-box-pack: justify;
      -ms-flex-pack: justify;
          justify-content: space-between;
  margin-bottom: 16px; }

.github-repo-name {
  margin: 0; }
  .github-repo-name a {
    color: #4078c0;
    font-size: 20px;
    padding-bottom: 1px;
    border-bottom: 2px solid transparent; }
    .github-repo-name a:hover {
      color: #2b5283;
      border-color: #2b5283; }

.github-repo-stat-item {
  display: inline-block;
  vertical-align: top;
  margin-left: 16px; }
  .github-repo-stat-item svg {
    display: inline-block;
    vertical-align: top; }

.github-repo-stats-star {
  width: 18px;
  height: 20px; }

.github-repo-stats-fork {
  width: 12px;
  height: 18px; }

.github-repo-update {
  font-size: 14px;
  color: #565656; }
/*# sourceMappingURL=app.css.map */


text:
void RunPoD(
  TString dataset = "Data;Period=LHC11h_2;Run=170593;Variant=ESD;Pass=pass2",
  Bool_t usePhysicsSelection = kTRUE,
  Int_t numEvents = 999999999,
  Int_t firstEvent = 0
) {

  // Not needed on the VAF
  //gEnv->SetValue("XSec.GSI.DelegProxy","2");

  TString alirootMode = "ALIROOT";
  TString extraLibs = "ANALYSIS:ANALYSISalice"; // extraLibs = "ANALYSIS:OADB:ANALYSISalice:CORRFW:OADB:PWGmuon";

  TList *list = new TList();
  list->Add(new TNamed("ALIROOT_MODE", alirootMode.Data()));
  list->Add(new TNamed("ALIROOT_EXTRA_LIBS", extraLibs.Data()));
  list->Add(new TNamed("ALIROOT_ENABLE_ALIEN", "1"));  // important: creates token on every PROOF worker

  // Not needed on the VAF
  //TProof::Mgr("alice-caf.cern.ch")->SetROOTVersion("VO_ALICE@ROOT::v5-34-08");

  // Note the difference between CAF and VAF
  //TProof::Open("alice-caf.cern.ch");
  TProof::Open("pod://");

  // Check the dataset before running the analysis!
  gProof->ShowDataSet( dataset.Data() );
  //return;
  gProof->SetParameter("PROOF_UseMergers", (Int_t)0);
  // Not needed on the VAF
  //gProof->EnablePackage("VO_ALICE@AliRoot::v5-04-81-AN", list);

  // A single AliRoot package for *all* AliRoot versions: new on VAF
  TFile::Cp("http://personalpages.to.infn.it/~berzano/cloud/extras/AliRoot.par", "AliRoot.par");
  gProof->UploadPackage("AliRoot.par");
  gProof->EnablePackage("AliRoot.par", list);  // this "list" is the same as always

  AliAnalysisManager *mgr  = new AliAnalysisManager("Analysis Train");

  AliESDInputHandler *esdH = new AliESDInputHandler();
  mgr->SetInputEventHandler(esdH);

  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");
  AliPhysicsSelectionTask *physSel = AddTaskPhysicsSelection(kFALSE);
  // Centrality selection
  gROOT->LoadMacro("$ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
  AliCentralitySelectionTask *taskCentr = AddTaskCentrality();

  gProof->Load("AliAnalysisTaskFlowd.cxx+");  // DON'T use double '+' when running multiple times: it uselessly recompiles everything!
  gROOT->LoadMacro("AddTaskFlowd.C");
  AliAnalysisTaskFlowd *flowTask = AddTaskFlowd();
  //if (usePhysicsSelection) {
  //flowTask->SelectCollisionCandidates(AliVEvent::kAny);
    //}

  if (!mgr->InitAnalysis()) return;

  mgr->StartAnalysis("proof", dataset, numEvents, firstEvent);

}


text:
require File.join( File.dirname(__FILE__), "..", "spec_helper" )

include RepertoireCore

describe Role do

  before(:each) do
    User.auto_migrate!
    Membership.auto_migrate!
    Role.auto_migrate!
  end

  describe "declarations" do

    it "should create new roles when given with a title" do
      Role.declare do
        Role[:admin, "The system administrator"]
      end
      Role.all.size.should == 1
    end

    it "should allow access to roles outside declarations" do
      Role.declare do
        Role[:admin]
      end
      Role[:admin].should == Role.first(:name => 'admin')
    end

    it "should disallow creating roles outside declarations" do
      lambda { Role[:admin] }.should raise_error
    end

    it "should create new roles as they are mentioned subsequently" do
      Role.declare do
        Role[:admin].implies(:member)
      end
      Role.all.size.should == 2
    end

    it "should chain the state of roles as they are declared" do
      Role.declare do
        Role[:admin].implies(:manager).implies(:member)
      end
      Role[:admin].parent.should be_nil
      Role[:manager].parent.should == Role[:admin]
      Role[:member].parent.should == Role[:manager]
    end

    it "should set parentage according to grants by default" do
      Role.declare do
        Role[:admin].grants(:manager).grants(:member)
      end

      Role[:admin].granted_by.should   be_nil
      Role[:manager].granted_by.should == Role[:admin]
      Role[:member].granted_by.should  == Role[:manager]

      Role[:admin].parent.should   be_nil
      Role[:manager].parent.should == Role[:admin]
      Role[:member].parent.should  == Role[:manager]
    end

    it "should allow grants to differ from parents" do
      Role.declare do
        Role[:admin].implies(:manager).implies(:member)
        Role[:admin].grants(:manager, :member)
      end

      Role[:admin].parent.should   be_nil
      Role[:manager].parent.should == Role[:admin]
      Role[:member].parent.should  == Role[:manager]

      Role[:manager].granted_by.should == Role[:admin]
      Role[:member].granted_by.should  == Role[:admin]
    end

    it "should allow grant to default a parent only if role declared in this block" do
      Role.declare do
        Role[:admin, "The admin"]
        Role[:manager, "The manager"]                   # should still have undefined parent
        Role[:admin].grants(:manager)
      end

      Role[:admin].granted_by.should   be_nil
      Role[:manager].granted_by.should == Role[:admin]

      Role[:admin].parent.should   be_nil
      Role[:manager].parent.should == Role[:admin]
    end

    it "should permit opening and closing role" do
      Role.declare do
        Role[:admin].grants(:manager).open
        Role[:guest].open
      end

      Role[:admin].should       be_closed_membership
      Role[:manager].should_not be_closed_membership
      Role[:manager].should_not be_open_membership
      Role[:guest].should       be_open_membership
    end

  end

  describe "membership checking logic" do

    before(:each) do
      Role.declare do
        Role[:admin].grants(:manager).grants(:member).grants(:guest)
      end

      @suzy, @nick = (1..2).map { User.create(valid_user_hash) }
      Role.grant!(:admin, @nick)
      Role.grant!(:member, @suzy)
    end

    it "should complain when accessing a non-existent role outside a declaration" do
      lambda { Role[:foobar] }.should raise_error
    end

    it "should allow users to easily check if they match a certain role" do
      @nick.has_role?(:admin).should be_true
    end

    it "should implement hierarchical roles" do
      Role[:admin].implies?(:member).should be_true
      Role[:member].implies?(:admin).should be_false
    end

    it "should allow role checking to use either symbol or object" do
      @nick.has_role?(:admin).should == @nick.has_role?(Role[:admin])
    end

    it "should treat users with nesting roles hierarchically" do
      @nick.has_role?(:admin).should  be_true
      @nick.has_role?(:member).should be_true

      @suzy.has_role?(:admin).should  be_false
      @suzy.has_role?(:member).should be_true
    end

    it "should provide complete lists of all a user's roles" do
      @nick.expanded_roles.size.should == 4
      (@nick.expanded_roles - [ Role[:admin], Role[:manager], Role[:member], Role[:guest] ]).should be_empty

      @suzy.expanded_roles.size.should == 2
      (@suzy.expanded_roles - [ Role[:member], Role[:guest] ]).should be_empty
    end

  end

  describe "granting logic" do

    it "should automatically grant memberships issued by super-user" do
      Role.declare do
        Role[:admin]
      end

      nicholas = User.create(valid_user_hash)
      Role.grant!(:admin, nicholas)
      nicholas.has_role?(:admin).should be_true
    end

    it "should allow roles to access granted_by directly" do
      Role.declare do
        Role[:secretary].grants(:janitor)
      end

      Role[:janitor].granted_by.should == Role[:secretary]
    end

    it "should require all user level grants be authorized" do
      Role.declare do
        Role[:admin].grants(:lackey)
      end
      nicholas = User.create(valid_user_hash)
      Role.grant!(:lackey, nicholas)

      # nicholas attempts to grant himself a closed role
      lambda { nicholas.grant(:admin, nicholas) }.should raise_error
    end

    it "should allow users specified in a role's granted_by relation to grant it without review" do
      Role.declare do
        Role[:secretary].grants(:janitor)
      end
      jack, tim, joe = (1..3).map { User.create(valid_user_hash) }
      Role.grant!(:secretary, jack)

      # secretaries can appoint janitors, so no error
      jack.grant(:janitor, tim)
      tim.has_role?(:janitor).should be_true

      # having a role doesn't mean you can also grant it:  janitors can't appoint other janitors
      lambda { tim.grant(:janitor, joe) }.should raise_error
    end

    it "should allow users with access to a granting role by implication to grant it" do
      Role.declare do
        Role[:president].implies(:secretary).implies(:janitor)
        Role[:secretary].grants(:janitor)
      end
      nick, jack = (1..2).map { User.create(valid_user_hash) }
      Role.grant!(:president, nick)

      # grant role by proxy: president can act as secretary, and secretary can grant janitor
      nick.grant(:janitor, jack)
      jack.has_role?(:janitor).should be_true
    end

    it "failed grants should leave no record in the memberships table" do
      Role.declare do
        Role[:president].implies(:janitor)
      end
      nick, jack = (1..2).map { User.create(valid_user_hash) }
      Role.grant!(:janitor, nick)

      lambda { nick.grant(:president, jack) }.should raise_error
      Membership.all.size.should == 1
    end

    it "should return the relevant membership on grants, subscriptions and reviews" do
      Role.declare do
        Role[:president].grants(:secretary)
        Role[:secretary].grants(:janitor)
      end
      nick, jack, suzy = (1..3).map { User.create(valid_user_hash) }

      Role.grant!(:president, nick).should be_approved
      nick.grant(:secretary, jack).should be_approved
      (request = suzy.subscribe(:janitor)).should_not be_reviewed
      jack.review(request, true).should be_approved
    end

    it "should grant automatically if the subscribing user could grant the role" do
      Role.declare do
        Role[:president].grants(:secretary).grants(:janitor).open
      end
      nick, jack = (1..2).map { User.create(valid_user_hash) }

      Role.grant!(:president, nick).should be_approved
      nick.subscribe(:janitor).should be_approved

      jack.subscribe(:janitor).should_not be_reviewed
    end

    it "should use an existing pending or approved request if the user attempts to re-grant" do
      Role.declare do
        Role[:kiwanis].grants(:toastmasters).open
      end
      @john, @tim, @suzy, @bill, @ted = (1..5).map { User.create(valid_user_hash) }
      Role.grant!(:kiwanis, @john)

      # check granting with a pending review available (actually same as review)
      req = @tim.subscribe(:toastmasters)
      @john.grant(:toastmasters, @tim).should == req

      req = @bill.subscribe(:toastmasters)
      Role.grant!(:toastmasters, @bill).should == req

      # check granting an already approved role
      req = Role.grant!(:toastmasters, @suzy)
      @john.grant(:toastmasters, @suzy).should == req

      req = Role.grant!(:toastmasters, @ted)
      Role.grant!(:toastmasters, @ted).should == req
    end
  end

  describe "granting inference rules" do

    before(:each) do
      Role.declare do
        Role[:admin].grants(:gaffer, :lackey)
        Role[:lackey].grants(:chav)
      end

      @tim, @john = (1..2).map { User.create(valid_user_hash) }
      Role.grant!(:admin,  @tim)
      Role.grant!(:lackey, @john)
    end

    it "should accurately list direct grantable roles" do
      (@tim.grantable_roles  - [Role[:lackey], Role[:gaffer]]).should be_empty
      (@john.grantable_roles - [ Role[:chav] ]).should                be_empty
    end

    it "should detect directly grantable roles" do
      @tim.can_grant?(:lackey, :gaffer).should be_true
      @john.can_grant?(:chav).should           be_true
    end

    it "should detect roles grantable through a role the user holds" do
      @tim.can_grant?(:chav).should be_true
    end

    it "shouln't allow users to grant roles other than these" do
      @john.can_grant?(:lackey).should be_false
      @john.can_grant?(:gaffer).should be_false
      @john.can_grant?(:admin).should be_false
      @tim.can_grant?(:admin).should be_false
    end
  end

  describe "subscription logic" do

    it "subscriptions to roles with open membership approve automatically" do
      Role.declare do
        Role[:toastmasters].open
      end
      nick = User.create(valid_user_hash)
      nick.subscribe(:toastmasters)

      # membership for open roles succeeds immediately
      nick.has_role?(:toastmasters).should be_true
    end

    it "should return an existing pending or approved request if the user attempts to re-subscribe" do
      Role.declare do
        Role[:kiwanis].grants(:toastmasters).open
      end
      @john, @tim = (1..2).map { User.create(valid_user_hash) }
      Role.grant!(:kiwanis, @john)

      # check subscribing twice in a row without intervening review
      req = @tim.subscribe(:toastmasters)
      @tim.subscribe(:toastmasters).should == req

      # check subscribing to an approved role
      @john.review(req, true)
      req.reload
      @tim.subscribe(:toastmasters).should == req
    end

  end

  describe "review process" do

    before :each do
      Role.declare do
        Role[:yacht_club_secretary].grants(:yacht_club_member)
      end
      @suzy, @nick = (1..2).map { User.create(valid_user_hash) }
      Role.grant!(:yacht_club_secretary, @suzy)
    end

    it "review process should allow users to subscribe for roles; membership requests are reviewed later" do
      yacht_club_request = @nick.subscribe(:yacht_club_member)
      @nick.has_role?(:yacht_club_member).should be_false

      # at a later date suzy reviews nick's membership request
      @suzy.review(yacht_club_request, true, "Paid his $10000 annual fee")
      @nick.has_role?(:yacht_club_member).should be_true
    end

    it "unapproved or denied role memberships should not be available to users" do
      yacht_club_request = @nick.subscribe(:yacht_club_member)
      @nick.has_role?(:yacht_club_member).should be_false

      # at a later date suzy denies nick's membership request
      @suzy.review(yacht_club_request, false, "Killed the watchdog last night")
      @nick.has_role?(:yacht_club_member).should be_false
    end

  end

end


text:
=head1 LICENSE
# Copyright [1999-2015] Wellcome Trust Sanger Institute and the EMBL-European Bioinformatics Institute
# Copyright [2016-2018] EMBL-European Bioinformatics Institute
#
# 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.

=head1 CONTACT

  Please email comments or questions to the public Ensembl
  developers list at <http://lists.ensembl.org/mailman/listinfo/dev>.

  Questions may also be sent to the Ensembl help desk at
  <http://www.ensembl.org/Help/Contact>.

=cut

=head1 NAME

Bio::EnsEMBL::Analysis::RunnableDB::MissingOrthologues -

=head1 SYNOPSIS

my $orthologueanalysis = Bio::EnsEMBL::Analysis::RunnableDB::MissingOrthologues->new(
			      -analysis   => $analysis_obj,
			     );

$orthologueanalysis->fetch_input();
$orthologueanalysis->run();
$orthologueanalysis->output();
$orthologueanalysis->write_output();

=head1 DESCRIPTION

This object wraps Bio::EnsEMBL::Analysis::Runnable::OrthologueEvaluator and is
use warnings ;
used to fetch the input from different databases as well as writing results
the results to the database.a

=head1 METHODS

=head1 APPENDIX

The rest of the documentation details each of the object methods.
Internal methods are usually preceded with a '_'

=cut

package Bio::EnsEMBL::Analysis::RunnableDB::MissingOrthologues;
use strict;
use Bio::SeqIO;
use Bio::EnsEMBL::Utils::Exception qw(throw warning);
use Bio::EnsEMBL::Analysis::RunnableDB;
use Bio::EnsEMBL::Gene;

use Bio::EnsEMBL::Analysis::Config::GeneBuild::OrthologueEvaluator;
use Bio::EnsEMBL::Analysis::Config::Exonerate2Genes;
use Bio::EnsEMBL::Analysis::Tools::GeneBuildUtils::GeneUtils qw (
                                                                 get_one2one_orth_for_gene_in_other_species
                                                                 get_transcript_with_longest_CDS
                                                                 ) ;

use Bio::EnsEMBL::Analysis::Tools::GeneBuildUtils::TranslationUtils qw (contains_internal_stops);
use Bio::EnsEMBL::Analysis::Tools::Utilities qw (shuffle ) ;
use Bio::EnsEMBL::Registry;
use vars qw(@ISA);
use Bio::EnsEMBL::Analysis::RunnableDB::OrthologueEvaluator;

@ISA = qw ( Bio::EnsEMBL::Analysis::RunnableDB::OrthologueEvaluator ) ;

sub new {
  my ($class,@args) = @_;
  my $self = $class->SUPER::new(@args);
  $self->read_and_check_config ;
  $self->verbose(1) ;

  my $trusted_one2one_set= $$FIND_MISSING_ORTHOLOGUES{ANALYSIS_SETS}{$self->post_logic_name};

  print "Searching for 1:1 orthoologues between $$trusted_one2one_set[0] and $$trusted_one2one_set[1]\n" ;

  $self->species_1($$trusted_one2one_set[0]) ;
  $self->species_2($$trusted_one2one_set[1]) ;

  return $self;
}

# first analysis runs module MissingOrthologues and identifies possible targets, dumps them and
# creates input_ids , than exonerate2genes wrapper runs with logich_name in Exoner2Genes config ....
# --> do the logic_names in both configs need to be the same ? ??

# fetches the genes which have homologues in different species

sub fetch_input {
  my( $self ) = @_;

  # get all genes on slice for 1st species in array (species 1)
  $self->get_initial_geneset($self->species_1, $$FIND_MISSING_ORTHOLOGUES{DEFAULT_GENE_BIOTYPES}) ;
}

sub run {
  my ($self) = @_;

  my $query_spec = $$MAIN_CONFIG{QUERY_SPECIES};
  my (%missing_orth,%trusted_orth);

  QUERY_GENES : for my $gene_spec1 (@{$self->genes} ) {
     #print " processing gene " . $gene_spec1->stable_id . "\n" ;
     my $tg1_homol = get_one2one_orth_for_gene_in_other_species($gene_spec1 ,$self->species_2) ;

     if ( $tg1_homol ) {
       $trusted_orth{$gene_spec1->stable_id}=1;
       foreach my $homolog_to_check  ( @{ $gene_spec1->get_all_homologous_Genes()} ) {
         my ($check_homg, $check_homology, $check_species ) = @$homolog_to_check ;
           if  ($check_species eq $query_spec ) {
             #print "orth. between $query_spec and $$trusted_one2one_set[0] known\n" ;
             next QUERY_GENES  ;
           }else {
            $missing_orth{$gene_spec1->stable_id} =  $gene_spec1 ;
           }
         }
      } else {
        #print " - no 1:1 homologue found for " . $self->species_2 . "\n" ;
      }
  }

  for ( keys %missing_orth) {
    print "missing_orthologue: $_\n";
  }

  print scalar( keys %missing_orth)." missing orthologues identifed beteen " . $self->species_1 .
        " and $query_spec ( using " . $self->species_2 ." as informant )\n";

   # dump sequences of identified missing orthologues

   my @input_id_file_names ;

   my @longest_transcripts;
   for my $stable_id ( keys %missing_orth ) {
     # check for stop codon
     my ($ltr, $m,$n) = get_transcript_with_longest_CDS($missing_orth{$stable_id}) ;
     unless (contains_internal_stops($ltr)){
       push @longest_transcripts, $ltr;
     } else {
       print "Skipping transcript because it contains internal stops\n" ;
     }
   }
   my @cds ;
   for my $tr ( @longest_transcripts ) {
     my $cds = $tr->translate;
     $cds->display_id($tr->translation->stable_id ) ;
     push @cds, $cds ;
   }
   $self->output(shuffle(\@cds))   ;
}

sub write_output{
  my ($self) = @_;
  my $written_files = $self->chunk_and_write_fasta_sequences( $self->output) ;
  if ( $written_files ) {
    print scalar(@$written_files) . " fasta-files written for " . $self->species_1."\n" ;
    $self->upload_input_ids( $written_files );
    print STDERR "input_ids uploaded\n" ;
  } else {
    print STDERR "NO input_ids uploaded\n" ;
 }
}

sub check_transcript {
      my $tr = shift ;
      my $transstr = $tr->translate->seq;
      $transstr =~ s/(.{1,60})/$1\n/g;
      #print ">$sid\n$transstr\n\n" ;
      if ($transstr =~m/\*/ ) {
        print "SKIPPING " . $tr->translation->stable_id .
        " : translation contain stop codon\n$transstr\n\n";
        return undef ;
      }
  return $tr ;
}

sub filter_homologies {
  my ( $all_homologies , $look_for_this_species) = @_ ;
  my @result ;

  HOMOLOGIES :for my $homology ( @$all_homologies ) {
     my @all_members = @{$homology->get_all_Members} ;
     # first object is source itself so don't process this
     shift @all_members ;

     MA: foreach my $new_member (@all_members) {
       my $species_name_of_orthologue = $new_member->genome_db->name ;
       if ( $species_name_of_orthologue =~m/$look_for_this_species/) {
         push @result, $homology ;
       }
     }
  }
  return \@result ;
}

sub read_and_check_config {
  (my $self) = @_ ;

  $self->SUPER::read_and_check_config();

  # - registry file is checked by OrthologueEvaluator
  # - compara init file and schema-versions checked by OrtholgoueAnalysis

  # check config for MissingOrthologues
   my %config_hash = %{$FIND_MISSING_ORTHOLOGUES};
}

# methods which need to go into Utils :

sub get_longest_transcripts{
  my ($ga, $stable_ids) = @_ ;
  my @cds ;

  GENES : for my $sid (@$stable_ids ) {
    my $gene = $ga->fetch_by_stable_id ($sid) ;
    my $maxlen = 0;
    my $nexonmax = 0;
    my $longest_transcript;

    foreach my $trans (@{$gene->get_all_Transcripts}) {
      my $len = 0;
      if ($trans->translation) {
        my @trans_exons = @{$trans->get_all_translateable_Exons()};
        foreach my $exon (@trans_exons) {
          $len+= $exon->length;
        }
        if ($len > $maxlen) {
          $maxlen = $len;
          $longest_transcript = $trans;
          $nexonmax = scalar($trans->get_all_Exons)
        }
      }
    }

    if (!defined($longest_transcript)) {
      print "No longest_transcript  transcript found for " . $gene->stable_id . "\n" ;
      next GENES ;
    }
    my $transstr = $longest_transcript->translate->seq;
    $transstr =~ s/(.{1,60})/$1\n/g;
    #print ">$sid\n$transstr\n\n" ;
    if ($transstr =~m/\*/ ) {
      print "SKIPPING " . $longest_transcript->translation->stable_id .
        " : translation contain stop codon\n$transstr\n\n";
      next GENES ;
    }
    my $cds = $longest_transcript->translate ;
    $cds->display_id( $longest_transcript->translation->stable_id)  ;
    push @cds, $cds ;
  }
  my @rand_cds ;
  # randomize
  return shuffle(\@cds) ;
}

1;


text: "C:\Program Files\MongoDB\Server\3.2\bin\mongod.exe" --dbpath "%~dp0data"


text:
module Awsborn
  class Server
    include Awsborn::AwsConstants

    def initialize (name, options = {})
      @name = name
      @options = options.dup
      self.host_name = elastic_ip
    end

    class << self
      attr_accessor :logger

      def get_class_attr(class_attr)
        if (class_var = instance_variable_get("@#{class_attr}"))
          class_var
        elsif self != ::Awsborn::Server
          superclass.send(class_attr)
        else
          nil
        end
      end

      # Set image_id.  Examples:
      #   image_id 'ami-123123'
      #   image_id 'ami-123123', :sudo_user => 'ubuntu'
      #   image_id :i386 => 'ami-323232', :x64 => 'ami-646464', :sudo_user => 'ubuntu'
      def image_id (*args)
        unless args.empty?
          @image_id = args.first
          @sudo_user = args.last[:sudo_user] if args.last.is_a?(Hash)
        end
        get_class_attr(:image_id)
      end
      def instance_type (*args)
        @instance_type = args.first unless args.empty?
        get_class_attr(:instance_type)
      end
      def security_group (*args)
        @security_group = args unless args.empty?
        get_class_attr(:security_group)
      end
      def individual_security_group (*args)
        @individual_security_group = args.first unless args.empty?
        get_class_attr(:individual_security_group)
      end
      def keys (*args)
        @keys = args unless args.empty?
        get_class_attr(:keys)
      end
      def sudo_user (*args)
        @sudo_user = args.first unless args.empty?
        get_class_attr(:sudo_user)
      end
      def bootstrap_script (*args)
        @bootstrap_script = args.first unless args.empty?
        get_class_attr(:bootstrap_script)
      end
      def monitor (*args)
        @monitor = args.first unless args.empty?
        get_class_attr(:monitor)
      end

      def cluster (name = ServerCluster.next_name, &block)
        ServerCluster.build(self, name, &block)
      end
      def logger
        @logger ||= Awsborn.logger
      end
    end

    def find_instance_id_by_name
      instances = ec2.connection.describe_instances(
        :filters => {'tag:Name' => full_name,
                     'instance-state-name' => ['pending', 'running']}
      )
      if instances.count > 1
        raise ServerError, "Found multiple instances with full_name = #{full_name}."
      end
      instances.empty? ? nil : instances.first[:aws_instance_id]
    end

    def find_instance_id_by_volume
      map = {}
      disk_volume_ids.each { |vol_id| map[vol_id] = ec2.instance_id_for_volume(vol_id) }
      ids = map.values.uniq
      if ids.size > 1
        raise ServerError, "Volumes for #{self.class.name}:#{name} are connected to several instances: #{map.inspect}"
      end
      ids.first
    end

    def running?
      name_id = find_instance_id_by_name
      volume_id = find_instance_id_by_volume

      if name_id && volume_id && name_id != volume_id
        raise ServerError, "Volumes #{disk_volume_ids} are attached to #{volume_id}, not to instance #{name_id} with name #{full_name}"
      else
        ec2.instance_id = name_id || volume_id
      end
    end

    def refresh
      start_or_stop_monitoring unless monitor.nil?
      associate_address if elastic_ip

      begin
        update_known_hosts
        install_ssh_keys if keys
      rescue SecurityError => e
        logger.warn "Could not update known_hosts for #{name}:"
        logger.warn e
      end
    end

    def start_or_stop_monitoring
      if monitor && ! ec2.monitoring?
        ec2.monitor
      elsif ec2.monitoring? && ! monitor
        ec2.unmonitor
      end
    end

    def start (key_pair)
      launch_instance(key_pair)

      update_known_hosts
      install_ssh_keys(key_pair) if keys

      if elastic_ip
        associate_address
        update_known_hosts
      end

      bootstrap if bootstrap_script
      attach_volumes
    end

    def launch_instance (key_pair)
      @launch_response = ec2.launch_instance(image_id,
        :instance_type => symbol_to_aws_instance_type(instance_type),
        :availability_zone => symbol_to_aws_zone(zone),
        :key_name => key_pair.name,
        :group_ids => security_group,
        :monitoring_enabled => monitor,
        :user_data => user_data
      )
      logger.debug @launch_response

      ec2.set_instance_name full_name

      Awsborn.wait_for("instance #{instance_id} (#{name}) to start", 10) { instance_running? }
      self.host_name = aws_dns_name
    end

    def update_known_hosts
      KnownHostsUpdater.update_for_server self
    end

    def install_ssh_keys (temp_key_pair = nil)
      logger.debug "Installing ssh keys on #{name}"
      raise ArgumentError, "No host_name for #{name}" unless host_name
      install_ssh_keys_for_sudo_user_or_root(temp_key_pair)
      copy_sudo_users_keys_to_root if sudo_user
    end

    def install_ssh_keys_for_sudo_user_or_root (temp_key_pair)
      current_key = "-i #{temp_key_pair.path}" if temp_key_pair
      IO.popen("ssh #{current_key} #{sudo_user || 'root'}@#{host_name} 'cat > .ssh/authorized_keys'", "w") do |pipe|
        pipe.puts key_data
      end
    end

    def key_data
      Dir[*keys].inject([]) do |memo, file_name|
        memo + File.readlines(file_name).map { |line| line.chomp }
      end.join("\n")
    end

    def copy_sudo_users_keys_to_root
      system("ssh #{sudo_user}@#{host_name} 'sudo cp .ssh/authorized_keys /root/.ssh/authorized_keys'")
    end

    def associate_address
      logger.debug "Associating address #{elastic_ip} to #{name}"
      ec2.associate_address(elastic_ip)
      self.host_name = elastic_ip
    end

    def bootstrap
      logger.debug "Bootstrapping #{name}"
      script = bootstrap_script
      basename = File.basename(script)
      system "scp #{script} root@#{host_name}:/tmp"
      system "ssh root@#{host_name} 'cd /tmp && chmod 700 #{basename} && ./#{basename}'"
    end

    def attach_volumes
      logger.debug "Attaching volumes #{disk.values.join(', ')} to #{name}" unless disk.empty?
      disk.each_pair do |device, str_or_ary|
        volume = str_or_ary.is_a?(Array) ? str_or_ary.first : str_or_ary
        device = "/dev/#{device}" if device.is_a?(Symbol) || ! device.match('/')
        res = ec2.attach_volume(volume, device)
      end
    end

    def cook
      raise "#{host_name} not running" unless running?
      upload_cookbooks
      run_chef
    end

    def upload_cookbooks
      logger.info "Uploading cookbooks to #{host_name}"

      cookbooks_dir = '../cookbooks' # Hard coded for now
      temp_link = File.directory?(cookbooks_dir) && ! File.directory?('cookbooks')
      File.symlink(cookbooks_dir, 'cookbooks') if temp_link

      File.open("config/dna.json", "w") { |f| f.write(chef_dna.to_json) }
      system "rsync -rL --chmod=o-rw -p --delete --exclude '.*' ./ root@#{host_name}:#{Awsborn.remote_chef_path}"
    ensure
      FileUtils.rm_f("config/dna.json")
      File.delete("cookbooks") if temp_link
    end

    def run_chef
      logger.info "Running chef on #{host_name}"
      # Absolute path to config files to avoid a nasty irrational bug.
      sh "ssh root@#{host_name} \"cd #{Awsborn.remote_chef_path}; chef-solo -l #{Awsborn.chef_log_level} -c #{Awsborn.remote_chef_path}/config/solo.rb -j #{Awsborn.remote_chef_path}/config/dna.json\""
    end

    def ec2
      @ec2 ||= Ec2.new(zone)
    end

    begin :accessors
      attr_accessor :name, :logger
      def host_name= (string)
        logger.debug "Setting host_name of #{name} to #{string.inspect}"
        @host_name = string
      end
      def host_name
        unless @host_name
          logger.debug 'Looking up DNS name from volume ID'
          self.host_name = aws_dns_name
          logger.debug "got DNS name #{@host_name}"
        end
        @host_name
      end
      def zone
        @options[:zone]
      end
      def disk
        @options[:disk] || {}
      end
      def disk_volume_ids
        disk.values.map { |str_or_ary| str_or_ary.is_a?(Array) ? str_or_ary.first : str_or_ary }
      end
      def format_disk_on_device? (device)
        volume = disk[device.to_sym]
        volume.is_a?(Array) && volume.last == :format
      end
      def image_id
        return @options[:image_id] if @options[:image_id]
        tmp = self.class.image_id
        tmp.is_a?(String) ? tmp : tmp[architecture]
      end
      def architecture
        string = symbol_to_aws_instance_type(instance_type)
        case
        when INSTANCE_TYPES_32_BIT.include?(string) then :i386
        when INSTANCE_TYPES_64_BIT.include?(string) then :x64
        else raise "Don't know if #{instance_type} is i386 or x64"
        end
      end
      def instance_type
        @options[:instance_type] || self.class.instance_type
      end
      def security_group
        groups = @options[:security_group] || self.class.security_group || []
        groups.each { |group_name| ec2.create_security_group_if_missing(group_name) }
        if self.class.individual_security_group
          group_name = "#{self.class.name} #{name}"
          ec2.create_security_group_if_missing(group_name, "#{group_name} private security group")
          groups + [group_name]
        else
          groups
        end
      end
      def sudo_user
        @options[:sudo_user] || self.class.sudo_user
      end
      def bootstrap_script
        @options[:bootstrap_script] || self.class.bootstrap_script
      end
      def keys
        @options[:keys] || self.class.keys
      end
      def monitor
        @options[:monitor] || self.class.monitor
      end
      def elastic_ip
        @options[:ip]
      end
      def instance_id
        ec2.instance_id
      end
      def aws_dns_name
        describe_instance[:dns_name]
      end
      def launch_time
        xml_time = describe_instance[:aws_launch_time]
        logger.debug xml_time
        Time.xmlschema(xml_time)
      end
      def instance_running?
        describe_instance![:aws_state] == 'running'
      end
      def describe_instance!
        @describe_instance = nil
        logger.debug describe_instance
        describe_instance
      end
      def describe_instance
        @describe_instance ||= ec2.describe_instance
      end
      def cluster_name
        cluster = ServerCluster.cluster_for(self)
        cluster ? cluster.name : "<unknown>"
      end
      def full_name
        "#{self.class.name.downcase}-#{cluster_name}-#{name}"
      end
      def user_data
        '' # Likely overridden in subclass
      end
    end

    def logger
      @logger ||= self.class.logger
    end

  end
end