text:
package com.out4food.domain;

import com.google.common.collect.ImmutableList;
//import com.google.devrel.training.conference.form.ProfileForm.TeeShirtSize;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;

import java.util.ArrayList;
import java.util.List;

/**
 * Profile class stores user's profile data.
 */
@Entity
public class Profile {
    /**
     *  Use userId as the datastore key.
     */
    @Id
    private String userId;

    /**
     * Any string user wants us to display him/her on this system.
     */
    private String displayName;

    /**
     * User's main e-mail address.
     */
    private String mainEmail;

   private String age;
    private String city;
    private String country;
    private String gender;

    /**
     * Keys of the conferences that this user registers to attend.
     */
    private List<String> conferenceKeysToAttend = new ArrayList<>(0);

    public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	public String getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public String getCountry() {
		return country;
	}

	public void setCountry(String country) {
		this.country = country;
	}

    /**
     * Just making the default constructor private.
     */
    private Profile() {}

    /**
     * Public constructor for Profile.
     * @param userId The datastore key.
     * @param displayName Any string user wants us to display him/her on this system.
     * @param mainEmail User's main e-mail address.
     */
    public Profile(String userId, String displayName, String mainEmail, String sex, String age, String city, String country) {

    	this.userId = userId;
        this.displayName = displayName;
        this.mainEmail = mainEmail;
        this.age=age;
        this.city=city;
        this.country=country;

    }

    /**
     * Getter for userId.
     * @return userId.
     */
    public String getUserId() {
        return userId;
    }

    /**
     * Getter for displayName.
     * @return displayName.
     */
    public String getDisplayName() {
        return displayName;
    }

    /**
     * Getter for mainEmail.
     * @return mainEmail.
     */
    public String getMainEmail() {
        return mainEmail;
    }

    /**
     * Update the Profile with the given displayName and teeShirtSize
     * @param displayName
     * @param teeShirtSize
     */
    public void update(String displayName, String age, String country, String city, String sex) {
        if (displayName != null) {
            this.displayName = displayName;
        }
        if (age != null) {
            this.age = age;
        }

        if (country != null) {
            this.country = country;
        }

        if (city != null) {
            this.city = city;
        }

        if (sex != null) {
            this.city = sex;
        }
    }

    /**
     * Getter for conferenceIdsToAttend.
     * @return an immutable copy of conferenceIdsToAttend.
     */
    public List<String> getConferenceKeysToAttend() {
    	return ImmutableList.copyOf(conferenceKeysToAttend);
    }

    /**
     * Adds a ConferenceId to conferenceIdsToAttend.
     *
     * The method initConferenceIdsToAttend is not thread-safe, but we need a transaction for
     * calling this method after all, so it is not a practical issue.
     *
     * @param conferenceKey a websafe String representation of the Conference Key.
     */
    public void addToConferenceKeysToAttend(String conferenceKey) {
        conferenceKeysToAttend.add(conferenceKey);
    }

    /**
     * Remove the conferenceId from conferenceIdsToAttend.
     *
     * @param conferenceKey a websafe String representation of the Conference Key.
     */
    public void unregisterFromConference(String conferenceKey) {
        if (conferenceKeysToAttend.contains(conferenceKey)) {
            conferenceKeysToAttend.remove(conferenceKey);
        } else {
            throw new IllegalArgumentException("Invalid conferenceKey: " + conferenceKey);
        }
    }
}

redpajama_set_name: RedPajamaGithub


text:
import angular from 'angular';

export default class DesignerCtrl {

  constructor($scope, $http, $uibModal, $templateCache) {
    'ngInject';

    $scope.loadDrawApiList = function() {
      $http.get('/api/drawapis')
      .then(function (res) {
        $scope.drawApiList = res.data;
      });
    };

    $scope.addStructure = function(type) {
      var structures = $scope.currentCanvas.structures;
      var item = {
        id: type,
        type: type
      };

      function test(s) {
        return s.id == item.id;
      }
      var surfix = 1;
      while (structures.some(test)) {
        item.id = type + surfix++;
      }

      structures.push(item);
      $scope.selectStructure(item);
    };

    $scope.selectStructure = function (item) {
      $scope.selectedStructure = item;
    };

    $scope.removeStructure = function (item) {
      var structures = $scope.currentCanvas.structures;
      structures.splice(structures.indexOf(item), 1);

      $scope.editor.getEachGutterMarkers(function (gm) {
        if (!gm.draws) {
          return;
        }
        var temp = [];
        gm.draws.forEach(function (draw) {
          if (draw.structure.id === item.id) {
            return;
          }
          temp.push(draw);
        });
        gm.draws = temp;
      });

      $scope.syncBreaksToCurrentCanvas();

      if ($scope.selectedStructure === item) {
        delete $scope.selectedStructure;
      }
    };

    $scope.openAddDrawApiModal = function (api) {
      var structure = $scope.selectedStructure;
      var gutter = $scope.selectedGutter;

      var modalInstance = $uibModal.open({
        template: $templateCache.get(
          'modal/drawapi-modal.tpl.html'),
        controller: DrawApiModalCtrl,
        resolve: {
          api: function () {
            return api;
          }
        }
      });

      modalInstance.result
      .then(function success(output) {
        var draw = {
          structure: structure,
          api: output
        };
        gutter.draws.push(draw);
        $scope.syncBreaksToCurrentCanvas();
      }, function dismissed() {

      });
    };

    $scope.drawListFilter = function (item) {
      if (!$scope.selectedStructure || !item) {
        return false;
      }
      return $scope.selectedStructure.id === item.structure.id;
    };

    $scope.drawApiToString = function (draw) {
      var str = draw.api.name;

      if (draw.api.params.length === 1 &&
        !draw.api.params[0].value) {
        return str + '()';
      }

      str += '(';
      draw.api.params.forEach(function (param) {
        if (param.value) {
          str += param.value;
          str += ', ';
        }
      });
      str = str.substring(0, str.length - 2);
      str += ')';
      return str;
    };

    $scope.removeDrawApi = function (draw) {
      var draws = $scope.selectedGutter.draws;
      draws.splice(draws.indexOf(draw), 1);
      $scope.syncBreaksToCurrentCanvas();
    };

    $scope.openModifyDrawApiModal = function (draw) {
      var modalInstance = $uibModal.open({
        template: $templateCache.get(
          'modal/drawapi-modal.tpl.html'),
        controller: DrawApiModalCtrl,
        resolve: {
          api: function () {
            return draw.api;
          }
        }
      });

      modalInstance.result
      .then(function success(output) {
        draw.api = output;
        $scope.syncBreaksToCurrentCanvas();
      }, function dismissed() {

      });
    };

    function DrawApiModalCtrl($scope, $uibModalInstance, api) {
      $scope.api = angular.copy(api);

      $scope.save = function () {
        $scope.error = false;
        $scope.api.params.forEach(function (param) {
          if (!param.optional && !param.value) {
            $scope.error = true;
          }
        });

        if ($scope.error) {
          return;
        }

        $uibModalInstance.close($scope.api);
      };

      $scope.cancel = function () {
        $uibModalInstance.dismiss('cancel');
      };
    }

    $scope.$on('changedCurrentCanvas', function () {
      delete $scope.selectedStructure;
    });
  }
}


text:
namespace Miruken.Http.Patch
{
    using System.Net.Http;
    using System.Threading.Tasks;
    using Callback;

    public class PatchHandler : ResourceHandler
    {
        [Handles]
        public async Task<PatchResponse<TResource>>
            Patch<TPatch, TResource>(PatchRequest<TPatch, TResource> patch,
            IHandler composer)
        {
            var request = GetRequest(patch.Request, HttpExtensions.PatchMethod)
                ?? new HttpRequestMessage(HttpExtensions.PatchMethod, patch.ResourceUri)
                   {
                       Content = GetContent(patch.Request, patch)
                   };
            var response      = await SendRequest(patch, request, composer,
                    out var options).ConfigureAwait(false);
            var resource      = await ExtractResource<TResource>(response, options);
            var patchResponse = new PatchResponse<TResource>(resource);
            SetResponseUri(patchResponse, response);
            return patchResponse;
        }
    }
}


text:
package cn.featherfly.conversion.core.basic;

import java.math.BigInteger;

/**
 * <p>
 * BigInteger转换器
 * </p>
 *
 * @author 钟冀
 */
public class BigIntegerConvertor extends NumberConvertor<BigInteger>{

    /**
     */
    public BigIntegerConvertor() {
    }
}


text:
#![crate_name = "uu_join"]

extern crate clap;

#[macro_use]
extern crate uucore;

use std::fs::File;
use std::io::{stdin, BufRead, BufReader, Lines, Stdin};
use std::cmp::{min, Ordering};
use clap::{App, Arg};

static NAME: &'static str = "join";
static VERSION: &'static str = env!("CARGO_PKG_VERSION");

#[derive(Copy, Clone, PartialEq)]
enum FileNum {
    None,
    File1,
    File2,
}

#[derive(Copy, Clone)]
enum Sep {
    Char(char),
    Line,
    Whitespaces,
}

#[derive(Copy, Clone, PartialEq)]
enum CheckOrder {
    Default,
    Disabled,
    Enabled,
}

struct Settings {
    key1: usize,
    key2: usize,
    print_unpaired: FileNum,
    print_joined: bool,
    ignore_case: bool,
    separator: Sep,
    autoformat: bool,
    format: Vec<Spec>,
    empty: String,
    check_order: CheckOrder,
    headers: bool,
}

impl Default for Settings {
    fn default() -> Settings {
        Settings {
            key1: 0,
            key2: 0,
            print_unpaired: FileNum::None,
            print_joined: true,
            ignore_case: false,
            separator: Sep::Whitespaces,
            autoformat: false,
            format: vec![],
            empty: String::new(),
            check_order: CheckOrder::Default,
            headers: false,
        }
    }
}

/// Output representation.
struct Repr<'a> {
    separator: char,
    format: &'a [Spec],
    empty: &'a str,
}

