text:
function Percentile()
    return Percentile(())
end

function Percentile(arg0::Percentile)
    return Percentile((Percentile,), arg0)
end

function Percentile(arg0::jdouble)
    return Percentile((jdouble,), arg0)
end

function copy(obj::Percentile)
    return jcall(obj, "copy", Percentile, ())
end

function evaluate(obj::Percentile, arg0::Vector{jdouble}, arg1::jdouble)
    return jcall(obj, "evaluate", jdouble, (Vector{jdouble}, jdouble), arg0, arg1)
end

function evaluate(obj::Percentile, arg0::Vector{jdouble}, arg1::jint, arg2::jint)
    return jcall(obj, "evaluate", jdouble, (Vector{jdouble}, jint, jint), arg0, arg1, arg2)
end

function evaluate(obj::Percentile, arg0::Vector{jdouble}, arg1::jint, arg2::jint, arg3::jdouble)
    return jcall(obj, "evaluate", jdouble, (Vector{jdouble}, jint, jint, jdouble), arg0, arg1, arg2, arg3)
end

function evaluate(obj::Percentile, arg0::jdouble)
    return jcall(obj, "evaluate", jdouble, (jdouble,), arg0)
end

function get_estimation_type(obj::Percentile)
    return jcall(obj, "getEstimationType", Percentile_EstimationType, ())
end

function get_kth_selector(obj::Percentile)
    return jcall(obj, "getKthSelector", KthSelector, ())
end

function get_na_n_strategy(obj::Percentile)
    return jcall(obj, "getNaNStrategy", NaNStrategy, ())
end

function get_pivoting_strategy(obj::Percentile)
    return jcall(obj, "getPivotingStrategy", PivotingStrategy, ())
end

function get_quantile(obj::Percentile)
    return jcall(obj, "getQuantile", jdouble, ())
end

function set_data(obj::Percentile, arg0::Vector{jdouble})
    return jcall(obj, "setData", void, (Vector{jdouble},), arg0)
end

function set_data(obj::Percentile, arg0::Vector{jdouble}, arg1::jint, arg2::jint)
    return jcall(obj, "setData", void, (Vector{jdouble}, jint, jint), arg0, arg1, arg2)
end

function set_quantile(obj::Percentile, arg0::jdouble)
    return jcall(obj, "setQuantile", void, (jdouble,), arg0)
end

function with_estimation_type(obj::Percentile, arg0::Percentile_EstimationType)
    return jcall(obj, "withEstimationType", Percentile, (Percentile_EstimationType,), arg0)
end

function with_kth_selector(obj::Percentile, arg0::KthSelector)
    return jcall(obj, "withKthSelector", Percentile, (KthSelector,), arg0)
end

function with_na_n_strategy(obj::Percentile, arg0::NaNStrategy)
    return jcall(obj, "withNaNStrategy", Percentile, (NaNStrategy,), arg0)
end


text:
using PyCall
using Test

@pyimport math
@pyimport numpy as np

math.sin(math.pi) - sin(pi)

n = 6
m = 4

A = rand(n, m)
println(A)

Apy = PyObject(A)
println(Apy)

for i in 1:size(A, 1)
    for j in 1:size(A, 2)
        @test A[i,j] == Apy[i,j]
    end
end

@test 1 == 1

ext: jl


text:
# With the scanners fully deployed, you turn their attention to mapping the
# floor of the ocean trench.
#
# When you get back the image from the scanners, it seems to just be random
# noise. Perhaps you can combine an image enhancement algorithm and the input
# image (your puzzle input) to clean it up a little.
#
# For example:
#
# ..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..##
# #..######.###...####..#..#####..##..#.#####...##.#.#..#.##..#.#......#.###
# .######.###.####...#.##.##..#..#..#####.....#.#....###..#.##......#.....#.
# .#..#..##..#...##.######.####.####.#.#...#.......#..#.#.#...####.##.#.....
# .#..#...##.#.##..#...##.#.##..###.#......#.#.......#.#.#.####.###.##...#..
# ...####.#..#..#.##.#....##..#.####....##...##..#...#......#.#.......#.....
# ..##..####..#...#.#.#...##..#.#..###..#####........#..####......#..#
#
# #..#.
# #....
# ##..#
# ..#..
# ..###
#
# The first section is the image enhancement algorithm. It is normally given on
# a single line, but it has been wrapped to multiple lines in this example for
# legibility. The second section is the input image, a two-dimensional grid of
# light pixels (#) and dark pixels (.).
#
# The image enhancement algorithm describes how to enhance an image by
# simultaneously converting all pixels in the input image into an output image.
# Each pixel of the output image is determined by looking at a 3x3 square of
# pixels centered on the corresponding input image pixel. So, to determine the
# value of the pixel at (5,10) in the output image, nine pixels from the input
# image need to be considered: (4,9), (4,10), (4,11), (5,9), (5,10), (5,11),
# (6,9), (6,10), and (6,11). These nine input pixels are combined into a single
# binary number that is used as an index in the image enhancement algorithm
# string.
#
# For example, to determine the output pixel that corresponds to the very
# middle pixel of the input image, the nine pixels marked by [...] would need
# to be considered:
#
# # . . # .
# #[. . .].
# #[# . .]#
# .[. # .].
# . . # # #
#
# Starting from the top-left and reading across each row, these pixels are ...,
# then #.., then .#.; combining these forms ...#...#.. By turning dark pixels
# (.) into 0 and light pixels (#) into 1, the binary number 000100010 can be
# formed, which is 34 in decimal.
#
# The image enhancement algorithm string is exactly 512 characters long, enough
# to match every possible 9-bit binary number. The first few characters of the
# string (numbered starting from zero) are as follows:
#
# 0         10        20        30  34    40        50        60        70
# |         |         |         |   |     |         |         |         |
# ..#.#..#####.#.#.#.###.##.....###.##.#..###.####..#####..#....#..#..##..##
#
# In the middle of this first group of characters, the character at index 34
# can be found: #. So, the output pixel in the center of the output image
# should be #, a light pixel.
#
# This process can then be repeated to calculate every pixel of the output
# image.
#
# Through advances in imaging technology, the images being operated on here are
# infinite in size. Every pixel of the infinite output image needs to be
# calculated exactly based on the relevant pixels of the input image. The small
# input image you have is only a small region of the actual infinite input
# image; the rest of the input image consists of dark pixels (.). For the
# purposes of the example, to save on space, only a portion of the
# infinite-sized input and output images will be shown.
#
# The starting input image, therefore, looks something like this, with more
# dark pixels (.) extending forever in every direction not shown here:
#
# ...............
# ...............
# ...............
# ...............
# ...............
# .....#..#......
# .....#.........
# .....##..#.....
# .......#.......
# .......###.....
# ...............
# ...............
# ...............
# ...............
# ...............
#
# By applying the image enhancement algorithm to every pixel simultaneously,
# the following output image can be obtained:
#
# ...............
# ...............
# ...............
# ...............
# .....##.##.....
# ....#..#.#.....
# ....##.#..#....
# ....####..#....
# .....#..##.....
# ......##..#....
# .......#.#.....
# ...............
# ...............
# ...............
# ...............
#
# Through further advances in imaging technology, the above output image can
# also be used as an input image! This allows it to be enhanced a second time:
#
# ...............
# ...............
# ...............
# ..........#....
# ....#..#.#.....
# ...#.#...###...
# ...#...##.#....
# ...#.....#.#...
# ....#.#####....
# .....#.#####...
# ......##.##....
# .......###.....
# ...............
# ...............
# ...............
#
# Truly incredible - now the small details are really starting to come through.
# After enhancing the original input image twice, 35 pixels are lit.
#
# Start with the original input image and apply the image enhancement algorithm
# twice, being careful to account for the infinite size of the images. How many
# pixels are lit in the resulting image?

const passes = 2

