text:
module Flugbuch

import CSV
import SQLite
using LightGraphs: Graph, connected_components, add_edge!
using PrettyTables
using Dates
using ArgParse
using IniFile
using DataFrames

abstract type Flighty end
const NumberedOld{T} = Tuple{Int, T}

struct Numbered{T}
	nr::Int
	value::T
end

include("flight.jl")
include("flight_group.jl")
include("flight_accumulator.jl")
include("util.jl")

export create, load, unload, prt, csv, help, n, p, expand, deadlines, rudi
export Date	# re-export

dbFilename = missing 		#::String
db = missing				#::SQLite.DB
selfNames = missing 		#::Vector{String}
bufferedFlighties = missing #::Vector{Numbered{<:Flighty}}

lastFrameBegin = missing
lastFrameEnd = missing

cErr = crayon"red"
cWarn = crayon"yellow"
cSucc = crayon"green"

function loadConfig(configFilename::String)
	if !isfile(configFilename)
		println(cWarn, "Konfigurationsdatei ~/.flugbuchrc nicht vorhanden.")
		return
	end

	conf = read(Inifile(), configFilename)

	s = get(conf, "", "mynames", "default")
	global selfNames = filter(x -> x != "", strip.(split(s, ";")))

	global dbFilename = get(conf, "", "defaultdb", missing)
end

function loadConfig()
	loadConfig(joinpath(homedir(), ".flugbuchrc"))
end

loadConfig()

function help()
	println()
	println("""Kommandos:
--------------------------------------------------------------------------------

 > create("foo.db")              Erstellt ein neues Flugbuch in der Datei
                                'foo.db' und öffnet es
 > load("foo.db")                Öffnet das Flugbuch in der Datei 'foo.db'
 > load()                        Öffnet das Standard-Flugbuch, das in der
                                 Konfigurationsdatei festgelegt ist
 > unload()                      Schließt das geöffnete Flugbuch
 > prt()                         Gibt das komplette Flugbuch aus
 > prt(10, 20)                   Gibt die Zeilen 10 bis 20 des Flugbuchs aus
 > prt(11)                       Gibt die Zeile 11 des Flugbuchs aus
 > csv("foo.csv")                Liest Flüge aus der CSV-Datei 'foo.csv' ein
 > help()                        Gibt diese Hilfe aus
 > n()                           Zeigt den nächsten Flug an
 > p()                           Zeigt den vorherigen Flug an
 > expand(34)                    Zeigt die in der Zeile 34 gruppierten Flüge
                                 einzeln an
 > deadlines()                   Zeigt an, ob die gesetzlichen Fristen zur Zeit
                                 erfüllt sind, und wann sie ablaufen werden

Zusatzparameter, die den meisten Funktionen mitgegeben werden können:
--------------------------------------------------------------------------------

 - beginNr = 10                  Beginne die Ausgabe mit Zeile 10
 - endNr = 50                    Beende die Ausgabe mit Zeile 50
 - beginDate = Date(2017,1,1)    Zeige nur Flüge am und nach dem 01.01.2017
 - endDate = Date(2019,2,1)      Zeige nur Flüge am und bis zum 01.02.2019
 - limitAircraft = 10            Kürze die Flugzeugtypen auf 10 Zeichen
 - limitPilots = 10              Kürze Pilot und Copilot auf 10 Zeichen
 - limitLocations = 10           Kürze Start- und Landeort auf 10 Zeichen
 - limitComments = 20            Kürze die Bemerkungen auf 10 Zeichen
 - frameGroups = true            Umrahme gruppierte Flüge
 - printSums= true               Gebe die Summen in der Fußzeile aus
""")
end

function deadlines()

end

function create(filename::String)
	if isdir(filename)
		println("Der angegebene Pfad '$filename' ist ein Verzeichnis.")
		return
	end
	if isfile(filename)
		println("Die Datei '$filename' ist bereits vorhanden.")
		return
	end

	global db = SQLite.DB(filename)

	SQLite.Query(db, "CREATE TABLE IF NOT EXISTS flights (
						id INTEGER PRIMARY KEY,
						nr INTEGER NOT NULL,
						callsign TEXT NULL,
						aircraftType TEXT NULL,
						pilot TEXT NOT NULL,
						copilot TEXT NULL,
						launch TEXT NOT NULL,
						date TEXT NOT NULL,
						departureTime TEXT NOT NULL,
						arrivalTime TEXT NOT NULL,
						numberOfLandings INTEGER NOT NULL default 1,
						departureLocation TEXT NULL,
						arrivalLocation TEXT NULL,
						dual BOOLEAN NOT NULL,
						instr BOOLEAN NOT NULL default false,
						comments TEXT NULL
						);")

	println(cSucc, "Flugbuch '$filename' erstellt und geöffnet.")
end

function rudi()
	if !ismissing(dbFilename)
		global db = SQLite.DB(dbFilename)
		#SQLite.execute(db, "SELECT * FROM flights LIMIT 1") |> DataFrame
		print(SQLite.execute(db, "SELECT * FROM flights"))
	else
		println(cWarn, "Kein Standard-Flugbuch in der Konfigurationsdatei festgelegt.")
	end
end

function load(filename::AbstractString)
	if !isfile(filename)
		println(cErr, "Datei '$filename' existiert nicht.")
		return
	end

	global db = SQLite.DB(filename)

	try
		SQLite.Query(db, "SELECT * FROM flights LIMIT 1");
	catch e
		println(cErr, "Fehler beim Lesen aus dem Flugbuch: $e")
		throw(e)
		db = missing
		return
	end

	println(cSucc, "Flugbuch '$filename' geöffnet.")
end

function load()
	if !ismissing(dbFilename)
		load(dbFilename)
	else
		println(cWarn, "Kein Standard-Flugbuch in der Konfigurationsdatei festgelegt.")
	end
end

function unload()
	if ismissing(db)
		println(cWarn, "Es war kein Flugbuch geladen.")
		return
	end

	global db = missing
	global lastFrameBegin = missing
	global lastFrameEnd = missing
	global bufferedFlighties = missing
	println(cSucc, "Flugbuch geschlossen.")
end

function prt(;
		beginDate = missing,
		endDate = missing,
		beginNr = missing,
		endNr = missing,
		kwargs...
	)

	if ismissing(bufferedFlighties)
		if !loadBuffer()
			return
		end
	end

	filteredFlighties = filter(bufferedFlighties) do f
		(ismissing(beginNr) || f.nr >= beginNr) &&
		(ismissing(endNr) || f.nr <= endNr) &&
		(ismissing(endDate) || date(f.value) <= endDate) &&
		(ismissing(beginDate) || date(f.value) >= beginDate)
	end

	if isempty(filteredFlighties)
	 	println("\nKeine Flüge entsprechen dem Filter.")
		global lastFrameBegin = missing
		global lastFrameEnd = missing
	 	return
	end

	last = filteredFlighties[end]
	allUpToLast = filter(f -> f.nr <= last.nr, bufferedFlighties)

	filteredAcc = FlightAccumulator([f.value for f in filteredFlighties])
	totalAcc = FlightAccumulator([f.value for f in allUpToLast])

	global lastFrameBegin = filteredFlighties[1].nr
	global lastFrameEnd = filteredFlighties[end].nr

	pretty_table(filteredFlighties, sums = [(filteredAcc, "Σ"), (totalAcc, "Σ (total)")]; kwargs...)
	nothing
end

function prt(beginNr::Int, endNr::Int; kwargs...)
	prt(beginNr=beginNr, endNr=endNr; kwargs...)
end

function prt(nr::Int; kwargs...)
	prt(beginNr=nr, endNr=nr; kwargs...)
end

function n(; kwargs...)
	if ismissing(lastFrameEnd)
		println(cWarn, "\nKein vorheriger Flug, dessen Nachfolger angezeigt werden kann.")
		return
	end
	prt(beginNr = lastFrameEnd+1, endNr = lastFrameEnd+1; kwargs...)
end

function p(; kwargs...)
	if ismissing(lastFrameBegin)
		println(cWarn, "\nKein vorheriger Flug, dessen Vorgänger angezeigt werden kann.")
		return
	end
	prt(beginNr = lastFrameBegin-1, endNr = lastFrameBegin-1; kwargs...)
end

function expand(nr::Int)

	if ismissing(bufferedFlighties)
		loadBuffer()
	end

	if nr < 1 || nr > length(bufferedFlighties)
		println(cErr, "\nUngültige Flugnummer $nr.")
		return
	end

	f = bufferedFlighties[nr]

	if isa(f.value, Flight)
		pretty_table(Numbered{<:Flighty}[f])
	else
		flights = f.value.flights
		numbered = Numbered{<:Flighty}[Numbered(i, flights[i]) for i in eachindex(flights)]
		acc = FlightAccumulator([flt for flt in flights])
		pretty_table(numbered, sums=[(acc, "Σ")])
	end
end

function loadBuffer()

	if ismissing(db)
		println(cErr, "Kein Flugbuch geladen.")
		return false
	end

	flights = fetchAllFlights(db)

	flightsByDate = Dict{Date, Vector{Flight}}()
	for f in flights
		if !haskey(flightsByDate, f.date)
			flightsByDate[f.date] = [f]
		else
			push!(flightsByDate[f.date], f)
		end
	end

	flighties = Flighty[]
	for (date, flights) in flightsByDate
		g = Graph(length(flights))

		for i in 1:length(flights)
			for j in i+1:length(flights)
				!groupable(flights[i], flights[j]) || add_edge!(g, i, j)
			end
		end

		for component in connected_components(g)
			groupedFlights = flights[component]

			if length(groupedFlights) == 1
				push!(flighties, groupedFlights[1])
			else
				push!(flighties, FlightGroup(groupedFlights))
			end
		end
	end

	sort!(flighties)
	flighties = Numbered{<:Flighty}[Numbered(i, flighties[i]) for i in eachindex(flighties)]

	global bufferedFlighties = flighties
	return true
end

function csv(fileName::String; autoconfirm = false, kwargs...)

	if ismissing(db)
		println(cErr, "Kein Flugbuch geladen.")
		return
	end

	if ismissing(selfNames)
		println(cErr, "Eigener Name nicht festgelegt.")
		return
	end

	csv = CSV.File(fileName, footerskip=1, normalizenames=true, silencewarnings=true, delim = ";")

	flights = Flight[]
	ignoredFlights = Flight[]
	overlappingFlights = Flight[]
	i = 1

	for row in csv
		try
			(f, forMe) = Flight(row)
			if forMe
				if  sum(overlap.(Ref(f), flights)) > 0
					push!(overlappingFlights, f)
				else
					f.nr = i
					i += 1
					push!(flights, f)
				end
			else
				push!(ignoredFlights, f)
			end
		catch e
			println("error: ", e)
			println("aborting!")
			throw(e)
			return
		end
	end

	if !isempty(ignoredFlights)
		println("\n$(length(ignoredFlights)) ignorierte Flüge (nicht für mein Flugbuch): ")
		pretty_table(ignoredFlights; kwargs...)
	end

	if !isempty(overlappingFlights)
		println("\n$(length(overlappingFlights)) ignorierte Flüge (in den Importdaten überlappend): ")
		pretty_table(overlappingFlights; kwargs...)
	end

	presentFlights = fetchAllFlights(db)

	overlappingFlights = Flight[]
	insertableFlights = Flight[]

	for f in flights
		if sum(overlap.(Ref(f), presentFlights)) > 0
			push!(overlappingFlights, f)
		else
			push!(insertableFlights, f)
		end
	end

	if !isempty(overlappingFlights)
		println("\n$(length(overlappingFlights)) ignorierte Flüge (mit bestehenden Flügen überlappend): ")
		pretty_table(overlappingFlights; kwargs...)
	else
		println("\nKeine Flüge überlappen mit bestehenden Flügen.")
	end

	if !isempty(insertableFlights)
		println("\n$(length(insertableFlights)) Flüge für den Import:")
		pretty_table(insertableFlights; kwargs...)
	else
		println("\nKeine Flüge zu importieren.")
		return
	end

	if !autoconfirm
		println("\nÜberprüfen Sie die obigen Angaben und geben Sie 'ja' ein, wenn der Import durchgeführt werden soll.")
		userInput = readline()

		if userInput != "ja"
			println("Vorgang abgebrochen.")
			return
		end
	end

	#invalidate buffer
	global bufferedFlighties = missing

	stmt = SQLite.Stmt(db, "INSERT INTO flights (nr, callsign, aircraftType, pilot, copilot, launch, date, departureTime, arrivalTime, departureLocation, arrivalLocation, dual, instr, comments) VALUES (?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10, ?11, ?12, ?13, ?14)")

	for f in insertableFlights
		SQLite.bind!(stmt, 1, string(f.nr))
		SQLite.bind!(stmt, 2, f.callsign)
		SQLite.bind!(stmt, 3, f.aircraftType)
		SQLite.bind!(stmt, 4, f.pilot)
		SQLite.bind!(stmt, 5, f.copilot)
		SQLite.bind!(stmt, 6, convert(String, f.launch))
		SQLite.bind!(stmt, 7, Dates.format(f.date, "dd.mm.yyyy"))
		SQLite.bind!(stmt, 8, Dates.format(f.departureTime, "HH:MM"))
		SQLite.bind!(stmt, 9, Dates.format(f.arrivalTime, "HH:MM"))
		SQLite.bind!(stmt, 10, f.departureLocation)
		SQLite.bind!(stmt, 11, f.arrivalLocation)
		SQLite.bind!(stmt, 12, f.dual ? "1" : "0")
		SQLite.bind!(stmt, 13, f.instr ? "1" : "0")
		SQLite.bind!(stmt, 14, f.comments)
		SQLite.execute!(stmt)
	end

	println("\nFlüge importiert.")
	nothing