impl<'a> Repr<'a> {
    fn new(separator: char, format: &'a [Spec], empty: &'a str) -> Repr<'a> {
        Repr {
            separator,
            format,
            empty,
        }
    }

    fn uses_format(&self) -> bool {
        !self.format.is_empty()
    }

    /// Print the field or empty filler if the field is not set.
    fn print_field(&self, field: Option<&str>) {
        let value = match field {
            Some(field) => field,
            None => self.empty,
        };

        print!("{}", value);
    }

    /// Print each field except the one at the index.
    fn print_fields(&self, line: &Line, index: usize, max_fields: usize) {
        for i in 0..min(max_fields, line.fields.len()) {
            if i != index {
                print!("{}{}", self.separator, line.fields[i]);
            }
        }
    }

    /// Print each field or the empty filler if the field is not set.
    fn print_format<F>(&self, f: F)
    where
        F: Fn(&Spec) -> Option<&'a str>,
    {
        for i in 0..self.format.len() {
            if i > 0 {
                print!("{}", self.separator);
            }

            let field = match f(&self.format[i]) {
                Some(value) => value,
                None => self.empty,
            };

            print!("{}", field);
        }
    }
}

/// Input processing parameters.
struct Input {
    separator: Sep,
    ignore_case: bool,
    check_order: CheckOrder,
}

impl Input {
    fn new(separator: Sep, ignore_case: bool, check_order: CheckOrder) -> Input {
        Input {
            separator,
            ignore_case,
            check_order,
        }
    }

    fn compare(&self, field1: Option<&str>, field2: Option<&str>) -> Ordering {
        if let (Some(field1), Some(field2)) = (field1, field2) {
            if self.ignore_case {
                field1.to_lowercase().cmp(&field2.to_lowercase())
            } else {
                field1.cmp(field2)
            }
        } else {
            match field1 {
                Some(_) => Ordering::Greater,
                None => match field2 {
                    Some(_) => Ordering::Less,
                    None => Ordering::Equal,
                },
            }
        }
    }
}

enum Spec {
    Key,
    Field(FileNum, usize),
}

impl Spec {
    fn parse(format: &str) -> Spec {
        let mut chars = format.chars();

        let file_num = match chars.next() {
            Some('0') => {
                // Must be all alone without a field specifier.
                if let None = chars.next() {
                    return Spec::Key;
                }

                crash!(1, "invalid field specifier: '{}'", format);
            }
            Some('1') => FileNum::File1,
            Some('2') => FileNum::File2,
            _ => crash!(1, "invalid file number in field spec: '{}'", format),
        };

        if let Some('.') = chars.next() {
            return Spec::Field(file_num, parse_field_number(chars.as_str()));
        }

        crash!(1, "invalid field specifier: '{}'", format);
    }
}

struct Line {
    fields: Vec<String>,
}

impl Line {
    fn new(string: String, separator: Sep) -> Line {
        let fields = match separator {
            Sep::Whitespaces => string.split_whitespace().map(String::from).collect(),
            Sep::Char(sep) => string.split(sep).map(String::from).collect(),
            Sep::Line => vec![string],
        };

        Line { fields }
    }

    /// Get field at index.
    fn get_field(&self, index: usize) -> Option<&str> {
        if index < self.fields.len() {
            Some(&self.fields[index])
        } else {
            None
        }
    }
}

struct State<'a> {
    key: usize,
    file_name: &'a str,
    file_num: FileNum,
    print_unpaired: bool,
    lines: Lines<Box<BufRead + 'a>>,
    seq: Vec<Line>,
    max_fields: usize,
    line_num: usize,
    has_failed: bool,
}

impl<'a> State<'a> {
    fn new(
        file_num: FileNum,
        name: &'a str,
        stdin: &'a Stdin,
        key: usize,
        print_unpaired: FileNum,
    ) -> State<'a> {
        let f = if name == "-" {
            Box::new(stdin.lock()) as Box<BufRead>
        } else {
            match File::open(name) {
                Ok(file) => Box::new(BufReader::new(file)) as Box<BufRead>,
                Err(err) => crash!(1, "{}: {}", name, err),
            }
        };

        State {
            key: key,
            file_name: name,
            file_num: file_num,
            print_unpaired: print_unpaired == file_num,
            lines: f.lines(),
            seq: Vec::new(),
            max_fields: usize::max_value(),
            line_num: 0,
            has_failed: false,
        }
    }

    /// Skip the current unpaired line.
    fn skip_line(&mut self, input: &Input, repr: &Repr) {
        if self.print_unpaired {
            self.print_first_line(repr);
        }

        self.reset_next_line(input);
    }

    /// Keep reading line sequence until the key does not change, return
    /// the first line whose key differs.
    fn extend(&mut self, input: &Input) -> Option<Line> {
        while let Some(line) = self.next_line(input) {
            let diff = input.compare(self.get_current_key(), line.get_field(self.key));

            if diff == Ordering::Equal {
                self.seq.push(line);
            } else {
                return Some(line);
            }
        }

        return None;
    }

    /// Print lines in the buffers as headers.
    fn print_headers(&self, other: &State, repr: &Repr) {
        if self.has_line() {
            if other.has_line() {
                self.combine(other, repr);
            } else {
                self.print_first_line(repr);
            }
        } else if other.has_line() {
            other.print_first_line(repr);
        }
    }

    /// Combine two line sequences.
    fn combine(&self, other: &State, repr: &Repr) {
        let key = self.get_current_key();

        for line1 in &self.seq {
            for line2 in &other.seq {
                if repr.uses_format() {
                    repr.print_format(|spec| match spec {
                        &Spec::Key => key,
                        &Spec::Field(file_num, field_num) => {
                            if file_num == self.file_num {
                                return line1.get_field(field_num);
                            }

                            if file_num == other.file_num {
                                return line2.get_field(field_num);
                            }

                            None
                        }
                    });
                } else {
                    repr.print_field(key);
                    repr.print_fields(&line1, self.key, self.max_fields);
                    repr.print_fields(&line2, other.key, other.max_fields);
                }

                println!();
            }
        }
    }

    /// Reset with the next line.
    fn reset(&mut self, next_line: Option<Line>) {
        self.seq.clear();

        if let Some(line) = next_line {
            self.seq.push(line);
        }
    }

    fn reset_read_line(&mut self, input: &Input) {
        let line = self.read_line(input.separator);
        self.reset(line);
    }

    fn reset_next_line(&mut self, input: &Input) {
        let line = self.next_line(input);
        self.reset(line);
    }

    fn has_line(&self) -> bool {
        !self.seq.is_empty()
    }

    fn initialize(&mut self, read_sep: Sep, autoformat: bool) {
        if let Some(line) = self.read_line(read_sep) {
            if autoformat {
                self.max_fields = line.fields.len();
            }

            self.seq.push(line);
        }
    }

    fn finalize(&mut self, input: &Input, repr: &Repr) {
        if self.has_line() && self.print_unpaired {
            self.print_first_line(repr);

            while let Some(line) = self.next_line(input) {
                self.print_line(&line, repr);
            }
        }
    }

    /// Get the next line without the order check.
    fn read_line(&mut self, sep: Sep) -> Option<Line> {
        let value = self.lines.next()?;
        self.line_num += 1;
        Some(Line::new(crash_if_err!(1, value), sep))
    }

    /// Get the next line with the order check.
    fn next_line(&mut self, input: &Input) -> Option<Line> {
        let line = self.read_line(input.separator)?;

        if input.check_order == CheckOrder::Disabled {
            return Some(line);
        }

        let diff = input.compare(self.get_current_key(), line.get_field(self.key));

        if diff == Ordering::Greater {
            eprintln!("{}:{}: is not sorted", self.file_name, self.line_num);

            // This is fatal if the check is enabled.
            if input.check_order == CheckOrder::Enabled {
                exit!(1);
            }

            self.has_failed = true;
        }

        Some(line)
    }

    /// Gets the key value of the lines stored in seq.
    fn get_current_key(&self) -> Option<&str> {
        self.seq[0].get_field(self.key)
    }

    fn print_line(&self, line: &Line, repr: &Repr) {
        if repr.uses_format() {
            repr.print_format(|spec| match spec {
                &Spec::Key => line.get_field(self.key),
                &Spec::Field(file_num, field_num) => if file_num == self.file_num {
                    line.get_field(field_num)
                } else {
                    None
                },
            });
        } else {
            repr.print_field(line.get_field(self.key));
            repr.print_fields(line, self.key, self.max_fields);
        }

        println!();
    }

    fn print_first_line(&self, repr: &Repr) {
        self.print_line(&self.seq[0], repr);
    }
}