# read input
iter = eachline("input.txt")
enhancementmap = BitVector(map(isequal('#'), collect(iterate(iter)[1])))
iterate(iter) # blank line
img = BitArray(vcat(map(l -> map(isequal('#'), collect(l))', iter)...))
(width, height) = size(img)

# pad the image with zeros around the edge - we'll pad by 2 in each direction
# because that'll make it easier to grab 9x9 squares, ignoring the edge
(width, height) = (width+4, height+4)
nextimg = falses(width, height)
nextimg[3:(width-2), 3:(height-2)] = img
img = nextimg

# this is used to calculate the numeric value of a 3x3 square of bits
bitvalue = reshape([1 << x for x in 8:-1:0], 3, :)'

# run the image enhancement algo
for _ in 1:passes
  # on each pass the image size increases by one pixel in every direction
  global (width, height) = (width+2, height+2)

  # The edge pixels extend infinitely - on each pass, the 9 pixels that make up
  # the input for the next edge will all have the same value. So, if the
  # current edge is made of falses, the next edge will be the first value from
  # the enhancement map. If the current edge is trues, the next edge will be
  # the last value from the enhancement map.
  edge = img[1,1] ? enhancementmap[end] : enhancementmap[1]
  global nextimg = edge ? trues(width, height) : falses(width, height)

  # enhance image
  for j in 3:(height-2), i in 3:(width-2)
    nextimg[j,i] = enhancementmap[sum(bitvalue .* img[(j-2):j, (i-2):i]) + 1]
  end

  # update img
  global img = nextimg
end

println("Result: ", count(img))


text:
# Julia wrapper for header: /usr/include/libavutil/rational.h
# Automatically generated using Clang.jl wrap_c, version 0.0.0

export
    av_make_q,
    av_cmp_q,
    av_q2d,
    av_reduce,
    av_mul_q,
    av_div_q,
    av_add_q,
    av_sub_q,
    av_inv_q,
    av_d2q,
    av_nearer_q,
    av_find_nearest_q_idx,
    av_q2intfloat

function av_make_q(num::Integer, den::Integer)
    ccall((:av_make_q, libavutil), AVRational, (Cint, Cint), num, den)
end

function av_cmp_q(a::AVRational, b::AVRational)
    ccall((:av_cmp_q, libavutil), Cint, (AVRational, AVRational), a, b)
end

function av_q2d(a::AVRational)
    ccall((:av_q2d, libavutil), Cdouble, (AVRational,), a)
end

function av_reduce(dst_num, dst_den, num::Int64, den::Int64, max::Int64)
    ccall((:av_reduce, libavutil), Cint, (Ptr{Cint}, Ptr{Cint}, Int64, Int64, Int64), dst_num, dst_den, num, den, max)
end

function av_mul_q(b::AVRational, c::AVRational)
    ccall((:av_mul_q, libavutil), AVRational, (AVRational, AVRational), b, c)
end

function av_div_q(b::AVRational, c::AVRational)
    ccall((:av_div_q, libavutil), AVRational, (AVRational, AVRational), b, c)
end

function av_add_q(b::AVRational, c::AVRational)
    ccall((:av_add_q, libavutil), AVRational, (AVRational, AVRational), b, c)
end

function av_sub_q(b::AVRational, c::AVRational)
    ccall((:av_sub_q, libavutil), AVRational, (AVRational, AVRational), b, c)
end

function av_inv_q(q::AVRational)
    ccall((:av_inv_q, libavutil), AVRational, (AVRational,), q)
end

function av_d2q(d::Cdouble, max::Integer)
    ccall((:av_d2q, libavutil), AVRational, (Cdouble, Cint), d, max)
end

function av_nearer_q(q::AVRational, q1::AVRational, q2::AVRational)
    ccall((:av_nearer_q, libavutil), Cint, (AVRational, AVRational, AVRational), q, q1, q2)
end

function av_find_nearest_q_idx(q::AVRational, q_list)
    ccall((:av_find_nearest_q_idx, libavutil), Cint, (AVRational, Ptr{AVRational}), q, q_list)
end

function av_q2intfloat(q::AVRational)
    ccall((:av_q2intfloat, libavutil), UInt32, (AVRational,), q)
end


text:
include("required.jl")

## Conditional arguments
# save_prepdata = true # should preparation data be overwritten (optional)
# save_figures = true # should figures be overwritten (optional)

## Run bash scripts to download & coarsen landcover data from Zenodo (if files missing)
if (@isdefined save_prepdata) && save_prepdata == true
    # List files in landcover folder
    @info "Starting landcover data saving process"
    lc_files = readdir("assets/landcover/")

    # Check if landcover files are missing
    if !any(startswith.(lc_files, r"^lc_"))
        @info "Landcover files missing. Starting extraction"

        # Check if full resolution files are missing
        if !any(startswith.(lc_files, r"^landcover_copernicus_global_100m"))
            # Download full resolution files
            # BEWARE, can be long to download, 25 GB of data
            @info "Full resolution files missing. Starting download"
            run(`bash src/shell/landcover_download.sh`)
        end

        # Coarsen resolution
        @info "Coarsening resolution"
        run(`bash src/shell/landcover_coarsen.sh`)
    end
else
    @info "Not saving landcover data"
end

## Test landcover variables
# Define coordinates range
coords = (left=-145.0, right=-50.0, bottom=20.0, top=75.0)

# Test loading variables
lc_vars = SimpleSDMPredictor(Copernicus, LandCover, 1:10; resolution=5.0)
lc_vars = SimpleSDMPredictor(Copernicus, LandCover, 1:10; resolution=10.0)
lc_vars = SimpleSDMPredictor(Copernicus, LandCover, 1:10; resolution=10.0, coords...)

# Load worldclim variables to compare
wc_vars = SimpleSDMPredictor(WorldClim, BioClim, 1:19; resolution=10.0, coords...);

## Export to CSV

# Combine environmental data
env_vars = vcat(wc_vars, lc_vars)

# Create env dataframe (environmental data)
env_df = DataFrame(convert.(Float64, env_vars))
select!(env_df, Not([:longitude, :latitude]))
rename!(env_df, vcat(Symbol.("wc", 1:size(wc_vars, 1)), Symbol.("lc", 1:size(lc_vars, 1))))
insertcols!(env_df, 1, :site => 1:nrow(env_df))

# Create spa DataFrame (spatial coordinates)
spa_df = DataFrame(wc_vars[1])
select!(spa_df, Not(:values))
insertcols!(spa_df, 1, :site => Float64.(1:nrow(spa_df)))
rename!(spa_df, [:site, :lon, :lat])

# Create spa layers
spa_vars = [
    SimpleSDMPredictor(spa_df, x, wc_vars[1]; latitude=:lat, longitude=:lon) for
    x in [:site, :lon, :lat]
]

# Export dataframes
# save_prepdata = true
if (@isdefined save_prepdata) && save_prepdata == true
    @info "Exporting env & spa to CSV"
    CSV.write(joinpath("data", "proc", "distributions_env_full.csv"), env_df; delim="\t")
    CSV.write(joinpath("data", "proc", "distributions_spa_full.csv"), spa_df; delim="\t")
    geotiff(joinpath("data", "raster", "env_stack.tif"), env_vars)
    geotiff(joinpath("data", "raster", "spa_stack.tif"), spa_vars)
end

# Test load
#=
testspa = CSV.read(joinpath("data", "proc", "distributions_spa_full.csv"), DataFrame, header=true, delim="\t")
testenv = CSV.read(joinpath("data", "proc", "distributions_env_full.csv"), DataFrame, header=true, delim="\t")
testjoin = innerjoin(testspa, testenv, on = :site) =#

## Export QC sites coordinates (for smaller scale analyses)

# Define Quebec coordinates
coords_qc = (left=-80.0, right=-55.0, bottom=45.0, top=63.0)

# Get site indices
spa_qc = filter(:lon => >=(coords_qc.left - stride(wc_vars[1]; dims=2)), spa_df)
filter!(:lon => <(coords_qc.right), spa_qc)
filter!(:lat => >=(coords_qc.bottom - stride(wc_vars[1], dims=1)), spa_qc)
filter!(:lat => <(coords_qc.top), spa_qc)

# Subset layers to QC only
env_vars_qc = [v[coords_qc] for v in env_vars]
spa_vars_qc = [v[coords_qc] for v in spa_vars]

# Export QC dataframes
# save_prepdata = true
if (@isdefined save_prepdata) && save_prepdata == true
    @info "Exporting QC env & spa to CSV"
    CSV.write(joinpath("data", "proc", "distributions_spa_qc.csv"), spa_qc; delim="\t")
    geotiff(joinpath("data", "raster", "env_stack_qc.tif"), env_vars_qc)
    geotiff(joinpath("data", "raster", "spa_stack_qc.tif"), spa_vars_qc)
end

max_stars_repo_name: gabrieldansereau/betadiversity-hotspots

max_issues_repo_name: gabrieldansereau/betadiversity-hotspots

max_forks_repo_name: gabrieldansereau/betadiversity-hotspots


text:
using Compat
using Compat.Test

using MathOptInterface
const MOI = MathOptInterface
const MOIT = MathOptInterface.Test
const MOIU = MathOptInterface.Utilities
const MOIB = MathOptInterface.Bridges

# Model not supporting Interval
MOIU.@model(SimpleModel,
            (),
            (MOI.EqualTo, MOI.GreaterThan, MOI.LessThan, MOI.Interval),
            (MOI.Zeros, MOI.Nonnegatives, MOI.Nonpositives, MOI.SecondOrderCone,
             MOI.RotatedSecondOrderCone, MOI.GeometricMeanCone,
             MOI.PositiveSemidefiniteConeTriangle, MOI.ExponentialCone),
            (MOI.PowerCone, MOI.DualPowerCone),
            (MOI.SingleVariable,),
            (MOI.ScalarAffineFunction, MOI.ScalarQuadraticFunction),
            (MOI.VectorOfVariables,),
            (MOI.VectorAffineFunction, MOI.VectorQuadraticFunction))

function test_noc(bridged_mock, F, S, n)
    @test MOI.get(bridged_mock, MOI.NumberOfConstraints{F, S}()) == n
    @test length(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{F, S}())) == n
    @test ((F, S) in MOI.get(bridged_mock, MOI.ListOfConstraints())) == !iszero(n)
end

struct UnknownConstraintAttribute <: MOI.AbstractConstraintAttribute end
MOI.is_set_by_optimize(::UnknownConstraintAttribute) = true

# Test deletion of bridge
function test_delete_bridge(m::MOIB.AbstractBridgeOptimizer,
                            ci::MOI.ConstraintIndex{F, S}, nvars::Int,
                            nocs::Tuple; used_bridges = 1) where {F, S}
    num_bridges = length(m.bridges)
    @test MOI.get(m, MOI.NumberOfVariables()) == nvars
    test_noc(m, F, S, 1)
    for noc in nocs
        test_noc(m, noc...)
    end
    @test MOI.is_valid(m, ci)
    MOI.delete(m, ci)
    @test_throws MOI.InvalidIndex{typeof(ci)} MOI.delete(m, ci)
    try
        MOI.delete(m, ci)
    catch err
        @test err.index == ci
    end
    @test !MOI.is_valid(m, ci)
    @test length(m.bridges) == num_bridges - used_bridges
    test_noc(m, F, S, 0)
    # As the bridge has been removed, if the constraints it has created where not removed, it wouldn't be there to decrease this counter anymore
    @test MOI.get(m, MOI.NumberOfVariables()) == nvars
    for noc in nocs
        test_noc(m, noc...)
    end
end

@testset "BridgeOptimizer" begin
    mock = MOIU.MockOptimizer(SimpleModel{Float64}())
    bridged_mock = MOIB.SplitInterval{Float64}(mock)

    @testset "Unsupported constraint attribute" begin
        attr = UnknownConstraintAttribute()
        err = ArgumentError(
            "Constraint bridge of type `MathOptInterface.Bridges.SplitIntervalBridge{Float64,MathOptInterface.SingleVariable}` " *
            "does not support accessing the attribute `$attr`.")
        x = MOI.add_variable(bridged_mock)
        ci = MOI.add_constraint(bridged_mock, MOI.SingleVariable(x),
                                MOI.Interval(0.0, 1.0))
        if VERSION < v"0.7-"
            @test_throws typeof(err) MOI.get(bridged_mock, attr, ci)
        else
            @test_throws err MOI.get(bridged_mock, attr, ci)
        end
    end

    @testset "Issue #453" begin
        MOI.empty!(bridged_mock)
        MOIU.loadfromstring!(bridged_mock, """
            variables: x
            maxobjective: 3.0x
            c: 2.0x in Interval(1.0, 4.0)
            d: x in LessThan(1.5)
        """)
        x = MOI.get(bridged_mock, MOI.VariableIndex, "x")
        @test isa(x, MOI.VariableIndex)
        c1 = MOI.get(bridged_mock, MOI.ConstraintIndex{MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}}, "c")
        @test isa(c1, MOI.ConstraintIndex{MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}})
        c2 = MOI.get(bridged_mock, MOI.ConstraintIndex, "c")
        @test c1 == c2
        d1 = MOI.get(bridged_mock, MOI.ConstraintIndex{MOI.SingleVariable, MOI.LessThan{Float64}}, "d")
        @test isa(d1, MOI.ConstraintIndex{MOI.SingleVariable, MOI.LessThan{Float64}})
        d2 = MOI.get(bridged_mock, MOI.ConstraintIndex, "d")
        @test d1 == d2
    end

    MOI.empty!(bridged_mock)

    @testset "Name test" begin
        MOIT.nametest(bridged_mock)
    end

    @testset "Copy test" begin
        MOIT.failcopytestc(bridged_mock)
        MOIT.failcopytestia(bridged_mock)
        MOIT.failcopytestva(bridged_mock)
        MOIT.failcopytestca(bridged_mock)
        MOIT.copytest(bridged_mock, SimpleModel{Float64}())
    end

    @testset "Custom test" begin
        model = MOIB.SplitInterval{Int}(SimpleModel{Int}())
        @test !MOIB.supports_bridging_constraint(model, MOI.VectorAffineFunction{Float64}, MOI.Interval{Float64})

        x, y = MOI.add_variables(model, 2)
        @test MOI.get(model, MOI.NumberOfVariables()) == 2

        f1 = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(3, x)], 7)
        c1 = MOI.add_constraint(model, f1, MOI.Interval(-1, 1))

        @test MOI.get(model, MOI.ListOfConstraints()) == [(MOI.ScalarAffineFunction{Int},MOI.Interval{Int})]
        test_noc(model, MOI.ScalarAffineFunction{Int}, MOI.GreaterThan{Int}, 0)
        test_noc(model, MOI.ScalarAffineFunction{Int}, MOI.Interval{Int}, 1)
        @test (@inferred MOI.get(model, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Int},MOI.Interval{Int}}())) == [c1]

        f2 = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2, -1], [x, y]), 2)
        c2 = MOI.add_constraint(model, f1, MOI.GreaterThan(-2))

        @test MOI.get(model, MOI.ListOfConstraints()) == [(MOI.ScalarAffineFunction{Int},MOI.GreaterThan{Int}), (MOI.ScalarAffineFunction{Int},MOI.Interval{Int})]
        test_noc(model, MOI.ScalarAffineFunction{Int}, MOI.GreaterThan{Int}, 1)
        test_noc(model, MOI.ScalarAffineFunction{Int}, MOI.Interval{Int}, 1)
        @test (@inferred MOI.get(model, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Int},MOI.Interval{Int}}())) == [c1]
        @test (@inferred MOI.get(model, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Int},MOI.GreaterThan{Int}}())) == [c2]

        @test MOI.is_valid(model, c2)
        MOI.delete(model, c2)

        @test MOI.get(model, MOI.ListOfConstraints()) == [(MOI.ScalarAffineFunction{Int},MOI.Interval{Int})]
        test_noc(model, MOI.ScalarAffineFunction{Int}, MOI.GreaterThan{Int}, 0)
        test_noc(model, MOI.ScalarAffineFunction{Int}, MOI.Interval{Int}, 1)
        @test (@inferred MOI.get(model, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Int},MOI.Interval{Int}}())) == [c1]
    end

    @testset "Continuous Linear" begin
        exclude = ["partial_start"] # VariablePrimalStart not supported.
        MOIT.contlineartest(bridged_mock, MOIT.TestConfig(solve=false), exclude)
    end