end

function pretty_table(flights::Vector{<:Flighty}; kwargs...)
	tuples = Numbered{<:Flighty}[Numbered(i, flights[i]) for i in eachindex(flights)]
	pretty_table(tuples; kwargs...)
end

function pretty_table(
	flights::Vector{Numbered{T} where T <: Flighty};
	sums::Vector{Tuple{FlightAccumulator, String}} = Tuple{FlightAccumulator, String}[],
	limitAircraft::Int = -1,
	limitPilots::Int = -1,
	limitLocations::Int = -1,
	limitComments::Int = -1,
	frameGroups::Bool = true,
	printSums::Bool = true)

	tabRows = [toPrettyTableRow(f) for f in flights]

	hlines = isempty(sums) ? Int[] : [length(tabRows)]
	if frameGroups
		for i in eachindex(flights)
			if isa(flights[i].value, FlightGroup)
				push!(hlines, i)
				push!(hlines, i-1)
			end
		end
	end

	if printSums
		sumRows = collect(length(tabRows)+1:length(tabRows) + length(sums))
		for (acc, name) in sums
			push!(tabRows, toPrettyTableRow(acc,  name))
		end
	else
		sumRows = []
	end

	tab = permutedims(hcat(tabRows...))

	sumCrayon = crayon"negative bold"
	dualCrayon = crayon"light_blue"
	picCrayon = crayon"light_green"
	instrCrayon = crayon"magenta"
	groupCrayon = crayon"yellow negative"

	columnFilter = (data, i) ->
		!(i in 3:4 && limitAircraft == 0) &&
		!(i in 5:6 && limitPilots == 0) &&
		!(i in 8:9 && limitLocations == 0) &&
		!(i == 18 && limitComments == 0)

	formatter = Dict(
		4 => (value, i) -> ellipsis(value, limitAircraft),
		5 => (value, i) -> ellipsis(value, limitPilots),
		6 => (value, i) -> ellipsis(value, limitPilots),
		8 => (value, i) -> ellipsis(value, limitLocations),
		9 => (value, i) -> ellipsis(value, limitLocations),
		18 => (value, i) -> ellipsis(value, limitComments),
	)

	sumHighlighter = Highlighter(
		f = (data, i, j) -> i in [sumRows] && j in [1,13,18],
		crayon = sumCrayon
	)

	dualHighlighter = Highlighter(
		f = (data, i, j) -> (j in 13:14 && i <= length(flights) && dual(flights[i].value)) || j == 16,
		crayon = dualCrayon
	)

	picHighlighter = Highlighter(
		f = (data, i, j) -> (j in 13:14 && i <= length(flights) && !dual(flights[i].value)) || j == 15,
		crayon = picCrayon
	)

	instrHighlighter = Highlighter(
		f = (data, i, j) -> j == 17,
		crayon = instrCrayon
	)

	picSumHighlighter = Highlighter(
		f = (data, i, j) -> j == 14 && i in sumRows,
		crayon = sumCrayon * picCrayon
	)

	dualSumHighlighter = Highlighter(
		f = (data, i, j) -> j == 15 && i in sumRows,
		crayon = sumCrayon * dualCrayon
	)

	instrSumHighlighter = Highlighter(
		f = (data, i, j) -> j == 16 && i in sumRows,
		crayon = sumCrayon * instrCrayon
	)

	groupHighlighter = Highlighter(
		f = (data, i, j) -> j == 1 && i <= length(flights) && isa(flights[i].value, FlightGroup),
		crayon = groupCrayon
	)

	println()
	PrettyTables.pretty_table(
		tab,
		toPrettyTableHeader(),
		unicode_rounded,
		crop = :horizontal,
		hlines = hlines,
		formatter = formatter,
		alignment = :l,
		linebreaks = true,
		highlighters = (
			sumHighlighter,
			dualSumHighlighter,
			dualHighlighter,
			instrSumHighlighter,
			instrHighlighter,
			picSumHighlighter,
			picHighlighter,
			groupHighlighter
		),
		filters_col = (columnFilter,)
	)
end

#
# main
#

# Base.@ccallable function julia_main(ARGS::Vector{String})::Cint
#     main(join(ARGS, " "))
#     return 0
# end
#
# function main(argstr)
# 	args = split(argstr)
#
# 	s = ArgParseSettings("Flugbuch",
#                          version = "Version 1.0",
#                          add_version = true,
# 						 prog = "Flugbuch.jl")
#
# 	@add_arg_table s begin
#         "--from", "-f"
# 			help = "Sichtbare Flüge einschränken anhand Datum oder Flugnr. (beides inklusive) für den Beginn des sichtbaren Bereichs"
#         "--to", "-t"
# 			help = "Sichtbare Flüge einschränken anhand Datum oder Flugnr. (beides inklusive) für das Ende des sichtbaren Bereichs"
#     end
#
#     parsed_args = parse_args(args, s)
# 	function_args = Dict()
#
# 	from_fail, to_fail = false, false
#
# 	if haskey(parsed_args, "from") && parsed_args["from"] != nothing
# 		from = parsed_args["from"]
# 		from_fail = false
#
# 		if tryparse(Int, from) != nothing
# 			function_args[:beginNr] = parse(Int, from)
# 		else
# 			if occursin(r"^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,4}$", parsed_args["from"])
# 				try
# 					function_args[:beginDate] = Date(parsed_args["from"], DateFormat("d.m.Y"))
# 				catch
# 					from_fail = true
# 				end
# 			else
# 				from_fail = true
# 			end
# 		end
# 	end
#
# 	if haskey(parsed_args, "to") && parsed_args["to"] != nothing
# 		to = parsed_args["to"]
# 		to_fail = false
#
# 		if tryparse(Int, to) != nothing
# 			function_args[:endNr] = parse(Int, to)
# 		else
# 			if occursin(r"^[0-9]{1,2}\.[0-9]{1,2}\.[0-9]{1,4}$", parsed_args["to"])
# 				try
# 					function_args[:endDate] = Date(parsed_args["to"], DateFormat("d.m.Y"))
# 				catch
# 					to_fail = true
# 				end
# 			else
# 				to_fail = true
# 			end
# 		end
#
# 	end
#
#
# 	!from_fail || print("Das Argument --from ist im falschen Format (es wird eine Zahl oder ein Datum erwartet) und wird ignoriert.")
# 	!to_fail || print("Das Argument --to ist im falschen Format (es wird eine Zahl oder ein Datum erwartet) und wird ignoriert.")
#
# 	println("helo")
# end

end

max_stars_repo_name: julianschick/flugbuch

max_issues_repo_name: julianschick/flugbuch

max_forks_repo_name: julianschick/flugbuch


text:
abstract type AbstractDisjunctiveSet <: MOI.AbstractVectorSet end

# For alternative $j$, impose that entry $i$ lies in [lbs[i,j], ubs[i,j]]
struct DisjunctiveSet{T<:Real} <: AbstractDisjunctiveSet
    lbs::Matrix{T}
    ubs::Matrix{T}

    function DisjunctiveSet(
        lbs::Matrix{R},
        ubs::Matrix{S},
    ) where {R<:Real,S<:Real}
        if size(lbs) != size(ubs)
            throw(
                DimensionMismatch(
                    "Dimensions of lowerbounds and upperbounds must match.",
                ),
            )
        end
        return new{promote_type(R, S)}(lbs, ubs)
    end
end

MOI.dimension(ds::DisjunctiveSet) = size(ds.lbs, 1)
num_alternatives(ds::DisjunctiveSet) = size(ds.lbs, 2)

Base.copy(ds::DisjunctiveSet) = DisjunctiveSet(copy(ds.lbs), copy(ds.ubs))

const DisjunctionCI{T} =
    MOI.ConstraintIndex{MOI.VectorAffineFunction{T},DisjunctiveSet}

# Constrains f in Simplex AND sparsity matches disjunction
struct CombinatorialDisjunctiveSet <: AbstractDisjunctiveSet
    sparsity::Vector{Vector{Int}}
    dim::Int

    function CombinatorialDisjunctiveSet(sparsity::Vector{Vector{Int}})
        dim = 0
        for disjunct in sparsity
            if minimum(disjunct) <= 0
                throw(ArgumentError("Nonpositive variable index."))
            end
            dim = max(0, maximum(disjunct))
        end
        return new(sparsity, dim)
    end
end

MOI.dimension(cdc::CombinatorialDisjunctiveSet) = cdc.dim

struct Disjunction{F<:MOI.AbstractVectorFunction,S<:AbstractDisjunctiveSet}
    f::F
    s::S

    function Disjunction(
        f::F,
        s::S,
    ) where {F<:MOI.AbstractVectorFunction,S<:AbstractDisjunctiveSet}
        if MOI.output_dimension(f) != MOI.dimension(s)
            throw(
                DimensionMismatch(
                    "Incompatible dimensions between function and set.",
                ),
            )
        end
        return new{F,S}(f, s)
    end
end

num_alternatives(disj::Disjunction) = num_alternatives(disj.s)

ext: jl


text:
"""
Bridges `CP.Domain` to MILP by adding one binary variable per possible
combination.
"""
struct Domain2MILPBridge{T} <: MOIBC.AbstractBridge
    vars::Vector{MOI.VariableIndex}
    vars_bin::Vector{MOI.ConstraintIndex{MOI.VariableIndex, MOI.ZeroOne}}
    con_choose_one::MOI.ConstraintIndex{MOI.ScalarAffineFunction{T}, MOI.EqualTo{T}}
    con_value::MOI.ConstraintIndex{MOI.ScalarAffineFunction{T}, MOI.EqualTo{T}}
end

function MOIBC.bridge_constraint(
    ::Type{Domain2MILPBridge{T}},
    model,
    f::MOI.VariableIndex,
    s::CP.Domain{T},
) where {T}
    return MOIBC.bridge_constraint(
        Domain2MILPBridge{T},
        model,
        MOI.ScalarAffineFunction{T}(f),
        s,
    )
end

function MOIBC.bridge_constraint(
    ::Type{Domain2MILPBridge{T}},
    model,
    f::MOI.ScalarAffineFunction{T},
    s::CP.Domain{T},
) where {T}
    vars, vars_bin = MOI.add_constrained_variables(model, [MOI.ZeroOne() for _ in 1:length(s.values)])

    con_choose_one = MOI.add_constraint(
        model,
        sum(one(T) .* vars),
        MOI.EqualTo(one(T))
    )

    values = collect(s.values)

    con_value = MOI.add_constraint(
        model,
        f - sum(one(T) * vars[i] * values[i] for i in 1:length(s.values)),
        MOI.EqualTo(zero(T))
    )

    return Domain2MILPBridge(vars, vars_bin, con_choose_one, con_value)
end

function MOI.supports_constraint(
    ::Type{Domain2MILPBridge{T}},
    ::Union{Type{MOI.VariableIndex}, Type{MOI.ScalarAffineFunction{T}}},
    ::Type{CP.Domain{T}},
) where {T}
    return true