pub fn uumain(args: Vec<String>) -> i32 {
    let matches = App::new(NAME)
        .version(VERSION)
        .about(
            "For each pair of input lines with identical join fields, write a line to
standard output. The default join field is the first, delimited by blanks.

When FILE1 or FILE2 (not both) is -, read standard input.",
        )
        .help_message("display this help and exit")
        .version_message("display version and exit")
        .arg(
            Arg::with_name("a")
                .short("a")
                .takes_value(true)
                .possible_values(&["1", "2"])
                .value_name("FILENUM")
                .help(
                    "also print unpairable lines from file FILENUM, where
FILENUM is 1 or 2, corresponding to FILE1 or FILE2",
                ),
        )
        .arg(
            Arg::with_name("v")
                .short("v")
                .value_name("FILENUM")
                .help("like -a FILENUM, but suppress joined output lines"),
        )
        .arg(
            Arg::with_name("e")
                .short("e")
                .takes_value(true)
                .value_name("EMPTY")
                .help("replace missing input fields with EMPTY"),
        )
        .arg(
            Arg::with_name("i")
                .short("i")
                .long("ignore-case")
                .help("ignore differences in case when comparing fields"),
        )
        .arg(
            Arg::with_name("j")
                .short("j")
                .takes_value(true)
                .value_name("FIELD")
                .help("equivalent to '-1 FIELD -2 FIELD'"),
        )
        .arg(
            Arg::with_name("o")
                .short("o")
                .takes_value(true)
                .value_name("FORMAT")
                .help("obey FORMAT while constructing output line"),
        )
        .arg(
            Arg::with_name("t")
                .short("t")
                .takes_value(true)
                .value_name("CHAR")
                .help("use CHAR as input and output field separator"),
        )
        .arg(
            Arg::with_name("1")
                .short("1")
                .takes_value(true)
                .value_name("FIELD")
                .help("join on this FIELD of file 1"),
        )
        .arg(
            Arg::with_name("2")
                .short("2")
                .takes_value(true)
                .value_name("FIELD")
                .help("join on this FIELD of file 2"),
        )
        .arg(Arg::with_name("check-order").long("check-order").help(
            "check that the input is correctly sorted, \
             even if all input lines are pairable",
        ))
        .arg(
            Arg::with_name("nocheck-order")
                .long("nocheck-order")
                .help("do not check that the input is correctly sorted"),
        )
        .arg(Arg::with_name("header").long("header").help(
            "treat the first line in each file as field headers, \
             print them without trying to pair them",
        ))
        .arg(
            Arg::with_name("file1")
                .required(true)
                .value_name("FILE1")
                .hidden(true),
        )
        .arg(
            Arg::with_name("file2")
                .required(true)
                .value_name("FILE2")
                .hidden(true),
        )
        .get_matches_from(args);

    let keys = parse_field_number_option(matches.value_of("j"));
    let key1 = parse_field_number_option(matches.value_of("1"));
    let key2 = parse_field_number_option(matches.value_of("2"));

    let mut settings: Settings = Default::default();

    if let Some(value) = matches.value_of("v") {
        settings.print_unpaired = parse_file_number(value);
        settings.print_joined = false;
    } else if let Some(value) = matches.value_of("a") {
        settings.print_unpaired = parse_file_number(value);
    }

    settings.ignore_case = matches.is_present("i");
    settings.key1 = get_field_number(keys, key1);
    settings.key2 = get_field_number(keys, key2);

    if let Some(value) = matches.value_of("t") {
        settings.separator = match value.len() {
            0 => Sep::Line,
            1 => Sep::Char(value.chars().nth(0).unwrap()),
            _ => crash!(1, "multi-character tab {}", value),
        };
    }

    if let Some(format) = matches.value_of("o") {
        if format == "auto" {
            settings.autoformat = true;
        } else {
            settings.format = format
                .split(|c| c == ' ' || c == ',' || c == '\t')
                .map(Spec::parse)
                .collect();
        }
    }

    if let Some(empty) = matches.value_of("e") {
        settings.empty = empty.to_string();
    }

    if matches.is_present("nocheck-order") {
        settings.check_order = CheckOrder::Disabled;
    }

    if matches.is_present("check-order") {
        settings.check_order = CheckOrder::Enabled;
    }

    if matches.is_present("header") {
        settings.headers = true;
    }

    let file1 = matches.value_of("file1").unwrap();
    let file2 = matches.value_of("file2").unwrap();

    if file1 == "-" && file2 == "-" {
        crash!(1, "both files cannot be standard input");
    }

    exec(file1, file2, &settings)
}

fn exec(file1: &str, file2: &str, settings: &Settings) -> i32 {
    let stdin = stdin();

    let mut state1 = State::new(
        FileNum::File1,
        &file1,
        &stdin,
        settings.key1,
        settings.print_unpaired,
    );

    let mut state2 = State::new(
        FileNum::File2,
        &file2,
        &stdin,
        settings.key2,
        settings.print_unpaired,
    );

    let input = Input::new(
        settings.separator,
        settings.ignore_case,
        settings.check_order,
    );

    let repr = Repr::new(
        match settings.separator {
            Sep::Char(sep) => sep,
            _ => ' ',
        },
        &settings.format,
        &settings.empty,
    );

    state1.initialize(settings.separator, settings.autoformat);
    state2.initialize(settings.separator, settings.autoformat);

    if settings.headers {
        state1.print_headers(&state2, &repr);
        state1.reset_read_line(&input);
        state2.reset_read_line(&input);
    }

    while state1.has_line() && state2.has_line() {
        let diff = input.compare(state1.get_current_key(), state2.get_current_key());

        match diff {
            Ordering::Less => {
                state1.skip_line(&input, &repr);
            }
            Ordering::Greater => {
                state2.skip_line(&input, &repr);
            }
            Ordering::Equal => {
                let next_line1 = state1.extend(&input);
                let next_line2 = state2.extend(&input);

                if settings.print_joined {
                    state1.combine(&state2, &repr);
                }

                state1.reset(next_line1);
                state2.reset(next_line2);
            }
        }
    }

    state1.finalize(&input, &repr);
    state2.finalize(&input, &repr);

    (state1.has_failed || state2.has_failed) as i32
}

/// Check that keys for both files and for a particular file are not
/// contradictory and return the key index.
fn get_field_number(keys: Option<usize>, key: Option<usize>) -> usize {
    if let Some(keys) = keys {
        if let Some(key) = key {
            if keys != key {
                // Show zero-based field numbers as one-based.
                crash!(1, "incompatible join fields {}, {}", keys + 1, key + 1);
            }
        }

        return keys;
    }

    match key {
        Some(key) => key,
        None => 0,
    }
}

/// Parse the specified field string as a natural number and return
/// the zero-based field number.
fn parse_field_number(value: &str) -> usize {
    match value.parse::<usize>() {
        Ok(result) if result > 0 => result - 1,
        _ => crash!(1, "invalid field number: '{}'", value),
    }
}

fn parse_file_number(value: &str) -> FileNum {
    match value {
        "1" => FileNum::File1,
        "2" => FileNum::File2,
        value => crash!(1, "invalid file number: '{}'", value),
    }
}

fn parse_field_number_option(value: Option<&str>) -> Option<usize> {
    Some(parse_field_number(value?))
}


text:
<?php namespace System\Models;

use Model;
use ApplicationException;

/**
 * Mail layout
 *
 * @package october\system
 * @author Alexey Bobkov, Samuel Georges
 */
class MailLayout extends Model
{
    use \October\Rain\Database\Traits\Validation;

    /**
     * @var string The database table used by the model.
     */
    protected $table = 'system_mail_layouts';

    public $rules = [
        'code'                  => 'required|unique:system_mail_layouts',
        'name'                  => 'required',
        'content_html'          => 'required',
    ];

    public function beforeDelete()
    {
        if ($this->is_locked) {
            throw new ApplicationException('Cannot delete this template because it is locked');
        }
    }
}


text:
package org.apache.river.test.impl.start;

import net.jini.lookup.ServiceProxyAccessor;

import net.jini.security.proxytrust.ServerProxyTrust;

import java.rmi.Remote;

public interface BadServiceProxyAccessor extends Remote,
    ServiceProxyAccessor, ServerProxyTrust
{
    // aggregate interface declaration
}


text:
import {AnimationMetadata, animate, group, sequence, style, transition, trigger} from '@angular/core';
import {AsyncTestCompleter, beforeEach, beforeEachProviders, ddescribe, describe, expect, iit, inject, it, xdescribe, xit} from '@angular/core/testing/testing_internal';

import {AnimationCompiler, CompiledAnimation} from '../../src/animation/animation_compiler';
import {CompileDirectiveMetadata, CompileTemplateMetadata, CompileTypeMetadata} from '../../src/compile_metadata';
import {CompileMetadataResolver} from '../../src/metadata_resolver';

export function main() {
  describe('RuntimeAnimationCompiler', () => {
    var resolver: any /** TODO #9100 */;
    beforeEach(
        inject([CompileMetadataResolver], (res: CompileMetadataResolver) => { resolver = res; }));

    var compiler = new AnimationCompiler();

    var compileAnimations = (component: CompileDirectiveMetadata): CompiledAnimation => {
      return compiler.compileComponent(component)[0];
    };

    var compile = (seq: AnimationMetadata) => {
      var entry = trigger('myAnimation', [transition('state1 => state2', seq)]);

      var compiledAnimationEntry = resolver.getAnimationEntryMetadata(entry);
      var component = CompileDirectiveMetadata.create({
        type: new CompileTypeMetadata({name: 'something'}),
        template: new CompileTemplateMetadata({animations: [compiledAnimationEntry]})
      });

      return compileAnimations(component);
    };

    it('should throw an exception containing all the inner animation parser errors', () => {
      var animation = sequence([
        style({'color': 'red'}), animate(1000, style({'font-size': '100px'})),
        style({'color': 'blue'}), animate(1000, style(':missing_state')), style({'color': 'gold'}),
        animate(1000, style('broken_state'))
      ]);

      var capturedErrorMessage: string;
      try {
        compile(animation);
      } catch (e) {
        capturedErrorMessage = e.message;
      }

      expect(capturedErrorMessage)
          .toMatchPattern(/Unable to apply styles due to missing a state: "missing_state"/g);

      expect(capturedErrorMessage)
          .toMatchPattern(/Animation states via styles must be prefixed with a ":"/);
    });
  });
}


text:
// Copyright (c) 2005-2017 Poderosa Project, All Rights Reserved.
// This file is a part of the Granados SSH Client Library that is subject to
// the license included in the distributed package.
// You may not use this file except in compliance with the license.

using Granados.IO;
using Granados.IO.SSH2;
using Granados.SSH;
using Granados.Util;
using Granados.X11;
using Granados.X11Forwarding;
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;

namespace Granados.SSH2 {

    ///
    /// SSH2 channel base class.
    ///
    internal class SSH2ChannelBase : ISSHChannel {
        #region

        protected enum State {
            /// channel has been requested by the server
            InitiatedByServer,
            /// channel has been requested by the client
            InitiatedByClient,
            /// channel has been established. more request may be requested.
            Established,
            /// channel is ready for use
            Ready,
            /// closing has been requested
            Closing,
            /// channel has been closed
            Closed,
        }

        protected enum SubPacketProcessResult {
            /// the packet was not consumed
            NotConsumed,
            /// the packet was consumed
            Consumed,
        }

        protected enum ChannelRequestResult {
            /// server replied SSH_MSG_REQUEST_SUCCESS
            Success,
            /// server replied SSH_MSG_REQUEST_FAILURE
            Failure,
            /// no response
            Timeout,
        }

        // Min/Max size of the SSH_MSG_CHANNEL_DATA datagram
        // Maximum payload size is 32768 bytes. (described in RFC4253)
        // SSH_MSG_CHANNEL_DATA:
        //   Packet type (SSH_MSG_CHANNEL_DATA) : 1 byte
        //   Recipient channel : 4 bytes
        //   Data length : 4 bytes
        //   Data : n bytes
        private const int CHANNEL_DATA_INFO_SIZE = 1 + 4 + 4;
        private const int MIN_DATAGRAM_SIZE = 512;
        private const int MAX_DATAGRAM_SIZE = 32768 - CHANNEL_DATA_INFO_SIZE;

        private readonly SSHTimeouts _timeouts;
        private readonly IPacketSender<SSH2Packet> _packetSender;
        private readonly SSHProtocolEventManager _protocolEventManager;
        private readonly int _localMaxPacketSize;
        private readonly int _localWindowSize;
        private int _localWindowSizeLeft;
        private uint _serverMaxPacketSize;
        private uint _serverWindowSizeLeft;

