text:
################################################################
### Different types used in library with proper constructors ###
################################################################

#########################
### Coordinates Types ###
#########################

"""
    LLA

Point in Latitude-Longitude-Altitude (LLA) coordinates
Used to store node data in OpenStreetMapX XML files

**Constructors**

    LLA(lat::Float64, lon::Float64)
	LLA(lat::Float64, lon::Float64, alt::Float64)
	LLA(xyz::XYZ)

**Arguments**

* `lat` : lattitude
* `lon` : Longitude
* `alt` : altitude

"""
struct LLA
    lat::Float64
    lon::Float64
    alt::Float64
end
LLA(lat, lon) = LLA(lat, lon, 0.0)

"""
    ECEF

Point in Earth-Centered-Earth-Fixed (ECEF) coordinates.
Global cartesian coordinate system rotating with the Earth.

**Constructors**

	ECEF(x::Float64, y::Float64, z::Float64)

"""
struct ECEF
    x::Float64
    y::Float64
    z::Float64
end

"""
    ENU

Point in East-North-Up (ENU) coordinates.

Local cartesian coordinate system.
Linearized about a reference point.

**Constructors**

	ENU(east::Float64, north::Float64, up::Float64)
	ENU(east::Float64, north::Float64)
	ENU(xyz::XYZ)

"""
struct ENU
    east::Float64
    north::Float64
    up::Float64
end
ENU(east, north) = ENU(east, north, 0.0)

### XYZ
#
"""
    XYZ

Helper for creating other point types in generic code
e.g. myfunc{T <: Union(ENU, LLA)}(...) = (x, y = ...; T(XY(x, y)))

**Constructors**

	XYZ(x::Float64, y::Float64, z::Float64)
	XY(x::Float64, y::Float64)
"""
struct XYZ
    x::Float64
    y::Float64
    z::Float64
end

XY(x, y) = XYZ(x, y, 0.0)
LLA(xyz::XYZ) = LLA(xyz.y, xyz.x, xyz.z)
ENU(xyz::XYZ) = ENU(xyz.x, xyz.y, xyz.z)

### Ellipsoid
# Specify datum for translation between LLA and other coordinate systems
struct Ellipsoid
    a::Float64        # Semi-major axis
    b::Float64        # Semi-minor axis
    e²::Float64       # Eccentricity squared
    e′²::Float64      # Second eccentricity squared
end

#auxiliary function
function ellipsoid(a::BigFloat, b::BigFloat)
    e² = (a^2 - b^2) / a^2
    e′² = (a^2 - b^2) / b^2
    OpenStreetMapX.Ellipsoid(a, b, e², e′²)
end
#constructor
function Ellipsoid(; a::Float64 = NaN, b::Float64= NaN, f_inv::Float64= NaN)
    if isnan(a) || isnan(b) == isnan(f_inv)
        throw(ArgumentError("Specify parameter 'a' and either 'b' or 'f_inv'"))
    elseif isnan(b)
        b = BigFloat(a) * (1 - inv(BigFloat(f_inv)))
        OpenStreetMapX.ellipsoid(BigFloat(a), BigFloat(b))
    else
        OpenStreetMapX.ellipsoid(BigFloat(a), BigFloat(b))
    end
end

"""
    Bounds{T <: Union{LLA, ENU}}

Bounds for the `LLA` or `ENU `coordinates.
"""
struct Bounds{T <: Union{LLA, ENU}}
    min_y::Float64
    max_y::Float64
    min_x::Float64
    max_x::Float64
end

function Bounds(min_lat, max_lat, min_lon, max_lon)
    if !(-90 <= min_lat <= max_lat <= 90 &&
         -180 <= min_lon <= 180 &&
         -180 <= max_lon <= 180)
        throw(ArgumentError("Bounds out of range of LLA coordinate system. " *
                            "Perhaps you're looking for Bounds{ENU}(...)"))
    end
    OpenStreetMapX.Bounds{OpenStreetMapX.LLA}(min_lat, max_lat, min_lon, max_lon)
end

##################
### Main Types ###
##################

abstract type
    OSMElement
end

mutable struct Way <: OSMElement
    id::Int
    nodes::Vector{Int}
    tags::Dict{String,String}
    Way(id::Int) = new(id, Vector{Int}(), Dict{String,String}())
end
tags(w::Way) = w.tags

mutable struct Relation <: OSMElement
    id::Int
    members::Vector{Dict{String,String}}
    tags::Dict{String,String}
    Relation(id::Int) = new(id, Vector{Dict{String,String}}(), Dict{String,String}())
end
tags(r::Relation) = r.tags

mutable struct Segment
    node0::Int          # Source node ID
    node1::Int          # Target node ID
    nodes::Vector{Int}  # List of nodes falling within node0 and node1
    distance::Real      # Length of the segment
    parent::Int         # ID of parent highway
end

######################
### OSM Data Types ###
######################

mutable struct OSMData
    nodes::Dict{Int,OpenStreetMapX.LLA}
    ways::Vector{OpenStreetMapX.Way}
    relations::Vector{OpenStreetMapX.Relation}
    features::Dict{Int,Tuple{String,String}}
    bounds::OpenStreetMapX.Bounds
    way_tags::Set{String}
    relation_tags::Set{String}
end
OSMData() = OSMData(Dict{Int, OpenStreetMapX.LLA}(), Vector{OpenStreetMapX.Way}(),
	            Vector{OpenStreetMapX.Relation}(), Dict{Int,String}(),
	            Bounds(0.0, 0.0, 0.0, 0.0), Set{String}(), Set{String}())

mutable struct DataHandle
    element::Symbol
    osm::OpenStreetMapX.OSMData
    node::Tuple{Int64,OpenStreetMapX.LLA} # initially undefined
    way::OpenStreetMapX.Way # initially undefined
    relation::OpenStreetMapX.Relation # initially undefined
    bounds::OpenStreetMapX.Bounds # initially undefined
    DataHandle() = new(:None, OpenStreetMapX.OSMData())
end

"""
The `MapData` represents all data that have been processed from OpenStreetMap osm file
This is the main data structure used fot map data analytics.

**Fields**

* `bounds` :  bounds of the area map (stored as a OpenStreetMapX.Bounds object)
* `nodes` :  dictionary of nodes representing all the objects on the map (with coordinates in East, North, Up system)
* `roadways` :  unique roads stored as a OpenStreetMapX.Way objects
* `intersections` : roads intersections
* `g` : `LightGraphs` directed graph representing a road network
* `v` : vertices in the road network
* `e` : edges in the graph represented as a tuple (source,destination)
* `w` : edge weights, indexed by graph id
* `class` : road class of each edge
"""
struct MapData
    bounds::Bounds{LLA}
    nodes::Dict{Int,ENU}
    roadways::Array{Way,1}
    intersections::Dict{Int,Set{Int}}
    # Transporation network graph data and helpers to increase routing speed
    g::LightGraphs.SimpleGraphs.SimpleDiGraph{Int64} # Graph object
    v::Dict{Int,Int}                             # (node id) => (graph vertex)
	n::Dict{Int,Int}                             # (graph vertex) => (node id)
    e::Array{Tuple{Int64,Int64},1}                # Edges in graph, stored as a tuple (source,destination)
    w::SparseArrays.SparseMatrixCSC{Float64, Int}   # Edge weights, indexed by graph id
    class::Vector{Int}                           # Road class of each edge
	#MapData(bounds, nodes, roadways, intersections) = new(bounds, nodes, roadways, intersections, LightGraphs.SimpleGraphs.SimpleDiGraph{Int64}(), Dict{Int,Int}(), Tuple{Int64,Int64}[],  SparseMatrixCSC(Matrix{Float64}(undef,0,0)),Int[])
end