end

function MOIB.added_constrained_variable_types(::Type{Domain2MILPBridge{T}}) where {T}
    return [(MOI.ZeroOne,)]
end

function MOIB.added_constraint_types(::Type{Domain2MILPBridge{T}}) where {T}
    return [
        (MOI.ScalarAffineFunction{T}, MOI.EqualTo{T}),
    ]
end

function MOI.get(b::Domain2MILPBridge, ::MOI.NumberOfVariables)
    return length(b.vars)
end

function MOI.get(
    b::Domain2MILPBridge{T},
    ::MOI.NumberOfConstraints{
        MOI.VariableIndex, MOI.ZeroOne,
    },
) where {T}
    return length(b.vars_bin)
end

function MOI.get(
    ::Domain2MILPBridge{T},
    ::MOI.NumberOfConstraints{
        MOI.ScalarAffineFunction{T}, MOI.EqualTo{T},
    },
) where {T}
    return 2
end

function MOI.get(
    b::Domain2MILPBridge{T},
    ::MOI.ListOfVariableIndices,
) where {T}
    return copy(b.vars)
end

function MOI.get(
    b::Domain2MILPBridge{T},
    ::MOI.ListOfConstraintIndices{
        MOI.VariableIndex, MOI.ZeroOne,
    },
) where {T}
    return copy(b.vars_bin)
end

function MOI.get(
    b::Domain2MILPBridge{T},
    ::MOI.ListOfConstraintIndices{
        MOI.ScalarAffineFunction{T}, MOI.EqualTo{T},
    },
) where {T}
    return [b.con_choose_one, b.con_value]
end


text:
using Koala
using KoalaPlots
using Base.Test

using Plots

const srcdir = dirname(@__FILE__)

pyplot()
v = randn(50)
bootstrap_histogram_of_mean(v)
bootstrap_histogram_of_mean!(2*v, label="two big")
recordfig(joinpath(srcdir, "output", "testplot.png"), ConstantRegressor())


text:
@testset "li2" begin
    data = open(readdlm, joinpath(@__DIR__, "data", "Li2.txt"))

    for r in 1:size(data, 1)
        row      = data[r, :]
        z        = row[1] + row[2]*1im
        expected = row[3] + row[4]*1im

        if imag(z) == 0.0
            @test PolyLog.li2(real(z)) ≈ real(expected) atol=1e-14
        end

        @test PolyLog.li2(z) ≈ expected atol=1e-14
    end

    @test PolyLog.li2(1.0) == 1.6449340668482264
    @test real(PolyLog.li2(-1.08371e-08 + 1.32716e-24*im)) == -1.0837099970639316e-08
    @test imag(PolyLog.li2(-1.08371e-08 + 1.32716e-24*im)) ==  1.3271599928087172e-24
end


text:
using Pkg
Pkg.activate(@__DIR__)

using DiffEqFlux, Flux, Optim, OrdinaryDiffEq

using Zygote

Zygote.@adjoint function vcat(xs::Union{Number, AbstractVector}...)
    vcat(xs...), dy -> begin
        d = 0
        map(xs) do x
            x isa Number && return dy[d+=1]
            l = length(x)
            dx = dy[d+1:d+l]
            d += l
            return dx
        end
    end
end

u0 = Float32(1.1)
tspan = (0.0f0,25.0f0)

ann = FastChain(FastDense(5,16,tanh), FastDense(16,16,tanh), FastDense(16,3))
p = initial_params(ann)
θ = Float32[u0;p]

function dudt_(u,p,t)
    ann([u;t;t],p)
end
prob = ODEProblem(dudt_,[0f0,0f0,u0],tspan,p)
concrete_solve(prob,Tsit5(),[0f0,0f0,u0],p,abstol=1e-8,reltol=1e-6)

function predict_adjoint(θ)
  Array(concrete_solve(prob,Tsit5(),[θ[1],0f0,0f0],θ[2:end],saveat=0.0:1:25.0))
end
loss_adjoint(θ) = sum(abs2,predict_adjoint(θ)[2,:].-1)
l = loss_adjoint(θ)

cb = function (θ,l)
  println(l)
  #display(plot(solve(remake(prob,p=Flux.data(p3),u0=Flux.data(u0)),Tsit5(),saveat=0.1),ylim=(0,6)))
  return false
end

# Display the ODE with the current parameter values.
cb(θ,l)

loss1 = loss_adjoint(θ)
res = DiffEqFlux.sciml_train(loss_adjoint, θ, BFGS(initial_stepnorm=0.01), cb = cb)


text:
VERSION >= v"0.4.0-dev+6521" && __precompile__(true)

module ClusterDicts
using Compat

export GlobalDict, DistributedDict, Pids, PidsAll, PidsWorkers, ValueF

abstract AbstractPids

type Pids <: AbstractPids
    pids::Array
end

type PidsAll <: AbstractPids end
type PidsWorkers <: AbstractPids end

type ValueF
    f::Function
end

Base.in(x, pids::Pids) = x in pids.pids
Base.in(x, pids::PidsAll) = x in procs()
Base.in(x, pids::PidsWorkers) = x in workers()

Base.start(d::Pids) = (1, d.pids)
Base.start(::PidsAll) = (1, procs())
Base.start(::PidsWorkers) = (1, workers())

Base.length(d::Pids) = length(d.pids)
Base.length(::PidsAll) = nprocs()
Base.length(::PidsWorkers) = nworkers()

Base.getindex(d::Pids, idx::Int) = d.pids[idx]
Base.getindex(::PidsAll, idx::Int) = procs()[idx]
Base.getindex(::PidsWorkers, idx::Int) = workers()[idx]

function Base.done(::AbstractPids, state)
    (idx, pids) = state
    return idx > length(pids)
end

function Base.next(::AbstractPids, state)
    (idx, pids) = state
    return (pids[idx], (idx+1, pids))
end

let DID = 0
    global next_name
    function next_name()
        DID = DID + 1
        return string(randstring(), '_', myid(), '_', DID)
    end
end

const directory = Dict()

function exists(pids, name, K, V, dtype)
    assert(myid() == 1)

    global directory
    D = get(directory, (name, :dtype), nothing)
    D == nothing && return (false, false)

    if (D.pids == pids) && (keytype(D) == K) && (valtype(D) == V) && isa(D, dtype)
        return (true, true)
    else
        return (true, false)
    end
end

function init_dict_local(pids, name, K, V, dtype)
    if (myid() in pids)
        directory[name] = Dict{K,V}()
    end
    directory[(name, :dtype)] = dtype{K, V}(name, pids)
    nothing
end

function init_dict(pids, name, K, V, dtype)
    # Ensure no dict with the same name but different specifications exists
    (name_exists, specs_exists) = remotecall_fetch(exists, 1, pids, name, K, V, dtype)
    if specs_exists
        return true
    elseif name_exists
        error("A cluster dictionary with name " * name * " but different specifications already exists.")
    end

    # Instantiate on 1 first. Master holds meta data for all dicts.
    remotecall_fetch(init_dict_local, 1, pids, name, K, V, dtype)

    @sync begin
        for p in filter(x->x!=1, pids)
            @async remotecall_fetch(init_dict_local, p, pids, name, K, V, dtype)
        end
    end

    return false
end

abstract DistributedAssociative{K,V} <: Associative{K,V}

for DT in [:GlobalDict, :DistributedDict]
    @eval type $DT{K,V} <: DistributedAssociative{K,V}
            name::AbstractString
            pids::AbstractPids

            function $DT(name::AbstractString, pids::AbstractPids, ktype, vtype)
                pre_exists = init_dict(pids, name, ktype, vtype, $DT)
                pre_exists && warn("A cluster dictionary with name " * name * " and similar specification exists.")
                if (myid()==1) || (myid() in pids)
                    return directory[(name, :dtype)]
                else
                    $DT(name, pids)
                end
            end

            $DT(name::AbstractString, pids::AbstractPids) = new(name, pids)
        end

    @eval $DT(;kwargs...) = $DT(PidsWorkers(); kwargs...)
    @eval function $DT(pids::Array; name=next_name(), ktype=Any, vtype=Any)
            if pids == procs()
                return $DT(PidsAll(); name=name, ktype=ktype, vtype=vtype)
            elseif pids == workers()
                return $DT(PidsWorkers(); name=name, ktype=ktype, vtype=vtype)
            else
                return $DT(Pids(pids); name=name, ktype=ktype, vtype=vtype)
            end
        end

    @eval $DT(pids::AbstractPids; name=next_name(), ktype=Any, vtype=Any) = $DT{ktype, vtype}(name, pids, ktype, vtype)

    @eval function $DT(name::AbstractString)
            # this method expects the directory to have an entry
            return directory[(name, :dtype)]
        end

    @eval Base.show(io::IO, d::$DT) = println(typeof(d), "(", d.name, ",", d.pids, ")")
end

function serialize(S::SerializationState, d::DistributedAssociative)
    p = Base.worker_id_from_socket(s.io)
    Serializer.serialize_type(S, typeof(d))

    # Optimize ser/deser by sending pids array only if the destination worker does
    # not have it.

    if (p in rr.pids) || (p == 1)
        serialize(S, (d.name, nothing))
    else
        serialize(S, (d.name, d.pids))
    end
end

function deserialize{T<:DistributedAssociative}(S::SerializationState, t::Type{T})
    global directory
    (name, pids) = deserialize(S)
    if pids == nothing
        # we expect the local directory to have an entry
        return T(name)
    else
        return T(name, pids)
    end
end

where(d::DistributedDict, k) = d.pids[Int(hash(k) % length(d.pids) + 1)]
function where(d::GlobalDict, k=nothing)
    if myid() in d.pids
        return myid()
    else
        return d.pids[rand(1:length(d.pids))]   # Pick a random worker where this dict exists
    end
end

Base.haskey(d::DistributedAssociative, k) = remotecall_fetch((n, k)->(global directory; haskey(directory[n], k)), where(d, k), d.name, k)

import Base.get, Base.get!
export get, get!
for (f, f_local, insert) in Any[(:get, :get_local, false), (:get!, :get!_local, true)]
    @eval function ($f_local)(name, k)
            global directory
            kd = directory[name]
            if haskey(kd, k)
                return (:OK, kd[k])
            else
                return :NOTFOUND
            end
        end

    @eval function ($f)(d::DistributedAssociative, k, default)
            pid = where(d,k)
            if myid() == pid
                return ($f)(directory[d.name], k, default)
            else
                response = remotecall_fetch(($f_local), pid, d.name, k)
                if response == :NOTFOUND
                    if $insert
                        d[k] = default
                    end
                    return default
                else
                    (_, v) = response
                    return v
                end
            end
        end
end

function pop_impl!(d::DistributedAssociative, k, f)
    response = remotecall_fetch(get_local, where(d,k), d.name, k)
    if response == :NOTFOUND
        return f()
    else
        delete!(d, k)   # delete from everywhere
        (_, v) = response
        return v
    end
end
Base.pop!(d::DistributedAssociative, k) = pop_impl!(d, k, ()->throw(KeyError("No mapping found for key : ", string(k))))
Base.pop!(d::DistributedAssociative, k, default) = pop_impl!(d, k, ()->default)

setindex!_local(name, k, v) = (global directory; directory[name][k] = v; nothing)
setindex!_local(name, k, v::ValueF) = (global directory; directory[name][k] = v.f(); nothing)

function Base.setindex!(d::GlobalDict, v, k)
    @sync begin
        for p in d.pids
            @async remotecall_fetch(setindex!_local, p, d.name, k, v)
        end
    end
    d
end
Base.setindex!(d::DistributedDict, v, k) = remotecall_fetch(setindex!_local, where(d, k), d.name, k, v)

getindex_local(name, k) = (global directory; return directory[name][k])
Base.getindex(d::DistributedAssociative, k) = remotecall_fetch(getindex_local, where(d,k), d.name, k)

delete!_local(name, k) = (global directory; delete!(directory[name], k); nothing)
Base.delete!(d::GlobalDict, k) = (collect_from_everywhere(d, delete!_local, d.name, k); d)
Base.delete!(d::DistributedDict, k) = remotecall_fetch(delete!, where(d,k), d.name, k)