        private volatile State _state;
        private readonly object _stateSync = new object();

        private readonly object _channelRequestStatusSync = new object();
        private volatile bool _channelRequestStatus = false;
        private readonly AtomicBox<bool> _channelRequestResult = new AtomicBox<bool>();

        private ISSHChannelEventHandler _handler = new SimpleSSHChannelEventHandler();

        private int? _maxDatagramSize = null;

        ///
        /// Event that notifies that this channel is already dead.
        ///
        internal event Action<ISSHChannel> Died;

        ///
        /// Constructor (initiated by server)
        ///
        public SSH2ChannelBase(
                SSHTimeouts timeouts,
                IPacketSender<SSH2Packet> packetSender,
                SSHConnectionParameter param,
                SSHProtocolEventManager protocolEventManager,
                uint localChannel,
                uint remoteChannel,
                ChannelType channelType,
                string channelTypeString,
                uint serverWindowSize,
                uint serverMaxPacketSize)
            : this(
                state: State.InitiatedByServer, // SendOpenConfirmation() will change state to "Opened"
                timeouts: timeouts,
                packetSender: packetSender,
                param: param,
                protocolEventManager: protocolEventManager,
                localChannel: localChannel,
                remoteChannel: remoteChannel,
                channelType: channelType,
                channelTypeString: channelTypeString,
                serverWindowSize: serverWindowSize,
                serverMaxPacketSize: serverMaxPacketSize) {}

        ///
        /// Constructor (initiated by client)
        ///
        public SSH2ChannelBase(
                SSHTimeouts timeouts,
                IPacketSender<SSH2Packet> packetSender,
                SSHConnectionParameter param,
                SSHProtocolEventManager protocolEventManager,
                uint localChannel,
                ChannelType channelType,
                string channelTypeString)
            : this(
                state: State.InitiatedByClient, // receiving SSH_MSG_CHANNEL_OPEN_CONFIRMATION will change state to "Opened"
                timeouts: timeouts,
                packetSender: packetSender,
                param: param,
                protocolEventManager: protocolEventManager,
                localChannel: localChannel,
                remoteChannel: 0,
                channelType: channelType,
                channelTypeString: channelTypeString,
                serverWindowSize: 0,
                serverMaxPacketSize: 0) {}

        ///
        /// Internal Constructor
        ///
        private SSH2ChannelBase(
                State state,
                SSHTimeouts timeouts,
                IPacketSender<SSH2Packet> packetSender,
                SSHConnectionParameter param,
                SSHProtocolEventManager protocolEventManager,
                uint localChannel,
                uint remoteChannel,
                ChannelType channelType,
                string channelTypeString,
                uint serverWindowSize,
                uint serverMaxPacketSize) {

            _timeouts = timeouts;
            _packetSender = packetSender;
            _protocolEventManager = protocolEventManager;
            LocalChannel = localChannel;
            RemoteChannel = remoteChannel;
            ChannelType = channelType;
            ChannelTypeString = channelTypeString;

            _localMaxPacketSize = param.MaxPacketSize;
            _localWindowSize = _localWindowSizeLeft = param.WindowSize;
            _serverMaxPacketSize = serverMaxPacketSize;
            _serverWindowSizeLeft = serverWindowSize;

            _state = state;
        }

        ///
        /// Major state
        ///
        protected State MajorState {
            get {
                return _state;
            }
        }

        ///
        /// Sends SSH_MSG_CHANNEL_REQUEST packet (no response)
        ///
        /// <param name="requestPacket">SSH_MSG_CHANNEL_REQUEST packet</param>
        protected void SendRequest(SSH2Packet requestPacket) {
            lock (_channelRequestStatusSync) {
                SpinWait.SpinUntil(() => _channelRequestStatus == false);
                _channelRequestStatus = true;
            }
            try {
                Transmit(0, requestPacket);
            }
            finally {
                lock (_channelRequestStatusSync) {
                    _channelRequestStatus = false;
                }
            }
        }

        ///
        /// Sends SSH_MSG_CHANNEL_REQUEST packet and wait response asynchronously.
        ///
        /// <param name="requestPacket">SSH_MSG_CHANNEL_REQUEST packet</param>
        /// <returns>asynchronous task that wait for the response</returns>
        protected Task<ChannelRequestResult> SendRequestAndWaitResponseAsync(SSH2Packet requestPacket) {
            lock (_channelRequestStatusSync) {
                SpinWait.SpinUntil(() => _channelRequestStatus == false);
                _channelRequestStatus = true;
            }

            try {
                _channelRequestResult.Clear();
                Transmit(0, requestPacket);
                return WaitResponseAsync();
            }
            finally {
                lock (_channelRequestStatusSync) {
                    _channelRequestStatus = false;
                }
            }
        }

        private Task<ChannelRequestResult> WaitResponseAsync() {
            return Task<ChannelRequestResult>.Run(() => {
                bool result = false;
                if (_channelRequestResult.TryGet(ref result, _timeouts.ResponseTimeout)) {
                    return result ? ChannelRequestResult.Success : ChannelRequestResult.Failure;
                }
                else {
                    return ChannelRequestResult.Timeout;
                }
            });
        }

        #region ISSHChannel properties

        ///
        /// Local channel number.
        ///
        public uint LocalChannel {
            get;
            private set;
        }

        ///
        /// Remote channel number.
        ///
        public uint RemoteChannel {
            get;
            private set;
        }

        ///
        /// Channel type. (predefined type)
        ///
        public ChannelType ChannelType {
            get;
            private set;
        }

        ///
        /// Channel type string. (actual channel type name)
        ///
        public string ChannelTypeString {
            get;
            private set;
        }

        ///
        /// true if this channel is open.
        ///
        public bool IsOpen {
            get {
                return _state != State.Closed;
            }
        }

        ///
        /// true if this channel is ready for use.
        ///
        public bool IsReady {
            get {
                return _state == State.Ready;
            }
        }

        ///
        /// Maximum size of the channel data which can be sent with a single SSH packet.
        ///
        /// <remarks>
        /// In SSH2, this size will be determined from the maximum packet size specified by the server.
        /// </remarks>
        public int MaxChannelDatagramSize {
            get {
                if (_maxDatagramSize == null) {
                    if (_serverMaxPacketSize == 0) {
                        return MIN_DATAGRAM_SIZE;
                    }
                    _maxDatagramSize =
                        (_serverMaxPacketSize < CHANNEL_DATA_INFO_SIZE) ?
                            MIN_DATAGRAM_SIZE :
                            (int)Math.Max(Math.Min(_serverMaxPacketSize - CHANNEL_DATA_INFO_SIZE, MAX_DATAGRAM_SIZE), MIN_DATAGRAM_SIZE);
                }
                return _maxDatagramSize.Value;
            }
        }

        #endregion

        #region ISSHChannel methods

        ///
        /// Send window dimension change message.
        ///
        /// <param name="width">terminal width, columns</param>
        /// <param name="height">terminal height, rows</param>
        /// <param name="pixelWidth">terminal width, pixels</param>
        /// <param name="pixelHeight">terminal height, pixels</param>
        /// <exception cref="SSHChannelInvalidOperationException">the channel is already closed.</exception>
        public void ResizeTerminal(uint width, uint height, uint pixelWidth, uint pixelHeight) {
            lock (_stateSync) {
                if (_state == State.Closing || _state == State.Closed) {
                    throw new SSHChannelInvalidOperationException("Channel already closed");
                }

                SendRequest(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                        .WriteUInt32(RemoteChannel)
                        .WriteString("window-change")
                        .WriteBool(false)
                        .WriteUInt32(width)
                        .WriteUInt32(height)
                        .WriteUInt32(pixelWidth)
                        .WriteUInt32(pixelHeight)
                );
            }

            _protocolEventManager.Trace(
                "CH[{0}] window-change : width={1} height={2} pixelWidth={3} pixelHeight={4}",
                LocalChannel, width, height, pixelWidth, pixelHeight);
        }

        ///
        /// Block execution of the current thread until the channel is ready for the communication.
        ///
        /// <returns>
        /// true if this channel is ready for the communication.

        /// false if this channel failed to open.

        /// false if this channel is going to close or is already closed.
        /// </returns>
        public bool WaitReady() {
            // quick check before the lock block
            if (_state == State.Ready) {
                return true;
            }
            lock (_stateSync) {
                while (true) {
                    if (_state == State.Ready) {
                        return true;
                    }
                    if (_state == State.Closing || _state == State.Closed) {
                        return false;
                    }
                    Monitor.Wait(_stateSync);
                }
            }
        }

        ///
        /// Send data.
        ///
        /// <param name="data">data to send</param>
        /// <exception cref="SSHChannelInvalidOperationException">the channel is already closed.</exception>
        public void Send(DataFragment data) {
            lock (_stateSync) {
                if (_state == State.Closing || _state == State.Closed) {
                    throw new SSHChannelInvalidOperationException("Channel already closed");
                }

                int offset = data.Offset;
                int length = data.Length;
                int maxSize = MaxChannelDatagramSize;

                do {
                    int datagramSize = (length > maxSize) ? maxSize : length;
                    Transmit(
                        datagramSize,
                        new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_DATA)
                            .WriteUInt32(RemoteChannel)
                            .WriteAsString(data.Data, offset, datagramSize)
                    );
                    offset += datagramSize;
                    length -= datagramSize;
                } while (length > 0);
            }
        }

        ///
        /// Send EOF.
        ///
        /// <exception cref="SSHChannelInvalidOperationException">the channel is already closed.</exception>
        public void SendEOF() {
            lock (_stateSync) {
                if (_state == State.Closing || _state == State.Closed) {
                    throw new SSHChannelInvalidOperationException("Channel already closed");
                }

                Transmit(
                    0,
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_EOF)
                        .WriteUInt32(RemoteChannel)
                );
            }