text:
using Dates
Faker.language("es-MX")
Faker.seed(80)
@test typeof(  Faker.random_digit() )                                          == String
@test typeof(  Faker.random_digit_not_null() )                                 == String
@test typeof(  Faker.random_digit_or_empty() )                                 == String
@test typeof(  Faker.random_digit_not_null_or_empty() )                        == String
@test typeof(  Faker.random_number(digits= 1) )                                == String
@test typeof(  Faker.random_int(min=0, max=9999) )                             == String
@test typeof(  Faker.randomize_nb_elements(number=10, le=false, ge=false) )    == String
@test typeof(  Faker.random_letter() )                                         == String
@test typeof(  Faker.random_element(("a", "b", "b")) )                         == String
@test typeof(  Faker.lexify("????") )                                          == String
@test typeof(  Faker.numerify("####") )                                        == String
@test typeof(  Faker.bothify("## ??") )                                        == String
@test typeof(  Faker.state_abbr() )                                            == String
@test typeof(  Faker.latitude() )                                              == Float64
@test typeof(  Faker.street_name() )                                           == String
@test typeof(  Faker.address((Faker.street_address(),Faker.city(),Faker.state_abbr(),Faker.postcode())) )                                                                           == String
@test typeof(  Faker.street_address() )                                        == String
@test typeof(  Faker.postcode() )                                              == String
@test typeof(  Faker.longitude() )                                             == Float64
@test typeof(  Faker.country() )                                               == String
@test typeof(  Faker.geo_coordinate(center=0, radius=0.001))                   == Float16
@test typeof(  Faker.secondary_address() )                                     == String
@test typeof(  Faker.city_prefix() )                                           == String
@test typeof(  Faker.city_suffix() )                                           == String
@test typeof(  Faker.building_number() )                                       == String
@test typeof(  Faker.city() )                                                  == String
@test typeof(  Faker.state() )                                                 == String
@test typeof(  Faker.company() )                                               == String
@test typeof(  Faker.company_suffix() )                                        == String
@test typeof(  Faker.catch_phrase() )                                          == String
@test typeof(  Faker.bs() )                                                    == String
@test typeof(  Faker.months() )                                                == Int64
@test typeof(  Faker.am_pm() )                                                 == String
@test typeof(  Faker.iso8601() )                                               == Dates.DateTime
@test typeof(  Faker.date_time("Y-m-d HH:MM:SS") )                             == String
@test typeof(  Faker.month_name() )                                            == String
@test typeof(  Faker.day_of_week() )                                           == String
@test typeof(  Faker.day_of_month() )                                          == Int64
@test typeof(  Faker.date_time_between("-30y", "now","Y-m-d HH:MM:SS") )       == String
@test typeof(  Faker.time("H:M:S") )                                           == String
@test typeof(  Faker.unix_time() )                                             == Int64
@test typeof(  Faker.timezone() )                                              == String
@test typeof(  Faker.century() )                                               == String
@test typeof(  Faker.date("Y-m-d") )                                           == String
@test typeof(  Faker.year() )                                                  == Int64
@test typeof(  Faker.date_time_this_century(before_now=true, after_now=false, pattern="Y-m-d HH:MM:SS") )== String
@test typeof(  Faker.date_time_this_decade(before_now=true, after_now=false, pattern="Y-m-d HH:MM:SS") ) == String
@test typeof(  Faker.date_time_this_year(before_now=true, after_now=false, pattern="Y-m-d HH:MM:SS") )   == String
@test typeof(  Faker.date_time_this_month(before_now=true, after_now=false, pattern="Y-m-d HH:MM:SS") )  == String
@test typeof(  Faker.email() )                                                 == String
@test typeof(  Faker.free_email((Faker.user_name(),"@",Faker.free_email_domain())) ) == String
@test typeof(  Faker.safe_email((Faker.user_name(),"@example.", Faker.domain_suffix())) )== String
@test typeof(  Faker.user_name() )                                             == String
@test typeof(  Faker.domain_name((Faker.domain_word(),".",Faker.domain_suffix())) )== String
@test typeof(  Faker.domain_word() )                                           == String
@test typeof(  Faker.domain_suffix() )                                         == String
@test typeof(  Faker.ipv4() )                                                  == String
@test typeof(  Faker.ipv6() )                                                  == String
@test typeof(  Faker.uri() )                                                   == String
@test typeof(  Faker.url() )                                                   == String
@test typeof(  Faker.image_url() )                                             == String
@test typeof(  Faker.uri_extension() )                                         == String
@test typeof(  Faker.uri_path(deep=0) )                                        == String
@test typeof(  Faker.uri_page() )                                              == String
@test typeof(  Faker.mac_address() )                                           == String
@test typeof(  Faker.company_email((Faker.user_name(),"@",Faker.domain_name())))== String
@test typeof(  Faker.text(number_chars=2) )                                    == String
@test typeof(  Faker.text(number_chars=20) )                                   == String
@test typeof(  Faker.text(number_chars=187) )                                  == String
@test typeof(  Faker.text(number_chars=200) )                                  == String
@test typeof(  Faker.sentence(number_words=6, variable_nb_words=true) )        == String
@test typeof(  Faker.word() )                                                  == String
@test typeof(  Faker.paragraphs() )                                            == Array{String,1}
@test typeof(  Faker.words(number_words=3) )                                   == Array{String,1}
@test typeof(  Faker.paragraph(number=3, variable_nb_sentences=true) )         == String
@test typeof(  Faker.sentences(number_sentences=3) )                           == Array{String,1}
@test typeof(  Faker.phone_number() )                                          == String
@test typeof(  Faker.cell_phone() )                                            ==  String
@test typeof(  Faker.password(longitud=10, special_caracteres=true, digitos=true, upper_case=true, lower_case=true) )                                              == String
@test typeof(  Faker.locale((Faker.language_code(),"_",Faker.country_code())) )                                                                           == String
data= Faker.null_boolean()
@test (typeof(data)              == Bool) || typeof(data) == String
@test typeof(  Faker.country_code() )                                          == String
@test typeof(  Faker.language_code() )                                         == String
@test typeof(  Faker.boolean(chance_of_getting_true=50) )                      == Bool
@test typeof(  Faker.color_name() )                                            == String
@test typeof(  Faker.safe_color_name() )                                       == String
@test typeof(  Faker.hex_color() )                                             == String
@test typeof(  Faker.rgb_color_list() )                                        == String
@test typeof(  Faker.rgb_color() )                                             == String
@test typeof(  Faker.rgb_css_color() )                                         == String
@test typeof(  Faker.credit_card_security_code() )                             == String
@test typeof(  Faker.credit_card_full() )                                      == String
@test typeof(  Faker.credit_card_full("amex") )                                == String
@test typeof(  Faker.credit_card_number() )                                    == String
@test typeof(  Faker.credit_card_number("amex") )                              == String
@test typeof(  Faker.credit_card_provider() )                                  == String
@test typeof(  Faker.generate_card_number() )                                  == String
@test typeof(  Faker.generate_card_number("52",16) )                           == String
@test typeof(  Faker.mime_type() )                                             == String
@test typeof(  Faker.file_extension() )                                        == String
@test typeof(  Faker.file_name() )                                             == String
@test typeof(  Faker.first_name() )                                            == String
@test typeof(  Faker.last_name() )                                             == String
@test typeof(  Faker.prefixe() )                                               == String
@test typeof(  Faker.simple_profile() )                                        == Dict{String,String}
@test typeof(  Faker.job() )                                                   == String
@test typeof(  Faker.blood_type() )                                            == String
@test typeof(  Faker.user_profile((Faker.user_name(),Faker.first_name(),rand(["M","F"]),Faker.address(),Faker.free_email(),Faker.date(),Faker.job(),Faker.company(),Faker.address(),string(Faker.latitude(), Faker.longitude()),Faker.blood_type(),Faker.url())) )                                               == String
@test typeof(  Faker.profile() )                                               == Dict{String,Any}
@test typeof(  Faker.profile("username") )                                     == Dict{Any,Any}
@test typeof(  Faker.profile("username","blood_group") )                       == Dict{Any,Any}
@test typeof(  Faker.simple_profile("birthdate","address","sex") )             == Dict{Any,Any}
@test typeof(  Faker.simple_profile("name") )                                  == Dict{Any,Any}
@test typeof(  Faker.mac_processor() )                                         == String
@test typeof(  Faker.linux_processor() )                                       == String
@test typeof(  Faker.user_agent() )                                            == String
@test typeof(  Faker.windows_platform_token() )                                == String
@test typeof(  Faker.linux_platform_token() )                                  == String
@test typeof(  Faker.mac_platform_token() )                                    == String
@test typeof(  Faker.chrome() )                                                == String
@test typeof(  Faker.internet_explorer() )                                     == String
@test typeof(  Faker.safari() )                                                == String
@test typeof(  Faker.firefox() )                                               == String
@test typeof(  Faker.opera() )                                                 == String
@test typeof(  Faker.random_lowercase_letter() )                               == String
@test typeof(  Faker.random_uppercase_letter() )                               == String
@test typeof(  Faker.random_special_caracteres() )                             == String
@test typeof(  Faker.unicode() )                                               == String
@test typeof( Faker.generator(items=(Faker.user_name(),Faker.first_name(),Faker.city(),Faker.postcode(), Faker.user_name(),"@",Faker.domain_name()), separator=Faker.stringWithComa))              == String
@test typeof( Faker.generator(items=(Faker.user_name(),Faker.first_name(),Faker.city(),Faker.postcode(), Faker.user_name(),"@",Faker.domain_name()), separator=Faker.stringWithSpaces))            == String
@test typeof( Faker.generator(items=(Faker.user_name(),Faker.first_name(),Faker.city(),Faker.postcode(), Faker.user_name(),"@",Faker.domain_name()), separator=Faker.string))                      == String