end

# Model not supporting RotatedSecondOrderCone
MOIU.@model(NoRSOCModel,
            (),
            (MOI.EqualTo, MOI.GreaterThan, MOI.LessThan),
            (MOI.Zeros, MOI.Nonnegatives, MOI.Nonpositives, MOI.SecondOrderCone,
             MOI.ExponentialCone, MOI.PositiveSemidefiniteConeTriangle),
            (),
            (MOI.SingleVariable,),
            (MOI.ScalarAffineFunction, MOI.ScalarQuadraticFunction),
            (MOI.VectorOfVariables,),
            (MOI.VectorAffineFunction, MOI.VectorQuadraticFunction))

MOIU.@model(GreaterNonnegModel,
            (),
            (MOI.GreaterThan,),
            (MOI.Nonnegatives,),
            (),
            (MOI.SingleVariable,),
            (MOI.ScalarAffineFunction, MOI.ScalarQuadraticFunction),
            (MOI.VectorOfVariables,),
            (MOI.VectorAffineFunction, MOI.VectorQuadraticFunction))

MOIU.@model(ModelNoVAFinSOC,
            (),
            (MOI.EqualTo, MOI.GreaterThan, MOI.LessThan, MOI.Interval),
            (MOI.Zeros, MOI.Nonnegatives, MOI.Nonpositives, MOI.SecondOrderCone,
             MOI.RotatedSecondOrderCone, MOI.GeometricMeanCone,
             MOI.PositiveSemidefiniteConeTriangle, MOI.ExponentialCone),
            (MOI.PowerCone, MOI.DualPowerCone),
            (MOI.SingleVariable,),
            (MOI.ScalarAffineFunction, MOI.ScalarQuadraticFunction),
            (MOI.VectorOfVariables,),
            (MOI.VectorAffineFunction, MOI.VectorQuadraticFunction))

MOI.supports_constraint(::ModelNoVAFinSOC{Float64},
                        ::Type{MOI.VectorAffineFunction{Float64}},
                        ::Type{MOI.SecondOrderCone}) = false

# Model supporting nothing
MOIU.@model NothingModel () () () () () () () ()

struct BridgeAddingNoConstraint{T} <: MOI.Bridges.AbstractBridge end
MOIB.added_constraint_types(::Type{BridgeAddingNoConstraint{T}}) where {T} = []
function MOI.supports_constraint(::Type{<:BridgeAddingNoConstraint},
                                 ::Type{MOI.SingleVariable},
                                 ::Type{MOI.Integer})
    return true
end
function MOIB.concrete_bridge_type(::Type{<:BridgeAddingNoConstraint{T}},
                                   ::Type{MOI.SingleVariable},
                                   ::Type{MOI.Integer}) where {T}
    return BridgeAddingNoConstraint{T}
end

@testset "LazyBridgeOptimizer" begin
    @testset "Bridge adding no constraint" begin
        mock = MOIU.MockOptimizer(NothingModel{Int}())
        bridged = MOIB.LazyBridgeOptimizer(mock, NothingModel{Int}())
        MOI.Bridges.add_bridge(bridged, BridgeAddingNoConstraint{Float64})
        @test MOI.Bridges.supports_bridging_constraint(bridged,
                                                       MOI.SingleVariable,
                                                       MOI.Integer)
    end

    @testset "Unsupported constraint with cycles" begin
        # Test that `supports_constraint` works correctly when it is not
        # supported but the bridges forms a cycle
        mock = MOIU.MockOptimizer(NothingModel{Float64}())
        bridged = MOIB.full_bridge_optimizer(mock, Float64)
        @test !MOI.supports_constraint(
            bridged, MOI.SingleVariable, MOI.GreaterThan{Float64})
        @test !MOI.supports_constraint(
            bridged, MOI.VectorAffineFunction{Float64}, MOI.Nonpositives)
    end

    mock = MOIU.MockOptimizer(NoRSOCModel{Float64}())
    bridged_mock = MOIB.LazyBridgeOptimizer(
        mock, MOIB.AllBridgedConstraints{Float64}())

    @testset "UnsupportedConstraint when it cannot be bridged" begin
        x = MOI.add_variables(bridged_mock, 4)
        err = MOI.UnsupportedConstraint{MOI.VectorOfVariables,
                                        MOI.RotatedSecondOrderCone}()
        if VERSION < v"0.7-"
            @test_throws typeof(err) begin
                MOI.add_constraint(bridged_mock, MOI.VectorOfVariables(x),
                                   MOI.RotatedSecondOrderCone(4))
            end
        else
            @test_throws err begin
                MOI.add_constraint(bridged_mock, MOI.VectorOfVariables(x),
                                   MOI.RotatedSecondOrderCone(4))
            end
        end
    end

    MOIB.add_bridge(bridged_mock, MOIB.SplitIntervalBridge{Float64})
    MOIB.add_bridge(bridged_mock, MOIB.RSOCtoPSDBridge{Float64})
    MOIB.add_bridge(bridged_mock, MOIB.SOCtoPSDBridge{Float64})
    MOIB.add_bridge(bridged_mock, MOIB.RSOCBridge{Float64})

    @testset "Name test" begin
        MOIT.nametest(bridged_mock)
    end

    @testset "Copy test" begin
        MOIT.failcopytestc(bridged_mock)
        MOIT.failcopytestia(bridged_mock)
        MOIT.failcopytestva(bridged_mock)
        MOIT.failcopytestca(bridged_mock)
        MOIT.copytest(bridged_mock, NoRSOCModel{Float64}())
    end

    # Test that RSOCtoPSD is used instead of RSOC+SOCtoPSD as it is a shortest path.
    @testset "Bridge selection" begin
        MOI.empty!(bridged_mock)
        @test !(MOI.supports_constraint(bridged_mock,
                                        MOI.VectorAffineFunction{Float64},
                                        MOI.LogDetConeTriangle))
        x = MOI.add_variables(bridged_mock, 3)
        err = MOI.UnsupportedConstraint{MOI.VectorAffineFunction{Float64},
                                        MOI.LogDetConeTriangle}()
        if VERSION < v"0.7-"
            @test_throws typeof(err) begin
                MOIB.bridge_type(bridged_mock, MOI.VectorAffineFunction{Float64},
                                 MOI.LogDetConeTriangle)
            end
        else
            @test_throws err begin
                MOIB.bridge_type(bridged_mock, MOI.VectorAffineFunction{Float64},
                                 MOI.LogDetConeTriangle)
            end
        end
        c = MOI.add_constraint(bridged_mock, MOI.VectorOfVariables(x),
                               MOI.RotatedSecondOrderCone(3))
        @test MOIB.bridge_type(bridged_mock, MOI.VectorOfVariables,
                    MOI.RotatedSecondOrderCone) == MOIB.RSOCtoPSDBridge{Float64}
        @test MOIB.bridge(bridged_mock, c) isa MOIB.RSOCtoPSDBridge
        @test bridged_mock.dist[(MOI.VectorOfVariables,
                                MOI.RotatedSecondOrderCone)] == 1
    end

    @testset "Supports" begin
        full_bridged_mock = MOIB.full_bridge_optimizer(mock, Float64)
        greater_nonneg_mock = MOIU.MockOptimizer(GreaterNonnegModel{Float64}())
        full_bridged_greater_nonneg = MOIB.full_bridge_optimizer(
            greater_nonneg_mock, Float64)
        for F in [MOI.SingleVariable, MOI.ScalarAffineFunction{Float64},
                  MOI.ScalarQuadraticFunction{Float64}]
            @test MOI.supports_constraint(full_bridged_mock, F,
                                          MOI.Interval{Float64})
            @test !MOI.supports_constraint(
                greater_nonneg_mock, F, MOI.LessThan{Float64})
            @test MOI.supports_constraint(
                full_bridged_greater_nonneg, F, MOI.LessThan{Float64})
        end
        for F in [MOI.VectorOfVariables, MOI.VectorAffineFunction{Float64},
                  MOI.VectorQuadraticFunction{Float64}]
            @test MOI.supports_constraint(full_bridged_mock, F,
                                          MOI.PositiveSemidefiniteConeSquare)
            @test MOI.supports_constraint(full_bridged_mock, F,
                                          MOI.GeometricMeanCone)
            @test !MOI.supports_constraint(
                greater_nonneg_mock, F, MOI.Nonpositives)
            @test MOI.supports_constraint(
                full_bridged_greater_nonneg, F, MOI.Nonnegatives)
        end
        for F in [MOI.VectorOfVariables, MOI.VectorAffineFunction{Float64}]
            # The bridges in this for loop do not support yet
            # VectorQuadraticFunction. See TODO's for the reason.
            # TODO: Missing vcat for quadratic for supporting quadratic.
            @test MOI.supports_constraint(full_bridged_mock, F,
                                          MOI.RotatedSecondOrderCone)
            # TODO: Det bridges need to use MOIU.operate to support quadratic.
            @test MOI.supports_constraint(full_bridged_mock, F,
                                          MOI.LogDetConeTriangle)
            @test MOI.supports_constraint(full_bridged_mock, F,
                                          MOI.RootDetConeTriangle)
        end
        mock2 = MOIU.MockOptimizer(ModelNoVAFinSOC{Float64}())
        @test !MOI.supports_constraint(mock2, MOI.VectorAffineFunction{Float64},
                                       MOI.SecondOrderCone)
        full_bridged_mock2 = MOIB.full_bridge_optimizer(mock2, Float64)
        @test MOI.supports_constraint(full_bridged_mock2, MOI.VectorAffineFunction{Float64},
                                      MOI.SecondOrderCone)
    end

    @testset "Combining two briges" begin
        full_bridged_mock = MOIB.full_bridge_optimizer(mock, Float64)
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1, 1, 0, 1, 1, 0, 1, √2])
        config = MOIT.TestConfig()
        MOIT.rootdett1vtest(full_bridged_mock, config)
        MOIT.rootdett1ftest(full_bridged_mock, config)
        # Dual is not yet implemented for RootDet and GeoMean bridges
        ci = first(MOI.get(full_bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.RootDetConeTriangle}()))
        test_delete_bridge(full_bridged_mock, ci, 4, ((MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone, 0),
                                                    (MOI.VectorAffineFunction{Float64}, MOI.GeometricMeanCone, 0),
                                                    (MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, 0)),
                           used_bridges = 3)
    end

    @testset "Continuous Linear" begin
        exclude = ["partial_start"] # VariablePrimalStart not supported.
        MOIT.contlineartest(bridged_mock, MOIT.TestConfig(solve=false), exclude)
    end

    @testset "Continuous Conic" begin
        MOIT.contconictest(MOIB.full_bridge_optimizer(mock, Float64), MOIT.TestConfig(solve=false), ["logdets", "rootdets", "psds"])
    end