            _protocolEventManager.Trace("CH[{0}] send EOF", LocalChannel);
        }

        ///
        /// Send Break. (SSH2, session channel only)
        ///
        /// <param name="breakLength">break-length in milliseconds</param>
        /// <returns>true if succeeded. false if the request failed.</returns>
        /// <exception cref="SSHChannelInvalidOperationException">the channel is already closed.</exception>
        public virtual bool SendBreak(int breakLength) {
            // derived class can override this.
            return false;
        }

        ///
        /// Close this channel.
        ///
        /// <remarks>
        /// After calling this method, all mothods of the <see cref="ISSHChannel"/> will throw <see cref="SSHChannelInvalidOperationException"/>.
        /// </remarks>
        /// <remarks>
        /// If this method was called under the inappropriate channel state, the method call will be ignored silently.
        /// </remarks>
        public void Close() {
            // quick check for avoiding deadlock
            if (_state != State.Established && _state != State.Ready) {
                return;
            }

            lock (_stateSync) {
                if (_state != State.Established && _state != State.Ready) {
                    return;
                }

                _state = State.Closing;
                Monitor.PulseAll(_stateSync);   // notifies state change
            }

            _handler.OnClosing(false);

            Transmit(
                0,
                new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_CLOSE)
                    .WriteUInt32(RemoteChannel)
            );

            _protocolEventManager.Trace("CH[{0}] SSH_MSG_CHANNEL_CLOSE", LocalChannel);
        }

        #endregion

        ///
        /// Sets handler
        ///
        /// <param name="handler"></param>
        public void SetHandler(ISSHChannelEventHandler handler) {
            _handler = new SSHChannelEventHandlerIgnoreErrorWrapper(handler);
        }

        ///
        /// Sends SSH_MSG_CHANNEL_OPEN
        ///
        public void SendOpen() {
            Transmit(0, BuildOpenPacket());
            _protocolEventManager.Trace(
                "CH[{0}] SSH_MSG_CHANNEL_OPEN channelType={1} windowSize={2} maxPacketSize={3}",
                LocalChannel, ChannelTypeString, _localWindowSize, _localMaxPacketSize);
        }

        ///
        /// Builds SSH_MSG_CHANNEL_OPEN packet
        ///
        protected virtual SSH2Packet BuildOpenPacket() {
            return new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_OPEN)
                        .WriteString(ChannelTypeString)
                        .WriteUInt32(LocalChannel)
                        .WriteInt32(_localWindowSize)
                        .WriteInt32(_localMaxPacketSize);
        }

        ///
        /// Sends SSH_MSG_CHANNEL_OPEN_CONFIRMATION
        ///
        /// <exception cref="InvalidOperationException">inappropriate channel state</exception>
        public void SendOpenConfirmation() {
            lock (_stateSync) {
                if (_state != State.InitiatedByServer) {
                    throw new InvalidOperationException();
                }

                Transmit(
                    0,
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION)
                        .WriteUInt32(RemoteChannel)
                        .WriteUInt32(LocalChannel)
                        .WriteInt32(_localWindowSize)
                        .WriteInt32(_localMaxPacketSize)
                );

                _state = State.Established;
                Monitor.PulseAll(_stateSync);   // notifies state change
            }

            _protocolEventManager.Trace(
                "CH[{0}] SSH_MSG_CHANNEL_OPEN_CONFIRMATION windowSize={1} maxPacketSize={2}",
                LocalChannel, _localWindowSize, _localMaxPacketSize);

            _handler.OnEstablished(new DataFragment(0));
            OnChannelEstablished();
        }

        ///
        /// Do additional work when <see cref="State"/> was changed to <see cref="State.Established"/>.
        ///
        /// <returns>true if the channel is ready for use.</returns>
        protected virtual void OnChannelEstablished() {
            // derived class can override this.
            SetStateReady();
        }

        ///
        /// The derived class can change state from "Established" to "Ready" by calling this method.
        ///
        protected void SetStateReady() {
            lock (_stateSync) {
                if (_state == State.Established) {
                    _state = State.Ready;
                    Monitor.PulseAll(_stateSync);   // notifies state change
                }
            }
            _handler.OnReady();
        }

        ///
        /// The derived class can change state from "Established" to "Closing" by calling this method.
        ///
        protected void RequestFailed() {
            lock (_stateSync) {
                if (_state == State.Established) {
                    goto Close;
                }
                else if (_state == State.InitiatedByClient) {
                    goto SetStateClosedByClient;
                }
            }

            return;

        Close:
            _handler.OnRequestFailed();
            Close();
            return;

        SetStateClosedByClient:
            _handler.OnRequestFailed();
            SetStateClosed(false);
            return;
        }

        ///
        /// Set state to "Closed".
        ///
        /// <param name="byServer"></param>
        private void SetStateClosed(bool byServer) {
            lock (_stateSync) {
                if (_state == State.Closed) {
                    return;
                }
                if (_state == State.Closing) {
                    _state = State.Closed;
                    Monitor.PulseAll(_stateSync);   // notifies state change
                    goto OnClosed;
                }
                _state = State.Closing;
                Monitor.PulseAll(_stateSync);   // notifies state change
            }

            _handler.OnClosing(byServer);

            lock (_stateSync) {
                if (_state == State.Closed) {   // state transition has occurred in OnClosing()
                    return;
                }
                _state = State.Closed;
                Monitor.PulseAll(_stateSync);   // notifies state change
            }

        OnClosed:
            _handler.OnClosed(byServer);

            Die();
        }

        ///
        /// Process packet additionally.
        ///
        /// <remarks>
        /// This method will be called repeatedly while <see cref="State"/> is <see cref="State.Established"/> or <see cref="State.Ready"/>.
        /// </remarks>
        /// <param name="packetType">a packet type (message number)</param>
        /// <param name="packetFragment">a packet image except message number and recipient channel.</param>
        /// <returns>result</returns>
        protected virtual SubPacketProcessResult ProcessPacketSub(SSH2PacketType packetType, DataFragment packetFragment) {
            // derived class can override this.
            return SubPacketProcessResult.NotConsumed;
        }

        ///
        /// Process packet about this channel.
        ///
        /// <param name="packetType">a packet type (message number)</param>
        /// <param name="packetFragment">a packet image except message number and recipient channel.</param>
        public void ProcessPacket(SSH2PacketType packetType, DataFragment packetFragment) {
            if (_state == State.Closed) {
                return; // ignore
            }

            DataFragment dataFragmentArg;
            uint dataTypeCodeArg;

            lock (_stateSync) {
                switch (_state) {
                    case State.InitiatedByServer:
                        break;
                    case State.InitiatedByClient:
                        if (packetType == SSH2PacketType.SSH_MSG_CHANNEL_OPEN_CONFIRMATION) {
                            SSH2DataReader reader = new SSH2DataReader(packetFragment);
                            RemoteChannel = reader.ReadUInt32();
                            _serverWindowSizeLeft = reader.ReadUInt32();
                            _serverMaxPacketSize = reader.ReadUInt32();

                            _state = State.Established;
                            Monitor.PulseAll(_stateSync);   // notifies state change
                            dataFragmentArg = reader.GetRemainingDataView();
                            goto OnEstablished; // do it out of the lock block
                        }
                        if (packetType == SSH2PacketType.SSH_MSG_CHANNEL_OPEN_FAILURE) {
                            SSH2DataReader reader = new SSH2DataReader(packetFragment);
                            uint reasonCode = reader.ReadUInt32();
                            string description = reader.ReadUTF8String();
                            string lang = reader.ReadString();
                            goto RequestFailed; // do it out of the lock block
                        }
                        break;
                    case State.Closing:
                        if (packetType == SSH2PacketType.SSH_MSG_CHANNEL_CLOSE) {
                            goto SetStateClosedByClient;    // do it out of the lock block
                        }
                        break;
                    case State.Established:
                    case State.Ready:
                        if (ProcessPacketSub(packetType, packetFragment) == SubPacketProcessResult.Consumed) {
                            return;
                        }
                        switch (packetType) {
                            case SSH2PacketType.SSH_MSG_CHANNEL_DATA: {
                                    SSH2DataReader reader = new SSH2DataReader(packetFragment);
                                    int len = reader.ReadInt32();
                                    dataFragmentArg = reader.GetRemainingDataView(len);
                                    AdjustWindowSize(len);
                                }
                                goto OnData;    // do it out of the lock block
                            case SSH2PacketType.SSH_MSG_CHANNEL_EXTENDED_DATA: {
                                    SSH2DataReader reader = new SSH2DataReader(packetFragment);
                                    dataTypeCodeArg = reader.ReadUInt32();
                                    int len = reader.ReadInt32();
                                    dataFragmentArg = reader.GetRemainingDataView(len);
                                    AdjustWindowSize(len);
                                }
                                goto OnExtendedData;    // do it out of the lock block
                            case SSH2PacketType.SSH_MSG_CHANNEL_REQUEST: {
                                    SSH2DataReader reader = new SSH2DataReader(packetFragment);
                                    string request = reader.ReadString();
                                    bool wantReply = reader.ReadBool();
                                    if (wantReply) { //we reject unknown requests including keep-alive check
                                        Transmit(
                                            0,
                                            new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_FAILURE)
                                                .WriteUInt32(RemoteChannel)
                                        );
                                    }
                                }
                                break;
                            case SSH2PacketType.SSH_MSG_CHANNEL_EOF:
                                goto OnEOF; // do it out of the lock block
                            case SSH2PacketType.SSH_MSG_CHANNEL_CLOSE:
                                Transmit(
                                    0,
                                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_CLOSE)
                                        .WriteUInt32(RemoteChannel)
                                );
                                goto SetStateClosedByServer;    // do it out of the lock block
                            case SSH2PacketType.SSH_MSG_CHANNEL_WINDOW_ADJUST: {
                                    SSH2DataReader reader = new SSH2DataReader(packetFragment);
                                    uint bytesToAdd = reader.ReadUInt32();
                                    // some servers may not send SSH_MSG_CHANNEL_WINDOW_ADJUST.
                                    // it is dangerous to wait this message in send procedure
                                    _serverWindowSizeLeft += bytesToAdd;
                                }
                                goto OnWindowAdjust;
                            case SSH2PacketType.SSH_MSG_CHANNEL_SUCCESS:
                            case SSH2PacketType.SSH_MSG_CHANNEL_FAILURE: {
                                    _channelRequestResult.TrySet(packetType == SSH2PacketType.SSH_MSG_CHANNEL_SUCCESS, 1000);
                                }
                                break;
                            default:
                                goto OnUnhandledPacket;
                        }
                        break;  // case State.Ready
                }
            }

            return;

        OnEstablished:
            _protocolEventManager.Trace(
                "CH[{0}] remoteCH={1} remoteWindowSize={2} remoteMaxPacketSize={3}",
                LocalChannel, RemoteChannel, _serverWindowSizeLeft, _serverMaxPacketSize);
            _handler.OnEstablished(dataFragmentArg);
            OnChannelEstablished();
            return;

        RequestFailed:
            _protocolEventManager.Trace("CH[{0}] request failed", LocalChannel);
            RequestFailed();
            return;

        SetStateClosedByClient:
            _protocolEventManager.Trace("CH[{0}] closed completely", LocalChannel);
            SetStateClosed(false);
            return;

        SetStateClosedByServer:
            _protocolEventManager.Trace("CH[{0}] closed by server", LocalChannel);
            SetStateClosed(true);
            return;

        OnData:
            _handler.OnData(dataFragmentArg);
            return;

        OnExtendedData:
            _handler.OnExtendedData(dataTypeCodeArg, dataFragmentArg);
            return;

        OnEOF:
            _protocolEventManager.Trace("CH[{0}] caught EOF", LocalChannel);
            _handler.OnEOF();
            return;

        OnWindowAdjust:
            _protocolEventManager.Trace(
                "CH[{0}] adjusted remote window size to {1}",
                LocalChannel, _serverWindowSizeLeft);
            return;

        OnUnhandledPacket:
            _handler.OnUnhandledPacket((byte)packetType, packetFragment);
            return;

        }

        ///
        /// Sends a packet.
        ///
        /// <param name="consumedSize">consumed window size.</param>
        /// <param name="packet">packet object</param>
        protected void Transmit(int consumedSize, SSH2Packet packet) {
            if (_serverWindowSizeLeft < (uint)consumedSize) {
                // FIXME: currently, window size on the remote side is totally ignored...
                _serverWindowSizeLeft = 0;
            }
            else {
                _serverWindowSizeLeft -= (uint)consumedSize;
            }

            _packetSender.Send(packet);
        }

        ///
        /// Outputs Trace message.
        ///
        /// <param name="format">format string</param>
        /// <param name="args">format arguments</param>
        protected void Trace(string format, params object[] args) {
            _protocolEventManager.Trace(format, args);
        }

        ///
        /// Adjust window size.
        ///
        /// <param name="dataLength">consumed length.</param>
        private void AdjustWindowSize(int dataLength) {
            _localWindowSizeLeft = Math.Max(_localWindowSizeLeft - dataLength, 0);

            if (_localWindowSizeLeft < _localWindowSize / 2) {
                Transmit(
                    0,
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_WINDOW_ADJUST)
                        .WriteUInt32(RemoteChannel)
                        .WriteInt32(_localWindowSize - _localWindowSizeLeft)
                );

                _protocolEventManager.Trace(
                    "CH[{0}] adjusted local window size : {1} --> {2}",
                    LocalChannel, _localWindowSizeLeft, _localWindowSize);

                _localWindowSizeLeft = _localWindowSize;
            }
        }

        ///
        /// Notifies terminating this channel.
        ///
        protected void Die() {
            if (Died != null) {
                Died(this);
            }
        }

        #endregion
    }

    ///
    /// SSH2 channel operator for the session.
    ///
    internal class SSH2SessionChannel : SSH2ChannelBase {
        #region

        private const ChannelType CHANNEL_TYPE = ChannelType.Session;
        private const string CHANNEL_TYPE_STRING = "session";

        ///
        /// Constructor (initiated by client)
        ///
        public SSH2SessionChannel(
                SSHTimeouts timeouts,
                IPacketSender<SSH2Packet> packetSender,
                SSHConnectionParameter param,
                SSHProtocolEventManager protocolEventManager,
                uint localChannel)
            : base(timeouts, packetSender, param, protocolEventManager, localChannel, CHANNEL_TYPE, CHANNEL_TYPE_STRING) {
        }

        ///
        /// Send Break. (SSH2, session channel only)
        ///
        /// <param name="breakLength">break-length in milliseconds</param>
        /// <returns>true if succeeded. false if the request failed.</returns>
        /// <exception cref="SSHChannelInvalidOperationException">the channel is already closed.</exception>
        public override bool SendBreak(int breakLength) {
            if (MajorState == State.Closing || MajorState == State.Closed) {
                throw new SSHChannelInvalidOperationException("Channel already closed");
            }

            var reqTask =
                SendRequestAndWaitResponseAsync(
                            new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                                .WriteUInt32(RemoteChannel)
                                .WriteString("break")
                                .WriteBool(true)
                                .WriteInt32(breakLength)
                );

            Trace("CH[{0}] break : breakLength={1}", LocalChannel, breakLength);

            var result = reqTask.Result;

            return result == ChannelRequestResult.Success;
        }

        #endregion
    }

    ///
    /// SSH2 channel operator for the shell.
    ///
    internal class SSH2ShellChannel : SSH2SessionChannel {
        #region

        private enum MinorState {
            /// initial state
            NotReady,
            /// waiting SSH_MSG_CHANNEL_SUCCESS | SSH_MSG_CHANNEL_FAILURE for "pty-req" request
            WaitPtyReqConfirmation,
            /// waiting SSH_MSG_CHANNEL_SUCCESS | SSH_MSG_CHANNEL_FAILURE for "auth-agent-req@openssh.com" request
            WaitAuthAgentReqConfirmation,
            /// waiting SSH_MSG_CHANNEL_SUCCESS | SSH_MSG_CHANNEL_FAILURE for "x11-req" request
            WaitX11ReqConfirmation,
            /// waiting SSH_MSG_CHANNEL_SUCCESS | SSH_MSG_CHANNEL_FAILURE for "shell" request
            WaitShellConfirmation,
            ///
            Ready,
        }

        private readonly SSHConnectionParameter _param;
        // X11 connection manager (null if X11 forwarding is inactive)
        private readonly X11ConnectionManager _x11ConnectionManager;

        private volatile MinorState _state;
        private readonly object _stateSync = new object();

        ///
        /// Constructor (initiated by client)
        ///
        public SSH2ShellChannel(
                SSHTimeouts timeouts,
                IPacketSender<SSH2Packet> packetSender,
                SSHConnectionParameter param,
                SSHProtocolEventManager protocolEventManager,
                uint localChannel,
                X11ConnectionManager x11ConnectionManager)
            : base(timeouts, packetSender, param, protocolEventManager, localChannel) {
            _param = param;
            _x11ConnectionManager = x11ConnectionManager;
        }

        ///
        /// Do additional work when <see cref="SSH2ChannelBase.State"/> was changed to <see cref="SSH2ChannelBase.State.Established"/>.
        ///
        /// <returns>true if the channel is ready for use.</returns>
        protected override void OnChannelEstablished() {
            Task.Run(() => {
                var reqPtyResult = SendPtyRequest();
                if (!reqPtyResult) {
                    return;
                }

                var reqAuthAgentResult = SendAuthAgentRequest();
                if (!reqAuthAgentResult) {
                    return;
                }

                var reqX11Result = SendX11Request();
                if (!reqX11Result) {
                    return;
                }

                var reqShellResult = SendShellRequest();
                if (!reqShellResult) {
                    return;
                }
            });
        }

        ///
        /// Sends SSH_MSG_CHANNEL_REQUEST "pty-req"
        ///
        private bool SendPtyRequest() {
            lock (_stateSync) {
                if (_state != MinorState.NotReady) {
                    return false;
                }
                _state = MinorState.WaitPtyReqConfirmation;
            }

            var reqTask =
                SendRequestAndWaitResponseAsync(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                        .WriteUInt32(RemoteChannel)
                        .WriteString("pty-req")
                        .WriteBool(true)
                        .WriteString(_param.TerminalName)
                        .WriteInt32(_param.TerminalWidth)
                        .WriteInt32(_param.TerminalHeight)
                        .WriteInt32(_param.TerminalPixelWidth)
                        .WriteInt32(_param.TerminalPixelHeight)
                        .WriteAsString(new byte[0])
                );

            Trace("CH[{0}] pty-req : term={1} width={2} height={3} pixelWidth={4} pixelHeight={5}",
                LocalChannel, _param.TerminalName,
                _param.TerminalWidth, _param.TerminalHeight,
                _param.TerminalPixelWidth, _param.TerminalPixelHeight);

            var result = reqTask.Result;

            lock (_stateSync) {
                if (_state != MinorState.WaitPtyReqConfirmation) {
                    return false;
                }
                if (result == ChannelRequestResult.Success) {
                    return true;    // do the next task
                }
                else {
                    _state = MinorState.NotReady;
                    goto RequestFailed;
                }
            }

        RequestFailed:
            RequestFailed();
            return false;
        }

        ///
        /// Sends SSH_MSG_CHANNEL_REQUEST "auth-agent-req@openssh.com"
        ///
        private bool SendAuthAgentRequest() {
            if (_param.AgentForwardingAuthKeyProvider == null) {
                return true;    // do the next task
            }

            lock (_stateSync) {
                _state = MinorState.WaitAuthAgentReqConfirmation;
            }

            var reqTask =
                SendRequestAndWaitResponseAsync(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                        .WriteUInt32(RemoteChannel)
                        .WriteString("auth-agent-req@openssh.com")
                        .WriteBool(true)
                );

            Trace("CH[{0}] auth-agent-req@openssh.com", LocalChannel);

            var result = reqTask.Result;

            lock (_stateSync) {
                if (_state != MinorState.WaitAuthAgentReqConfirmation) {
                    return false;
                }
                if (result == ChannelRequestResult.Success) {
                    Trace("CH[{0}] the request of the agent forwarding has been accepted.", LocalChannel);
                    return true;    // do the next task
                }
                else {
                    Trace("CH[{0}] the request of the agent forwarding has been rejected.", LocalChannel);
                    _state = MinorState.NotReady;
                    goto RequestFailed;
                }
            }

        RequestFailed:
            RequestFailed();
            return false;
        }

        ///
        /// Sends SSH_MSG_CHANNEL_REQUEST "x11-req"
        ///
        private bool SendX11Request() {
            if (_param.X11ForwardingParams == null || _x11ConnectionManager == null) {
                return true;    // do the next task
            }

            lock (_stateSync) {
                _state = MinorState.WaitX11ReqConfirmation;
            }

            var reqTask =
                SendRequestAndWaitResponseAsync(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                        .WriteUInt32(RemoteChannel)
                        .WriteString("x11-req")
                        .WriteBool(true)
                        .WriteBool(false)   // not single-connection
                        .WriteString(_x11ConnectionManager.SpoofedAuthProtocolName)
                        .WriteString(_x11ConnectionManager.SpoofedAuthProtocolDataHex)
                        .WriteUInt32((uint)_x11ConnectionManager.Params.Screen) // screen number
                );

            Trace("CH[{0}] x11-req", LocalChannel);

            var result = reqTask.Result;

            lock (_stateSync) {
                if (_state != MinorState.WaitX11ReqConfirmation) {
                    return false;
                }
                if (result == ChannelRequestResult.Success) {
                    Trace("CH[{0}] the request of the X11 forwarding has been accepted.", LocalChannel);
                    return true;    // do the next task
                }
                else {
                    Trace("CH[{0}] the request of the X11 forwarding has been rejected.", LocalChannel);
                    _state = MinorState.NotReady;
                    goto RequestFailed;
                }
            }

        RequestFailed:
            RequestFailed();
            return false;
        }

        ///
        /// Sends SSH_MSG_CHANNEL_REQUEST "shell"
        ///
        private bool SendShellRequest() {
            lock (_stateSync) {
                _state = MinorState.WaitShellConfirmation;
            }

            var reqTask =
                SendRequestAndWaitResponseAsync(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                        .WriteUInt32(RemoteChannel)
                        .WriteString("shell")
                        .WriteBool(true)
                );

            Trace("CH[{0}] shell", LocalChannel);

            var result = reqTask.Result;

            lock (_stateSync) {
                if (_state != MinorState.WaitShellConfirmation) {
                    return false;
                }
                if (result == ChannelRequestResult.Success) {
                    _state = MinorState.Ready;
                    goto SetStateReady;
                }
                else {
                    _state = MinorState.NotReady;
                    goto RequestFailed;
                }
            }

        SetStateReady:
            SetStateReady();
            return true;

        RequestFailed:
            RequestFailed();
            return false;
        }

        #endregion
    }

    ///
    /// SSH2 channel operator for the command execution.
    ///
    internal class SSH2ExecChannel : SSH2SessionChannel {
        #region

        private enum MinorState {
            /// initial state
            NotReady,
            /// waiting SSH_MSG_CHANNEL_SUCCESS | SSH_MSG_CHANNEL_FAILURE for "exec" request
            WaitExecConfirmation,
            ///
            Ready,
        }

        private readonly string _command;

        private volatile MinorState _state;
        private readonly object _stateSync = new object();

        ///
        /// Constructor (initiated by client)
        ///
        public SSH2ExecChannel(
                SSHTimeouts timeouts,
                IPacketSender<SSH2Packet> packetSender,
                SSHConnectionParameter param,
                SSHProtocolEventManager protocolEventManager,
                uint localChannel,
                string command)
            : base(timeouts, packetSender, param, protocolEventManager, localChannel) {

            _command = command;
        }

        ///
        /// Do additional work when <see cref="SSH2ChannelBase.State"/> was changed to <see cref="SSH2ChannelBase.State.Established"/>.
        ///
        /// <returns>true if the channel is ready for use.</returns>
        protected override void OnChannelEstablished() {
            Task.Run(() => SendExecRequest());
        }

        ///
        /// Sends SSH_MSG_CHANNEL_REQUEST "exec"
        ///
        private void SendExecRequest() {
            lock (_stateSync) {
                if (_state != MinorState.NotReady) {
                    return;
                }
                _state = MinorState.WaitExecConfirmation;
            }

            var reqTask =
                SendRequestAndWaitResponseAsync(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                        .WriteUInt32(RemoteChannel)
                        .WriteString("exec")
                        .WriteBool(true)
                        .WriteString(_command)
                );

            Trace("CH[{0}] exec : command={1}", LocalChannel, _command);

            var result = reqTask.Result;

            lock (_stateSync) {
                if (_state != MinorState.WaitExecConfirmation) {
                    return;
                }
                if (result == ChannelRequestResult.Success) {
                    _state = MinorState.Ready;
                    goto SetStateReady;
                }
                else {
                    _state = MinorState.NotReady;
                    goto RequestFailed;
                }
            }

        SetStateReady:
            SetStateReady();
            return;

        RequestFailed:
            RequestFailed();
            return;
        }

        #endregion
    }

    ///
    /// SSH2 channel operator for the subsystem.
    ///
    internal class SSH2SubsystemChannel : SSH2SessionChannel {
        #region

        private enum MinorState {
            /// initial state
            NotReady,
            /// waiting SSH_MSG_CHANNEL_SUCCESS | SSH_MSG_CHANNEL_FAILURE for "subsystem" request
            WaitSubsystemConfirmation,
            ///
            Ready,
        }

        private readonly string _subsystemName;

        private volatile MinorState _state;
        private readonly object _stateSync = new object();

        ///
        /// Constructor (initiated by client)
        ///
        public SSH2SubsystemChannel(
                SSHTimeouts timeouts,
                IPacketSender<SSH2Packet> packetSender,
                SSHConnectionParameter param,
                SSHProtocolEventManager protocolEventManager,
                uint localChannel,
                string subsystemName)
            : base(timeouts, packetSender, param, protocolEventManager, localChannel) {

            _subsystemName = subsystemName;
        }

        ///
        /// Do additional work when <see cref="SSH2ChannelBase.State"/> was changed to <see cref="SSH2ChannelBase.State.Established"/>.
        ///
        /// <returns>true if the channel is ready for use.</returns>
        protected override void OnChannelEstablished() {
            Task.Run(() => SendSubsystemRequest());
        }

        ///
        /// Sends SSH_MSG_CHANNEL_REQUEST "subsystem"
        ///
        private void SendSubsystemRequest() {
            lock (_stateSync) {
                if (_state != MinorState.NotReady) {
                    return;
                }
                _state = MinorState.WaitSubsystemConfirmation;
            }

            var reqTask =
                SendRequestAndWaitResponseAsync(
                    new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_REQUEST)
                        .WriteUInt32(RemoteChannel)
                        .WriteString("subsystem")
                        .WriteBool(true)
                        .WriteString(_subsystemName)
                );

            Trace("CH[{0}] subsystem : subsystem={1}", LocalChannel, _subsystemName);

            var result = reqTask.Result;

            lock (_stateSync) {
                if (_state != MinorState.WaitSubsystemConfirmation) {
                    return;
                }
                if (result == ChannelRequestResult.Success) {
                    _state = MinorState.Ready;
                    goto SetStateReady;
                }
                else {
                    _state = MinorState.NotReady;
                    goto RequestFailed;
                }
            }

        SetStateReady:
            SetStateReady();
            return;

        RequestFailed:
            RequestFailed();
            return;
        }

        #endregion
    }

    ///
    /// SSH2 channel operator for the local port forwarding.
    ///
    internal class SSH2LocalPortForwardingChannel : SSH2ChannelBase {
        #region

        private const ChannelType CHANNEL_TYPE = ChannelType.ForwardedLocalToRemote;
        private const string CHANNEL_TYPE_STRING = "direct-tcpip";

        private readonly int _localWindowSize;
        private readonly int _localMaxPacketSize;
        private readonly string _remoteHost;
        private readonly uint _remotePort;
        private readonly string _originatorIp;
        private readonly uint _originatorPort;

        ///
        /// Constructor (initiated by client)
        ///
        public SSH2LocalPortForwardingChannel(
                SSHTimeouts timeouts,
                IPacketSender<SSH2Packet> packetSender,
                SSHConnectionParameter param,
                SSHProtocolEventManager protocolEventManager,
                uint localChannel,
                string remoteHost,
                uint remotePort,
                string originatorIp,
                uint originatorPort)
            : base(timeouts, packetSender, param, protocolEventManager, localChannel, CHANNEL_TYPE, CHANNEL_TYPE_STRING) {

            _localWindowSize = param.WindowSize;
            _localMaxPacketSize = param.WindowSize;
            _remoteHost = remoteHost;
            _remotePort = remotePort;
            _originatorIp = originatorIp;
            _originatorPort = originatorPort;
        }

        ///
        /// Builds SSH_MSG_CHANNEL_OPEN packet
        ///
        protected override SSH2Packet BuildOpenPacket() {
            return new SSH2Packet(SSH2PacketType.SSH_MSG_CHANNEL_OPEN)
                    .WriteString("direct-tcpip")
                    .WriteUInt32(LocalChannel)
                    .WriteInt32(_localWindowSize)
                    .WriteInt32(_localMaxPacketSize)
                    .WriteString(_remoteHost)
                    .WriteUInt32(_remotePort)
                    .WriteString(_originatorIp)
                    .WriteUInt32(_originatorPort);
        }

        #endregion
    }

    ///
    /// SSH2 channel operator for the remote port forwarding.
    ///
    internal class SSH2RemotePortForwardingChannel : SSH2ChannelBase {
        #region

        private const ChannelType CHANNEL_TYPE = ChannelType.ForwardedRemoteToLocal;
        private const string CHANNEL_TYPE_STRING = "forwarded-tcpip";

        ///
        /// Constructor (initiated by server)
        ///
        public SSH2RemotePortForwardingChannel(
                SSHTimeouts timeouts,
                IPacketSender<SSH2Packet> packetSender,
                SSHConnectionParameter param,
                SSHProtocolEventManager protocolEventManager,
                uint localChannel,
                uint remoteChannel,
                uint serverWindowSize,
                uint serverMaxPacketSize)
            : base(timeouts, packetSender, param, protocolEventManager, localChannel, remoteChannel, CHANNEL_TYPE, CHANNEL_TYPE_STRING, serverWindowSize, serverMaxPacketSize) {
        }

        #endregion
    }

    ///
    /// SSH2 channel operator for OpenSSH's agent forwarding.
    ///
    internal class SSH2OpenSSHAgentForwardingChannel : SSH2ChannelBase {
        #region

        private const ChannelType CHANNEL_TYPE = ChannelType.AgentForwarding;
        private const string CHANNEL_TYPE_STRING = "auth-agent@openssh.com";

        ///
        /// Constructor (initiated by server)
        ///
        public SSH2OpenSSHAgentForwardingChannel(
                SSHTimeouts timeouts,
                IPacketSender<SSH2Packet> packetSender,
                SSHConnectionParameter param,
                SSHProtocolEventManager protocolEventManager,
                uint localChannel,
                uint remoteChannel,
                uint serverWindowSize,
                uint serverMaxPacketSize)
            : base(timeouts, packetSender, param, protocolEventManager, localChannel, remoteChannel, CHANNEL_TYPE, CHANNEL_TYPE_STRING, serverWindowSize, serverMaxPacketSize) {
        }

        #endregion
    }

    ///
    /// SSH2 channel operator for the X11 forwarding.
    ///
    internal class SSH2X11ForwardingChannel : SSH2ChannelBase {
        #region

        private const ChannelType CHANNEL_TYPE = ChannelType.X11Forwarding;
        private const string CHANNEL_TYPE_STRING = "x11";

        ///
        /// Constructor (initiated by server)
        ///
        public SSH2X11ForwardingChannel(
                SSHTimeouts timeouts,
                IPacketSender<SSH2Packet> packetSender,
                SSHConnectionParameter param,
                SSHProtocolEventManager protocolEventManager,
                uint localChannel,
                uint remoteChannel,
                uint serverWindowSize,
                uint serverMaxPacketSize)
            : base(timeouts, packetSender, param, protocolEventManager, localChannel, remoteChannel, CHANNEL_TYPE, CHANNEL_TYPE_STRING, serverWindowSize, serverMaxPacketSize) {
        }

        #endregion
    }

}