@test typeof(  Faker.ssn()              )== String
@test typeof(  Faker.ssn("SSN")         )== String
@test typeof(  Faker.ssn("ITIN")        )== String
@test typeof(  Faker.ssn("EIN")         )== String
@test typeof(  Faker.ssn("INVALID_SSN") )== String

@test typeof(  Faker.female_first_name())== String
@test typeof(  Faker.male_first_name()  )== String

@test typeof(  Faker.first_name()       )== String
@test typeof(  Faker.first_name("M")    )== String
@test typeof(  Faker.first_name("F")    )== String

ext: jl


text:
type ProtoServiceException <: Exception
    msg::AbstractString
end

abstract ProtoRpcChannel
abstract ProtoRpcController
abstract AbstractProtoServiceStub{B}

#
# MethodDescriptor begin
# ==============================
type MethodDescriptor
    name::AbstractString
    index::Int
    input_type::DataType
    output_type::DataType
end
get_request_type(meth::MethodDescriptor) = meth.input_type
get_response_type(meth::MethodDescriptor) = meth.output_type

# ==============================
# MethodDescriptor end
#

#
# ServiceDescriptor begin
# ==============================
type ServiceDescriptor
    name::AbstractString
    index::Int
    methods::Array{MethodDescriptor}
    _method_name_idx::Dict{AbstractString,MethodDescriptor}
    _method_index_idx::Dict{Int,MethodDescriptor}

    function ServiceDescriptor(name::AbstractString, index::Int, methods::Array{MethodDescriptor})
        name_idx = Dict{AbstractString,MethodDescriptor}()
        index_idx = Dict{Int,MethodDescriptor}()
        for method in methods
            name_idx[method.name] = method
            index_idx[method.index] = method
        end
        new(name, index, methods, name_idx, index_idx)
    end
end

function find_method(svc::ServiceDescriptor, name::AbstractString)
    (name in keys(svc._method_name_idx)) || throw(ProtoServiceException("Service $(svc.name) has no method named $(name)"))
    svc._method_name_idx[name]
end
function find_method(svc::ServiceDescriptor, index::Int)
    (0 < index <= length(svc.methods)) || throw(ProtoServiceException("Service $(svc.name) has no method at index $(index)"))
    svc._method_index_idx[index]
end
find_method(svc::ServiceDescriptor, meth::MethodDescriptor) = isempty(meth.name) ? find_method(svc, meth.index) : find_method(svc, meth.name)
# ==============================
# ServiceDescriptor end
#

#
# Service begin
# ==============================
type ProtoService
    desc::ServiceDescriptor
    impl_module::Module
end

find_method(svc::ProtoService, name_or_index) = find_method(svc.desc, name_or_index)
get_request_type(svc::ProtoService, meth::MethodDescriptor) = get_request_type(find_method(svc, meth))
get_response_type(svc::ProtoService, meth::MethodDescriptor) = get_response_type(find_method(svc, meth))
get_descriptor_for_type(svc::ProtoService) = svc.desc
call_method(svc::ProtoService, meth::MethodDescriptor, controller::ProtoRpcController, request, done::Function) = @async done(call_method(svc, meth, controller, request))
function call_method(svc::ProtoService, meth::MethodDescriptor, controller::ProtoRpcController, request)
    meth_desc = find_method(svc, meth)
    m = eval(svc.impl_module, @compat(Symbol(meth_desc.name)))
    isa(request, meth_desc.input_type) || throw(ProtoServiceException("Invalid input type $(typeof(request)) for service $(meth_desc.name). Expected type $(meth_desc.input_type)"))
    m(request)
end
# ==============================
# Service end
#

#
# Service Stubs begin
# ==============================
type GenericProtoServiceStub{B} <: AbstractProtoServiceStub{B}
    desc::ServiceDescriptor
    channel::ProtoRpcChannel
    blocking::Bool
    GenericProtoServiceStub(desc::ServiceDescriptor, channel::ProtoRpcChannel) = new(desc, channel, B)
end

typealias ProtoServiceStub GenericProtoServiceStub{false}
typealias ProtoServiceBlockingStub GenericProtoServiceStub{true}

find_method(stub::GenericProtoServiceStub, name_or_index) = find_method(stub.desc, name_or_index)
call_method(stub::ProtoServiceBlockingStub, meth::MethodDescriptor, controller::ProtoRpcController, request) = call_method(stub.channel, find_method(stub, meth), controller, request)
call_method(stub::ProtoServiceStub, meth::MethodDescriptor, controller::ProtoRpcController, request, done::Function) = @async done(call_method(stub.channel, find_method(stub, meth), controller, request))
# ==============================
# Service Stubs end
#


text:
#####
##### These functions return the transforms required to solve Poisson's equation with
##### periodic boundary conditions or staggered Neumann boundary conditions.
#####
##### Fast Fourier transforms (FFTs) are used in the periodic dimensions and
##### real-to-real discrete cosine transforms are used in the wall-bounded dimensions.
##### Note that the DCT-II is used for the DCT and the DCT-III for the IDCT
##### which correspond to REDFT10 and REDFT01 in FFTW.
#####
##### They operate on an array with the shape of `A`, which is needed to plan
##### efficient transforms. `A` will be mutated.
#####

##### Only for regular grids (FX == FY == FZ <: Number)
##### and vertically stretched grids (FX == FY <: Number)

const Regular             = RegRectilinearGrid
const VerticallyStretched = HRegRectilinearGrid

function plan_forward_transform(A::Array, ::Periodic, dims, planner_flag=FFTW.PATIENT)
    length(dims) == 0 && return nothing
    return FFTW.plan_fft!(A, dims, flags=planner_flag)
end

function plan_forward_transform(A::Array, ::Bounded, dims, planner_flag=FFTW.PATIENT)
    length(dims) == 0 && return nothing
    return FFTW.plan_r2r!(A, FFTW.REDFT10, dims, flags=planner_flag)
end

function plan_backward_transform(A::Array, ::Periodic, dims, planner_flag=FFTW.PATIENT)
    length(dims) == 0 && return nothing
    return FFTW.plan_ifft!(A, dims, flags=planner_flag)
end

function plan_backward_transform(A::Array, ::Bounded, dims, planner_flag=FFTW.PATIENT)
    length(dims) == 0 && return nothing
    return FFTW.plan_r2r!(A, FFTW.REDFT01, dims, flags=planner_flag)
end

function plan_forward_transform(A::CuArray, ::Union{Bounded, Periodic}, dims, planner_flag)
    length(dims) == 0 && return nothing
    return CUDA.CUFFT.plan_fft!(A, dims)
end

function plan_backward_transform(A::CuArray, ::Union{Bounded, Periodic}, dims, planner_flag)
    length(dims) == 0 && return nothing
    return CUDA.CUFFT.plan_ifft!(A, dims)
end

plan_backward_transform(A::Union{Array, CuArray}, ::Flat, args...) = nothing
plan_forward_transform(A::Union{Array, CuArray}, ::Flat, args...) = nothing

batchable_GPU_topologies = ((Periodic, Periodic, Periodic),
                            (Periodic, Periodic, Bounded),
                            (Bounded,  Periodic, Periodic))