end

@testset "Bridge tests" begin
    mock = MOIU.MockOptimizer(SimpleModel{Float64}())
    config = MOIT.TestConfig()
    config_with_basis = MOIT.TestConfig(basis = true)

    @testset "GreaterToLess" begin
        bridged_mock = MOIB.GreaterToLess{Float64}(mock)

        MOIU.set_mock_optimize!(mock,
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 0]),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, 0]),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, -100]))
        MOIT.linear6test(bridged_mock, config)

        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}}()))
        test_delete_bridge(bridged_mock, ci, 2,
                           ((MOI.ScalarAffineFunction{Float64},
                             MOI.LessThan{Float64}, 1),))
    end

    @testset "LessToGreater" begin
        bridged_mock = MOIB.LessToGreater{Float64}(mock)

        MOIU.set_mock_optimize!(mock,
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock,
                MOI.OPTIMAL, (MOI.FEASIBLE_POINT, [1.0]),
                MOI.FEASIBLE_POINT,
                    (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [1.0]
            ),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock,
                MOI.OPTIMAL, (MOI.FEASIBLE_POINT, [2.0]),
                MOI.FEASIBLE_POINT,
                    (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [1.0]
            )
        )
        MOIT.solve_set_scalaraffine_lessthan(bridged_mock, config)

        MOIU.set_mock_optimize!(mock,
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock,
                MOI.OPTIMAL, (MOI.FEASIBLE_POINT, [1.0]),
                MOI.FEASIBLE_POINT,
                    (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [1.0]
            ),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock,
                MOI.OPTIMAL, (MOI.FEASIBLE_POINT, [0.5]),
                MOI.FEASIBLE_POINT,
                    (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [0.5]
            )
        )
        MOIT.solve_coef_scalaraffine_lessthan(bridged_mock, config)

        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}}()))
        test_delete_bridge(bridged_mock, ci, 1,
                           ((MOI.ScalarAffineFunction{Float64},
                             MOI.GreaterThan{Float64}, 0),))
    end

    @testset "NonnegToNonpos" begin
        bridged_mock = MOIB.NonnegToNonpos{Float64}(mock)

        MOIU.set_mock_optimize!(mock,
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 0]),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, 0]),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, -100]))
        MOIT.linear7test(bridged_mock, config)

        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.Nonnegatives}()))
        test_delete_bridge(bridged_mock, ci, 2,
                           ((MOI.VectorAffineFunction{Float64},
                             MOI.Nonpositives, 1),))
    end

    @testset "NonposToNonneg" begin
        bridged_mock = MOIB.NonposToNonneg{Float64}(mock)

        MOIU.set_mock_optimize!(mock,
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 0]),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, 0]),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, -100]))
        MOIT.linear7test(bridged_mock, config)

        MOIU.set_mock_optimize!(mock,
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock,
                MOI.OPTIMAL, (MOI.FEASIBLE_POINT, [0.0, 0.0])
            ),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock,
                MOI.OPTIMAL, (MOI.FEASIBLE_POINT, [1.0, 0.75])
            )
        )
        MOIT.solve_const_vectoraffine_nonpos(bridged_mock, config)

        MOIU.set_mock_optimize!(mock,
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(
                mock, MOI.OPTIMAL, (MOI.FEASIBLE_POINT, [0.5])
            ),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(
                mock, MOI.OPTIMAL, (MOI.FEASIBLE_POINT, [0.25])
            )
        )
        MOIT.solve_multirow_vectoraffine_nonpos(bridged_mock, config)

        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.Nonpositives}()))
        test_delete_bridge(bridged_mock, ci, 1,
                           ((MOI.VectorAffineFunction{Float64},
                             MOI.Nonnegatives, 0),))
    end

    @testset "Scalarize" begin
        bridged_mock = MOIB.Scalarize{Float64}(mock)
        # VectorOfVariables-in-Nonnegatives
        # VectorAffineFunction-in-Zeros
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1.0, 0.0, 2.0],
            (MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}) => [-3, -1])
        MOIT.lin1vtest(bridged_mock, config)
        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.Zeros}()))
        test_delete_bridge(bridged_mock, ci, 3,
            ((MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, 0),
             (MOI.SingleVariable, MOI.GreaterThan{Float64}, 0)))
        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorOfVariables, MOI.Nonnegatives}()))
        test_delete_bridge(bridged_mock, ci, 3,
            ((MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, 0),
             (MOI.SingleVariable, MOI.GreaterThan{Float64}, 0)))
        # VectorAffineFunction-in-Nonnegatives
        # VectorAffineFunction-in-Zeros
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1.0, 0.0, 2.0],
            (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [0, 2, 0],
            (MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64})     => [-3, -1])
        MOIT.lin1ftest(bridged_mock, config)
        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.Zeros}()))
        test_delete_bridge(bridged_mock, ci, 3,
            ((MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, 0),
             (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}, 0)))
        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.Nonnegatives}()))
        test_delete_bridge(bridged_mock, ci, 3,
            ((MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, 0),
             (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}, 0)))
        # VectorOfVariables-in-Nonnegatives
        # VectorOfVariables-in-Nonpositives
        # VectorOfVariables-in-Zeros
        # VectorAffineFunction-in-Zeros
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [-4, -3, 16, 0],
            (MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64})        => [7, 2, -4])
        MOIT.lin2vtest(bridged_mock, config)
        # VectorAffineFunction-in-Nonnegatives
        # VectorAffineFunction-in-Nonpositives
        # VectorAffineFunction-in-Zeros
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [-4, -3, 16, 0],
            (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [0],
            (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64})    => [0],
            (MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64})     => [7, 2, -4, 7])
        MOIT.lin2ftest(bridged_mock, config)
    end

    @testset "Vectorize" begin
        bridged_mock = MOIB.Vectorize{Float64}(mock)

        MOIT.scalar_function_constant_not_zero(bridged_mock)

        MOIT.basic_constraint_tests(bridged_mock, config,
                                    include=Iterators.product(
                                        [MOI.SingleVariable,
                                         MOI.ScalarAffineFunction{Float64}],
                                         # TODO add it when operate(vcat, ...)
                                         # is implemented for quadratic
                                         #MOI.ScalarQuadraticFunction{Float64}],
                                        [MOI.EqualTo{Float64},
                                         MOI.GreaterThan{Float64},
                                         MOI.LessThan{Float64}]))

        MOIU.set_mock_optimize!(mock,
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1, 0],
                (MOI.VectorAffineFunction{Float64}, MOI.Nonpositives) => [[-1]],
                (MOI.VectorAffineFunction{Float64}, MOI.Nonnegatives) => [[0], [1]]))
        MOIT.linear2test(bridged_mock, config)

        MOIU.set_mock_optimize!(mock,
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 0]),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, 0]),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, -100]))
        MOIT.linear4test(bridged_mock, config)

        MOIU.set_mock_optimize!(mock,
        (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [4/3, 4/3]),
        (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [2, 0]),
        (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [4, 0]),
        (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [2]))
        MOIT.linear5test(mock, config)

        MOIU.set_mock_optimize!(mock,
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 0]),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, 0]),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, -100]))
        MOIT.linear6test(mock, config)

        MOIU.set_mock_optimize!(mock,
             (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 1/2, 1],
                 (MOI.VectorAffineFunction{Float64}, MOI.Nonpositives) => [[-1], [-2]],
                 (MOI.VectorAffineFunction{Float64}, MOI.Nonnegatives) => [[2], [0], [0]]),
             (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1],
                 (MOI.VectorAffineFunction{Float64}, MOI.Nonpositives) => [[-1]],
                 (MOI.VectorAffineFunction{Float64}, MOI.Nonnegatives) => [[0]]))
        # linear14 has double variable bounds for the z variable
        mock.eval_variable_constraint_dual = false
        MOIT.linear14test(bridged_mock, config)
        mock.eval_variable_constraint_dual = true

        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, ones(3),
                               (MOI.VectorAffineFunction{Float64}, MOI.Zeros) => [[2]])
        MOIT.psdt0vtest(bridged_mock, config)
        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}}()))
        test_delete_bridge(bridged_mock, ci, 3,
                           ((MOI.VectorAffineFunction{Float64},
                             MOI.Zeros, 0),))
   end

    @testset "Interval" begin
        bridged_mock = MOIB.SplitInterval{Float64}(mock)
        MOIT.basic_constraint_tests(bridged_mock, config,
                                    include=[(MOI.SingleVariable,
                                              MOI.Interval{Float64}),
                                             (MOI.ScalarAffineFunction{Float64},
                                              MOI.Interval{Float64}),
                                             (MOI.ScalarQuadraticFunction{Float64},
                                              MOI.Interval{Float64})])
        MOIU.set_mock_optimize!(mock,
             (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [5.0, 5.0], con_basis =
                 [(MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [MOI.BASIC],
                  (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64})    => [MOI.NONBASIC],
                  (MOI.SingleVariable, MOI.GreaterThan{Float64})                => [MOI.BASIC, MOI.BASIC]],
                  (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [0],
                  (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64})    => [-1]),
             (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [2.5, 2.5], con_basis =
                 [(MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [MOI.NONBASIC],
                  (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64})    => [MOI.BASIC],
                  (MOI.SingleVariable, MOI.GreaterThan{Float64})                => [MOI.BASIC, MOI.BASIC]],
                  (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [1],
                  (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64})    => [0]),
             (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1.0, 1.0], con_basis =
                 [(MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [MOI.NONBASIC],
                  (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64})    => [MOI.BASIC],
                  (MOI.SingleVariable, MOI.GreaterThan{Float64})                => [MOI.BASIC, MOI.BASIC]]),
             (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [6.0, 6.0], con_basis =
                 [(MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [MOI.BASIC],
                  (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64})    => [MOI.NONBASIC],
                  (MOI.SingleVariable, MOI.GreaterThan{Float64})                => [MOI.BASIC, MOI.BASIC]]))
        MOIT.linear10test(bridged_mock, config_with_basis)
        MOIU.set_mock_optimize!(mock,
             (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0.0, 0.0], con_basis =
                 [(MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [MOI.BASIC],
                  (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64})    => [MOI.BASIC],
                  (MOI.SingleVariable, MOI.GreaterThan{Float64})                => [MOI.NONBASIC, MOI.NONBASIC]],
                  (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [0],
                  (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64})    => [0]))
        MOIT.linear10btest(bridged_mock, config_with_basis)

        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}}()))
        newf = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, -1.0], MOI.get(bridged_mock, MOI.ListOfVariableIndices())), 0.0)
        MOI.set(bridged_mock, MOI.ConstraintFunction(), ci, newf)
        @test MOI.get(bridged_mock, MOI.ConstraintFunction(), ci) ≈ newf
        test_delete_bridge(bridged_mock, ci, 2, ((MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}, 0),
                                                (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64},    0)))
    end
    @testset "Scalar slack" begin
        MOI.empty!(mock)
        bridgedmock = MOIB.ScalarSlack{Float64}(mock)
        x = MOI.add_variable(bridgedmock)
        y = MOI.add_variable(bridgedmock)
        f = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{Float64}.([1.0, 2.0], [x, y]), 0.0)
        ci = MOI.add_constraint(bridgedmock, f, MOI.GreaterThan(0.0))
        @test MOI.get(bridgedmock, MOI.ConstraintFunction(), ci) ≈ f
        newf = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{Float64}.([2.0, 1.0], [x, y]), 0.0)
        MOI.set(bridgedmock, MOI.ConstraintFunction(), ci, newf)
        @test MOI.get(bridgedmock, MOI.ConstraintFunction(), ci) ≈ newf
        @test MOI.get(bridgedmock, MOI.ConstraintSet(), ci) == MOI.GreaterThan(0.0)
        MOI.set(bridgedmock, MOI.ConstraintSet(), ci, MOI.GreaterThan(1.0))
        @test MOI.get(bridgedmock, MOI.ConstraintSet(), ci) == MOI.GreaterThan(1.0)
        MOI.modify(bridgedmock, ci, MOI.ScalarConstantChange{Float64}(1.0))
        @test MOI.get(bridgedmock, MOI.ConstraintFunction(), ci) ≈
            MOI.ScalarAffineFunction(MOI.ScalarAffineTerm{Float64}.([2.0, 1.0], [x, y]), 1.0)
        test_delete_bridge(bridgedmock, ci, 2, ((MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}, 0),))

        MOIT.basic_constraint_tests(bridgedmock, config,
                                    include=[(F, S) for
                                    F in [MOI.ScalarAffineFunction{Float64},
                                          MOI.ScalarQuadraticFunction{Float64}],
                                    S in [MOI.GreaterThan{Float64},
                                          MOI.LessThan{Float64}]
                                          ])

        # There are extra variables due to the bridge
        MOIU.set_mock_optimize!(mock,
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1, 0, 1], con_basis =
                [(MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64})  => [MOI.NONBASIC],
                 (MOI.SingleVariable, MOI.GreaterThan{Float64})             => [MOI.BASIC, MOI.NONBASIC],
                 (MOI.SingleVariable, MOI.LessThan{Float64})                => [MOI.NONBASIC]]))
        MOIT.linear2test(bridgedmock, MOIT.TestConfig(duals = false, basis = true))
        c1 = MOI.get(bridgedmock, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}}())
        @test length(c1) == 1
        @test MOI.get(bridgedmock, MOI.ConstraintBasisStatus(), c1[]) == MOI.NONBASIC

        MOIU.set_mock_optimize!(mock,
         (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1.0, 1.0, 2.0, 2.0]),
         (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0.5, 0.5, 1.0, 1.0],
            (MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}) => [1, 0],
            (MOI.SingleVariable, MOI.GreaterThan{Float64})            => [1],
            (MOI.SingleVariable, MOI.LessThan{Float64})               => [0]))
        MOIT.linear11test(bridgedmock, MOIT.TestConfig(duals = false))

        c1 = MOI.get(bridgedmock, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}}())
        @test length(c1) == 1
        @test MOI.get(bridgedmock, MOI.ConstraintPrimal(), c1[]) ≈ 1.0
        @test MOI.get(bridgedmock, MOI.ConstraintDual(), c1[]) ≈ 1.0
        c2 = MOI.get(bridgedmock, MOI.ListOfConstraintIndices{MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}}())
        @test length(c2) == 1
        @test MOI.get(bridgedmock, MOI.ConstraintPrimal(), c2[]) ≈ 1.0
        @test MOI.get(bridgedmock, MOI.ConstraintDual(), c2[]) ≈ 0.0

        loc = MOI.get(bridgedmock, MOI.ListOfConstraints())
        @test length(loc) == 2
        @test (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) in loc
        @test (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) in loc
        loc = MOI.get(mock, MOI.ListOfConstraints())
        @test length(loc) == 3
        @test (MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}) in loc
        @test (MOI.SingleVariable, MOI.LessThan{Float64}) in loc
        @test (MOI.SingleVariable, MOI.GreaterThan{Float64}) in loc

        for T in [Int, Float64], S in [MOI.GreaterThan{T}, MOI.GreaterThan{T}]
            for F in [MOI.ScalarAffineFunction{T}, MOI.ScalarQuadraticFunction{T}]
                @test MOIB.added_constraint_types(MOIB.ScalarSlackBridge{T, F, S}) == [(F, MOI.EqualTo{T}), (MOI.SingleVariable, S)]
            end
        end
    end

    @testset "Vector slack" begin
        MOI.empty!(mock)
        bridgedmock = MOIB.VectorSlack{Float64}(mock)
        x = MOI.add_variable(bridgedmock)
        y = MOI.add_variable(bridgedmock)
        f = MOI.VectorAffineFunction(MOI.VectorAffineTerm.(1, MOI.ScalarAffineTerm.([1.0, 2.0], [x, y])), [0.0])
        ci = MOI.add_constraint(bridgedmock, f, MOI.Nonpositives(1))
        @test MOI.get(bridgedmock, MOI.ConstraintFunction(), ci) ≈ f
        newf = MOI.VectorAffineFunction(MOI.VectorAffineTerm.(1, MOI.ScalarAffineTerm.([2.0, 1.0], [x, y])), [0.0])
        MOI.set(bridgedmock, MOI.ConstraintFunction(), ci, newf)
        @test MOI.get(bridgedmock, MOI.ConstraintFunction(), ci) ≈ newf
        @test MOI.get(bridgedmock, MOI.ConstraintSet(), ci) == MOI.Nonpositives(1)
        MOI.modify(bridgedmock, ci, MOI.VectorConstantChange([1.0]))
        @test MOI.get(bridgedmock, MOI.ConstraintFunction(), ci) ≈
            MOI.VectorAffineFunction(MOI.VectorAffineTerm.(1, MOI.ScalarAffineTerm.([2.0, 1.0], [x, y])), [1.0])
        test_delete_bridge(bridgedmock, ci, 2, ((MOI.VectorAffineFunction{Float64}, MOI.Zeros, 0),))

        fp = MOI.VectorAffineFunction(MOI.VectorAffineTerm.([1,2,3], MOI.ScalarAffineTerm.([1.0, 2.0, 3.0], [x, y, y])), [0.0, 0.0, 0.0])
        cp = MOI.add_constraint(bridgedmock, fp, MOI.PowerCone(0.1))
        @test MOI.get(bridgedmock, MOI.ConstraintSet(), cp) == MOI.PowerCone(0.1)
        MOI.set(bridgedmock, MOI.ConstraintSet(), cp, MOI.PowerCone(0.2))
        @test MOI.get(bridgedmock, MOI.ConstraintSet(), cp) == MOI.PowerCone(0.2)

        MOIT.basic_constraint_tests(bridgedmock, config,
                                    include=[(F, S) for
                                    F in [MOI.VectorAffineFunction{Float64},
                                          MOI.VectorQuadraticFunction{Float64}],
                                    S in [MOI.Nonnegatives,
                                          MOI.Nonpositives]
                                        ])

        # There are extra variables due to the bridge
        MOIU.set_mock_optimize!(mock,
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 0, 0, 0]),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, 0, 100, 0]),
            (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, -100, 100, -100],
            (MOI.VectorAffineFunction{Float64}, MOI.Zeros) => [[1.], [1.]],
            (MOI.VectorOfVariables, MOI.Nonnegatives)      => [[1.]],
            (MOI.VectorOfVariables, MOI.Nonpositives)      => [[1.]]))
        MOIT.linear7test(bridgedmock, config)

        c1 = MOI.get(bridgedmock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.Nonnegatives}())
        @test length(c1) == 1
        @test MOI.get(bridgedmock, MOI.ConstraintPrimal(), c1[]) ≈ [100.0]
        @test MOI.get(bridgedmock, MOI.ConstraintDual(), c1[]) ≈ [1.0]
        c2 = MOI.get(bridgedmock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.Nonpositives}())
        @test length(c2) == 1
        @test MOI.get(bridgedmock, MOI.ConstraintPrimal(), c2[]) ≈ [-100.0]
        @test MOI.get(bridgedmock, MOI.ConstraintDual(), c2[]) ≈ [1.0]

        loc = MOI.get(bridgedmock, MOI.ListOfConstraints())
        @test length(loc) == 2
        @test (MOI.VectorAffineFunction{Float64}, MOI.Nonnegatives) in loc
        @test (MOI.VectorAffineFunction{Float64}, MOI.Nonpositives) in loc
        loc = MOI.get(mock, MOI.ListOfConstraints())
        @test length(loc) == 3
        @test (MOI.VectorAffineFunction{Float64}, MOI.Zeros) in loc
        @test (MOI.VectorOfVariables, MOI.Nonnegatives) in loc
        @test (MOI.VectorOfVariables, MOI.Nonpositives) in loc

        for T in [Int, Float64], S in [MOI.Nonnegatives, MOI.Nonpositives]
            for F in [MOI.VectorAffineFunction{T}, MOI.VectorQuadraticFunction{T}]
                @test MOIB.added_constraint_types(MOIB.VectorSlackBridge{T, F, S}) == [(F, MOI.Zeros), (MOI.VectorOfVariables, S)]
            end
        end
    end

    @testset "RSOC" begin
        bridged_mock = MOIB.RSOC{Float64}(mock)
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1/√2, 1/√2, 0.5, 1.0],
                              (MOI.SingleVariable,                MOI.EqualTo{Float64}) => [-√2, -1/√2],
                              (MOI.VectorAffineFunction{Float64}, MOI.SecondOrderCone)  => [[3/2, 1/2, -1.0, -1.0]])
        MOIT.rotatedsoc1vtest(bridged_mock, config)
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1/√2, 1/√2],
                              (MOI.VectorAffineFunction{Float64}, MOI.SecondOrderCone)  => [[3/2, 1/2, -1.0, -1.0]])
        MOIT.rotatedsoc1ftest(bridged_mock, config)
        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone}()))
        test_delete_bridge(bridged_mock, ci, 2, ((MOI.VectorAffineFunction{Float64}, MOI.SecondOrderCone, 0),))
    end

    @testset "QuadtoSOC" begin
        bridged_mock = MOIB.QuadtoSOC{Float64}(mock)
        @testset "Error for non-convex quadratic constraints" begin
            x = MOI.add_variable(bridged_mock)
            @test_throws ErrorException begin
                MOI.add_constraint(bridged_mock,
                                   MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm{Float64}[],
                                                               [MOI.ScalarQuadraticTerm(1.0, x, x)],
                                                               0.0),
                                   MOI.GreaterThan(0.0))
            end
            @test_throws ErrorException begin
                MOI.add_constraint(bridged_mock,
                                   MOI.ScalarQuadraticFunction(MOI.ScalarAffineTerm{Float64}[],
                                                               [MOI.ScalarQuadraticTerm(-1.0, x, x)],
                                                               0.0),
                                   MOI.LessThan(0.0))
            end
        end
        @testset "Quadratic constraints with 2 variables" begin
            MOIU.set_mock_optimize!(mock,
                (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock,
                    MOI.OPTIMAL,
                    (MOI.FEASIBLE_POINT, [0.5, 0.5])
                ),
                (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock,
                    MOI.OPTIMAL,
                    (MOI.FEASIBLE_POINT, [0.5, (√13 - 1)/4])
                )
            )
            MOIT.solve_qcp_edge_cases(bridged_mock, config)
            ci = first(MOI.get(mock,
                               MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64},
                                                           MOI.RotatedSecondOrderCone}()))
            x, y = MOI.get(mock, MOI.ListOfVariableIndices())
            # The matrix is
            # 2 1
            # 1 2
            # for which the cholesky factorization is U' * U with U =
            # √2 √2/2
            #  . √3/√2
            expected = MOI.VectorAffineFunction{Float64}(MOI.VectorAffineTerm.([3, 3, 4],
                                                                               MOI.ScalarAffineTerm.([√2, √2/2, √3/√2],
                                                                                [x, y, y])),
                                                         [1.0, 1.0, 0.0, 0.0])
            @test MOI.get(mock, MOI.ConstraintFunction(), ci) ≈ expected
        end
        @testset "QCP tests" begin
            MOIU.set_mock_optimize!(mock,
                (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1/2, 7/4], MOI.FEASIBLE_POINT))
            MOIT.qcp1test(bridged_mock, config)
            MOIU.set_mock_optimize!(mock,
                (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [√2], MOI.FEASIBLE_POINT))
            MOIT.qcp2test(bridged_mock, config)
            MOIU.set_mock_optimize!(mock,
                (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [√2], MOI.FEASIBLE_POINT))
            MOIT.qcp3test(bridged_mock, config)
            @testset "Bridge deletion" begin
                ci = first(MOI.get(bridged_mock,
                                   MOI.ListOfConstraintIndices{MOI.ScalarQuadraticFunction{Float64},
                                                               MOI.LessThan{Float64}}()))
                test_delete_bridge(bridged_mock, ci, 1, ((MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone, 0),))
            end
        end
    end

    @testset "SquarePSD" begin
        bridged_mock = MOIB.SquarePSD{Float64}(mock)
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, ones(4),
                              (MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64})                 => [2, 2])
        MOIT.psds0vtest(bridged_mock, config)
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, ones(4),
                              (MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle) => [[1, -1, 1]],
                              (MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64})                 => [2, 2])
        MOIT.psds0ftest(bridged_mock, config)
        ci = first(MOI.get(bridged_mock,
                           MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64},
                                                       MOI.PositiveSemidefiniteConeSquare}()))
        test_delete_bridge(bridged_mock, ci, 4,
                           ((MOI.VectorAffineFunction{Float64},
                             MOI.PositiveSemidefiniteConeTriangle, 0),
                            (MOI.ScalarAffineFunction{Float64},
                             MOI.EqualTo{Float64}, 1)))
    end

    @testset "GeoMean" begin
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [ones(4); 2; √2; √2])
        bridged_mock = MOIB.GeoMean{Float64}(mock)
        MOIT.geomean1vtest(bridged_mock, config)
        MOIT.geomean1ftest(bridged_mock, config)
        # Dual is not yet implemented for GeoMean bridge
        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.GeometricMeanCone}()))
        test_delete_bridge(bridged_mock, ci, 4, ((MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone, 0),
                                                (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64},      1)))
    end

    @testset "SOCtoPSD" begin
        bridged_mock = MOIB.SOCtoPSD{Float64}(mock)
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1.0, 1/√2, 1/√2],
                              (MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle) => [[√2/2, -1/2, √2/4, -1/2, √2/4, √2/4]],
                              (MOI.VectorAffineFunction{Float64}, MOI.Zeros)                            => [[-√2]])
        MOIT.soc1vtest(bridged_mock, config)
        MOIT.soc1ftest(bridged_mock, config)
        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.SecondOrderCone}()))
        test_delete_bridge(bridged_mock, ci, 3, ((MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, 0),))
    end

    @testset "RSOCtoPSD" begin
        bridged_mock = MOIB.RSOCtoPSD{Float64}(mock)
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1/√2, 1/√2, 0.5, 1.0],
                              (MOI.SingleVariable,                MOI.EqualTo{Float64})       => [-√2, -1/√2],
                              (MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle) => [[√2, -1/2, √2/8, -1/2, √2/8, √2/8]])
        MOIT.rotatedsoc1vtest(bridged_mock, config)
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1/√2, 1/√2],
                              (MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle) => [[√2, -1/2, √2/8, -1/2, √2/8, √2/8]])
        MOIT.rotatedsoc1ftest(bridged_mock, config)
        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone}()))
        test_delete_bridge(bridged_mock, ci, 2, ((MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, 0),))
    end

    @testset "LogDet" begin
        bridged_mock = MOIB.LogDet{Float64}(mock)
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 1, 0, 1, 1, 0, 1, 0, 0, 1])
        MOIT.logdett1vtest(bridged_mock, config)
        MOIT.logdett1ftest(bridged_mock, config)
        # Dual is not yet implemented for LogDet bridge
        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.LogDetConeTriangle}()))
        test_delete_bridge(bridged_mock, ci, 5, ((MOI.VectorAffineFunction{Float64}, MOI.ExponentialCone, 0), (MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, 0)))
    end

    @testset "RootDet" begin
        bridged_mock = MOIB.RootDet{Float64}(mock)
        mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1, 1, 0, 1, 1, 0, 1])
        MOIT.rootdett1vtest(bridged_mock, config)
        MOIT.rootdett1ftest(bridged_mock, config)
        # Dual is not yet implemented for RootDet bridge
        ci = first(MOI.get(bridged_mock, MOI.ListOfConstraintIndices{MOI.VectorAffineFunction{Float64}, MOI.RootDetConeTriangle}()))
        test_delete_bridge(bridged_mock, ci, 4, ((MOI.VectorAffineFunction{Float64}, MOI.RotatedSecondOrderCone, 0),
                                                (MOI.VectorAffineFunction{Float64}, MOI.GeometricMeanCone, 0),
                                                (MOI.VectorAffineFunction{Float64}, MOI.PositiveSemidefiniteConeTriangle, 0)))
    end