text:
package org.basex.gui.dialog;

import static org.basex.core.Text.*;
import static org.basex.util.Strings.*;

import java.io.*;
import java.util.*;

import javax.swing.*;

import org.basex.core.*;
import org.basex.core.MainOptions.MainParser;
import org.basex.gui.*;
import org.basex.gui.layout.*;
import org.basex.gui.layout.BaseXFileChooser.*;
import org.basex.gui.layout.BaseXLayout.*;
import org.basex.io.*;
import org.basex.io.in.*;
import org.basex.util.*;
import org.basex.util.list.*;

/**
 * Panel for importing new database resources. Embedded by both the database creation and
 * properties dialog.
 *
 * @author BaseX Team 2005-22, BSD License
 * @author Christian Gruen
 */
final class DialogImport extends BaseXBack {
  /** User feedback. */
  final BaseXLabel info;
  /** Resource to add. */
  final BaseXCombo input;
  /** Browse button. */
  final BaseXButton browse;
  /** Chosen parser. */
  final BaseXCombo parsers;
  /** DB name. */
  String dbName;

  /** GUI reference. */
  private final GUI gui;
  /** Dialog reference. */
  private final BaseXDialog dialog;
  /** Parsing options. */
  private final DialogParsing parsing;
  /** Add contents of archives. */
  private final BaseXCheckBox addArchives;
  /** Prefix database path with name of archive. */
  private final BaseXCheckBox archiveName;
  /** Skip corrupt files. */
  private final BaseXCheckBox skipCorrupt;
  /** Add remaining files as binary files. */
  private final BaseXCheckBox addBinary;
  /** Document filter. */
  private final BaseXTextField createFilter;