# In principle the order in which the transforms are applied does not matter of course,
# but in practice we want to perform the `Bounded` forward transforms first because on
# the GPU we take the real part after a forward transform, so if the `Periodic`
# transform is performed first we lose the information in the imaginary components after a
# `Bounded` forward transform.
#
# For the same reason, `Bounded` backward transforms are applied after `Periodic`
# backward transforms.
#
# Note that `Flat` "transforms" have no effect. To avoid defining forward_orders and `backward_orders`
# for Flat we reuse the orderings that apply to combinations of Periodic and Bounded.

forward_orders(::Type{Periodic}, ::Type{Bounded},  ::Type{Bounded})  = (3, 2, 1)
forward_orders(::Type{Periodic}, ::Type{Bounded},  ::Type{Periodic}) = (2, 1, 3)
forward_orders(::Type{Bounded},  ::Type{Periodic}, ::Type{Bounded})  = (1, 3, 2)
forward_orders(::Type{Bounded},  ::Type{Bounded},  ::Type{Periodic}) = (1, 2, 3)
forward_orders(::Type{Bounded},  ::Type{Bounded},  ::Type{Bounded})  = (1, 2, 3)

backward_orders(::Type{Periodic}, ::Type{Bounded},  ::Type{Bounded})  = (1, 2, 3)
backward_orders(::Type{Periodic}, ::Type{Bounded},  ::Type{Periodic}) = (3, 1, 2)
backward_orders(::Type{Bounded},  ::Type{Periodic}, ::Type{Bounded})  = (2, 1, 3)
backward_orders(::Type{Bounded},  ::Type{Bounded},  ::Type{Periodic}) = (3, 1, 2)
backward_orders(::Type{Bounded},  ::Type{Bounded},  ::Type{Bounded})  = (1, 2, 3)

" Used by FFTBasedPoissonSolver "
function plan_transforms(grid::Regular, storage, planner_flag)
    Nx, Ny, Nz = size(grid)
    topo = topology(grid)
    periodic_dims = findall(t -> t == Periodic, topo)
    bounded_dims = findall(t -> t == Bounded, topo)

    # Convert Flat to Bounded for inferring batchability and transform ordering
    # Note that transforms are omitted in Flat directions.
    unflattened_topo = Tuple(T() isa Flat ? Bounded : T for T in topo)

    arch = architecture(grid)

    if arch isa GPU && !(unflattened_topo in batchable_GPU_topologies)

        rs_storage = reshape(storage, (Ny, Nx, Nz))
        forward_plan_x = plan_forward_transform(storage,    topo[1](), [1], planner_flag)
        forward_plan_y = plan_forward_transform(rs_storage, topo[2](), [1], planner_flag)
        forward_plan_z = plan_forward_transform(storage,    topo[3](), [3], planner_flag)

        backward_plan_x = plan_backward_transform(storage,    topo[1](), [1], planner_flag)
        backward_plan_y = plan_backward_transform(rs_storage, topo[2](), [1], planner_flag)
        backward_plan_z = plan_backward_transform(storage,    topo[3](), [3], planner_flag)

        forward_plans = (forward_plan_x, forward_plan_y, forward_plan_z)
        backward_plans = (backward_plan_x, backward_plan_y, backward_plan_z)

        f_order = forward_orders(unflattened_topo...)
        b_order = backward_orders(unflattened_topo...)

        forward_transforms = (
            DiscreteTransform(forward_plans[f_order[1]], Forward(), grid, [f_order[1]]),
            DiscreteTransform(forward_plans[f_order[2]], Forward(), grid, [f_order[2]]),
            DiscreteTransform(forward_plans[f_order[3]], Forward(), grid, [f_order[3]])
        )

        backward_transforms = (
            DiscreteTransform(backward_plans[b_order[1]], Backward(), grid, [b_order[1]]),
            DiscreteTransform(backward_plans[b_order[2]], Backward(), grid, [b_order[2]]),
            DiscreteTransform(backward_plans[b_order[3]], Backward(), grid, [b_order[3]])
        )

    else
        # This is the case where batching transforms is possible. It's always possible on the CPU
        # since FFTW is awesome so it includes all topologies on the CPU.
        #
        # `batchable_GPU_topologies` occurs when there are two adjacent `Periodic` dimensions:
        # (Periodic, Periodic, Periodic), (Periodic, Periodic, Bounded), and (Bounded, Periodic, Periodic).

        forward_periodic_plan = plan_forward_transform(storage, Periodic(), periodic_dims, planner_flag)
        forward_bounded_plan = plan_forward_transform(storage, Bounded(), bounded_dims, planner_flag)

        forward_transforms = (
            DiscreteTransform(forward_bounded_plan, Forward(), grid, bounded_dims),
            DiscreteTransform(forward_periodic_plan, Forward(), grid, periodic_dims)
        )

        backward_periodic_plan = plan_backward_transform(storage, Periodic(), periodic_dims, planner_flag)
        backward_bounded_plan = plan_backward_transform(storage, Bounded(), bounded_dims, planner_flag)

        backward_transforms = (
            DiscreteTransform(backward_periodic_plan, Backward(), grid, periodic_dims),
            DiscreteTransform(backward_bounded_plan, Backward(), grid, bounded_dims)
        )
    end

    transforms = (forward=forward_transforms, backward=backward_transforms)

    return transforms
end

""" Used by FourierTridiagonalPoissonSolver. """
function plan_transforms(grid::VerticallyStretched, storage, planner_flag)
    Nx, Ny, Nz = size(grid)
    TX, TY, TZ = topo = topology(grid)

    # Limit ourselves to x, y transforms (z uses a tridiagonal solve)
    periodic_dims = findall(t -> t == Periodic, (TX, TY))
    bounded_dims = findall(t -> t == Bounded, (TX, TY))

    # Convert Flat to Bounded for ordering purposes (transforms are omitted in Flat directions anyways)

    !(topo[3] === Bounded) && error("Cannot plan transforms on z-periodic RectilinearGrids.")

    arch = architecture(grid)

    if arch isa CPU
        # This is the case where batching transforms is possible. It's always possible on the CPU
        # since FFTW is awesome so it includes all topologies on the CPU.
        #
        # On the GPU and for vertically Bounded grids, batching is possible either in horizontally-periodic
        # domains, or for domains that are `Bounded, Periodic, Bounded`.

        forward_periodic_plan = plan_forward_transform(storage, Periodic(), periodic_dims, planner_flag)
        forward_bounded_plan = plan_forward_transform(storage, Bounded(), bounded_dims, planner_flag)

        forward_transforms = (DiscreteTransform(forward_bounded_plan, Forward(), grid, bounded_dims),
                              DiscreteTransform(forward_periodic_plan, Forward(), grid, periodic_dims))

        backward_periodic_plan = plan_backward_transform(storage, Periodic(), periodic_dims, planner_flag)
        backward_bounded_plan = plan_backward_transform(storage, Bounded(), bounded_dims, planner_flag)

        backward_transforms = (DiscreteTransform(backward_periodic_plan, Backward(), grid, periodic_dims),
                               DiscreteTransform(backward_bounded_plan, Backward(), grid, bounded_dims))

    elseif !(Bounded in (TX, TY))
        # We're on the GPU and either (Periodic, Periodic), (Flat, Periodic), or (Periodic, Flat) in xy.
        # So, we pretend like we need a 2D doubly-periodic transform (even if one dimension is Flat).
        forward_periodic_plan = plan_forward_transform(storage, Periodic(), [1, 2], planner_flag)
        backward_periodic_plan = plan_backward_transform(storage, Periodic(), [1, 2], planner_flag)

        forward_transforms = tuple(DiscreteTransform(forward_periodic_plan, Forward(), grid, [1, 2]))
        backward_transforms = tuple(DiscreteTransform(backward_periodic_plan, Backward(), grid, [1, 2]))

    else # we are on the GPU and we cannot / should not batch!
        rs_storage = reshape(storage, (Ny, Nx, Nz))

        forward_plan_x = plan_forward_transform(storage,    topo[1](), [1], planner_flag)
        forward_plan_y = plan_forward_transform(rs_storage, topo[2](), [1], planner_flag)

        backward_plan_x = plan_backward_transform(storage,    topo[1](), [1], planner_flag)
        backward_plan_y = plan_backward_transform(rs_storage, topo[2](), [1], planner_flag)

        forward_plans = (forward_plan_x, forward_plan_y)
        backward_plans = (backward_plan_x, backward_plan_y)

        unflattened_topo = Tuple(T() isa Flat ? Bounded : T for T in topo)
        f_order = forward_orders(unflattened_topo...)
        b_order = backward_orders(unflattened_topo...)

        # Extract third dimension
        f_order = Tuple(f_order[i] for i in findall(d -> d != 3, f_order))
        b_order = Tuple(b_order[i] for i in findall(d -> d != 3, b_order))

        forward_transforms = (DiscreteTransform(forward_plans[f_order[1]], Forward(), grid, [f_order[1]]),
                              DiscreteTransform(forward_plans[f_order[2]], Forward(), grid, [f_order[2]]))

        backward_transforms = (DiscreteTransform(backward_plans[b_order[1]], Backward(), grid, [b_order[1]]),
                               DiscreteTransform(backward_plans[b_order[2]], Backward(), grid, [b_order[2]]))
    end

    transforms = (forward=forward_transforms, backward=backward_transforms)

    return transforms