end

# We need to test this in a module at the top level because it can't be defined
# in a testset. If it runs without error, then we're okay.
module TestExternalBridge
    using MathOptInterface

    struct StrictlyGreaterThan <: MathOptInterface.AbstractScalarSet end
    struct StrictlyGreaterBridge{T} <: MathOptInterface.Bridges.AbstractBridge end

    function StrictlyGreaterBridge(
            model,
            func::MathOptInterface.SingleVariable,
            set::StrictlyGreaterThan)
        return StrictlyGreaterBridge{Float64}()
    end

    function MathOptInterface.supports_constraint(
            ::Type{StrictlyGreaterBridge{T}},
            ::Type{MathOptInterface.SingleVariable},
            ::Type{StrictlyGreaterThan}) where {T}
        return true
    end

    function MathOptInterface.Bridges.added_constraint_types(
            ::Type{StrictlyGreaterBridge{T}},
            ::Type{MathOptInterface.SingleVariable},
            ::Type{StrictlyGreaterThan}) where {T}
        return [(
            MathOptInterface.SingleVariable,
            MathOptInterface.GreaterThan{T}
        )]
    end

    MathOptInterface.Bridges.@bridge(StrictlyGreater, StrictlyGreaterBridge,
        (StrictlyGreaterThan, ),
        (),
        (),
        (),
        (MathOptInterface.SingleVariable, ),
        (),
        (),
        ()
    )