isempty_local(name) = (global directory; isempty(directory[name]))
Base.isempty(d::GlobalDict) = remotecall_fetch(isempty_local, where(d), d.name)
Base.isempty(d::DistributedDict) = reduce(&, collect_from_everywhere(d, isempty_local, d.name))

length_local(name) = (global directory; length(directory[name]))
Base.length(d::GlobalDict) = remotecall_fetch(length_local, where(d), d.name)
Base.length(d::DistributedDict) = sum(collect_from_everywhere(d, length_local, d.name))

function collect_from_everywhere(d::DistributedAssociative, f, args...)
    results=Any[]
    @sync begin
        for p in d.pids
            @async push!(results, remotecall_fetch(f, p, args...))
        end
    end
    results
end

function delete!_local(name)
    global directory
    delete!(directory, name)
    delete!(directory, (name, :dtype))
    nothing
end

function Base.delete!(d::DistributedAssociative)
    collect_from_everywhere(d, delete!_local, d.name);
    if !(1 in d.pids)
        remotecall_fetch(delete!_local, 1, d.name)
    end
end

end # module


text:
@testset "Habitat" begin
    @test length(hab1) == 1
    @test length(hab2) == 2

    @test length(hab1[1][300]) == 1
    @test length(hab1[1][25, 25]) == 1
end


text:
module RocketActorTest

using Test
using Rocket

@testset "Actor" begin

    struct DummyType end
    struct AbstractDummyActor <: AbstractActor{Any} end

    struct SpecifiedAbstractActor end
    Rocket.as_actor(::Type{ <: SpecifiedAbstractActor }) = BaseActorTrait{Int}()

    struct NotImplementedActor <: Actor{Any}
        events :: Vector{Any}

        NotImplementedActor() = new(Vector{Any}())
    end

    struct NotImplementedNextActor <: NextActor{Int}
        events :: Vector{Any}

        NotImplementedNextActor() = new(Vector{Any}())
    end

    struct NotImplementedErrorActor <: ErrorActor{Float64}
        events :: Vector{Any}

        NotImplementedErrorActor() = new(Vector{Any}())
    end

    struct NotImplementedCompletionActor <: CompletionActor{String}
        events :: Vector{Any}

        NotImplementedCompletionActor() = new(Vector{Any}())
    end

    struct ImplementedActor <: Actor{Any}
        events :: Vector{Any}

        ImplementedActor() = new(Vector{Any}())
    end

    Rocket.on_next!(actor::ImplementedActor, data) = push!(actor.events, data)
    Rocket.on_error!(actor::ImplementedActor, err) = push!(actor.events, "err: $err")
    Rocket.on_complete!(actor::ImplementedActor)   = push!(actor.events, "completed")

    struct ImplementedNextActor <: NextActor{Int}
        events :: Vector{Any}

        ImplementedNextActor() = new(Vector{Any}())
    end

    Rocket.on_next!(actor::ImplementedNextActor, data) = push!(actor.events, data)
    Rocket.on_error!(actor::ImplementedNextActor, err) = push!(actor.events, "err: $err")
    Rocket.on_complete!(actor::ImplementedNextActor)   = push!(actor.events, "completed")

    struct ImplementedErrorActor <: ErrorActor{Float64}
        events :: Vector{Any}

        ImplementedErrorActor() = new(Vector{Any}())
    end

    Rocket.on_next!(actor::ImplementedErrorActor, data) = push!(actor.events, data)
    Rocket.on_error!(actor::ImplementedErrorActor, err) = push!(actor.events, "err: $err")
    Rocket.on_complete!(actor::ImplementedErrorActor)   = push!(actor.events, "completed")

    struct ImplementedCompletionActor <: CompletionActor{String}
        events :: Vector{Any}

        ImplementedCompletionActor() = new(Vector{Any}())
    end

    Rocket.on_next!(actor::ImplementedCompletionActor, data) = push!(actor.events, data)
    Rocket.on_error!(actor::ImplementedCompletionActor, err) = push!(actor.events, "err: $err")
    Rocket.on_complete!(actor::ImplementedCompletionActor)   = push!(actor.events, "completed")

    @testset "as_actor" begin
            # Check if arbitrary dummy type has undefined actor type
            @test as_actor(DummyType) === InvalidActorTrait()

            # Check if abstract actor type has undefined actor type
            @test as_actor(AbstractActor{Any}) === InvalidActorTrait()
            @test as_actor(AbstractDummyActor) === InvalidActorTrait()

            # Check if as_teardown return specified actor type
            @test as_actor(SpecifiedAbstractActor)  === BaseActorTrait{Int}()
            @test as_actor(Actor{Any})              === BaseActorTrait{Any}()
            @test as_actor(NextActor{Int})          === NextActorTrait{Int}()
            @test as_actor(ErrorActor{Float64})     === ErrorActorTrait{Float64}()
            @test as_actor(CompletionActor{String}) === CompletionActorTrait{String}()

            @test as_actor(NotImplementedActor)           === BaseActorTrait{Any}()
            @test as_actor(NotImplementedNextActor)       === NextActorTrait{Int}()
            @test as_actor(NotImplementedErrorActor)      === ErrorActorTrait{Float64}()
            @test as_actor(NotImplementedCompletionActor) === CompletionActorTrait{String}()

            @test as_actor(ImplementedActor)           === BaseActorTrait{Any}()
            @test as_actor(ImplementedNextActor)       === NextActorTrait{Int}()
            @test as_actor(ImplementedErrorActor)      === ErrorActorTrait{Float64}()
            @test as_actor(ImplementedCompletionActor) === CompletionActorTrait{String}()
    end

    @testset "next!" begin
            # Check if next! function throws an error for not valid actors
            @test_throws InvalidActorTraitUsageError next!(DummyType(), 1)
            @test_throws InvalidActorTraitUsageError next!(AbstractDummyActor(), 1)

            # Check if next! function throws an error without data argument
            @test_throws MissingDataArgumentInNextCall next!(ImplementedActor())

            # Check if next! function throws an error for not implemented actors
            @test_throws MissingOnNextImplementationError next!(NotImplementedActor(), 1)
            @test_throws MissingOnNextImplementationError next!(NotImplementedNextActor(), 1)

            # Check if next! function does nothing for incomplete actors
            actor = NotImplementedErrorActor()
            @test next!(actor, 1.0) === nothing
            @test actor.events == []

            actor = ImplementedErrorActor()
            @test next!(actor, 1.0) === nothing
            @test actor.events == []

            actor = NotImplementedCompletionActor()
            @test next!(actor, "1.0") === nothing
            @test actor.events == []

            actor = ImplementedCompletionActor()
            @test next!(actor, "1.0") === nothing
            @test actor.events == []

            # Check next! function returns nothing and saves incoming event in events array for implemented actors
            actor = ImplementedActor()
            @test next!(actor, 1) === nothing
            @test actor.events == [ 1 ]
            @test next!(actor, 2) === nothing
            @test actor.events == [ 1, 2 ]

            actor = ImplementedNextActor()
            @test next!(actor, 1) === nothing
            @test actor.events == [ 1 ]
            @test next!(actor, 2) === nothing
            @test actor.events == [ 1, 2 ]

            # Check next! function accepts wider types of data
            actor = ImplementedActor()
            @test next!(actor, 1)   === nothing
            @test next!(actor, 1.0) === nothing
            @test next!(actor, "1") === nothing
            @test actor.events == [ 1, 1.0, "1" ]

            # Check next! function throws an error for wrong type of message
            @test_throws InconsistentSourceActorDataTypesError{Int64,String}    next!(ImplementedNextActor(), "string")
            @test_throws InconsistentSourceActorDataTypesError{Int64,Float64}   next!(ImplementedNextActor(), 1.0)
            @test_throws InconsistentSourceActorDataTypesError{Int64,String}    next!(NotImplementedNextActor(), "string")
            @test_throws InconsistentSourceActorDataTypesError{Int64,Float64}   next!(NotImplementedNextActor(), 1.0)
            @test_throws InconsistentSourceActorDataTypesError{Float64,String}  next!(ImplementedErrorActor(), "string")
            @test_throws InconsistentSourceActorDataTypesError{Float64,Int}     next!(ImplementedErrorActor(), 1)
            @test_throws InconsistentSourceActorDataTypesError{Float64,String}  next!(NotImplementedErrorActor(), "string")
            @test_throws InconsistentSourceActorDataTypesError{Float64,Int}     next!(NotImplementedErrorActor(), 1)
            @test_throws InconsistentSourceActorDataTypesError{String,Float64}  next!(ImplementedCompletionActor(), 1.0)
            @test_throws InconsistentSourceActorDataTypesError{String,Int}      next!(ImplementedCompletionActor(), 1)
            @test_throws InconsistentSourceActorDataTypesError{String,Float64}  next!(NotImplementedCompletionActor(), 1.0)
            @test_throws InconsistentSourceActorDataTypesError{String,Int}      next!(NotImplementedCompletionActor(), 1)
    end

    @testset "error!" begin
            # Check if error! function throws an error for not valid actors
            @test_throws InvalidActorTraitUsageError error!(DummyType(), 1)
            @test_throws InvalidActorTraitUsageError error!(AbstractDummyActor(), 1)

            # Check if error! function throws an error without error argument
            @test_throws MissingErrorArgumentInErrorCall error!(ImplementedActor())

            # Check if error! function throws an error for not implemented actors
            @test_throws MissingOnErrorImplementationError error!(NotImplementedActor(), 1)
            @test_throws MissingOnErrorImplementationError error!(NotImplementedErrorActor(), 1)

            # Check if error! function doing nothing for incomplete actors
            actor = ImplementedNextActor()
            @test error!(actor, 1) === nothing
            @test actor.events == [ ]

            actor = NotImplementedNextActor()
            @test error!(actor, 1) === nothing
            @test actor.events == [ ]

            actor = ImplementedCompletionActor()
            @test error!(actor, 1) === nothing
            @test actor.events == [ ]

            actor = NotImplementedCompletionActor()
            @test error!(actor, 1) === nothing
            @test actor.events == [ ]

            # Check error! function returns nothing and saves incoming event in events array for implemented actors
            actor = ImplementedActor()
            @test error!(actor, 1) === nothing
            @test actor.events == [ "err: 1" ]
            @test error!(actor, 1.0) === nothing
            @test actor.events == [ "err: 1", "err: 1.0" ]
            @test error!(actor, "err") === nothing
            @test actor.events == [ "err: 1", "err: 1.0", "err: err" ]

            actor = ImplementedErrorActor()
            @test error!(actor, 1) === nothing
            @test actor.events == [ "err: 1" ]
            @test error!(actor, 1.0) === nothing
            @test actor.events == [ "err: 1", "err: 1.0" ]
            @test error!(actor, "err") === nothing
            @test actor.events == [ "err: 1", "err: 1.0", "err: err" ]
    end

    @testset "complete!" begin
            # Check if error! function throws an error for not valid actors
            @test_throws InvalidActorTraitUsageError complete!(DummyType())
            @test_throws InvalidActorTraitUsageError complete!(AbstractDummyActor())

            # Check if complete! function throws an error for not implemented actors
            @test_throws MissingOnCompleteImplementationError complete!(NotImplementedActor())
            @test_throws MissingOnCompleteImplementationError complete!(NotImplementedCompletionActor())

            # Check if complete! function doing nothing for incomplete actors
            actor = ImplementedNextActor()
            @test complete!(actor)  === nothing
            @test actor.events == []

            actor = NotImplementedNextActor()
            @test complete!(actor)  === nothing
            @test actor.events == []

            actor = ImplementedErrorActor()
            @test complete!(actor)  === nothing
            @test actor.events == []

            actor = NotImplementedErrorActor()
            @test complete!(actor)  === nothing
            @test actor.events == []

            # Check complete! function returns nothing and saves incoming event in events array for implemented actors
            actor = ImplementedActor()
            @test complete!(actor) === nothing
            @test actor.events == [ "completed" ]

            actor = ImplementedCompletionActor()
            @test complete!(actor) === nothing
            @test actor.events == [ "completed" ]
    end

    struct CustomActor{L} <: Actor{L} end

    Rocket.on_next!(actor::CustomActor{L}, data::L) where L = begin end
    Rocket.on_error!(actor::CustomActor, err)               = begin end
    Rocket.on_complete!(actor::CustomActor)                 = begin end

    struct NotImplementedCustomActorFactory <: AbstractActorFactory end
    struct ImplementedCustomActorFactory    <: AbstractActorFactory end

    Rocket.create_actor(::Type{L}, factory::ImplementedCustomActorFactory) where L = CustomActor{L}()

    @testset "Actor Factory" begin
            @test_throws MissingCreateActorFactoryImplementationError create_actor(Int, NotImplementedCustomActorFactory())

            @test create_actor(Int, ImplementedCustomActorFactory())    === CustomActor{Int}()
            @test create_actor(String, ImplementedCustomActorFactory()) === CustomActor{String}()
    end

    @testset "Actor extract type and eltype" begin

            @test Rocket.actor_extract_type(SpecifiedAbstractActor)        === Int
            @test Rocket.actor_extract_type(NotImplementedActor)           === Any
            @test Rocket.actor_extract_type(NotImplementedNextActor)       === Int
            @test Rocket.actor_extract_type(NotImplementedErrorActor)      === Float64
            @test Rocket.actor_extract_type(NotImplementedCompletionActor) === String
            @test Rocket.actor_extract_type(ImplementedActor)              === Any
            @test Rocket.actor_extract_type(ImplementedNextActor)          === Int
            @test Rocket.actor_extract_type(ImplementedErrorActor)         === Float64
            @test Rocket.actor_extract_type(ImplementedCompletionActor)    === String

            @test eltype(SpecifiedAbstractActor)        === Any
            @test eltype(NotImplementedActor)           === Any
            @test eltype(NotImplementedNextActor)       === Int
            @test eltype(NotImplementedErrorActor)      === Float64
            @test eltype(NotImplementedCompletionActor) === String
            @test eltype(ImplementedActor)              === Any
            @test eltype(ImplementedNextActor)          === Int
            @test eltype(ImplementedErrorActor)         === Float64
            @test eltype(ImplementedCompletionActor)    === String

            @test Rocket.actor_extract_type(SpecifiedAbstractActor())        === Int
            @test Rocket.actor_extract_type(NotImplementedActor())           === Any
            @test Rocket.actor_extract_type(NotImplementedNextActor())       === Int
            @test Rocket.actor_extract_type(NotImplementedErrorActor())      === Float64
            @test Rocket.actor_extract_type(NotImplementedCompletionActor()) === String
            @test Rocket.actor_extract_type(ImplementedActor())              === Any
            @test Rocket.actor_extract_type(ImplementedNextActor())          === Int
            @test Rocket.actor_extract_type(ImplementedErrorActor())         === Float64
            @test Rocket.actor_extract_type(ImplementedCompletionActor())    === String

            @test eltype(SpecifiedAbstractActor())        === Any
            @test eltype(NotImplementedActor())           === Any
            @test eltype(NotImplementedNextActor())       === Int
            @test eltype(NotImplementedErrorActor())      === Float64
            @test eltype(NotImplementedCompletionActor()) === String
            @test eltype(ImplementedActor())              === Any
            @test eltype(ImplementedNextActor())          === Int
            @test eltype(ImplementedErrorActor())         === Float64
            @test eltype(ImplementedCompletionActor())    === String

            @test_throws InvalidActorTraitUsageError Rocket.actor_extract_type(DummyType)
            @test_throws InvalidActorTraitUsageError Rocket.actor_extract_type(AbstractDummyActor)

            @test_throws InvalidActorTraitUsageError Rocket.actor_extract_type(DummyType())
            @test_throws InvalidActorTraitUsageError Rocket.actor_extract_type(AbstractDummyActor())
    end