end


text:
using Documenter
using BenchmarkCI

makedocs(;
    sitename = "BenchmarkCI",
    format = Documenter.HTML(),
    modules = [BenchmarkCI],
)

deploydocs(;
    repo = "github.com/tkf/BenchmarkCI.jl",
    push_preview = true,
)


text:
# TODO:  TO FIX !!!
#/////////////////////////////////////////////////
using LinearAlgebraicRepresentation
Lar = LinearAlgebraicRepresentation
using SparseArrays, LinearAlgebra
using ViewerGL
GL = ViewerGL

function randomshapes()
	V,EV,FV = Lar.randomcubes(5, .8)
	model3d = V,EV,FV
	VV = [[k] for k=1:size(V,2)]

	Sigma =  Lar.spaceindex((V,FV))
	GL.VIEW( GL.numbering(.15)((V,[VV, EV, FV])) )
	V,EVs = Lar.biconnectedComponent((V,EV::Lar.Cells)) # 2-connected components (H & T)
	GL.VIEW(GL.GLExplode(V,EVs,1.5,1.5,1.5,12,0.99));

	W,bases,coboundaries = Lar.chaincomplex(V,FV,EV)
	EV, FV, CV = bases
	copEV, copFE, copCF = coboundaries # OK

#
EV = Lar.cop2lar(copEV)
FE = [findnz(copFE[k,:])[1] for k=1:size(copFE,1)]
FV = [collect(Set(cat(EV[e] for e in FE[f]))) for f=1:length(FE)]
FV = convert(Lar.Cells, FV)
W = convert(Lar.Points, V')
WW = [[k] for k=1:size(W,2)]

GL.VIEW(GL.numbering(.2)((W,[WW,EV])));
#

	W = convert(Lar.Points, W')
	triangulated_faces = Lar.triangulate(W, [copEV, copFE])
	FVs = convert(Array{Lar.Cells}, triangulated_faces)

	Plasm.viewcolor(V::Lar.Points, FVs::Array{Lar.Cells})
end

randomshapes()


text:
type Trie{T}
    value::T
    children::Dict{Char,Trie{T}}
    is_key::Bool

    function Trie()
        self = new()
        self.children = Dict{Char,Trie{T}}()
        self.is_key = false
        self
    end

    function Trie(ks, vs)
        t = Trie{T}()
        for (k, v) in zip(ks, vs)
            t[k] = v
        end
        return t
    end

    function Trie(kv)
        t = Trie{T}()
        for (k,v) in kv
            t[k] = v
        end
        return t
    end
end

Trie() = Trie{Any}()
Trie{K<:String,V}(ks::AbstractVector{K}, vs::AbstractVector{V}) = Trie{V}(ks, vs)
Trie{K<:String,V}(kv::AbstractVector{@compat Tuple{K,V}}) = Trie{V}(kv)
Trie{K<:String,V}(kv::Associative{K,V}) = Trie{V}(kv)
Trie{K<:String}(ks::AbstractVector{K}) = Trie{Nothing}(ks, similar(ks, Nothing))

function setindex!{T}(t::Trie{T}, val::T, key::String)
    node = t
    for char in key
        if !haskey(node.children, char)
            node.children[char] = Trie{T}()
        end
        node = node.children[char]
    end
    node.is_key = true
    node.value = val
end

function getindex(t::Trie, key::String)
    node = subtrie(t, key)
    if node != nothing && node.is_key
        return node.value
    end
    throw(KeyError("key not found: $key"))
end

function subtrie(t::Trie, prefix::String)
    node = t
    for char in prefix
        if !haskey(node.children, char)
            return nothing
        else
            node = node.children[char]
        end
    end
    node
end

function haskey(t::Trie, key::String)
    node = subtrie(t, key)
    node != nothing && node.is_key
end

function get(t::Trie, key::String, notfound)
    node = subtrie(t, key)
    if node != nothing && node.is_key
        return node.value
    end
    notfound
end

function keys(t::Trie, prefix::String="", found=String[])
    if t.is_key
        push!(found, prefix)
    end
    for (char,child) in t.children
        keys(child, string(prefix,char), found)
    end
    found
end

function keys_with_prefix(t::Trie, prefix::String)
    st = subtrie(t, prefix)
    st != nothing ? keys(st,prefix) : []
end

# The state of a TrieIterator is a pair (t::Trie, i::Int),
# where t is the Trie which was the output of the previous iteration
# and i is the index of the current character of the string.
# The indexing is potentially confusing;
# see the comments and implementation below for details.
immutable TrieIterator
    t::Trie
    str::String
end

# At the start, there is no previous iteration,
# so the first element of the state is undefined.
# We use a "dummy value" of it.t to keep the type of the state stable.
# The second element is 0
# since the root of the trie corresponds to a length 0 prefix of str.
start(it::TrieIterator) = (it.t, 0)

function next(it::TrieIterator, state)
    t, i = state
    i == 0 && return it.t, (it.t, 1)

    t = t.children[it.str[i]]
    return (t, (t, i + 1))
end

function done(it::TrieIterator, state)
    t, i = state
    i == 0 && return false
    i == length(it.str) + 1 && return true
    return !(it.str[i] in keys(t.children))
end

path(t::Trie, str::String) = TrieIterator(t, str)

max_stars_repo_name: ambujone/DIDebug

max_issues_repo_name: ambujone/DIDebug

max_forks_repo_name: ambujone/DIDebug


text:
# This file was generated by the Julia Swagger Code Generator
# Do not modify this file directly. Modify the swagger specification instead.

struct VirtualNetworkGatewaysApi <: SwaggerApi
    client::Swagger.Client
end

"""

Creates or updates a virtual network gateway in the specified resource group.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: parameters::VirtualNetworkGateway (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: VirtualNetworkGateway
"""
function _swaggerinternal_virtualNetworkGatewaysCreateOrUpdate(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "PUT", VirtualNetworkGateway, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}", ["azure_auth"], parameters)
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysCreateOrUpdate(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysCreateOrUpdate(_api, resourceGroupName, virtualNetworkGatewayName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysCreateOrUpdate(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysCreateOrUpdate(_api, resourceGroupName, virtualNetworkGatewayName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Deletes the specified virtual network gateway.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: Nothing
"""
function _swaggerinternal_virtualNetworkGatewaysDelete(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "DELETE", Nothing, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysDelete(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysDelete(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysDelete(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysDelete(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Disconnect vpn connections of virtual network gateway in the specified resource group.
Param: subscriptionId::String (required)
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: request::P2SVpnConnectionRequest (required)
Param: api_version::String (required)
Return: Nothing
"""
function _swaggerinternal_virtualNetworkGatewaysDisconnectVirtualNetworkGatewayVpnConnections(_api::VirtualNetworkGatewaysApi, subscriptionId::String, resourceGroupName::String, virtualNetworkGatewayName::String, request, api_version::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", Nothing, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/disconnectVirtualNetworkGatewayVpnConnections", ["azure_auth"], request)
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysDisconnectVirtualNetworkGatewayVpnConnections(_api::VirtualNetworkGatewaysApi, subscriptionId::String, resourceGroupName::String, virtualNetworkGatewayName::String, request, api_version::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysDisconnectVirtualNetworkGatewayVpnConnections(_api, subscriptionId, resourceGroupName, virtualNetworkGatewayName, request, api_version; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysDisconnectVirtualNetworkGatewayVpnConnections(_api::VirtualNetworkGatewaysApi, response_stream::Channel, subscriptionId::String, resourceGroupName::String, virtualNetworkGatewayName::String, request, api_version::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysDisconnectVirtualNetworkGatewayVpnConnections(_api, subscriptionId, resourceGroupName, virtualNetworkGatewayName, request, api_version; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Generates VPN profile for P2S client of the virtual network gateway in the specified resource group. Used for IKEV2 and radius based authentication.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: parameters::VpnClientParameters (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: String
"""
function _swaggerinternal_virtualNetworkGatewaysGenerateVpnProfile(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", String, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/generatevpnprofile", ["azure_auth"], parameters)
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysGenerateVpnProfile(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGenerateVpnProfile(_api, resourceGroupName, virtualNetworkGatewayName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysGenerateVpnProfile(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGenerateVpnProfile(_api, resourceGroupName, virtualNetworkGatewayName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Generates VPN client package for P2S client of the virtual network gateway in the specified resource group.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: parameters::VpnClientParameters (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: String
"""
function _swaggerinternal_virtualNetworkGatewaysGeneratevpnclientpackage(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", String, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/generatevpnclientpackage", ["azure_auth"], parameters)
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysGeneratevpnclientpackage(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGeneratevpnclientpackage(_api, resourceGroupName, virtualNetworkGatewayName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysGeneratevpnclientpackage(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGeneratevpnclientpackage(_api, resourceGroupName, virtualNetworkGatewayName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Gets the specified virtual network gateway by resource group.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: VirtualNetworkGateway
"""
function _swaggerinternal_virtualNetworkGatewaysGet(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", VirtualNetworkGateway, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysGet(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGet(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysGet(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGet(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

This operation retrieves a list of routes the virtual network gateway is advertising to the specified peer.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: peer::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: GatewayRouteListResult
"""
function _swaggerinternal_virtualNetworkGatewaysGetAdvertisedRoutes(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, peer::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", GatewayRouteListResult, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/getAdvertisedRoutes", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "peer", peer)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysGetAdvertisedRoutes(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, peer::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGetAdvertisedRoutes(_api, resourceGroupName, virtualNetworkGatewayName, peer, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysGetAdvertisedRoutes(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, peer::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGetAdvertisedRoutes(_api, resourceGroupName, virtualNetworkGatewayName, peer, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

The GetBgpPeerStatus operation retrieves the status of all BGP peers.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Param: peer::String
Return: BgpPeerStatusListResult
"""
function _swaggerinternal_virtualNetworkGatewaysGetBgpPeerStatus(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; peer=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", BgpPeerStatusListResult, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/getBgpPeerStatus", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "peer", peer)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysGetBgpPeerStatus(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; peer=nothing, _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGetBgpPeerStatus(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; peer=peer, _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysGetBgpPeerStatus(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; peer=nothing, _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGetBgpPeerStatus(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; peer=peer, _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

This operation retrieves a list of routes the virtual network gateway has learned, including routes learned from BGP peers.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: GatewayRouteListResult
"""
function _swaggerinternal_virtualNetworkGatewaysGetLearnedRoutes(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", GatewayRouteListResult, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/getLearnedRoutes", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysGetLearnedRoutes(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGetLearnedRoutes(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysGetLearnedRoutes(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGetLearnedRoutes(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Gets pre-generated VPN profile for P2S client of the virtual network gateway in the specified resource group. The profile needs to be generated first using generateVpnProfile.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: String
"""
function _swaggerinternal_virtualNetworkGatewaysGetVpnProfilePackageUrl(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", String, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/getvpnprofilepackageurl", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysGetVpnProfilePackageUrl(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGetVpnProfilePackageUrl(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysGetVpnProfilePackageUrl(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGetVpnProfilePackageUrl(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Get VPN client connection health detail per P2S client connection of the virtual network gateway in the specified resource group.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: VpnClientConnectionHealthDetailListResult
"""
function _swaggerinternal_virtualNetworkGatewaysGetVpnclientConnectionHealth(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", VpnClientConnectionHealthDetailListResult, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/getVpnClientConnectionHealth", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysGetVpnclientConnectionHealth(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGetVpnclientConnectionHealth(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysGetVpnclientConnectionHealth(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGetVpnclientConnectionHealth(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

The Get VpnclientIpsecParameters operation retrieves information about the vpnclient ipsec policy for P2S client of virtual network gateway in the specified resource group through Network resource provider.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: VpnClientIPsecParameters
"""
function _swaggerinternal_virtualNetworkGatewaysGetVpnclientIpsecParameters(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", VpnClientIPsecParameters, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/getvpnclientipsecparameters", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysGetVpnclientIpsecParameters(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGetVpnclientIpsecParameters(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysGetVpnclientIpsecParameters(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysGetVpnclientIpsecParameters(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Gets all virtual network gateways by resource group.
Param: resourceGroupName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: VirtualNetworkGatewayListResult
"""
function _swaggerinternal_virtualNetworkGatewaysList(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", VirtualNetworkGatewayListResult, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysList(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysList(_api, resourceGroupName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysList(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysList(_api, resourceGroupName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Gets all the connections in a virtual network gateway.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: VirtualNetworkGatewayListConnectionsResult
"""
function _swaggerinternal_virtualNetworkGatewaysListConnections(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "GET", VirtualNetworkGatewayListConnectionsResult, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/connections", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysListConnections(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysListConnections(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysListConnections(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysListConnections(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Resets the primary of the virtual network gateway in the specified resource group.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Param: gatewayVip::String
Return: VirtualNetworkGateway
"""
function _swaggerinternal_virtualNetworkGatewaysReset(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; gatewayVip=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", VirtualNetworkGateway, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/reset", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "gatewayVip", gatewayVip)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysReset(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; gatewayVip=nothing, _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysReset(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; gatewayVip=gatewayVip, _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysReset(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; gatewayVip=nothing, _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysReset(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; gatewayVip=gatewayVip, _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Resets the VPN client shared key of the virtual network gateway in the specified resource group.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: Nothing
"""
function _swaggerinternal_virtualNetworkGatewaysResetVpnClientSharedKey(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", Nothing, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/resetvpnclientsharedkey", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysResetVpnClientSharedKey(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysResetVpnClientSharedKey(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysResetVpnClientSharedKey(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysResetVpnClientSharedKey(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

The Set VpnclientIpsecParameters operation sets the vpnclient ipsec policy for P2S client of virtual network gateway in the specified resource group through Network resource provider.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: vpnclientIpsecParams::VpnClientIPsecParameters (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: VpnClientIPsecParameters
"""
function _swaggerinternal_virtualNetworkGatewaysSetVpnclientIpsecParameters(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, vpnclientIpsecParams, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", VpnClientIPsecParameters, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/setvpnclientipsecparameters", ["azure_auth"], vpnclientIpsecParams)
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysSetVpnclientIpsecParameters(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, vpnclientIpsecParams, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysSetVpnclientIpsecParameters(_api, resourceGroupName, virtualNetworkGatewayName, vpnclientIpsecParams, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysSetVpnclientIpsecParameters(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, vpnclientIpsecParams, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysSetVpnclientIpsecParameters(_api, resourceGroupName, virtualNetworkGatewayName, vpnclientIpsecParams, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Starts packet capture on virtual network gateway in the specified resource group.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Param: parameters::VpnPacketCaptureStartParameters
Return: String
"""
function _swaggerinternal_virtualNetworkGatewaysStartPacketCapture(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; parameters=nothing, _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", String, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/startPacketCapture", ["azure_auth"], parameters)
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysStartPacketCapture(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; parameters=nothing, _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysStartPacketCapture(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; parameters=parameters, _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysStartPacketCapture(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; parameters=nothing, _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysStartPacketCapture(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; parameters=parameters, _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Stops packet capture on virtual network gateway in the specified resource group.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: parameters::VpnPacketCaptureStopParameters (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: String
"""
function _swaggerinternal_virtualNetworkGatewaysStopPacketCapture(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", String, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/stopPacketCapture", ["azure_auth"], parameters)
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysStopPacketCapture(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysStopPacketCapture(_api, resourceGroupName, virtualNetworkGatewayName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysStopPacketCapture(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysStopPacketCapture(_api, resourceGroupName, virtualNetworkGatewayName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Gets a xml format representation for supported vpn devices.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: String
"""
function _swaggerinternal_virtualNetworkGatewaysSupportedVpnDevices(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", String, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}/supportedvpndevices", ["azure_auth"])
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysSupportedVpnDevices(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysSupportedVpnDevices(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysSupportedVpnDevices(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysSupportedVpnDevices(_api, resourceGroupName, virtualNetworkGatewayName, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Updates a virtual network gateway tags.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayName::String (required)
Param: parameters::TagsObject (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: VirtualNetworkGateway
"""
function _swaggerinternal_virtualNetworkGatewaysUpdateTags(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "PATCH", VirtualNetworkGateway, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/virtualNetworkGateways/{virtualNetworkGatewayName}", ["azure_auth"], parameters)
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayName", virtualNetworkGatewayName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysUpdateTags(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysUpdateTags(_api, resourceGroupName, virtualNetworkGatewayName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysUpdateTags(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysUpdateTags(_api, resourceGroupName, virtualNetworkGatewayName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

"""

Gets a xml format representation for vpn device configuration script.
Param: resourceGroupName::String (required)
Param: virtualNetworkGatewayConnectionName::String (required)
Param: parameters::VpnDeviceScriptParameters (required)
Param: api_version::String (required)
Param: subscriptionId::String (required)
Return: String
"""
function _swaggerinternal_virtualNetworkGatewaysVpnDeviceConfigurationScript(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayConnectionName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = Swagger.Ctx(_api.client, "POST", String, "/subscriptions/{subscriptionId}/resourceGroups/{resourceGroupName}/providers/Microsoft.Network/connections/{virtualNetworkGatewayConnectionName}/vpndeviceconfigurationscript", ["azure_auth"], parameters)
    Swagger.set_param(_ctx.path, "resourceGroupName", resourceGroupName)  # type String
    Swagger.set_param(_ctx.path, "virtualNetworkGatewayConnectionName", virtualNetworkGatewayConnectionName)  # type String
    Swagger.set_param(_ctx.path, "subscriptionId", subscriptionId)  # type String
    Swagger.set_param(_ctx.query, "api-version", api_version)  # type String
    Swagger.set_header_accept(_ctx, ["application/json"])
    Swagger.set_header_content_type(_ctx, (_mediaType === nothing) ? ["application/json"] : [_mediaType])
    return _ctx
end

function virtualNetworkGatewaysVpnDeviceConfigurationScript(_api::VirtualNetworkGatewaysApi, resourceGroupName::String, virtualNetworkGatewayConnectionName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysVpnDeviceConfigurationScript(_api, resourceGroupName, virtualNetworkGatewayConnectionName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx)
end

function virtualNetworkGatewaysVpnDeviceConfigurationScript(_api::VirtualNetworkGatewaysApi, response_stream::Channel, resourceGroupName::String, virtualNetworkGatewayConnectionName::String, parameters, api_version::String, subscriptionId::String; _mediaType=nothing)
    _ctx = _swaggerinternal_virtualNetworkGatewaysVpnDeviceConfigurationScript(_api, resourceGroupName, virtualNetworkGatewayConnectionName, parameters, api_version, subscriptionId; _mediaType=_mediaType)
    Swagger.exec(_ctx, response_stream)
end

export virtualNetworkGatewaysCreateOrUpdate, virtualNetworkGatewaysDelete, virtualNetworkGatewaysDisconnectVirtualNetworkGatewayVpnConnections, virtualNetworkGatewaysGenerateVpnProfile, virtualNetworkGatewaysGeneratevpnclientpackage, virtualNetworkGatewaysGet, virtualNetworkGatewaysGetAdvertisedRoutes, virtualNetworkGatewaysGetBgpPeerStatus, virtualNetworkGatewaysGetLearnedRoutes, virtualNetworkGatewaysGetVpnProfilePackageUrl, virtualNetworkGatewaysGetVpnclientConnectionHealth, virtualNetworkGatewaysGetVpnclientIpsecParameters, virtualNetworkGatewaysList, virtualNetworkGatewaysListConnections, virtualNetworkGatewaysReset, virtualNetworkGatewaysResetVpnClientSharedKey, virtualNetworkGatewaysSetVpnclientIpsecParameters, virtualNetworkGatewaysStartPacketCapture, virtualNetworkGatewaysStopPacketCapture, virtualNetworkGatewaysSupportedVpnDevices, virtualNetworkGatewaysUpdateTags, virtualNetworkGatewaysVpnDeviceConfigurationScript


text:
import Base: size, transpose, -, *, getindex, Matrix
import LinearAlgebra: mul!, lmul!

# Define a CauchyLike Matrix Type
struct CauchyLike{T} <: AbstractMatrix{T}
    x::Vector{T}
    y::Vector{T}
    r::Array{T}  #ovaj ulaz može biti vektor ili matrica
    s::Array{T}  #ovaj ulaz može biti vektor ili matrica
end # struct

size(A::CauchyLike{T}, dim::Integer) where T = dim==1 ? length(A.x) : length(A.y)
size(A::CauchyLike{T}) where T = size(A,1), size(A,2)

struct CauchyLikeS{T} <: AbstractMatrix{T}
    x::Vector{T}
    r::AbstractArray{T}  # ovaj ulaz može biti vektor ili matrica
    s::AbstractArray{T}  # s=conj(r) tako da je kasnije brže
end # struct

# Define its size
size(A::CauchyLikeS{T}, dim::Integer) where T = length(A.x)
size(A::CauchyLikeS{T}) where T = size(A,1), size(A,2)

# Index into a CauchyLikeS
function getindex(A::CauchyLikeS{T},i::Integer,j::Integer) where T
    return (-A.r[j,:]⋅A.r[i,:])/(A.x[i]+conj(A.x[j]))
end # getindex
Matrix(A::CauchyLikeS{T}) where T =(-A.r*A.r')./(A.x.+Adjoint(A.x))

function getindex!(y::Vector{T},A::CauchyLikeS{T},i::Colon,j::Int) where T
    n=length(A.x)
    α=conj(A.x[j])
    if ndims(A.r)==1
        β=-conj(A.r[j])
        copy!(y,A.r)
        y.*=β
        y./=(A.x.+α)
    else
        BLAS.gemv!('N',-one(T),A.r,view(A.s,j,:),zero(T),y)
        y./=(A.x.+α)
    end
end # getindex

function lmul!(y::Array{T},A::CauchyLikeS{T},x::Array{T}) where T
    # Computes y=adjoint(A)*x
    dotd= T==ComplexF64 ? BLAS.dotc : BLAS.dot
    n=size(A,1)
    a=[Vector{T}(undef,n) for i=1:Threads.nthreads()]
    # Threads.@threads
    # Iz nekog razloga je nestabilno kada se ovo uključi
    # U 1.1. izgleda OK
    Threads.@threads for i=1:n
        tid=Threads.threadid()
        getindex!(a[tid],A,:,i)
        for j=1:size(y,2)
            # ne poziva se - c ili u
            y[i,j]=dotd(a[tid],view(x,:,j))
        end
    end
end

function *(A::CauchyLike{T},Y::CauchyLikeS{T}) where T
    if A.y==Y.x
        # Fast multiplication of Chained Cauchy-like matrices
        # (aka. V.Pan, A.Zheng)
        n=div(size(A,1),2)
        s=div(size(Y.r,2),2)
        M=[A.r Matrix{T}(-I,2n,s) [zeros(T,n,s);Matrix{T}(-I,n,s)]]
        # M=[A.r [-I,fill(zero(T),2n,s] [fill(zero(T),n,s);-I,fill(zero(T),n-s,s)]]
        # M=[A.r -A*Y.r]
        z=similar(A.s)
        lmul!(z,Y,A.s)
        N=[z Y.r]
        return CauchyLike(A.x,-conj(Y.x),M,N)
    else
        # Standard multiplication
        return Matrix(A)*Matrix(B)
    end
end

function househ!(a::AbstractVector{T},g::Vector{T}) where T
    dotd= T==ComplexF64 ? BLAS.dotu : BLAS.dot
    v=similar(g)
    copyto!(v,g)
    β=dotd(v,v)
    # v1=v[1]
    v[1]+=sqrt(β)
    # H=I-(2.0/(β+2*v1*sqrt(β)+β))*v*transpose(v)
    τ=(2.0*dotd(v,Vector(a)))/dotd(v,v)
    if !isnan(τ)
        for i=1:length(a)
            a[i]-=τ*v[i]
        end
    end
    # a.-=(2.0*BLAS.dotu(v,a)/(β+2*v1*sqrt(β)+β))*v
end

# Index into a CauchyLike
function getindex(A::CauchyLike{T},i::Integer,j::Integer) where T
    if ndims(A.r)==1
        return (conj(A.s[j])*A.r[i])/(A.x[i]-A.y[j])
    else
        return (A.s[j,:]⋅A.r[i,:])/(A.x[i]-A.y[j])
    end
end # getindex

# Submatrices
function getindex(A::CauchyLike{T},i::Union{UnitRange,Vector{Int},Colon},
    j::Union{UnitRange,Vector{Int},Colon}) where T
    return CauchyLike(A.x[i],A.y[j],A.r[i,:],A.s[j,:])
end # getindex

# Column
function getindex(A::CauchyLike{T},i::Colon,j::Int) where T
    return (A.r*A.s[j,:]')./(A.x.-A.y[j])
end # getindex

# Row
function getindex(A::CauchyLike{T},i::Int,j::Colon) where T
    return (A.r[i]*A.s')./(A.x[i].-A.y)
end # getindex

# Column in place
function getindex!(y::Vector{T},A::CauchyLike{T},i::Colon,j::Int) where T
    n=length(A.x)
    α=A.y[j]
    if ndims(A.r)==1
        β=conj(A.s[j])
        copy!(y,A.r)
        y.*=β
        y./=(A.x.-α)
        # y=(A.r*conj(A.s[j]))./(A.x.-A.y[j])
    else
        BLAS.gemv!('N',one(T),A.r,conj(A.s[j,:]),zero(T),y)
        y./=(A.x.-α)
    end
    # This part is for CauchyLike{T} matrix which is
    # eigenvector matrix of some SymDPR1{T} matrix
    if count(isnan,y)>0
        # typeof(findfirst(isnan,y))!=Nothing
        ind=findall(isnan,y)
        # Our case
        for i=1:n
            y[i]=zero(T)
        end
        if ndims(A.r)==1
            y[j]=one(T)
            if length(ind)>1
                househ!(view(y,ind),A.r[ind])
            end
        else
            m=size(A.r,2)
            y[j]=one(T)
            if length(ind)>1
                for i=m:-1:1
                    househ!(view(y,ind[i:end]),Uvec[ind[i:end],i])
                end
            end
        end
    end
end # getindex

# Basic functions for CauchyLike
# Matrix(A::CauchyLike{T}) where T =(A.r*A.s')./(A.x.-transpose(A.y))
function Matrix(A::CauchyLike{T}) where T
    n=length(A.x)
    Z=Matrix{T}(undef,n,n)
    a=[Vector{T}(undef,n) for i=1:Threads.nthreads()]
    # Threads.@threads
    for i=1:n
        tid=Threads.threadid()
        getindex!(a[tid],A,:,i)
        # view?
        # copy!(Z[:,i],a[tid])
        Z[:,i]=a[tid]
    end
    return Z
end
transpose(A::CauchyLike{T}) where T =CauchyLike(-A.y,-A.x,conj(A.s),conj(A.r))
adjoint(A::CauchyLike{T}) where T =CauchyLike(conj(-A.y),conj(-A.x),A.s,A.r)
-(A::CauchyLike{T}) where T =CauchyLike(-A.x,-A.y,A.r,A.s)

# Multiplication with CauchyLike
function *(A::CauchyLike{T}, x::AbstractVector{T}) where T
    n=length(x)
    y=[zeros(T,n) for i=1:Threads.nthreads()]
    z=[Vector{T}(undef,n) for i=1:Threads.nthreads()]
    # Ovo napravi malu numeričku razliku
    Threads.@threads for i=1:n
        tid=Threads.threadid()
        getindex!(z[tid],A,:,i)
        BLAS.axpy!(x[i],z[tid],y[tid])
    end
    return sum(y)
end

function mul!(y1::Vector{T}, A::CauchyLike{T}, x::Vector{T}) where T
    n=length(x)
    y=[zeros(T,n) for i=1:Threads.nthreads()]
    z=[Vector{T}(undef,n) for i=1:Threads.nthreads()]
    Threads.@threads for i=1:n
        tid=Threads.threadid()
        getindex!(z[tid],A,:,i)
        BLAS.axpy!(x[i],z[tid],y[tid])
    end
    copy!(y1,sum(y))
end

function *(A::CauchyLike{T}, x::Matrix{T}) where T
    # This could be improved?
    # It works well for narrow x
    dotd= T==ComplexF64 ? BLAS.dotc : BLAS.dot
    n=size(A,1)
    a=[Vector{T}(undef,n) for i=1:Threads.nthreads()]
    y=similar(x)
    #=
    for i=1:size(x,2)
        y[:,i]=A*view(x,:,i)
    end
    =#
    Threads.@threads for i=1:n
        tid=Threads.threadid()
        getindex!(a[tid],A,:,i)
        for j=1:size(y,2)
            # ne poziva se - c ili u
            y[i,j]=dotd(a[tid],view(x,:,j))
        end
    end
    return y
end

full(A::CauchyLike)=(A.r*A.s')./(A.x.-transpose(A.y))

# Multiplication of CauchyLike
function *(A::CauchyLike{T}, B::CauchyLike{T}) where T
    if A.y==B.x
        # Fast multiplication of Chained Cauchy-like matrices
        # (aka. V.Pan, A.Zheng)
        M=[A.r (A*B.r)]
        N=similar(A.s)
        lmul!(N,B,A.s)
        N=hcat(N, B.s)
        C=CauchyLike(A.x,B.y,M,N)
        return C
    else
        # Standard multiplication
        return Matrix(A)*Matrix(B)
    end
end

function *(A::CauchyLike{T}, B::CauchyLike{T}, y::Vector{T}) where T
    if A.y==B.x
        # Fast multiplication of Chained Cauchy-like matrices
        # (aka. V.Pan, A.Zheng)
        M=[A.r y]
        N=similar(A.s)
        lmul!(N,B,A.s)
        N=hcat(N, B.s)
        C=CauchyLike(A.x,B.y,M,N)
        return C
    else
        # Standard multiplication
        return Matrix(A)*Matrix(B)
    end
end

function lmult!(y::Vector{T},A::CauchyLike{T},x::Vector{T}) where T
    # Computes y=transpose(A)*x
    dotd= T==ComplexF64 ? BLAS.dotu : BLAS.dot
    n=length(x)
    a=[Vector{T}(undef,n) for i=1:Threads.nthreads()]
    Threads.@threads for i=1:n
        tid=Threads.threadid()
        getindex!(a[tid],A,:,i)
        y[i]=dotd(a[tid],x)
    end
end

function lmul!(y::Vector{T},A::CauchyLike{T},x::Vector{T}) where T
    # Computes y=Adjoint(A)*x
    dotd= T==ComplexF64 ? BLAS.dotc : BLAS.dot
    n=length(x)
    a=[Vector{T}(undef,n) for i=1:Threads.nthreads()]
    Threads.@threads for i=1:n
        tid=Threads.threadid()
        getindex!(a[tid],A,:,i)
        y[i]=dotd(a[tid],x)
    end
end

function lmul!(y::Matrix{T},A::CauchyLike{T},x::Matrix{T}) where T
    # Computes y=adjoint(A)*x
    dotd= T==ComplexF64 ? BLAS.dotc : BLAS.dot
    n=size(x,1)
    a=[Vector{T}(undef,n) for i=1:Threads.nthreads()]
    Threads.@threads for i=1:n
        tid=Threads.threadid()
        getindex!(a[tid],A,:,i)
        for j=1:size(y,2)
            # ne poziva se - c ili u
            y[i,j]=dotd(a[tid],x[:,j])
        end
    end
end