  /**
   * Constructor.
   * @param dialog dialog reference
   * @param panel feature panel
   * @param parsing parsing dialog
   */
  DialogImport(final BaseXDialog dialog, final BaseXBack panel, final DialogParsing parsing) {
    this.dialog = dialog;
    this.parsing = parsing;
    gui = dialog.gui();

    layout(new RowLayout());
    border(8);

    // add options
    add(new BaseXLabel(FILE_OR_DIR + COL, true, true).border(0, 0, 6, 0));

    final String path = gui.gopts.get(GUIOptions.INPUTPATH);
    input = new BaseXCombo(dialog, true).history(GUIOptions.INPUTS, gui.gopts);
    BaseXLayout.setWidth(input, BaseXTextField.DWIDTH);
    input.setText(path);

    final IO io = IO.get(path);
    if(io instanceof IOFile && !path.isEmpty()) dbName = io.dbName();

    browse = new BaseXButton(dialog, BROWSE_D);
    browse.addActionListener(e -> choose());
    final BaseXBack b = new BaseXBack(new ColumnLayout(8));
    b.add(input);
    b.add(browse);
    add(b);

    // add additional options
    add(panel);
    add(Box.createVerticalStrut(12));

    final MainOptions opts = gui.context.options;
    final StringList ps = new StringList();
    for(final MainParser mp : MainParser.values()) ps.add(mp.name());
    parsers = new BaseXCombo(dialog, ps.finish());
    parsers.setSelectedItem(opts.get(MainOptions.PARSER).name());

    createFilter = new BaseXTextField(dialog, opts.get(MainOptions.CREATEFILTER));
    createFilter.setColumns(30);

    addBinary = new BaseXCheckBox(dialog, ADD_BINARY_FILES, MainOptions.ADDRAW, opts);
    skipCorrupt = new BaseXCheckBox(dialog, SKIP_CORRUPT_FILES, MainOptions.SKIPCORRUPT, opts);
    addArchives = new BaseXCheckBox(dialog, PARSE_ARCHIVES, MainOptions.ADDARCHIVES, opts);
    archiveName = new BaseXCheckBox(dialog, ADD_ARCHIVE_NAME, MainOptions.ARCHIVENAME, opts);

    final BaseXBack p = new BaseXBack(new TableLayout(2, 2, 20, 0));
    p.add(new BaseXLabel(INPUT_FORMAT, false, true).border(0, 0, 6, 0));
    p.add(new BaseXLabel(FILE_PATTERNS + COL, false, true).border(0, 0, 6, 0));
    p.add(parsers);
    p.add(createFilter);
    add(p);
    add(Box.createVerticalStrut(8));
    add(addBinary);
    add(skipCorrupt);
    add(addArchives);
    add(archiveName);

    // add info label
    info = new BaseXLabel(" ").border(20, 0, 6, 0);
    add(info);

    final DropHandler dh = object -> {
      input.setText(object.toString());
      action(input, dialog instanceof DialogNew);
    };

    BaseXLayout.addDrop(this, dh);
    BaseXLayout.addDrop(input, dh);
  }