end

@testset "@bridge with external components" begin
    model = SimpleModel{Float64}();
    @test MOI.supports_constraint(model, MOI.SingleVariable, MOI.GreaterThan{Float64})
    @test !MOI.supports_constraint(model, MOI.SingleVariable, TestExternalBridge.StrictlyGreaterThan)

    bridge = TestExternalBridge.StrictlyGreater{Float64}(model);
    @test MOI.supports_constraint(bridge, MOI.SingleVariable, MOI.GreaterThan{Float64})
    @test MOI.supports_constraint(bridge, MOI.SingleVariable, TestExternalBridge.StrictlyGreaterThan)
end


text:
# An implementation of the Golub-Kahan version of Craig's method
# for the solution of the consistent (under/over-determined or square)
# linear system
#
#  Ax = b.
#
# The method seeks to solve the minimum-norm problem
#
#  min ‖x‖²  s.t. Ax = b,
#
# and is equivalent to applying the conjugate gradient method
# to the linear system
#
#  AA'y = b.
#
# This method, sometimes known under the name CRAIG, is the
# Golub-Kahan implementation of CGNE, and is described in
#
# C. C. Paige and M. A. Saunders, LSQR: An Algorithm for Sparse
# Linear Equations and Sparse Least Squares, ACM Transactions on
# Mathematical Software, Vol 8, No. 1, pp. 43-71, 1982.
#
# and
#
# M. A. Saunders, Solutions of Sparse Rectangular Systems Using
# LSQR and CRAIG, BIT, No. 35, pp. 588-604, 1995.
#
# Dominique Orban, <dominique.orban@gerad.ca>
# Montréal, QC, April 2015.
#
# This implementation is strongly inspired from Mike Saunders's.