end

end


text:
using RunTests
using Base.Test

@testmodule KNeighborsTest begin
  using MLLibrary

  function test_trainKMeans()
      # path = joinpath(Pkg.dir("MLLibrary"),"resources","datasets","test.csv")
      # seed=123
      # trainingSet, testSet = MLLibrary.DataSampling.ThresholdSampling.getSets(path, ",",.1,seed)
      #
      # trainingSet = MLLibrary.DataManipulation.DataTransform.convertToFloat(trainingSet)
      #
      # println(trainingSet)
      # println(MLLibrary.LearningAlgorithms.KMeans.trainKmeans(trainingSet, 4))
      #
      # @test 1==1

  end
end

max_stars_repo_name: ajermaky/CustomMLLibrary

max_issues_repo_name: ajermaky/CustomMLLibrary

max_forks_repo_name: ajermaky/CustomMLLibrary


text:
using InteractiveUtils: subtypes

@testset "Robot" begin
  @testset "test $rob_type interface" for rob_type in subtypes(Robot)
    par_type = eval(Symbol(string(rob_type)*"Params"))
    params = par_type()
    rob = rob_type(deviceID="test", params=params, dependencies=Dict{String, Union{Device, Missing}}())

    degrees = dof(rob)
    @test degrees isa Int

    axes = axisRange(rob)
    @test axes isa Vector{<:Vector{<:Unitful.Length}}
    @test length(axes) == degrees
    @test length(axes[1]) == 2
    for i in 1:degrees
      @test axes[i][1]<=axes[i][2]
    end

    def_vel = defaultVelocity(rob)
    @test def_vel isa Union{Vector{<:Unitful.Velocity},Nothing}
    if def_vel !== nothing
      @test length(def_vel) == degrees
    end
  end

  @testset "DummyRobot" begin
    include("DummyRobotTests.jl")
  end

  @testset "SimulatedRobot" begin
    include("SimulatedRobotTests.jl")
  end

  if "igus" in ARGS
    @testset "IgusRobot" begin
    include("IgusRobotTests.jl")
    end
  end

  if "isel" in ARGS
    @testset "IselRobot" begin
    include("IselRobotTests.jl")
    end
  end

  if "brukerrobot" in ARGS
    @testset "BrukerRobot" begin
    include("BrukerRobotTests.jl")
    end
  end
end


text:
# Computes the logarithmic mean: (aR-aL)/(LOG(aR)-LOG(aL)) = (aR-aL)/LOG(aR/aL)
# Problem: if aL~= aR, then 0/0, but should tend to --> 0.5*(aR+aL)
#
# introduce xi=aR/aL and f=(aR-aL)/(aR+aL) = (xi-1)/(xi+1)
# => xi=(1+f)/(1-f)
# => Log(xi) = log(1+f)-log(1-f), and for small f (f^2<1.0E-02) :
#
#    Log(xi) ~=     (f - 1/2 f^2 + 1/3 f^3 - 1/4 f^4 + 1/5 f^5 - 1/6 f^6 + 1/7 f^7)
#                  +(f + 1/2 f^2 + 1/3 f^3 + 1/4 f^4 + 1/5 f^5 + 1/6 f^6 + 1/7 f^7)
#             = 2*f*(1           + 1/3 f^2           + 1/5 f^4           + 1/7 f^6)
#  (aR-aL)/Log(xi) = (aR+aL)*f/(2*f*(1 + 1/3 f^2 + 1/5 f^4 + 1/7 f^6)) = (aR+aL)/(2 + 2/3 f^2 + 2/5 f^4 + 2/7 f^6)
#  (aR-aL)/Log(xi) = 0.5*(aR+aL)*(105/ (105+35 f^2+ 21 f^4 + 15 f^6)
function ln_mean(value1, value2)
  epsilon_f2 = 1.0e-4
  ratio = value2 / value1
  # f2 = f^2
  f2 = (ratio * (ratio - 2) + 1) / (ratio * (ratio + 2) + 1)
  if f2 < epsilon_f2
    return (value1 + value2) * 52.5 / (105 + f2 * (35 + f2 * (21 + f2 * 15)))
  else
    return (value2 - value1) / log(ratio)
  end
end


text:
using BenchmarkTools
using Test
using Statistics
using CUDAdrv
using CUDAnative
using CuArrays

N=2^10
x = fill(2.0f0, N)
y = fill(3.0f0, N)

function Kernel_Dot(x, y, z)
    i = blockDim().x * (blockIdx().x-1) + threadIdx().x
    tile = @cuStaticSharedMem(Float64, (blockDim().x, blockDim().y))
    z[i] = x[i] + y[i]
    return
end

a = rand(1024)
b = rand(1024)
c = zeros(1024)

d_a = CuArray(a)
d_b = CuArray(b)
d_c = CuArray(c)

@cuda blocks=(32,32) threads=(32,32) Kernel_Dot(d_a, d_b, d_c)

c = Array(d_c)


text:
# Extract of Combinatorics.jl
#
# You may (or may not!) want to call the function `permutations(a, t)` in your
# solution. If you would like to use it, include this file with
# `include("permutations.jl")`.
#
# License:
#
#    Copyright (c) 2013-2015: Alessandro Andrioni, Jiahao Chen and other
#    contributors.
#
#    Permission is hereby granted, free of charge, to any person obtaining a
#    copy of this software and associated documentation files (the "Software"),
#    to deal in the Software without restriction, including without limitation
#    the rights to use, copy, modify, merge, publish, distribute, sublicense,
#    and/or sell copies of the Software, and to permit persons to whom the
#    Software is furnished to do so, subject to the following conditions:
#
#    The above copyright notice and this permission notice shall be included in
#    all copies or substantial portions of the Software.
#
#    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
#    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
#    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
#    THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
#    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
#    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
#    DEALINGS IN THE SOFTWARE.

struct Permutations{T}
    a::T
    t::Int
end

Base.eltype(::Type{Permutations{T}}) where {T} = Vector{eltype(T)}

Base.length(p::Permutations) = (0 <= p.t <= length(p.a)) ? factorial(length(p.a), length(p.a)-p.t) : 0

"""
    permutations(a)

Generate all permutations of an indexable object `a` in lexicographic order. Because the number of permutations
can be very large, this function returns an iterator object.
Use `collect(permutations(a))` to get an array of all permutations.
"""
permutations(a) = Permutations(a, length(a))

"""
    permutations(a, t)

Generate all size `t` permutations of an indexable object `a`.
"""
function permutations(a, t::Integer)
    if t < 0
        t = length(a) + 1
    end
    Permutations(a, t)
end

function Base.iterate(p::Permutations, s = collect(1:length(p.a)))
    (!isempty(s) && max(s[1], p.t) > length(p.a) || (isempty(s) && p.t > 0)) && return
    nextpermutation(p.a, p.t ,s)
end

function nextpermutation(m, t, state)
    perm = [m[state[i]] for i in 1:t]
    n = length(state)
    if t <= 0
        return(perm, [n+1])
    end
    s = copy(state)
    if t < n
        j = t + 1
        while j <= n &&  s[t] >= s[j]; j+=1; end
    end
    if t < n && j <= n
        s[t], s[j] = s[j], s[t]
    else
        if t < n
            reverse!(s, t+1)
        end
        i = t - 1
        while i>=1 && s[i] >= s[i+1]; i -= 1; end
        if i > 0
            j = n
            while j>i && s[i] >= s[j]; j -= 1; end
            s[i], s[j] = s[j], s[i]
            reverse!(s, i+1)
        else
            s[1] = n+1
        end
    end
    return (perm, s)
end

max_stars_repo_name: stepinski/julia

max_issues_repo_name: stepinski/julia

max_forks_repo_name: stepinski/julia


text:
# This file is auto-generated by AWSMetadata.jl
using AWS
using AWS.AWSServices: fms
using AWS.Compat
using AWS.UUIDs

"""
    associate_admin_account(admin_account)
    associate_admin_account(admin_account, params::Dict{String,<:Any})

Sets the Firewall Manager administrator account. The account must be a member of the
organization in Organizations whose resources you want to protect. Firewall Manager sets
the permissions that allow the account to administer your Firewall Manager policies. The
account that you associate with Firewall Manager is called the Firewall Manager
administrator account.

# Arguments
- `admin_account`: The Amazon Web Services account ID to associate with Firewall Manager as
  the Firewall Manager administrator account. This must be an Organizations member account.
  For more information about Organizations, see Managing the Amazon Web Services Accounts in
  Your Organization.

"""
associate_admin_account(AdminAccount; aws_config::AbstractAWSConfig=global_aws_config()) = fms("AssociateAdminAccount", Dict{String, Any}("AdminAccount"=>AdminAccount); aws_config=aws_config)
associate_admin_account(AdminAccount, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("AssociateAdminAccount", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("AdminAccount"=>AdminAccount), params)); aws_config=aws_config)