  /**
   * Returns the input field path string.
   * @return path
   */
  String input() {
    return input.getText().trim();
  }

  /**
   * Updates the dialog window.
   * @param comp component
   * @param empty allow empty input
   * @return success flag, or {@code false} if specified input is not found
   */
  boolean action(final Object comp, final boolean empty) {
    boolean ok = parsing.action();

    final String in = input.getText().trim();
    final IO io = IO.get(in);
    gui.gopts.set(GUIOptions.INPUTPATH, in);

    final boolean multi = io.isDir() || io.isArchive();
    addArchives.setEnabled(multi);
    createFilter.setEnabled(multi);
    archiveName.setEnabled(addArchives.isSelected());

    final MainParser parser = MainParser.valueOf(parsers.getSelectedItem());
    final boolean binary = parser == MainParser.RAW;
    addBinary.setEnabled(multi && !binary && !gui.context.options.get(MainOptions.MAINMEM));
    skipCorrupt.setEnabled(!binary);

    if(comp == parsers) {
      parsing.setType(parser);
      if(multi) createFilter.setText(binary ? "*" : "*." + parser);
    }

    ok &= empty ? in.isEmpty() || io.exists() : !in.isEmpty() && io.exists();
    if(ok && comp == input) setType(in);

    info.setText(null, null);
    return ok;
  }

  /**
   * Sets the parsing options.
   */
  void setOptions() {
    gui.set(MainOptions.PARSER, MainParser.valueOf(parsers.getSelectedItem()));
    gui.set(MainOptions.CREATEFILTER, createFilter.getText());
    gui.set(MainOptions.ADDARCHIVES, addArchives.isSelected());
    gui.set(MainOptions.ARCHIVENAME, archiveName.isSelected());
    gui.set(MainOptions.SKIPCORRUPT, skipCorrupt.isSelected());
    gui.set(MainOptions.ADDRAW, addBinary.isSelected());
    input.updateHistory();
    parsing.setOptions();
  }

  /**
   * Opens a file dialog to choose an input file or directory,
   * and updates the panel.
   */
  private void choose() {
    String path = input.getText();
    final BaseXFileChooser fc = new BaseXFileChooser(dialog, FILE_OR_DIR, path);
    fc.textFilters().filter(ZIP_ARCHIVES, false, IO.ZIPSUFFIXES);
    final IOFile file = fc.select(Mode.FDOPEN);
    if(file == null) return;

    gui.gopts.setFile(GUIOptions.INPUTPATH, file);
    path = file.path();
    input.setText(path);
    setType(path);
  }

  /**
   * Sets the correct input type.
   * @param in input path
   */
  void setType(final String in) {
    // get file path, update input path and database name
    final IO io = IO.get(in);
    if(!in.isEmpty() && io instanceof IOFile) dbName = io.dbName();

    final boolean dir = io.isDir();
    final boolean archive = io.isArchive();
    if(dir || archive) return;

    // evaluate input type
    MainParser type = null;
    // input type of single file
    final String path = io.path();
    final int i = path.lastIndexOf('.');
    if(i != -1) {
      // analyze file suffix
      final String suf = path.substring(i).toLowerCase(Locale.ENGLISH);
      if(eq(suf, gui.gopts.xmlSuffixes()) || eq(suf, IO.XSLSUFFIXES)) type = MainParser.XML;
      else if(eq(suf, IO.HTMLSUFFIXES)) type = MainParser.HTML;
      else if(eq(suf, IO.CSVSUFFIX)) type = MainParser.CSV;
      else if(eq(suf, IO.TXTSUFFIXES)) type = MainParser.TEXT;
      else if(eq(suf, IO.JSONSUFFIX)) type = MainParser.JSON;
    }
    // unknown suffix: analyze first bytes
    if(type == null) type = guess(io);
    // default parser: XML
    if(type == null) type = MainParser.XML;

    // choose correct parser (default: XML)
    parsers.setSelectedItem(type.name());
  }

  /**
   * Guesses the content type of the specified input.
   * @param in input stream
   * @return type or {@code null}
   */
  private static MainParser guess(final IO in) {
    if(!in.exists() || in instanceof IOUrl) return null;

    try(BufferInput bi = BufferInput.get(in)) {
      int b = bi.read();
      // input starts with opening bracket: may be xml
      if(b == '<') return MainParser.XML;

      for(int c = 0; b >= 0 && ++c < IO.BLOCKSIZE;) {
        // treat as binary data if characters are no ascii
        if(b < ' ' && !Token.ws(b) || b >= 128) return MainParser.RAW;
        b = bi.read();
      }
      // all characters were of type ascii
      return MainParser.TEXT;
    } catch(final IOException ex) {
      Util.debug(ex);
    }
    // could not evaluate type
    return null;
  }
}