export craig

"""Find the least-norm solution of the consistent linear system

  Ax + √λs = b

using the Golub-Kahan implementation of Craig's method, where λ ≥ 0 is a
regularization parameter. This method is equivalent to CGNE but is more
stable.

For a system in the form Ax = b, Craig's method is equivalent to applying
CG to AA'y = b and recovering x = A'y. Note that y are the Lagrange
multipliers of the least-norm problem

  minimize ‖x‖  subject to Ax = b.

In this implementation, both the x and y-parts of the solution are returned.
"""
function craig(A :: AbstractLinearOperator, b :: AbstractVector{T};
               λ :: Float64=0.0, atol :: Float64=1.0e-8, rtol :: Float64=1.0e-6,
               conlim :: Float64=1.0e+8, itmax :: Int=0, verbose :: Bool=false) where T <: Number

  m, n = size(A);
  size(b, 1) == m || error("Inconsistent problem size");
  verbose && @printf("CRAIG: system of %d equations in %d variables\n", m, n);

  x = zeros(T, n);
  β₁ = @knrm2(m, b)   # Marginally faster than norm(b);
  β₁ == 0 && return x, zeros(m), SimpleStats(true, false, [0.0], Float64[], "x = 0 is a zero-residual solution");
  β = β₁;
  θ = β₁;   # θ will differ from β when there is regularization (λ > 0).
  ξ = -1;   # Most recent component of x in Range(V).
  δ = λ;
  ρ_prev = 1;

  # β₁ u₁ = b.
  u = copy(b);
  @kscal!(m, 1.0/β₁, u)

  v = zeros(T, n)
  w = zeros(T, m)  # Used to update y.

  y = zeros(T, m)
  λ > 0.0 && (w2 = zeros(T, n))

  Anorm² = 0.0;  # Estimate of ‖A‖²_F.
  Dnorm  = 0.0;  # Estimate of ‖(A'A)⁻¹‖.
  xNorm² = 0.0;  # Estimate of ‖x‖².

  iter = 0;
  itmax == 0 && (itmax = m + n);

  rNorm  = β₁;
  rNorms = [rNorm;];
  ɛ_c = atol + rtol * rNorm;  # Stopping tolerance for consistent systems.
  ɛ_i = atol;                 # Stopping tolerance for inconsistent systems.
  verbose && @printf("%5s  %8s  %8s  %8s\n", "Aprod", "‖r‖", "‖x‖²", "‖A‖²")
  verbose && @printf("%5d  %8.2e  %8.2e  %8.2e\n", 1, rNorm, xNorm², Anorm²);

  status = "unknown";
  solved = rNorm <= ɛ_c;
  inconsistent = false;
  tired = iter >= itmax;

  while ! (solved || inconsistent || tired)
    # Generate the next Golub-Kahan vectors
    # 1. αv = A'u - βv
    @kscal!(n, -β, v)
    @kaxpy!(n, 1.0, A' * u, v)
    α = @knrm2(n, v)
    if α == 0.0
      inconsistent = true;
      continue;
    end
    @kscal!(n, 1.0/α, v)

    Anorm² += α * α + λ * λ;

    if λ > 0.0
      # Givens rotation to zero out the δ in position (k, 2k):
      #      k-1  k   2k     k   2k      k-1  k   2k
      # k   [ θ   α   δ ] [ c₁   s₁ ] = [ θ   ρ      ]
      # k+1 [     β     ] [ s₁  -c₁ ]   [     θ+   γ ]
      ρ  = sqrt(α * α + δ * δ);
      c₁ =  α / ρ;
      s₁ = -δ / ρ;
    else
      ρ = α;
    end

    ξ = -θ / ρ * ξ;

    if λ > 0.0
      # w1 = c₁ * v + s₁ * w2
      # w2 = s₁ * v - c₁ * w2
      # x  = x + ξ * w1
      # Save storage on w1 since it cannot be updated
      # using a BLAS call.
      # TODO: use dot notation in Julia 0.6.
      @simd for i = 1 : n
        @inbounds x[i]  = x[i] + ξ * (c₁ * v[i] + s₁ * w2[i]);
        @inbounds w2[i] = s₁ * x[i] - c₁ * w2[i];
      end
    else
      @kaxpy!(n, ξ, v, x)  # x = x + ξ * v;
    end

    # Recur y.
    @kscal!(m, -θ/ρ_prev, w)
    @kaxpy!(m, 1.0, u, w)  # w = u - θ/ρ_prev * w;
    @kaxpy!(m, ξ/ρ, w, y)  # y = y + ξ/ρ * w;

    # 2. βu = A v - αu
    @kscal!(m, -α, u)
    @kaxpy!(m, 1.0, A * v, u)
    β = @knrm2(m, u)
    β > 0.0 && @kscal!(m, 1.0/β, u)

    # Finish  updates from the first Givens rotation.
    if λ > 0.0
      θ =  β * c₁;
      γ =  β * s₁;
    else
      θ = β;
    end

    if λ > 0.0
      # Givens rotation to zero out the γ in position (k+1, 2k)
      #       2k  2k+1    2k  2k+1      2k  2k+1
      # k+1 [  γ    λ ] [ c₂   s₂ ] = [  0    δ ]
      # k+2 [  0    0 ] [ s₂  -c₂ ]   [  0    0 ]
      δ  =  sqrt(γ * γ + λ * λ);
      c₂ = -λ / δ;
      s₂ =  γ / δ;
      @kscal!(n, s₂, w2)
    end

    Anorm² += β * β;
    xNorm² += ξ * ξ;
    rNorm   = β * abs(ξ);          # r = -     β * ξ * u
    λ > 0.0 && (rNorm *= abs(c₁)); # r = -c₁ * β * ξ * u when λ > 0.
    push!(rNorms, rNorm);
    iter = iter + 1;

    ρ_prev = ρ;  # Only differs from α if λ > 0.

    verbose && @printf("%5d  %8.2e  %8.2e  %8.2e\n", 1 + 2 * iter, rNorm, xNorm², Anorm²);

    solved = rNorm <= ɛ_c;
    inconsistent = false;
    tired = iter >= itmax;
  end

  inconsistent = !solved  # is there a smarter way?

  # TODO: transfer to LSQR point and update y.

  status = solved ? "solution good enough given atol and rtol" : (inconsistent ? "system probably inconsistent" : "maximum number of iterations exceeded")
  stats = SimpleStats(solved, inconsistent, rNorms, Float64[], status);
  return (x, y, stats);
end


text:
include("algoriths/FlowSeed-0.6.jl")

using MAT

mat = matread("data/BrainGraph")
A = mat["B"]

n = size(A,1)
d = sum(A,1)'
volA = sum(nonzeros(A))

mat = matread("Brain_Regions/BrainRegions_Train23.mat")

Regions = mat["RegionsTrain"]
RegionSize = round.(Int64,mat["RegionSizeTrain"])
RegionCond = mat["RegionCondTrain"]
RegionLabels = round.(Int64,mat["RegionLabelTrain"])
Seed2per = mat["Seed2perTrain"]
Seed3per = mat["Seed3perTrain"]

mat = matread("Brain_Regions/BrainRegions_Train.mat")
Seed1 = mat["Seed1Train"]
Seed2 = mat["Seed2Train"]

## Load a region, and its designated seed sets
# Seed sets were chosen and saved in advance for experimental reproduceability

# Set a single value for epsilon
epsilon = .1
tag = ""
for seedtype = 1:4

    TTA = "Train"
    if seedtype == 1
        Seeds = Seed1
        outputstring = "FlowSeed_"*TTA*"_Output/Seed_"*string(seedtype)*"_epsilon_"*string(epsilon)*tag*".txt"
        outputmatrix = "FlowSeed_"*TTA*"_Output/Seed_"*string(seedtype)*"_epsilon_"*string(epsilon)*tag*".mat"

    elseif seedtype == 2
        Seeds = Seed2
        outputstring = "FlowSeed_"*TTA*"_Output/Seed_"*string(seedtype)*"_epsilon_"*string(epsilon)*tag*".txt"
        outputmatrix = "FlowSeed_"*TTA*"_Output/Seed_"*string(seedtype)*"_epsilon_"*string(epsilon)*tag*".mat"

    elseif seedtype == 3
        Seeds = Seed2per
        # epsilon is fixed, seed type is fixed (i.e. an integer from 1 to 4)
        outputstring = "FlowSeed_"*TTA*"_Output/Seed_"*string(seedtype-1)*"per_epsilon_"*string(epsilon)*tag*".txt"
        outputmatrix = "FlowSeed_"*TTA*"_Output/Seed_"*string(seedtype-1)*"per_epsilon_"*string(epsilon)*tag*".mat"
    elseif seedtype == 4
        Seeds = Seed3per
        outputstring = "FlowSeed_"*TTA*"_Output/Seed_"*string(seedtype-1)*"per_epsilon_"*string(epsilon)*tag*".txt"
        outputmatrix = "FlowSeed_"*TTA*"_Output/Seed_"*string(seedtype-1)*"per_epsilon_"*string(epsilon)*tag*".mat"
    else
        println("For seedtype: Input 1,2,3, or 4 (100 nodes, 1%, 2%, or 3% of target set)")
        return
    end

    open(outputstring,"w") do f
         write(f,"Brain Dataset training region experiments for FlowSeed when epsilon = $epsilon\n")

         if seedtype == 1
             write(f,"Seed sets are made up of a set of 100 initial starter nodes inside the target region, which we grow by their neighborhood.\n")
         elseif seedtype == 2
             write(f,"Seed sets are made up of a set of initial random starter nodes that make up 1% of the target region, which we grow by their neighborhood.\n")
         elseif seedtype == 3
             write(f,"Seed sets are made up of a set of initial random starter nodes that make up 2% of the target region, which we grow by their neighborhood.\n")
         else
             write(f,"Seed sets are made up of a set of initial random starter nodes that make up 3% of the target region, which we grow by their neighborhood.\n")
         end
         write(f,"We use four different types of penalties on excluding seed nodes:\n")
         write(f,"Type 1: there is no penalty on excluding seed nodes, but no additional soft penalties.\n")
         write(f,"Type 2: there is a strict penalty on excluding any nodes from the initial starter set.\n")
         write(f,"Type 3: strict penalty for excluding starter set. Soft penalties for other nodes, of weight neighbs/2 \nwhere neighbs[r] = number of nodes in the starter set that are adjacent to node r in the seed set.\n")
         write(f,"Type 4: strict penalty for excluding starter set. Soft penalty of 1 for every other node.\n")
    end

        # Store output sets and stats for each set of experiments
        # There are 4 different types of penalties we will test
        sets1 = spzeros(n,17)
        sets2 = spzeros(n,17)
        sets3 = spzeros(n,17)
        sets4 = spzeros(n,17)

        stats1 = zeros(7,17)
        stats2 = zeros(7,17)
        stats3 = zeros(7,17)
        stats4 = zeros(7,17)

        for regi = 1:size(Regions,2)

            # Load target set and output results
            Target = find(Regions[:,regi])
            Label = RegionLabels[regi]
            Size = length(Target)
            Cond = round(RegionCond[regi],4)
            println("\nRegion $Label has conductance $Cond and size $Size")
            open(outputstring,"a") do f
                 write(f,"\nRegion $Label has conductance $Cond and size $Size \n")
            end
            T = Target

            # Load the seed set, grow it by its neighborhood
            Rstart = find(Seeds[:,regi])
            R = neighborhood(A,Rstart,1)    # Grow "starter" seed by their neighborhood
            Rn = neighborhood(A,R,1)    # get the immediate neighbors of R...
            Rn = setdiff(Rn,R)          # ...but we exclude R itself
            inRc = ones(n)
            inRc[R] = 0
            Rc = find(inRc)             # complement of R

            cut,volR,edges,condR = set_stats(A,R,volA)
            volR = sum(d[R])
            numR = length(R)
            cR = round(condR,4)
            fR = volR/(volA - volR)
            println("\tSeed set: conductance = $cR, size = $numR")
            open(outputstring,"a") do f
                 write(f,"\tSeed set: conductance = $cR, size = $numR \n")
            end

            println("Penalty \t _Size_ \t _Time_ \t _Cond_ \t R-cond \t precision \t recall \t F1-score")
            open(outputstring,"a") do f
                 write(f,"Penalty \t _Size_ \t _Time_ \t _Cond_ \t R-cond \t precision \t recall \t F1-score  \n")
            end

            for Type = 1:4

                # Set up four different versions of strict and soft penalties
                if Type == 1
                    pR = zeros(numR,1)
                    RinS = zeros(numR,1)
                elseif Type == 2
                    pR = zeros(numR,1)
                    RinS = zeros(numR,1)
                    for i = 1:numR
                        if in(R[i],Rstart)
                            RinS[i] = 1
                        end
                    end
                elseif Type == 3
                    pR = zeros(numR,1)
                    NeighbTime = zeros(n,1)    # count the number of nodes in Rstart are adjacent to each node
                    for i = 1:length(Rstart)
                        N = neighborhood(A,[Rstart[i]],1)
                        NeighbTime[N] += 1
                    end
                    ~, ~, times = findnz(NeighbTime)
                    pR = times/2    # penalize proportional to the percentage of nodes in Rstart that neighbor it

                    RinS = zeros(numR,1)
                    for i = 1:numR
                        if in(R[i],Rstart)
                            RinS[i] = 1
                        end
                    end
                else
                    RinS = zeros(numR,1)
                    for i = 1:numR
                        if in(R[i],Rstart)
                            RinS[i] = 1
                        end
                    end
                    pR = ones(numR,1)
                end

                tic()
                S, Rcond = FlowSeed(A,R,Rn,Rc,epsilon,pR,RinS,d,volA,volR,true)
                timerfull = toq()
                timer = round(timerfull,3)
                Sstats = set_stats(A,S,volA)
                condS = round(Sstats[4],4)
                RcondS = round(Rcond,4)
                Ssize = length(S)
                prf = PRF(Target,S)
                pr = round(prf[1],4)
                re = round(prf[2],4)
                f1 = round(prf[3],4)
                println("Type $Type \t\t $Ssize\t\t$timer\t\t $condS \t $RcondS \t $pr \t $re \t $f1 ")
                open(outputstring,"a") do f
                     write(f,"Type $Type \t\t $Ssize\t\t$timer\t\t $condS \t $RcondS \t $pr \t $re \t $f1  \n")
                end
                # Save the output, both the set and the main output stats

                if Type == 1
                    sets1[S,regi] = 1
                    stats1[:,regi] = [Ssize;timer;Sstats[4];Rcond;pr;re;f1]
                elseif Type ==2
                    sets2[S,regi] = 1
                    stats2[:,regi] = [Ssize;timer;Sstats[4];Rcond;pr;re;f1]
                elseif Type ==3
                    sets3[S,regi] = 1
                    stats3[:,regi] = [Ssize;timer;Sstats[4];Rcond;pr;re;f1]
                else
                    sets4[S,regi] = 1
                    stats4[:,regi] = [Ssize;timer;Sstats[4];Rcond;pr;re;f1]
                end
            end
        end

        matwrite(outputmatrix, Dict( "sets1" => sets1, "stats1" => stats1,
            "sets2" => sets2, "stats2" => stats2,"sets3" => sets3,
            "stats3" => stats3,"sets4" => sets4, "stats4" => stats4))

end

max_stars_repo_name: nveldt/FlowSeed

max_issues_repo_name: nveldt/FlowSeed

max_forks_repo_name: nveldt/FlowSeed


text:
function SolidTides(arg0::Frame, arg1::jdouble, arg2::jdouble, arg3::TideSystem, arg4::IERSConventions, arg5::UT1Scale, arg6::Vector{CelestialBody})
    return SolidTides((Frame, jdouble, jdouble, TideSystem, IERSConventions, UT1Scale, Vector{CelestialBody}), arg0, arg1, arg2, arg3, arg4, arg5, arg6)
end

function SolidTides(arg0::Frame, arg1::jdouble, arg2::jdouble, arg3::TideSystem, arg4::jboolean, arg5::jdouble, arg6::jint, arg7::IERSConventions, arg8::UT1Scale, arg9::Vector{CelestialBody})
    return SolidTides((Frame, jdouble, jdouble, TideSystem, jboolean, jdouble, jint, IERSConventions, UT1Scale, Vector{CelestialBody}), arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8, arg9)
end

function acceleration(obj::SolidTides, arg0::FieldSpacecraftState, arg1::Vector{RealFieldElement})
    return jcall(obj, "acceleration", FieldVector3D, (FieldSpacecraftState, Vector{RealFieldElement}), arg0, arg1)
end

function acceleration(obj::SolidTides, arg0::SpacecraftState, arg1::Vector{jdouble})
    return jcall(obj, "acceleration", Vector3D, (SpacecraftState, Vector{jdouble}), arg0, arg1)
end

function depends_on_position_only(obj::SolidTides)
    return jcall(obj, "dependsOnPositionOnly", jboolean, ())
end

function get_events_detectors(obj::SolidTides)
    return jcall(obj, "getEventsDetectors", Stream, ())
end

function get_field_events_detectors(obj::SolidTides, arg0::Field)
    return jcall(obj, "getFieldEventsDetectors", Stream, (Field,), arg0)
end

function get_parameters_drivers(obj::SolidTides)
    return jcall(obj, "getParametersDrivers", Vector{ParameterDriver}, ())
end


text:
module PortHamiltonianBenchmarkSystems

using LinearAlgebra, SparseArrays

include("./Utils/IOFormats.jl")
include("./Utils/Downloads.jl")

abstract type BenchmarkConfig end

struct PHSystem{TE, TJ, TR, TG, TP, TQ, TS, TN}
  E::TE
  J::TJ
  R::TR
  Q::TQ
  G::TG
  P::TP
  S::TS
  N::TN
  function PHSystem(E::TE, J::TJ, R::TR, Q::TQ, G::TG, P::TP, S::TS, N::TN) where {TE, TJ, TR, TQ, TG, TP, TS, TN}
    n = size(E, 1)
    m = size(G, 2)
    @assert size(E) == (n, n)
    @assert size(J) == (n, n)
    @assert size(R) == (n, n)
    @assert size(Q) == (n, n)
    @assert size(G) == (n, m)
    @assert size(P) == (n, m)
    @assert size(S) == (m, m)
    @assert size(N) == (m, m)
    return new{TE, TJ, TR, TQ, TG, TP, TS, TN}(E, J, R, Q, G, P, S, N)
  end
end

include("./SingleMSDChain.jl")
include("./PoroModel.jl")
include("./RCLLadders.jl")
include("./DampedWaveNet.jl")

export PHSystem, construct_system

end # module