"""
    delete_apps_list(list_id)
    delete_apps_list(list_id, params::Dict{String,<:Any})

Permanently deletes an Firewall Manager applications list.

# Arguments
- `list_id`: The ID of the applications list that you want to delete. You can retrieve this
  ID from PutAppsList, ListAppsLists, and GetAppsList.

"""
delete_apps_list(ListId; aws_config::AbstractAWSConfig=global_aws_config()) = fms("DeleteAppsList", Dict{String, Any}("ListId"=>ListId); aws_config=aws_config)
delete_apps_list(ListId, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("DeleteAppsList", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ListId"=>ListId), params)); aws_config=aws_config)

"""
    delete_notification_channel()
    delete_notification_channel(params::Dict{String,<:Any})

Deletes an Firewall Manager association with the IAM role and the Amazon Simple
Notification Service (SNS) topic that is used to record Firewall Manager SNS logs.

"""
delete_notification_channel(; aws_config::AbstractAWSConfig=global_aws_config()) = fms("DeleteNotificationChannel"; aws_config=aws_config)
delete_notification_channel(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("DeleteNotificationChannel", params; aws_config=aws_config)

"""
    delete_policy(policy_id)
    delete_policy(policy_id, params::Dict{String,<:Any})

Permanently deletes an Firewall Manager policy.

# Arguments
- `policy_id`: The ID of the policy that you want to delete. You can retrieve this ID from
  PutPolicy and ListPolicies.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"DeleteAllPolicyResources"`: If True, the request performs cleanup according to the
  policy type.  For WAF and Shield Advanced policies, the cleanup does the following:
  Deletes rule groups created by Firewall Manager   Removes web ACLs from in-scope resources
   Deletes web ACLs that contain no rules or rule groups   For security group policies, the
  cleanup does the following for each security group in the policy:   Disassociates the
  security group from in-scope resources    Deletes the security group if it was created
  through Firewall Manager and if it's no longer associated with any resources through
  another policy   After the cleanup, in-scope resources are no longer protected by web ACLs
  in this policy. Protection of out-of-scope resources remains unchanged. Scope is determined
  by tags that you create and accounts that you associate with the policy. When creating the
  policy, if you specify that only resources in specific accounts or with specific tags are
  in scope of the policy, those accounts and resources are handled by the policy. All others
  are out of scope. If you don't specify tags or accounts, all resources are in scope.
"""
delete_policy(PolicyId; aws_config::AbstractAWSConfig=global_aws_config()) = fms("DeletePolicy", Dict{String, Any}("PolicyId"=>PolicyId); aws_config=aws_config)
delete_policy(PolicyId, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("DeletePolicy", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("PolicyId"=>PolicyId), params)); aws_config=aws_config)

"""
    delete_protocols_list(list_id)
    delete_protocols_list(list_id, params::Dict{String,<:Any})

Permanently deletes an Firewall Manager protocols list.

# Arguments
- `list_id`: The ID of the protocols list that you want to delete. You can retrieve this ID
  from PutProtocolsList, ListProtocolsLists, and GetProtocolsLost.

"""
delete_protocols_list(ListId; aws_config::AbstractAWSConfig=global_aws_config()) = fms("DeleteProtocolsList", Dict{String, Any}("ListId"=>ListId); aws_config=aws_config)
delete_protocols_list(ListId, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("DeleteProtocolsList", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ListId"=>ListId), params)); aws_config=aws_config)

"""
    disassociate_admin_account()
    disassociate_admin_account(params::Dict{String,<:Any})

Disassociates the account that has been set as the Firewall Manager administrator account.
To set a different account as the administrator account, you must submit an
AssociateAdminAccount request.

"""
disassociate_admin_account(; aws_config::AbstractAWSConfig=global_aws_config()) = fms("DisassociateAdminAccount"; aws_config=aws_config)
disassociate_admin_account(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("DisassociateAdminAccount", params; aws_config=aws_config)

"""
    get_admin_account()
    get_admin_account(params::Dict{String,<:Any})

Returns the Organizations account that is associated with Firewall Manager as the Firewall
Manager administrator.

"""
get_admin_account(; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetAdminAccount"; aws_config=aws_config)
get_admin_account(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetAdminAccount", params; aws_config=aws_config)

"""
    get_apps_list(list_id)
    get_apps_list(list_id, params::Dict{String,<:Any})

Returns information about the specified Firewall Manager applications list.

# Arguments
- `list_id`: The ID of the Firewall Manager applications list that you want the details for.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"DefaultList"`: Specifies whether the list to retrieve is a default list owned by
  Firewall Manager.
"""
get_apps_list(ListId; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetAppsList", Dict{String, Any}("ListId"=>ListId); aws_config=aws_config)
get_apps_list(ListId, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetAppsList", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ListId"=>ListId), params)); aws_config=aws_config)

"""
    get_compliance_detail(member_account, policy_id)
    get_compliance_detail(member_account, policy_id, params::Dict{String,<:Any})

Returns detailed compliance information about the specified member account. Details include
resources that are in and out of compliance with the specified policy.    Resources are
considered noncompliant for WAF and Shield Advanced policies if the specified policy has
not been applied to them.   Resources are considered noncompliant for security group
policies if they are in scope of the policy, they violate one or more of the policy rules,
and remediation is disabled or not possible.   Resources are considered noncompliant for
Network Firewall policies if a firewall is missing in the VPC, if the firewall endpoint
isn't set up in an expected Availability Zone and subnet, if a subnet created by the
Firewall Manager doesn't have the expected route table, and for modifications to a firewall
policy that violate the Firewall Manager policy's rules.   Resources are considered
noncompliant for DNS Firewall policies if a DNS Firewall rule group is missing from the
rule group associations for the VPC.

# Arguments
- `member_account`: The Amazon Web Services account that owns the resources that you want
  to get the details for.
- `policy_id`: The ID of the policy that you want to get the details for. PolicyId is
  returned by PutPolicy and by ListPolicies.

"""
get_compliance_detail(MemberAccount, PolicyId; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetComplianceDetail", Dict{String, Any}("MemberAccount"=>MemberAccount, "PolicyId"=>PolicyId); aws_config=aws_config)
get_compliance_detail(MemberAccount, PolicyId, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetComplianceDetail", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("MemberAccount"=>MemberAccount, "PolicyId"=>PolicyId), params)); aws_config=aws_config)

"""
    get_notification_channel()
    get_notification_channel(params::Dict{String,<:Any})

Information about the Amazon Simple Notification Service (SNS) topic that is used to record
Firewall Manager SNS logs.

"""
get_notification_channel(; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetNotificationChannel"; aws_config=aws_config)
get_notification_channel(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetNotificationChannel", params; aws_config=aws_config)

"""
    get_policy(policy_id)
    get_policy(policy_id, params::Dict{String,<:Any})

Returns information about the specified Firewall Manager policy.

# Arguments
- `policy_id`: The ID of the Firewall Manager policy that you want the details for.

"""
get_policy(PolicyId; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetPolicy", Dict{String, Any}("PolicyId"=>PolicyId); aws_config=aws_config)
get_policy(PolicyId, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetPolicy", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("PolicyId"=>PolicyId), params)); aws_config=aws_config)

"""
    get_protection_status(policy_id)
    get_protection_status(policy_id, params::Dict{String,<:Any})

If you created a Shield Advanced policy, returns policy-level attack summary information in
the event of a potential DDoS attack. Other policy types are currently unsupported.

# Arguments
- `policy_id`: The ID of the policy for which you want to get the attack information.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"EndTime"`: The end of the time period to query for the attacks. This is a timestamp
  type. The request syntax listing indicates a number type because the default used by
  Firewall Manager is Unix time in seconds. However, any valid timestamp format is allowed.
- `"MaxResults"`: Specifies the number of objects that you want Firewall Manager to return
  for this request. If you have more objects than the number that you specify for MaxResults,
  the response includes a NextToken value that you can use to get another batch of objects.
- `"MemberAccountId"`: The Amazon Web Services account that is in scope of the policy that
  you want to get the details for.
- `"NextToken"`: If you specify a value for MaxResults and you have more objects than the
  number that you specify for MaxResults, Firewall Manager returns a NextToken value in the
  response, which you can use to retrieve another group of objects. For the second and
  subsequent GetProtectionStatus requests, specify the value of NextToken from the previous
  response to get information about another batch of objects.
- `"StartTime"`: The start of the time period to query for the attacks. This is a timestamp
  type. The request syntax listing indicates a number type because the default used by
  Firewall Manager is Unix time in seconds. However, any valid timestamp format is allowed.
"""
get_protection_status(PolicyId; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetProtectionStatus", Dict{String, Any}("PolicyId"=>PolicyId); aws_config=aws_config)
get_protection_status(PolicyId, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetProtectionStatus", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("PolicyId"=>PolicyId), params)); aws_config=aws_config)

"""
    get_protocols_list(list_id)
    get_protocols_list(list_id, params::Dict{String,<:Any})

Returns information about the specified Firewall Manager protocols list.

# Arguments
- `list_id`: The ID of the Firewall Manager protocols list that you want the details for.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"DefaultList"`: Specifies whether the list to retrieve is a default list owned by
  Firewall Manager.
"""
get_protocols_list(ListId; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetProtocolsList", Dict{String, Any}("ListId"=>ListId); aws_config=aws_config)
get_protocols_list(ListId, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetProtocolsList", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ListId"=>ListId), params)); aws_config=aws_config)

"""
    get_violation_details(member_account, policy_id, resource_id, resource_type)
    get_violation_details(member_account, policy_id, resource_id, resource_type, params::Dict{String,<:Any})

Retrieves violations for a resource based on the specified Firewall Manager policy and
Amazon Web Services account.

# Arguments
- `member_account`: The Amazon Web Services account ID that you want the details for.
- `policy_id`: The ID of the Firewall Manager policy that you want the details for. This
  currently only supports security group content audit policies.
- `resource_id`: The ID of the resource that has violations.
- `resource_type`: The resource type. This is in the format shown in the Amazon Web
  Services Resource Types Reference. Supported resource types are: AWS::EC2::Instance,
  AWS::EC2::NetworkInterface, AWS::EC2::SecurityGroup, AWS::NetworkFirewall::FirewallPolicy,
  and AWS::EC2::Subnet.

"""
get_violation_details(MemberAccount, PolicyId, ResourceId, ResourceType; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetViolationDetails", Dict{String, Any}("MemberAccount"=>MemberAccount, "PolicyId"=>PolicyId, "ResourceId"=>ResourceId, "ResourceType"=>ResourceType); aws_config=aws_config)
get_violation_details(MemberAccount, PolicyId, ResourceId, ResourceType, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("GetViolationDetails", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("MemberAccount"=>MemberAccount, "PolicyId"=>PolicyId, "ResourceId"=>ResourceId, "ResourceType"=>ResourceType), params)); aws_config=aws_config)

"""
    list_apps_lists(max_results)
    list_apps_lists(max_results, params::Dict{String,<:Any})

Returns an array of AppsListDataSummary objects.

# Arguments
- `max_results`: The maximum number of objects that you want Firewall Manager to return for
  this request. If more objects are available, in the response, Firewall Manager provides a
  NextToken value that you can use in a subsequent call to get the next batch of objects. If
  you don't specify this, Firewall Manager returns all available objects.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"DefaultLists"`: Specifies whether the lists to retrieve are default lists owned by
  Firewall Manager.
- `"NextToken"`: If you specify a value for MaxResults in your list request, and you have
  more objects than the maximum, Firewall Manager returns this token in the response. For all
  but the first request, you provide the token returned by the prior request in the request
  parameters, to retrieve the next batch of objects.
"""
list_apps_lists(MaxResults; aws_config::AbstractAWSConfig=global_aws_config()) = fms("ListAppsLists", Dict{String, Any}("MaxResults"=>MaxResults); aws_config=aws_config)
list_apps_lists(MaxResults, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("ListAppsLists", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("MaxResults"=>MaxResults), params)); aws_config=aws_config)

"""
    list_compliance_status(policy_id)
    list_compliance_status(policy_id, params::Dict{String,<:Any})

Returns an array of PolicyComplianceStatus objects. Use PolicyComplianceStatus to get a
summary of which member accounts are protected by the specified policy.

# Arguments
- `policy_id`: The ID of the Firewall Manager policy that you want the details for.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`: Specifies the number of PolicyComplianceStatus objects that you want
  Firewall Manager to return for this request. If you have more PolicyComplianceStatus
  objects than the number that you specify for MaxResults, the response includes a NextToken
  value that you can use to get another batch of PolicyComplianceStatus objects.
- `"NextToken"`: If you specify a value for MaxResults and you have more
  PolicyComplianceStatus objects than the number that you specify for MaxResults, Firewall
  Manager returns a NextToken value in the response that allows you to list another group of
  PolicyComplianceStatus objects. For the second and subsequent ListComplianceStatus
  requests, specify the value of NextToken from the previous response to get information
  about another batch of PolicyComplianceStatus objects.
"""
list_compliance_status(PolicyId; aws_config::AbstractAWSConfig=global_aws_config()) = fms("ListComplianceStatus", Dict{String, Any}("PolicyId"=>PolicyId); aws_config=aws_config)
list_compliance_status(PolicyId, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("ListComplianceStatus", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("PolicyId"=>PolicyId), params)); aws_config=aws_config)

"""
    list_member_accounts()
    list_member_accounts(params::Dict{String,<:Any})

Returns a MemberAccounts object that lists the member accounts in the administrator's
Amazon Web Services organization. The ListMemberAccounts must be submitted by the account
that is set as the Firewall Manager administrator.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`: Specifies the number of member account IDs that you want Firewall Manager
  to return for this request. If you have more IDs than the number that you specify for
  MaxResults, the response includes a NextToken value that you can use to get another batch
  of member account IDs.
- `"NextToken"`: If you specify a value for MaxResults and you have more account IDs than
  the number that you specify for MaxResults, Firewall Manager returns a NextToken value in
  the response that allows you to list another group of IDs. For the second and subsequent
  ListMemberAccountsRequest requests, specify the value of NextToken from the previous
  response to get information about another batch of member account IDs.
"""
list_member_accounts(; aws_config::AbstractAWSConfig=global_aws_config()) = fms("ListMemberAccounts"; aws_config=aws_config)
list_member_accounts(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("ListMemberAccounts", params; aws_config=aws_config)

"""
    list_policies()
    list_policies(params::Dict{String,<:Any})

Returns an array of PolicySummary objects.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"MaxResults"`: Specifies the number of PolicySummary objects that you want Firewall
  Manager to return for this request. If you have more PolicySummary objects than the number
  that you specify for MaxResults, the response includes a NextToken value that you can use
  to get another batch of PolicySummary objects.
- `"NextToken"`: If you specify a value for MaxResults and you have more PolicySummary
  objects than the number that you specify for MaxResults, Firewall Manager returns a
  NextToken value in the response that allows you to list another group of PolicySummary
  objects. For the second and subsequent ListPolicies requests, specify the value of
  NextToken from the previous response to get information about another batch of
  PolicySummary objects.
"""
list_policies(; aws_config::AbstractAWSConfig=global_aws_config()) = fms("ListPolicies"; aws_config=aws_config)
list_policies(params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("ListPolicies", params; aws_config=aws_config)

"""
    list_protocols_lists(max_results)
    list_protocols_lists(max_results, params::Dict{String,<:Any})

Returns an array of ProtocolsListDataSummary objects.

# Arguments
- `max_results`: The maximum number of objects that you want Firewall Manager to return for
  this request. If more objects are available, in the response, Firewall Manager provides a
  NextToken value that you can use in a subsequent call to get the next batch of objects. If
  you don't specify this, Firewall Manager returns all available objects.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"DefaultLists"`: Specifies whether the lists to retrieve are default lists owned by
  Firewall Manager.
- `"NextToken"`: If you specify a value for MaxResults in your list request, and you have
  more objects than the maximum, Firewall Manager returns this token in the response. For all
  but the first request, you provide the token returned by the prior request in the request
  parameters, to retrieve the next batch of objects.
"""
list_protocols_lists(MaxResults; aws_config::AbstractAWSConfig=global_aws_config()) = fms("ListProtocolsLists", Dict{String, Any}("MaxResults"=>MaxResults); aws_config=aws_config)
list_protocols_lists(MaxResults, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("ListProtocolsLists", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("MaxResults"=>MaxResults), params)); aws_config=aws_config)

"""
    list_tags_for_resource(resource_arn)
    list_tags_for_resource(resource_arn, params::Dict{String,<:Any})

Retrieves the list of tags for the specified Amazon Web Services resource.

# Arguments
- `resource_arn`: The Amazon Resource Name (ARN) of the resource to return tags for. The
  Firewall Manager resources that support tagging are policies, applications lists, and
  protocols lists.

"""
list_tags_for_resource(ResourceArn; aws_config::AbstractAWSConfig=global_aws_config()) = fms("ListTagsForResource", Dict{String, Any}("ResourceArn"=>ResourceArn); aws_config=aws_config)
list_tags_for_resource(ResourceArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("ListTagsForResource", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ResourceArn"=>ResourceArn), params)); aws_config=aws_config)

"""
    put_apps_list(apps_list)
    put_apps_list(apps_list, params::Dict{String,<:Any})

Creates an Firewall Manager applications list.

# Arguments
- `apps_list`: The details of the Firewall Manager applications list to be created.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"TagList"`: The tags associated with the resource.
"""
put_apps_list(AppsList; aws_config::AbstractAWSConfig=global_aws_config()) = fms("PutAppsList", Dict{String, Any}("AppsList"=>AppsList); aws_config=aws_config)
put_apps_list(AppsList, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("PutAppsList", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("AppsList"=>AppsList), params)); aws_config=aws_config)

"""
    put_notification_channel(sns_role_name, sns_topic_arn)
    put_notification_channel(sns_role_name, sns_topic_arn, params::Dict{String,<:Any})

Designates the IAM role and Amazon Simple Notification Service (SNS) topic that Firewall
Manager uses to record SNS logs. To perform this action outside of the console, you must
configure the SNS topic to allow the Firewall Manager role AWSServiceRoleForFMS to publish
SNS logs. For more information, see Firewall Manager required permissions for API actions
in the Firewall Manager Developer Guide.

# Arguments
- `sns_role_name`: The Amazon Resource Name (ARN) of the IAM role that allows Amazon SNS to
  record Firewall Manager activity.
- `sns_topic_arn`: The Amazon Resource Name (ARN) of the SNS topic that collects
  notifications from Firewall Manager.

"""
put_notification_channel(SnsRoleName, SnsTopicArn; aws_config::AbstractAWSConfig=global_aws_config()) = fms("PutNotificationChannel", Dict{String, Any}("SnsRoleName"=>SnsRoleName, "SnsTopicArn"=>SnsTopicArn); aws_config=aws_config)
put_notification_channel(SnsRoleName, SnsTopicArn, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("PutNotificationChannel", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("SnsRoleName"=>SnsRoleName, "SnsTopicArn"=>SnsTopicArn), params)); aws_config=aws_config)

"""
    put_policy(policy)
    put_policy(policy, params::Dict{String,<:Any})

Creates an Firewall Manager policy. Firewall Manager provides the following types of
policies:    An WAF policy (type WAFV2), which defines rule groups to run first in the
corresponding WAF web ACL and rule groups to run last in the web ACL.   An WAF Classic
policy (type WAF), which defines a rule group.    A Shield Advanced policy, which applies
Shield Advanced protection to specified accounts and resources.   A security group policy,
which manages VPC security groups across your Amazon Web Services organization.    An
Network Firewall policy, which provides firewall rules to filter network traffic in
specified Amazon VPCs.   A DNS Firewall policy, which provides Route 53 Resolver DNS
Firewall rules to filter DNS queries for specified VPCs.   Each policy is specific to one
of the types. If you want to enforce more than one policy type across accounts, create
multiple policies. You can create multiple policies for each type. You must be subscribed
to Shield Advanced to create a Shield Advanced policy. For more information about
subscribing to Shield Advanced, see CreateSubscription.

# Arguments
- `policy`: The details of the Firewall Manager policy to be created.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"TagList"`: The tags to add to the Amazon Web Services resource.
"""
put_policy(Policy; aws_config::AbstractAWSConfig=global_aws_config()) = fms("PutPolicy", Dict{String, Any}("Policy"=>Policy); aws_config=aws_config)
put_policy(Policy, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("PutPolicy", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("Policy"=>Policy), params)); aws_config=aws_config)

"""
    put_protocols_list(protocols_list)
    put_protocols_list(protocols_list, params::Dict{String,<:Any})

Creates an Firewall Manager protocols list.

# Arguments
- `protocols_list`: The details of the Firewall Manager protocols list to be created.

# Optional Parameters
Optional parameters can be passed as a `params::Dict{String,<:Any}`. Valid keys are:
- `"TagList"`: The tags associated with the resource.
"""
put_protocols_list(ProtocolsList; aws_config::AbstractAWSConfig=global_aws_config()) = fms("PutProtocolsList", Dict{String, Any}("ProtocolsList"=>ProtocolsList); aws_config=aws_config)
put_protocols_list(ProtocolsList, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("PutProtocolsList", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ProtocolsList"=>ProtocolsList), params)); aws_config=aws_config)

"""
    tag_resource(resource_arn, tag_list)
    tag_resource(resource_arn, tag_list, params::Dict{String,<:Any})

Adds one or more tags to an Amazon Web Services resource.

# Arguments
- `resource_arn`: The Amazon Resource Name (ARN) of the resource to return tags for. The
  Firewall Manager resources that support tagging are policies, applications lists, and
  protocols lists.
- `tag_list`: The tags to add to the resource.

"""
tag_resource(ResourceArn, TagList; aws_config::AbstractAWSConfig=global_aws_config()) = fms("TagResource", Dict{String, Any}("ResourceArn"=>ResourceArn, "TagList"=>TagList); aws_config=aws_config)
tag_resource(ResourceArn, TagList, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("TagResource", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ResourceArn"=>ResourceArn, "TagList"=>TagList), params)); aws_config=aws_config)

"""
    untag_resource(resource_arn, tag_keys)
    untag_resource(resource_arn, tag_keys, params::Dict{String,<:Any})

Removes one or more tags from an Amazon Web Services resource.

# Arguments
- `resource_arn`: The Amazon Resource Name (ARN) of the resource to return tags for. The
  Firewall Manager resources that support tagging are policies, applications lists, and
  protocols lists.
- `tag_keys`: The keys of the tags to remove from the resource.

"""
untag_resource(ResourceArn, TagKeys; aws_config::AbstractAWSConfig=global_aws_config()) = fms("UntagResource", Dict{String, Any}("ResourceArn"=>ResourceArn, "TagKeys"=>TagKeys); aws_config=aws_config)
untag_resource(ResourceArn, TagKeys, params::AbstractDict{String}; aws_config::AbstractAWSConfig=global_aws_config()) = fms("UntagResource", Dict{String, Any}(mergewith(_merge, Dict{String, Any}("ResourceArn"=>ResourceArn, "TagKeys"=>TagKeys), params)); aws_config=aws_config)


text:
using AmbientForcing
using PowerDynamics, Distributions

line_list = []
append!(line_list, [StaticLine(from = 1, to = 2, Y = -1im / 0.02 + 4)])
append!(line_list, [StaticLine(from = 1, to = 3, Y = -1im / 0.02 + 4)])

node_list = []
append!(node_list, [SlackAlgebraic(U = 1, Y_n = 0)])
append!(node_list, [FourthOrderEq(H = 3.318, P = -0.6337, D = 0.1, Ω = 50, E_f = 0.5, T_d_dash = 0.1,  T_q_dash = 8.690,X_d_dash = 0.111,  X_q_dash = 0.103, X_d = 0.1, X_q = 0.6)])
append!(node_list, [PQAlgebraic(P = -0.6337, Q = 0.0)])

pg = PowerGrid(node_list, line_list)
rpg = rhs(pg)

g = constraint_equations(rpg)

op = find_operationpoint(pg)

g(op.vec)

Frand = random_force(rpg, [0.0,1], Uniform)

z_new = ambient_forcing(rpg, op.vec, 2.0, Frand)
g(z_new)

# Next: let's perturb just the voltage at node 2!

idx = idx_exclusive(rpg, ["u_r_2", "u_i_2"])

Frand = random_force(rpg, [0.0, 1.0], Uniform, idx)

z_new = ambient_forcing(rpg, op.vec, 2.0, Frand);
g(z_new)

idx = idx_exclusive(rpg, ["u_r_2", "u_i_2", "θ_2", "ω_2"])
τ = 2.0 # the integration time

dist_vec = [[0,1], [0, 2], [0, 2π] ./τ, [-5, 5] ./τ]

Frand = Frand = random_force(rpg, dist_vec, Uniform, idx)
z_new = ambient_forcing(rpg, op.vec, τ, Frand)
g(z_new)

# This file was generated using Literate.jl, https://github.com/fredrikekre/Literate.jl


text:
complex1arg = Dict{Symbol,Any}(
#:cis => :todo,		# complex,operators
#:imag => :todo,  # complex,arraymath
#:real => :todo,  # complex,arraymath
#:angle => :todo, # angle(z::Real) = atan2(zero(z), z); angle(z::Complex) = atan2(imag(z), real(z)); complex,number,operators
#:conj => :todo,  # complex,number,abstractarraymath,arraymath,operators
)

# TODO:

# eval
# Complex
# convert
# promote_rule
# widen
# real
# imag
# reim
# isreal
# isimag: Not exported
# isinteger
# isfinite
# isnan
# isinf
# complex
# complex_show: Not exported
# show
# showcompact
# read
# write
# ==
# isequal
# hash
# conj
# abs
# abs2
# inv
# -
# +
# *
# /
# robust_cdiv1: Not exported
# robust_cdiv2: Not exported
# ssqs: Not exported
# sqrt
# cis
# angle
# log
# log10
# log2
# exp
# expm1
# log1p
# ^
# exp2
# exp10
# sin
# cos
# tan
# asin
# acos
# atan
# sinh
# cosh
# tanh
# asinh
# acosh
# atanh
# lexcmp
# round
# float
# big
# promote_array_type: Not exported


text:
# Extract citation in endnote format for a given PMID
# 08/31/2016

#using Requests
using NullableArrays

function citations_endnote(article::PubMedArticle, verbose=false)

    types_idx = find(x->!x, article.types.isnull)
    jrnl_art = find(x->(x=="Journal Article"), article.types.values[types_idx])

    if length(jrnl_art)!= 1
        error("EndNote can only export Journal Articles")
    end

    lines::Vector{UTF8String} = ["%0 Journal Article"]
    for au in article.authors
        if isnull(au[:Initials]) && isnull(au[:LastName])
            println("Skipping author, null field: ", au)
            continue
        end
        author = string(au[:LastName].value, ", ", au[:Initials].value)
        push!(lines, "%A $author")
    end

    !isnull(article.year) && push!(lines, "%D $(article.year.value)")
    !isnull(article.title) && push!(lines, "%T $(article.title.value)")
    !isnull(article.journal) && push!(lines, "%J $(article.journal.value)")
    !isnull(article.volume) && push!(lines, "%V $(article.volume.value)")
    !isnull(article.issue) && push!(lines, "%N $(article.issue.value)")
    !isnull(article.pages) && push!(lines, "%P $(article.pages.value)")
    !isnull(article.pmid) && push!(lines, "%M $(article.pmid.value)")
    !isnull(article.url) && push!(lines, "%U $(article.url.value)")
    !isnull(article.abstract_text) && push!(lines, "%X $(article.abstract_text.value)")

    for term in article.mesh
        !isnull(term) && push!(lines, "%K $(term.value)")
    end

    if !isempty(article.affiliations)
        idx = find(x->!x, article.affiliations.isnull)
        affiliations_str = join(article.affiliations.values[idx], ", ")
        push!(lines, "%+ $affiliations_str")
    end
    # for m in mesh_terms
    #     push!(lines, "%K $m")
    # end
    return join(lines, "\n")
end

function citations_bibtex(article::PubMedArticle, verbose=false)
    types_idx = find(x->!x, article.types.isnull)
    jrnl_art = find(x->(x=="Journal Article"), article.types.values[types_idx])

    if length(jrnl_art)!= 1
        error("EndNote can only export Journal Articles")
    end

    lines::Vector{UTF8String} = ["@article {PMID:$(article.pmid.value),"]
    authors_str = []
    for au in article.authors
        if isnull(au[:Initials]) && isnull(au[:LastName])
            println("Skipping author, null field: ", au)
            continue
        end
        author = string(au[:LastName].value, ", ", au[:Initials].value)
        push!(authors_str, "$author")
    end
    all_authors_str = join(authors_str, " and ")
    push!(lines, "  author  = {$all_authors_str},")
    !isnull(article.title)   && push!(lines, "  title   = {$(article.title.value)},")
    !isnull(article.journal) && push!(lines, "  journal = {$(article.journal.value)},")
    !isnull(article.year)    && push!(lines, "  year    = {$(article.year.value)},")
    !isnull(article.volume)  && push!(lines, "  volume  = {$(article.volume.value)},")
    !isnull(article.issue)   && push!(lines, "  number  = {$(article.issue.value)},")
    !isnull(article.pages)   && push!(lines, "  pages   = {$(article.pages.value)},")
    !isnull(article.url)     && push!(lines, "  url     = {$(article.url.value)},")
    push!(lines, "}\n")
    return join(lines, "\n")
end

function save_article_citations(efetch_dict, config, verbose=false)
    if !(haskey(config, :type) && haskey(config, :output_file) && haskey(config, :overwrite))
        error("Saving citations requires correct dictionary configuration")
    end
    output_file = config[:output_file]

    if config[:overwrite]
        if isfile(output_file)
            rm(output_file)
        end
    end

    if config[:type] == "bibtex"
        citation_func = citations_bibtex
    elseif config[:type] == "endnote"
        citation_func = citations_endnote
    else
        error("Reference type not supported")
    end

    #Decide type of article based on structrure of efetch
    if haskey(efetch_dict, "PubmedArticle")
        TypeArticle = PubMedArticle
        articles = efetch_dict["PubmedArticle"]
    else
        error("Saving citations is only supported for PubMed searches")
    end

    println("Saving citation for " , length(articles) ,  " articles")

    fout = open(output_file, "a")
    for xml_article in articles
        article = TypeArticle(xml_article)
        try
            citation = citation_func(article, verbose)
            print(fout, citation)
            println(fout) #two empty lines
            println(fout)
        catch
            println("Citation failed for PMDI: ", article.pmid)
            continue
        end
    end
    close(fout)
end


text:
########################
##### FEASIBLE LPS #####
########################

function test_lp1_feasible_MOI()
    solver = OnePhase.OnePhaseSolver()
    MOI.set(solver, MOI.RawParameter("output_level"), 0)

    x = MOI.add_variables(solver, 2)
    l = MOI.add_constraint(solver, x[1], MOI.GreaterThan(0.0))
    u = MOI.add_constraint(solver, x[2], MOI.GreaterThan(0.0))
    a = [1.0, 1.0]
    e = MOI.add_constraint(
        solver,
        MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(a, x), 0.0),
        MOI.LessThan(1.0),
    )
    c = [-1.0, -100.0]
    model_test = Model()
    set_optimizer(model_test, OnePhase.OnePhaseSolver)
    set_optimizer_attribute(model_test, "output_level", 0)
    @variable(model_test, x >= 0.0)
    @variable(model_test, y >= 0.0)
    @constraint(model_test, x + y <= 1.0)
    MOI.optimize!(solver, model_test)
    status = MOI.get(solver, MOI.TerminationStatus())
    @test status == :Optimal
end

function test_lp1_optimal_MOI()
    solver = OnePhase.OnePhaseSolver()
    MOI.set(solver, MOI.RawParameter("output_level"), 0)

    x = MOI.add_variables(solver, 2)
    l = MOI.add_constraint(solver, x[1], MOI.GreaterThan(0.0))
    u = MOI.add_constraint(solver, x[2], MOI.GreaterThan(0.0))
    a = [1.0, 1.0]
    e = MOI.add_constraint(
        solver,
        MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(a, x), 0.0),
        MOI.LessThan(1.0),
    )
    c = [-1.0, -100.0]
    MOI.set(
           solver,
           MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(),
           MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(c, x), 0.0),
       );
    MOI.set(solver, MOI.ObjectiveSense(), MOI.MIN_SENSE)
    model_test = Model()
    set_optimizer(model_test, OnePhase.OnePhaseSolver)
    set_optimizer_attribute(model_test, "output_level", 0)
    @variable(model_test, x >= 0.0)
    @variable(model_test, y >= 0.0)
    @constraint(model_test, x + y <= 1.0)
    MOI.optimize!(solver, model_test)
    status = MOI.get(solver, MOI.TerminationStatus())
    @test status == :Optimal
end

function test_nlp1_feasible_MOI()
    solver = OnePhase.OnePhaseSolver()
    MOI.set(solver, MOI.RawParameter("output_level"), 0)

    x = MOI.add_variables(solver, 2)
    l = MOI.add_constraint(solver, x[1], MOI.GreaterThan(0.0))
    u = MOI.add_constraint(solver, x[2], MOI.GreaterThan(0.0))
    a = [1.0, 1.0]
    e = MOI.add_constraint(
        solver,
        MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(a, x), 0.0),
        MOI.GreaterThan(0.1),
    )
    c = [-1.0, -100.0]

    model_test = Model()
    set_optimizer(model_test, OnePhase.OnePhaseSolver)
    set_optimizer_attribute(model_test, "output_level", 0)
    @variable(model_test, x >= 0.0)
    @variable(model_test, y >= 0.0)
    @constraint(model_test, x + y >= 0.1)
    MOI.optimize!(solver, model_test)
    status = MOI.get(solver, MOI.TerminationStatus())
    @test status == :Optimal
end

function test_nlp1_optimal_MOI()
    solver = OnePhase.OnePhaseSolver()
    MOI.set(solver, MOI.RawParameter("output_level"), 0)

    x = MOI.add_variables(solver, 2)
    l = MOI.add_constraint(solver, x[1], MOI.GreaterThan(0.0))
    u = MOI.add_constraint(solver, x[2], MOI.GreaterThan(0.0))
    a = [1.0, 1.0]
    e = MOI.add_constraint(
        solver,
        MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(a, x), 0.0),
        MOI.GreaterThan(0.1),
    )
    c = [-1.0, -100.0]

    model_test = Model()
    set_optimizer(model_test, OnePhase.OnePhaseSolver)
    set_optimizer_attribute(model_test, "output_level", 0)
    @variable(model_test, x >= 0.0)
    @variable(model_test, y >= 0.0)
    @NLconstraint(model_test, x^2 + y^2 <= 1)
    @NLobjective(model_test, Min, x ^ 2 + y ^ 2)
    @constraint(model_test, x + y >= 0.1)
    MOI.optimize!(solver, model_test)

    status = MOI.get(solver, MOI.TerminationStatus())
    @test status == :Optimal
end

function test_lp1_feasible_JuMP()
    #model_test = Model(with_optimizer(OnePhase.OnePhaseSolver))
    model_test = Model()
    set_optimizer(model_test, OnePhase.OnePhaseSolver)
    set_optimizer_attribute(model_test, "output_level", 0)
    @variable(model_test, x >= 0.0)
    @variable(model_test, y >= 0.0)
    @constraint(model_test, x + y <= 1.0)
    JuMP.optimize!(model_test)
    status =  MOI.get(model_test, MOI.TerminationStatus())
    @test status == :Optimal
end

function test_lp1_optimal_JuMP()
    model_test = Model()
    set_optimizer(model_test, OnePhase.OnePhaseSolver)
    set_optimizer_attribute(model_test, "output_level", 0)
    @variable(model_test, x >= 0.0)
    @variable(model_test, y >= 0.0)
    @NLobjective(model_test, Min, -x - 100 * y)
    @constraint(model_test, x + y <= 1.0)
    JuMP.optimize!(model_test)
    status =  MOI.get(model_test, MOI.TerminationStatus())
    @test status == :Optimal
end

function test_nlp1_optimal_JuMP()
    model_test = Model()
    set_optimizer(model_test, OnePhase.OnePhaseSolver)
    set_optimizer_attribute(model_test, "output_level", 0)
    @variable(model_test, x >= 0.0)
    @variable(model_test, y >= 0.0)
    @NLconstraint(model_test, x^2 + y^2 <= 1)
    @NLobjective(model_test, Min, x ^ 2 + y ^ 2)
    @constraint(model_test, x + y >= 0.1)
    JuMP.optimize!(model_test)
    status =  MOI.get(model_test, MOI.TerminationStatus())
    @test status == :Optimal
end