From 19914ddf1d9d94c7dee3f6ddb24b320b9b8dac5d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Legat?= <benoit.legat@gmail.com>
Date: Sun, 10 Mar 2019 23:29:33 +0100
Subject: [PATCH 1/6] Stop creating slacks thanks to bridges

---
 .gitignore                      |   1 +
 src/SemidefiniteOptInterface.jl | 124 +++++++--------
 src/constraint.jl               |  51 +------
 src/mock.jl                     |   4 +-
 src/variable.jl                 |  31 ++--
 test/contconic.jl               | 257 ++++++++++++++++----------------
 test/contlinear.jl              | 124 ++++++++-------
 test/mock_tests_generator.ipynb |  74 +++++----
 test/runtests.jl                |  17 ++-
 test/unit.jl                    |  56 +++----
 10 files changed, 364 insertions(+), 375 deletions(-)

diff --git a/.gitignore b/.gitignore
index 8c960ec..6014500 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,4 @@
 *.jl.cov
 *.jl.*.cov
 *.jl.mem
+.ipynb_checkpoints
diff --git a/src/SemidefiniteOptInterface.jl b/src/SemidefiniteOptInterface.jl
index d1999e1..a9eb9c1 100644
--- a/src/SemidefiniteOptInterface.jl
+++ b/src/SemidefiniteOptInterface.jl
@@ -15,10 +15,7 @@ const SVF = MOI.SingleVariable
 const VVF = MOI.VectorOfVariables
 const VF  = Union{SVF, VVF}
 const SAF{T} = MOI.ScalarAffineFunction{T}
-const VAF{T} = MOI.VectorAffineFunction{T}
-const AF{T}  = Union{SAF{T}, VAF{T}}
 const ASF{T} = Union{SVF, SAF{T}}
-const AVF{T} = Union{VVF, VAF{T}}
 
 const ZS = Union{MOI.EqualTo, MOI.Zeros}
 const NS = Union{MOI.GreaterThan, MOI.Nonnegatives}
@@ -43,7 +40,6 @@ mutable struct SOItoMOIBridge{T, SIT <: AbstractSDOptimizer} <: MOI.AbstractOpti
     varmap::Vector{Vector{Tuple{Int, Int, Int, T, T}}} # Variable Index vi -> blk, i, j, coef, shift # x = sum coef * block(X, blk)[i, j] + shift
     zeroblock::Dict{CI, Int}
     constrmap::Dict{CI, UnitRange{Int}} # Constraint Index ci -> cs
-    slackmap::Vector{Tuple{Int, Int, Int, T}} # c -> blk, i, j, coef
     double::Vector{CI} # created when there are two cones for same variable
     function SOItoMOIBridge{T}(sdoptimizer::SIT) where {T, SIT}
         new{T, SIT}(sdoptimizer, Dict{Int64, T}(), Dict{Int, T}(),
@@ -53,7 +49,6 @@ mutable struct SOItoMOIBridge{T, SIT <: AbstractSDOptimizer} <: MOI.AbstractOpti
             Vector{Tuple{Int, Int, Int, T}}[],
             Dict{CI, Int}(),
             Dict{CI, UnitRange{Int}}(),
-            Tuple{Int, Int, Int, T}[],
             CI[])
     end
 end
@@ -86,8 +81,7 @@ function MOI.is_empty(optimizer::SOItoMOIBridge)
     isempty(optimizer.free) &&
     isempty(optimizer.varmap) &&
     isempty(optimizer.zeroblock) &&
-    isempty(optimizer.constrmap) &&
-    isempty(optimizer.slackmap)
+    isempty(optimizer.constrmap)
 end
 function MOI.empty!(optimizer::SOItoMOIBridge{T}) where T
     for s in optimizer.double
@@ -107,37 +101,57 @@ function MOI.empty!(optimizer::SOItoMOIBridge{T}) where T
     optimizer.varmap = Vector{Tuple{Int, Int, Int, T}}[]
     optimizer.zeroblock = Dict{CI, Int}()
     optimizer.constrmap = Dict{CI, UnitRange{Int}}()
-    optimizer.slackmap = Tuple{Int, Int, Int, T}[]
 end
 
 function setconstant!(optimizer::SOItoMOIBridge, ci::CI, s) end
 function setconstant!(optimizer::SOItoMOIBridge, ci::CI, s::MOI.AbstractScalarSet)
     optimizer.setconstant[ci.value] = MOIU.getconstant(s)
 end
-function addsetconstant(optimizer::SOItoMOIBridge, ci::CI{<:Any, <:MOI.AbstractScalarSet}, x)
-    x + optimizer.setconstant[ci.value]
+function set_constant(optimizer::SOItoMOIBridge,
+                      ci::CI{<:MOI.AbstractScalarFunction,
+                             <:MOI.AbstractScalarSet})
+    return optimizer.setconstant[ci.value]
 end
-function addsetconstant(optimizer::SOItoMOIBridge, ci::CI, x)
-    x
+function set_constant(optimizer::SOItoMOIBridge{T}, ci::CI) where T
+    return zeros(T, length(optimizer.constrmap[ci]))
 end
 function addblkconstant(optimizer::SOItoMOIBridge, ci::CI{<:Any, <:Union{NS, PS}}, x)
     blk = -ci.value
-    x .+ optimizer.blkconstant[blk]
-end
-function addblkconstant(optimizer::SOItoMOIBridge, ci::CI, x)
-    x
+    return x .+ optimizer.blkconstant[blk]
 end
+addblkconstant(optimizer::SOItoMOIBridge, ci::CI, x) = x
 
-function MOI.supports(optimizer::SOItoMOIBridge{T},
-                      ::Union{MOI.ObjectiveSense,
-                              MOI.ObjectiveFunction{<:Union{MOI.SingleVariable,
-                                                            MOI.ScalarAffineFunction{T}}}}) where T
+function MOI.supports(
+    optimizer::SOItoMOIBridge{T},
+    ::Union{MOI.ObjectiveSense,
+            MOI.ObjectiveFunction{<:Union{MOI.SingleVariable,
+                                          MOI.ScalarAffineFunction{T}}}}) where T
     return true
 end
 
-function MOI.supports_constraint(::SOItoMOIBridge{T},
-                                 ::Type{<:Union{VF, AF{T}}},
-                                 ::Type{<:SupportedSets}) where T
+# Zeros and Nonpositives supports could be removed thanks to variable bridges
+# * `VectorOfVariables`-in-`Zeros` would return a `VectorAffineFunction` with
+#   zero constant and no variable created.
+# * `VectorOfVariables`-in-`Nonpositives` would create variables in
+#   `Nonnegatives` and return a `VectorAffineFunction` containing `-` the
+#    variables.
+function MOI.supports_constraint(
+    ::SOItoMOIBridge, ::Type{MOI.VectorOfVariables},
+    ::Type{<:Union{MOI.Zeros, MOI.Nonnegatives, MOI.Nonpositives,
+                   MOI.PositiveSemidefiniteConeTriangle}})
+    return true
+end
+# This support could be remove thanks to variable bridges.
+# The VectorizeVariableBridge would redirect to the above case and then the
+# resulting function would be shifted by the constant.
+function MOI.supports_constraint(
+    ::SOItoMOIBridge{T}, ::Type{MOI.SingleVariable},
+    ::Type{<:Union{MOI.EqualTo{T}, MOI.GreaterThan{T}, MOI.LessThan{T}}}) where T
+    return true
+end
+function MOI.supports_constraint(
+    ::SOItoMOIBridge{T}, ::Type{MOI.ScalarAffineFunction{T}},
+    ::Type{MOI.EqualTo{T}}) where T
     return true
 end
 
@@ -163,10 +177,10 @@ MOI.get(m::SOItoMOIBridge, s::SolverStatus) = MOI.get(m.sdoptimizer, s)
 MOI.get(m::SOItoMOIBridge, ::MOI.ResultCount) = 1
 
 function _getblock(M, blk::Integer, s::Type{<:Union{NS, ZS}})
-    diag(block(M, blk))
+    return diag(block(M, blk))
 end
 function _getblock(M, blk::Integer, s::Type{<:PS})
-    -diag(block(M, blk))
+    return -diag(block(M, blk))
 end
 # Vectorized length for matrix dimension d
 sympackedlen(d::Integer) = (d*(d+1)) >> 1
@@ -183,20 +197,22 @@ function _getblock(M::AbstractMatrix{T}, blk::Integer, s::Type{<:DS}) where T
         end
     end
     @assert k == n
-    v
+    return v
 end
 function getblock(M, blk::Integer, s::Type{<:MOI.AbstractScalarSet})
     vd = _getblock(M, blk, s)
     @assert length(vd) == 1
-    vd[1]
+    return vd[1]
 end
 function getblock(M, blk::Integer, s::Type{<:MOI.AbstractVectorSet})
-    _getblock(M, blk, s)
+    return _getblock(M, blk, s)
 end
 
 getvarprimal(m::SOItoMOIBridge, blk::Integer, S) = getblock(getX(m.sdoptimizer), blk, S)
 function getvardual(m::SOItoMOIBridge, blk::Integer, S)
-    getblock(getZ(m.sdoptimizer), blk, S)
+    z = getZ(m.sdoptimizer)
+    b = getblock(z, blk, S)
+    return getblock(getZ(m.sdoptimizer), blk, S)
 end
 
 function MOI.get(m::SOItoMOIBridge{T}, ::MOI.VariablePrimal, vi::VI) where T
@@ -208,41 +224,29 @@ function MOI.get(m::SOItoMOIBridge{T}, ::MOI.VariablePrimal, vi::VI) where T
             x += block(X, blk)[i, j] * sign(coef)
         end
     end
-    x
+    return x
 end
 function MOI.get(m::SOItoMOIBridge, vp::MOI.VariablePrimal, vi::Vector{VI})
-    MOI.get.(m, vp, vi)
+    return MOI.get.(m, vp, vi)
 end
 
 function _getattribute(m::SOItoMOIBridge, ci::CI{<:ASF}, f)
     cs = m.constrmap[ci]
     @assert length(cs) == 1
-    f(m, first(cs))
-end
-function _getattribute(m::SOItoMOIBridge, ci::CI{<:AVF}, f)
-    f.(m, m.constrmap[ci])
+    return f(m, first(cs))
 end
-
-function getslack(m::SOItoMOIBridge{T}, c::Integer) where T
-    X = getX(m.sdoptimizer)
-    blk, i, j, coef = m.slackmap[c]
-    if iszero(blk)
-        zero(T)
-    else
-        if i != j
-            coef *= 2 # We should take block(X, blk)[i, j] + block(X, blk)[j, i] but they are equal
-        end
-        coef * block(X, blk)[i, j]
-    end
+function _getattribute(m::SOItoMOIBridge, ci::CI{<:VVF}, f)
+    return f.(m, m.constrmap[ci])
 end
 
-function MOI.get(m::SOItoMOIBridge, a::MOI.ConstraintPrimal, ci::CI{F, S}) where {F, S}
+function MOI.get(m::SOItoMOIBridge, a::MOI.ConstraintPrimal,
+                 ci::CI{F, S}) where {F, S}
     if ci.value >= 0
-        addsetconstant(m, ci, _getattribute(m, ci, getslack))
+        return set_constant(m, ci)
     else
         # Variable Function-in-S with S different from Zeros and EqualTo and not a double variable constraint
         blk = -ci.value
-        addblkconstant(m, ci, getvarprimal(m, blk, S))
+        return addblkconstant(m, ci, getvarprimal(m, blk, S))
     end
 end
 
@@ -254,7 +258,7 @@ function getvardual(m::SOItoMOIBridge{T}, vi::VI) where T
             z += block(Z, blk)[i, j] * sign(coef)
         end
     end
-    z
+    return z
 end
 getvardual(m::SOItoMOIBridge, f::SVF) = getvardual(m, f.variable)
 getvardual(m::SOItoMOIBridge, f::VVF) = map(vi -> getvardual(m, vi), f.variables)
@@ -263,26 +267,26 @@ getvardual(m::SOItoMOIBridge, f::VVF) = map(vi -> getvardual(m, vi), f.variables
 #end
 function MOI.get(m::SOItoMOIBridge, ::MOI.ConstraintDual, ci::CI{<:VF, S}) where S<:SupportedSets
     if ci.value < 0
-        getvardual(m, -ci.value, S)
+        return getvardual(m, -ci.value, S)
     else
         dual = _getattribute(m, ci, getdual)
         if haskey(m.zeroblock, ci) # ZS
-            dual + getvardual(m, m.zeroblock[ci], S)
+            return dual + getvardual(m, m.zeroblock[ci], S)
         else # var constraint on unfree constraint
-            dual
+            return dual
         end
     end
 end
 
 function getdual(m::SOItoMOIBridge{T}, c::Integer) where T
     if c == 0
-        zero(T)
+        return zero(T)
     else
-        -gety(m.sdoptimizer)[c]
+        return -gety(m.sdoptimizer)[c]
     end
 end
 function MOI.get(m::SOItoMOIBridge, ::MOI.ConstraintDual, ci::CI)
-    _getattribute(m, ci, getdual)
+    return _getattribute(m, ci, getdual)
 end
 function scalevec!(v, c)
     d = div(isqrt(1+8length(v))-1, 2)
@@ -294,11 +298,11 @@ function scalevec!(v, c)
         end
         i += j
     end
-    v
+    return v
 end
 function MOI.get(m::SOItoMOIBridge{T}, ::MOI.ConstraintDual,
-                 ci::CI{<:AF{T}, DS}) where T
-    scalevec!(_getattribute(m, ci, getdual), one(T)/2)
+                 ci::CI{<:SAF{T}, DS}) where T
+    return scalevec!(_getattribute(m, ci, getdual), one(T)/2)
 end
 
 include("sdpa.jl")
diff --git a/src/constraint.jl b/src/constraint.jl
index d635977..30ec041 100644
--- a/src/constraint.jl
+++ b/src/constraint.jl
@@ -1,32 +1,5 @@
-function createslack!(m::SOItoMOIBridge{T}, cs, ::ZS) where T
-    m.slackmap[cs] .= ((0, 0, 0, zero(T)),)
-end
-function createslack!(m::SOItoMOIBridge, cs, ::S) where S <: Union{NS, PS}
-    blk = newblock(m, -length(cs))
-    for (i, c) in enumerate(cs)
-        m.slackmap[c] = (blk, i, i, vscaling(S))
-    end
-end
-function createslack!(m::SOItoMOIBridge{T}, cs, ::DS) where T
-    d = getmatdim(length(cs))
-    k = 0
-    blk = newblock(m, d)
-    for i in 1:d
-        for j in 1:i
-            k += 1
-            m.slackmap[cs[k]] = (blk, i, j, i == j ? one(T) : one(T)/2)
-        end
-    end
-end
-
-function createslack!(m::SOItoMOIBridge, ci::CI, f, s)
-    cs = m.constrmap[ci]
-    createslack!(m, cs, s)
-end
-
 nconstraints(f::Union{SVF, SAF}, s) = 1
 nconstraints(f::VVF, s) = length(f.variables)
-nconstraints(f::VAF, s) = MOI.output_dimension(f)
 
 function _allocate_constraint(m::SOItoMOIBridge, f, s)
     ci = CI{typeof(f), typeof(s)}(m.nconstrs)
@@ -35,27 +8,12 @@ function _allocate_constraint(m::SOItoMOIBridge, f, s)
     #m.constrmap[ci] = m.nconstrs .+ (1:n)
     m.constrmap[ci] = (m.nconstrs + 1):(m.nconstrs + n)
     m.nconstrs += n
-    resize!(m.slackmap, m.nconstrs)
-    createslack!(m, ci, f, s)
-    ci
+    return ci
 end
-function MOIU.allocate_constraint(m::SOItoMOIBridge, f::AF, s::SupportedSets)
+function MOIU.allocate_constraint(m::SOItoMOIBridge, f::SAF, s::SupportedSets)
     _allocate_constraint(m::SOItoMOIBridge, f, s)
 end
 
-function loadslack!(m::SOItoMOIBridge, c::Integer)
-    blk, i, j, coef = m.slackmap[c]
-    if blk != 0
-        @assert !iszero(coef)
-        setconstraintcoefficient!(m.sdoptimizer, -coef, c, blk, i, j)
-    end
-end
-function loadslacks!(m::SOItoMOIBridge, cs)
-    for c in cs
-        loadslack!(m, c)
-    end
-end
-
 output_index(::MOI.ScalarAffineTerm)  = 1
 output_index(t::MOI.VectorAffineTerm) = t.output_index
 scalar_term(t::MOI.ScalarAffineTerm) = t
@@ -64,7 +22,7 @@ scalar_term(t::MOI.VectorAffineTerm) = t.scalar_term
 _getconstant(m::SOItoMOIBridge, s::MOI.AbstractScalarSet) = MOIU.getconstant(s)
 _getconstant(m::SOItoMOIBridge{T}, s::MOI.AbstractSet) where T = zero(T)
 
-function loadcoefficients!(m::SOItoMOIBridge, cs::UnitRange, f::AF, s)
+function loadcoefficients!(m::SOItoMOIBridge, cs::UnitRange, f::SAF, s)
     f = MOIU.canonical(f) # sum terms with same variables and same outputindex
     if !isempty(cs)
         rhs = _getconstant(m, s) .- MOI._constant(f)
@@ -92,10 +50,9 @@ function loadcoefficients!(m::SOItoMOIBridge, cs::UnitRange, f::AF, s)
     end
 end
 
-function MOIU.load_constraint(m::SOItoMOIBridge, ci::CI, f::AF, s::SupportedSets)
+function MOIU.load_constraint(m::SOItoMOIBridge, ci::CI, f::SAF, s::SupportedSets)
     setconstant!(m, ci, s)
     cs = m.constrmap[ci]
     @assert !isempty(cs)
-    loadslacks!(m, cs)
     loadcoefficients!(m, cs, f, s)
 end
diff --git a/src/mock.jl b/src/mock.jl
index 5a9065d..2c6c3a4 100644
--- a/src/mock.jl
+++ b/src/mock.jl
@@ -6,8 +6,8 @@ nblocks(bm::BlockMatrix) = length(bm.blocks)
 block(bm::BlockMatrix, i::Integer) = bm.blocks[i]
 
 function Base.size(bm::AbstractBlockMatrix)
-    n = sum(blk -> Compat.LinearAlgebra.checksquare(block(bm, blk)),
-            1:nblocks(bm))
+    n = Compat.mapreduce(blk -> Compat.LinearAlgebra.checksquare(block(bm, blk)),
+                         +, 1:nblocks(bm), init=0)
     return (n, n)
 end
 function Base.getindex(bm::AbstractBlockMatrix, i::Integer, j::Integer)
diff --git a/src/variable.jl b/src/variable.jl
index eea3de4..7bcb2df 100644
--- a/src/variable.jl
+++ b/src/variable.jl
@@ -6,7 +6,6 @@ function newblock(m::SOItoMOIBridge, n)
 end
 
 isfree(m, v::VI) = v.value in m.free
-isfree(m, v::Vector{VI}) = all(isfree.(m, v))
 function unfree(m, v)
     @assert isfree(m, v)
     delete!(m.free, v.value)
@@ -61,20 +60,27 @@ function _constraintvariable!(m::SOItoMOIBridge{T}, vs::VIS, ::DS) where T
 end
 _var(f::SVF) = f.variable
 _var(f::VVF) = f.variables
+function _throw_error_if_unfree(m, vi::MOI.VariableIndex)
+    if !isfree(m, vi)
+        error("A variable cannot be constrained by multiple ",
+              "`MOI.SingleVariable` or `MOI.VectorOfVariables` constraints.")
+    end
+end
+function _throw_error_if_unfree(m, vis::MOI.Vector)
+    for vi in vis
+        _throw_error_if_unfree(m, vi)
+    end
+end
 function MOIU.allocate_constraint(m::SOItoMOIBridge{T}, f::VF, s::SupportedSets) where T
     vis = _var(f)
-    fr = isfree(m, vis)
-    if fr
-        blk = _constraintvariable!(m, vis, s)
-        if isa(s, ZS)
-            ci = _allocate_constraint(m, f, s)
-            m.zeroblock[ci] = blk
-            ci
-        else
-            CI{typeof(f), typeof(s)}(-blk)
-        end
+    _throw_error_if_unfree(m, vis)
+    blk = _constraintvariable!(m, vis, s)
+    if isa(s, ZS)
+        ci = _allocate_constraint(m, f, s)
+        m.zeroblock[ci] = blk
+        return ci
     else
-        _allocate_constraint(m, f, s)
+        return CI{typeof(f), typeof(s)}(-blk)
     end
 end
 
@@ -85,7 +91,6 @@ function MOIU.load_constraint(m::SOItoMOIBridge, ci::CI, f::VF, s::SupportedSets
         setconstant!(m, ci, s)
         cs = m.constrmap[ci]
         @assert !isempty(cs)
-        loadslacks!(m, cs)
         for k in 1:length(cs)
             vm = varmap(m, _var(f, k))
             # For free variables, the length of vm is 2, clearly not the case here
diff --git a/test/contconic.jl b/test/contconic.jl
index 78871c6..a833d29 100644
--- a/test/contconic.jl
+++ b/test/contconic.jl
@@ -1,135 +1,132 @@
-@testset "MOI Continuous Conic" begin
-    @testset "Linear" begin
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[1.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 2.0], [2.8924 0.0; 0.0 1.8924], [2.3501 0.0; 0.0 2.3501], [3.6263 0.0; 0.0 1.6263]],
-                                                                    [3.0, 1.0, -0.0, -2.0, -0.0]))
-        MOIT.lin1ftest(cached_mock_optimizer, config)
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[1.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 2.0]],
-                                                                    [3.0, 1.0]))
-        MOIT.lin1vtest(cached_mock_optimizer, config)
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[16.0], [3.0], [13.9279 0.0; 0.0 17.9279], [14.3814 0.0; 0.0 17.3814], [25.3959 0.0; 0.0 9.3959], [15.8211 0.0; 0.0 15.8211]],
-                                                                    [-7.0, -2.0, 4.0, -7.0, -0.0, 0.0]))
-        MOIT.lin2ftest(cached_mock_optimizer, config)
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[0.0], [16.0], [3.0], [75.9147 0.0; 0.0 79.9147]],
-                                                                    [70.2006, -7.0, -2.0, 4.0]))
-        MOIT.lin2vtest(cached_mock_optimizer, config)
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    MOI.INFEASIBLE,
-                                                                    MOI.INFEASIBLE_POINT,
-                                                                    [-0.5, 0.5]))
-        MOIT.lin3test(cached_mock_optimizer, config)
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    MOI.INFEASIBLE,
-                                                                    MOI.INFEASIBLE_POINT,
-                                                                    [-1.0]))
-        MOIT.lin4test(cached_mock_optimizer, config)
-    end
-    @testset "SOC" begin
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[1.0 0.7071 0.7071; 0.7071 1.0 -0.0; 0.7071 -0.0 1.0], [2.2375 0.0; 0.0 1.2375], [2.0662 0.0; 0.0 1.3591], [2.0662 0.0; 0.0 1.3591]],
-                                                                    [1.4142, -0.7071, 1.0, -0.3536, 1.0, -0.7071, -0.3536]))
-        MOIT.soc1ftest(MOIB.SOCtoPSD{Float64}(cached_mock_optimizer), config)
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[1.0 0.7071 0.7071; 0.7071 1.0 -0.0; 0.7071 -0.0 1.0], [2.2375 0.0; 0.0 1.2375], [2.0662 0.0; 0.0 1.3591], [2.0662 0.0; 0.0 1.3591]],
-                                                                    [1.4142, -0.7071, 1.0, -0.3536, 1.0, -0.7071, -0.3536]))
-        MOIT.soc1vtest(MOIB.SOCtoPSD{Float64}(cached_mock_optimizer), config)
+@testset "Linear" begin
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[1.0 0 0; 0 0 0; 0 0 2.0], [2.89241 0; 0 1.89241], [2.35008 0; 0 2.35008], [3.62629 0; 0 1.62629]],
+        [0.0, -2.0, 0.0, 3.0, 1.0]))
+    MOIT.lin1ftest(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[1.0 0.0 0.0; 0.0 0.0 0.0; 0.0 0.0 2.0]],
+        [3.0, 1.0]))
+    MOIT.lin1vtest(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[16.0], [3.0], [13.9279 0.0; 0.0 17.9279], [14.3814 0.0; 0.0 17.3814], [25.3959 0.0; 0.0 9.3959], [15.8211 0.0; 0.0 15.8211]],
+        [-7.0, -2.0, 4.0, 0.0, 0.0, -7.0]))
+    MOIT.lin2ftest(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[0.0], [16.0], [3.0], [75.9147 0.0; 0.0 79.9147]],
+        [-7.0, -2.0, 4.0, 70.2306]))
+    MOIT.lin2vtest(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        MOI.INFEASIBLE, MOI.INFEASIBLE_POINT, [-0.5, 0.5]))
+    MOIT.lin3test(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        MOI.INFEASIBLE, MOI.INFEASIBLE_POINT, [-1.0]))
+    MOIT.lin4test(bridged, config)
+end
+@testset "SOC" begin
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[1.0 0.7071 0.7071; 0.7071 1.0 -0.0; 0.7071 -0.0 1.0], [2.2375 0.0; 0.0 1.2375], [2.0662 0.0; 0.0 1.3591], [2.0662 0.0; 0.0 1.3591]],
+        [1.4142, -0.7071, 1.0, -0.3536, 1.0, -0.7071, -0.3536]))
+    MOIT.soc1ftest(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[1.0 0.7071 0.7071; 0.7071 1.0 -0.0; 0.7071 -0.0 1.0], [2.2375 0.0; 0.0 1.2375], [2.0662 0.0; 0.0 1.3591], [2.0662 0.0; 0.0 1.3591]],
+        [1.4142, -0.7071, 1.0, -0.3536, 1.0, -0.7071, -0.3536]))
+    MOIT.soc1vtest(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[0.0], [1.0 -0.7071 0.7071; -0.7071 1.0 0.0; 0.7071 0.0 1.0], [0.4046 0.0; 0.0 1.1117], [1.0895 0.0; 0.0 0.3824], [1.3079 0.0; 0.0 0.3079]],
+        [-1, -√2, -√2/2, -1, -√2/4, 1, √2/2, -√2/4]))
+    MOIT.soc2ntest(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[0.0], [1.0 -0.7071 0.7071; -0.7071 1.0 0.0; 0.7071 0.0 1.0], [0.4046 0.0; 0.0 1.1117], [1.0895 0.0; 0.0 0.3824], [1.3079 0.0; 0.0 0.3079]],
+        [1, -√2, -√2/2, -1, -√2/4, 1, √2/2, -√2/4]))
+    MOIT.soc2ptest(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                                MOI.INFEASIBLE,
+                                                                MOI.INFEASIBLE_POINT,
+                                                                [-1.0, 1.0, -0.5, 1.0, -0.5]))
+    MOIT.soc3test(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                                [[1.0 0.8944 0.4472; 0.8944 1.0 0.0; 0.4472 0.0 1.0], [1.9332 0.0; 0.0 0.9332], [1.868 0.0; 0.0 0.9736], [1.5795 0.0; 0.0 1.1323], [1.868 0.0; 0.0 0.9736], [1.5795 0.0; 0.0 1.1323]],
+                                                                [2.2361, 2.0, 1.0, -1.118, 2.0, -0.8944, 1.0, -0.8944, -0.2236]))
+    MOIT.soc4test(bridged, config)
+end
+@testset "RSOC" begin
         MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[0.0], [1.0 -0.7071 0.7071; -0.7071 1.0 0.0; 0.7071 0.0 1.0], [0.4046 0.0; 0.0 1.1117], [1.0895 0.0; 0.0 0.3824], [1.3079 0.0; 0.0 0.3079]],
-                                                                    [-1.4142, -1.0, -0.7071, -1.0, -0.3536, 1.0, 0.7071, -0.3536]))
-        MOIT.soc2ntest(MOIB.SOCtoPSD{Float64}(cached_mock_optimizer), config)
+                                                                    [[0.5 0.7071 0.7071; 0.7071 2.0 0.0; 0.7071 0.0 2.0], [0.8667 0.0; 0.0 0.1596], [0.8667 0.0; 0.0 0.1596]],
+                                                                    [-1.4142, 1.0, -0.1768, 1.0, -0.3536, -0.1768]))
+        MOIT.rotatedsoc1ftest(bridged, config)
         MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[0.0], [1.0 -0.7071 0.7071; -0.7071 1.0 0.0; 0.7071 0.0 1.0], [0.4046 0.0; 0.0 1.1117], [1.0895 0.0; 0.0 0.3824], [1.3079 0.0; 0.0 0.3079]],
-                                                                    [-1.4142, 1.0, -0.7071, -1.0, -0.3536, 1.0, 0.7071, -0.3536]))
-        MOIT.soc2ptest(MOIB.SOCtoPSD{Float64}(cached_mock_optimizer), config)
+                                                                    [[0.0], [0.0], [0.5 0.7071 0.7071; 0.7071 2.0 0.0; 0.7071 0.0 2.0], [2.6164 0.0; 0.0 1.9093], [2.6164 0.0; 0.0 1.9093]],
+                                                                    [5183.15, 5182.44, -1.4142, 1.0, -0.1768, 1.0, -0.3536, -0.1768]))
+        MOIT.rotatedsoc1vtest(bridged, config)
         MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                     MOI.INFEASIBLE,
-                                                                    MOI.INFEASIBLE_POINT,
-                                                                    [-1.0, 1.0, -0.5, 1.0, -0.5]))
-        MOIT.soc3test(MOIB.SOCtoPSD{Float64}(cached_mock_optimizer), config)
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[1.0 0.8944 0.4472; 0.8944 1.0 0.0; 0.4472 0.0 1.0], [1.9332 0.0; 0.0 0.9332], [1.868 0.0; 0.0 0.9736], [1.5795 0.0; 0.0 1.1323], [1.868 0.0; 0.0 0.9736], [1.5795 0.0; 0.0 1.1323]],
-                                                                    [2.2361, 2.0, 1.0, -1.118, 2.0, -0.8944, 1.0, -0.8944, -0.2236]))
-        MOIT.soc4test(MOIB.SOCtoPSD{Float64}(cached_mock_optimizer), config)
-    end
-    @testset "RSOC" begin
-            MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                        [[0.5 0.7071 0.7071; 0.7071 2.0 0.0; 0.7071 0.0 2.0], [0.8667 0.0; 0.0 0.1596], [0.8667 0.0; 0.0 0.1596]],
-                                                                        [-1.4142, 1.0, -0.1768, 1.0, -0.3536, -0.1768]))
-            MOIT.rotatedsoc1ftest(MOIB.RSOCtoPSD{Float64}(cached_mock_optimizer), config)
-            MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                        [[0.0], [0.0], [0.5 0.7071 0.7071; 0.7071 2.0 0.0; 0.7071 0.0 2.0], [2.6164 0.0; 0.0 1.9093], [2.6164 0.0; 0.0 1.9093]],
-                                                                        [5183.15, 5182.44, -1.4142, 1.0, -0.1768, 1.0, -0.3536, -0.1768]))
-            MOIT.rotatedsoc1vtest(MOIB.RSOCtoPSD{Float64}(cached_mock_optimizer), config)
-            MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                        MOI.INFEASIBLE,
-                                                                        tuple(),
-                                                                        [141.088, -47.8864, 47.5533, -46.2201]))
-            MOIT.rotatedsoc2test(MOIB.RSOCtoPSD{Float64}(cached_mock_optimizer), config)
-            MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                        [[0.0], [0.0], [3.0], [0.0], [1.0 0.0; 0.0 0.0], [0.7071 1.0 0.0001; 1.0 1.4142 -0.0; 0.0001 -0.0 1.4142], [0.7071 1.7321; 1.7321 4.2426], [4.5908 0.0; 0.0 2.8588]],
-                                                                        [0.0, 0.0, 0.2887, -0.6124, 0.866, -0.3062, 0.0, -0.0001, -0.0, -1.2247, 1.0, -0.2041]))
-            MOIT.rotatedsoc3test(MOIB.RSOCtoPSD{Float64}(cached_mock_optimizer), config)
-    end
-    @testset "GeoMean" begin
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[0.0], [0.0], [1.4142 2.0; 2.0 2.8284], [1.0 1.4142; 1.4142 2.0], [1.0 1.4142; 1.4142 2.0], [1.8324 0.0; 0.0 0.8324], [1.7758 0.0; 0.0 0.7758], [1.7772 0.0; 0.0 0.7772], [1.7728 0.0; 0.0 0.7728], [2.5017 0.0; 0.0 0.5017], [2.0744 0.0; 0.0 0.6602], [2.0671 0.0; 0.0 0.6529]],
-                                                                    [1.0, 0.3333, -0.4714, 0.6667, -0.2357, -0.3333, 0.4714, -0.1667, -0.3333, 0.4714, -0.1667]))
-        MOIT.geomean1ftest(MOIB.GeoMean{Float64}(MOIB.RSOCtoPSD{Float64}(cached_mock_optimizer)), config)
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[0.0], [0.0], [1.4142 2.0; 2.0 2.8284], [1.0 1.4142; 1.4142 2.0], [1.0 1.4142; 1.4142 2.0], [1.8324 0.0; 0.0 0.8324], [1.7758 0.0; 0.0 0.7758], [1.7772 0.0; 0.0 0.7772], [1.7728 0.0; 0.0 0.7728], [2.5017 0.0; 0.0 0.5017], [2.0744 0.0; 0.0 0.6602], [2.0671 0.0; 0.0 0.6529]],
-                                                                    [1.0, 0.3333, -0.4714, 0.6667, -0.2357, -0.3333, 0.4714, -0.1667, -0.3333, 0.4714, -0.1667]))
-        MOIT.geomean1vtest(MOIB.GeoMean{Float64}(MOIB.RSOCtoPSD{Float64}(cached_mock_optimizer)), config)
-    end
-    @testset "PSD" begin
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[1.0 1.0; 1.0 1.0], [2.2633 0.0; 0.0 1.2633], [2.2669 0.0; 0.0 1.2669], [2.2633 0.0; 0.0 1.2633]],
-                                                                    [-2.0, -1.0, 2.0, -1.0]))
-        MOIT.psdt0ftest(cached_mock_optimizer, config)
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[1.0 1.0; 1.0 1.0]],
-                                                                    [-2.0]))
-        MOIT.psdt0vtest(cached_mock_optimizer, config)
-        # PSD1: see comments in MOI/src/Test/contconic.jl to see where these constants come from
-        δ = √(1 + (3*√2+2)*√(-116*√2+166) / 14) / 2
-        ε = √((1 - 2*(√2-1)*δ^2) / (2-√2))
-        y2 = 1 - ε*δ
-        y1 = 1 - √2*y2
-        obj = y1 + y2/2
-        k = -2*δ/ε
-        x2 = ((3-2obj)*(2+k^2)-4) / (4*(2+k^2)-4*√2)
-        α = √(3-2obj-4x2)/2
-        β = k*α
-        Xv = [α^2, α*β, β^2, α^2, α*β, α^2]
-        xv = [√2*x2, x2, x2]
-        cX0 = 1+(√2-1)*y2
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[Xv[1] Xv[2] Xv[1]; Xv[2] Xv[3] Xv[2]; Xv[1] Xv[2] Xv[1]],
-                                                                    [0.254409 0.179895 0.179895; 0.179895 0.254409 0.0; 0.179895 0.0 0.254409],
-                                                                    [0.349485 0; 0 0.132235],
-                                                                    [0.114062 0; 0 0.374032],
-                                                                    [0.419535 0; 0 0.108444],
-                                                                    [0.313002 0; 0 0.0957514],
-                                                                    [0.114062 0; 0 0.374032],
-                                                                    [0.349485 0; 0 0.132235],
-                                                                    [0.354357 0; 0 0.0999473],
-                                                                    [0.332125 0; 0 0.152231],
-                                                                    [0.332125 0; 0 0.152231]],
-                                                                    [y2*√2-1, -y2, -cX0, -1.35619, -cX0, 2y2, -1.35619, -cX0, -y2/√2, y2, -y2/√2/2, y2, -y2/√2, -y2/√2/2]))
-        MOIT.psdt1ftest(MOIB.SOCtoPSD{Float64}(cached_mock_optimizer), config)
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[Xv[1] Xv[2] Xv[1]; Xv[2] Xv[3] Xv[2]; Xv[1] Xv[2] Xv[1]],
-                                                                     [xv[1] xv[2] xv[2]; xv[2] xv[1] 0.0; xv[2] 0.0 xv[1]],
-                                                                     [0.486623 0; 0 0.486623-xv[1]],
-                                                                     [0.4475 0; 0 0.4475-xv[2]],
-                                                                     [0.4475 0; 0 0.4475-xv[2]]],
-                                                                    [y2*√2-1, -y2, -y2/√2, y2, -y2/√2/2, y2, -y2/√2, -y2/√2/2]))
-        MOIT.psdt1vtest(MOIB.SOCtoPSD{Float64}(cached_mock_optimizer), config)
-        MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                    [[0.0], [20/3 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 10/3 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.0], [4.0981 -2.1213; -2.1213 1.0981], [7.3275 0.0; 0.0 0.6608], [1.7945 0.0; 0.0 1.7945], [4.1881 0.0; 0.0 0.8547], [1.7945 0.0; 0.0 1.7945], [1.7945 0.0; 0.0 1.7945], [1.7945 0.0; 0.0 1.7945], [2.8504 0.0; 0.0 0.9485]],
-                                                                    [0.0, -0.1902, -0.0, 0.126, -0.0, 0.1426, 0.1426, 0.0127, -0.2113, -0.8165, -0.7887]))
-        MOIT.psdt2test(cached_mock_optimizer, config)
-    end
+                                                                    tuple(),
+                                                                    [141.088, -47.8864, 47.5533, -46.2201]))
+        MOIT.rotatedsoc2test(bridged, config)
+        # FIXME u >= 0.0 followed by u <= ub. We need to drop support for
+        #       SingleVariable-in-LessThan but we need variable bridge otherwise,
+        #       it creates a slack
+#            MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+#                                                                        [[0.0], [0.0], [3.0], [0.0], [1.0 0.0; 0.0 0.0], [0.7071 1.0 0.0001; 1.0 1.4142 -0.0; 0.0001 -0.0 1.4142], [0.7071 1.7321; 1.7321 4.2426], [4.5908 0.0; 0.0 2.8588]],
+#                                                                        [0.0, 0.0, 0.2887, -0.6124, 0.866, -0.3062, 0.0, -0.0001, -0.0, -1.2247, 1.0, -0.2041]))
+#            MOIT.rotatedsoc3test(bridged, config)
+end
+@testset "GeoMean" begin
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                                [[0.0], [0.0], [1.4142 2.0; 2.0 2.8284], [1.0 1.4142; 1.4142 2.0], [1.0 1.4142; 1.4142 2.0], [1.8324 0.0; 0.0 0.8324], [1.7758 0.0; 0.0 0.7758], [1.7772 0.0; 0.0 0.7772], [1.7728 0.0; 0.0 0.7728], [2.5017 0.0; 0.0 0.5017], [2.0744 0.0; 0.0 0.6602], [2.0671 0.0; 0.0 0.6529]],
+                                                                [1.0, 0.3333, -0.4714, 0.6667, -0.2357, -0.3333, 0.4714, -0.1667, -0.3333, 0.4714, -0.1667]))
+    MOIT.geomean1ftest(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                                [[0.0], [0.0], [1.4142 2.0; 2.0 2.8284], [1.0 1.4142; 1.4142 2.0], [1.0 1.4142; 1.4142 2.0], [1.8324 0.0; 0.0 0.8324], [1.7758 0.0; 0.0 0.7758], [1.7772 0.0; 0.0 0.7772], [1.7728 0.0; 0.0 0.7728], [2.5017 0.0; 0.0 0.5017], [2.0744 0.0; 0.0 0.6602], [2.0671 0.0; 0.0 0.6529]],
+                                                                [1.0, 0.3333, -0.4714, 0.6667, -0.2357, -0.3333, 0.4714, -0.1667, -0.3333, 0.4714, -0.1667]))
+    MOIT.geomean1vtest(bridged, config)
+end
+@testset "PSD" begin
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[1.0 1.0; 1.0 1.0], [2.2633 0.0; 0.0 1.2633], [2.2669 0.0; 0.0 1.2669], [2.2633 0.0; 0.0 1.2633]],
+        [-1.0, 2.0, -1.0, -2.0]))
+    MOIT.psdt0ftest(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[1.0 1.0; 1.0 1.0]],
+        [-2.0]))
+    MOIT.psdt0vtest(bridged, config)
+    # PSD1: see comments in MOI/src/Test/contconic.jl to see where these constants come from
+    δ = √(1 + (3*√2+2)*√(-116*√2+166) / 14) / 2
+    ε = √((1 - 2*(√2-1)*δ^2) / (2-√2))
+    y2 = 1 - ε*δ
+    y1 = 1 - √2*y2
+    obj = y1 + y2/2
+    k = -2*δ/ε
+    x2 = ((3-2obj)*(2+k^2)-4) / (4*(2+k^2)-4*√2)
+    α = √(3-2obj-4x2)/2
+    β = k*α
+    Xv = [α^2, α*β, β^2, α^2, α*β, α^2]
+    xv = [√2*x2, x2, x2]
+    cX0 = 1+(√2-1)*y2
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[Xv[1] Xv[2] Xv[1]; Xv[2] Xv[3] Xv[2]; Xv[1] Xv[2] Xv[1]],
+        [0.254409 0.179895 0.179895; 0.179895 0.254409 0.0; 0.179895 0.0 0.254409],
+        [0.349485 0; 0 0.132235],
+        [0.114062 0; 0 0.374032],
+        [0.419535 0; 0 0.108444],
+        [0.313002 0; 0 0.0957514],
+        [0.114062 0; 0 0.374032],
+        [0.349485 0; 0 0.132235],
+        [0.354357 0; 0 0.0999473],
+        [0.332125 0; 0 0.152231],
+        [0.332125 0; 0 0.152231]],
+        [-cX0, -1.35619, -cX0, 2y2, -1.35619, -cX0, -y2/√2, y2, -y2/√2/2, y2, -y2/√2, -y2/√2/2, y2*√2-1, -y2]))
+    MOIT.psdt1ftest(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[Xv[1] Xv[2] Xv[1]; Xv[2] Xv[3] Xv[2]; Xv[1] Xv[2] Xv[1]],
+         [xv[1] xv[2] xv[2]; xv[2] xv[1] 0.0; xv[2] 0.0 xv[1]],
+         [0.486623 0; 0 0.486623-xv[1]],
+         [0.4475 0; 0 0.4475-xv[2]],
+         [0.4475 0; 0 0.4475-xv[2]]],
+        [-y2/√2, y2, -y2/√2/2, y2, -y2/√2, -y2/√2/2, y2*√2-1, -y2]))
+    MOIT.psdt1vtest(bridged, config)
+    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+        [[0.0], [20/3 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 10/3 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.0; 0.0 0.0 0.0 0.0 0.0 0.0], [4.0981 -2.1213; -2.1213 1.0981], [7.3275 0.0; 0.0 0.6608], [1.7945 0.0; 0.0 1.7945], [4.1881 0.0; 0.0 0.8547], [1.7945 0.0; 0.0 1.7945], [1.7945 0.0; 0.0 1.7945], [1.7945 0.0; 0.0 1.7945], [2.8504 0.0; 0.0 0.9485]],
+        [-0.190192, 0, 0.125977, 0, 0.142644, 0.142644, 0.0127405, -0.211325, -0.816497, -0.788675, 0]))
+    MOIT.psdt2test(bridged, config)
 end
diff --git a/test/contlinear.jl b/test/contlinear.jl
index ec2b7e4..8380ae3 100644
--- a/test/contlinear.jl
+++ b/test/contlinear.jl
@@ -1,40 +1,42 @@
 @testset "MOI Continuous Linear" begin
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[1.0], [0.0], [0.0]],
-                                                                [1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[1.0], [0.0], [0.0]],
-                                                                [1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0], [1.0], [0.0]],
-                                                                [2.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0], [2.0], [0.0]],
-                                                                [2.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [1.0], [0.0], [0.0]],
-                                                                [54.4045, 1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [2.0], [0.0]],
-                                                                [61.2652, 1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0], [2.0]],
-                                                                [79.6537, 2.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [1.0], [1.0], [0.0]],
-                                                                [30.9277, 1.5, -0.5]))
-    MOIT.linear1test(cached_mock_optimizer, config)
+    # FIXME `ListOfVariableIndices` is not modified by bridges
+    #       see https://github.com/JuliaOpt/MathOptInterface.jl/issues/693
+#    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[1.0], [0.0], [0.0]],
+#                                                                [1.0]),
+#                                  (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[1.0], [0.0], [0.0]],
+#                                                                [1.0]),
+#                                  (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[0.0], [0.0], [1.0], [0.0]],
+#                                                                [2.0]),
+#                                  (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[0.0], [0.0], [2.0], [0.0]],
+#                                                                [2.0]),
+#                                  (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[0.0], [1.0], [0.0], [0.0]],
+#                                                                [54.4045, 1.0]),
+#                                  (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[0.0], [2.0], [0.0]],
+#                                                                [61.2652, 1.0]),
+#                                  (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[0.0], [0.0], [2.0]],
+#                                                                [79.6537, 2.0]),
+#                                  (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[0.0], [1.0], [1.0], [0.0]],
+#                                                                [30.9277, 1.5, -0.5]))
+#    MOIT.linear1test(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[1.0], [0.0], [0.0]],
                                                                 [1.0]))
-    MOIT.linear2test(cached_mock_optimizer, config)
+    MOIT.linear2test(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[3.0], [0.0]],
                                                                 [-1.0]),
                                   (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0], [3.0]],
                                                                 [-0.0]))
-    MOIT.linear3test(cached_mock_optimizer, config)
+    MOIT.linear3test(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0], [0.0]],
                                                                 [-0.0]),
@@ -44,7 +46,7 @@
                                   (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0], [0.0]],
                                                                 [-0.0]))
-    MOIT.linear4test(cached_mock_optimizer, config)
+    MOIT.linear4test(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[1.3333], [1.3333], [0.0], [0.0]],
                                                                 [0.3333, 0.3333]),
@@ -57,7 +59,7 @@
                                   (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[2.0], [0.0]],
                                                                 [0.5]))
-    MOIT.linear5test(cached_mock_optimizer, config)
+    MOIT.linear5test(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0], [0.0], [0.0 0.0; 0.0 0.0], [0.0 0.0; 0.0 0.0]],
                                                                 [-1.0, 1.0]),
@@ -67,7 +69,7 @@
                                   (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0], [0.0], [250.152 0.0; 0.0 150.152], [150.152 0.0; 0.0 250.152]],
                                                                 [-1.0, 1.0]))
-    MOIT.linear6test(cached_mock_optimizer, config)
+    MOIT.linear6test(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0], [0.0], [0.0 0.0; 0.0 0.0], [0.0 0.0; 0.0 0.0]],
                                                                 [-1.0, 1.0]),
@@ -77,59 +79,65 @@
                                   (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0], [0.0], [250.152 0.0; 0.0 150.152], [150.152 0.0; 0.0 250.152]],
                                                                 [-1.0, 1.0]))
-    MOIT.linear7test(cached_mock_optimizer, config)
+    MOIT.linear7test(bridged, config)
 
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 MOI.INFEASIBLE,
                                                                 tuple(),
                                                                 [1.0]))
-    MOIT.linear8atest(cached_mock_optimizer, config)
+    MOIT.linear8atest(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 MOI.DUAL_INFEASIBLE,
                                                                 (MOI.INFEASIBILITY_CERTIFICATE, [[0.7709], [0.2291], [0.3126]])))
-    MOIT.linear8btest(cached_mock_optimizer, config)
+    MOIT.linear8btest(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 MOI.DUAL_INFEASIBLE,
                                                                 (MOI.INFEASIBILITY_CERTIFICATE, [[0.5], [0.5]])))
-    MOIT.linear8ctest(cached_mock_optimizer, config)
+    MOIT.linear8ctest(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[29.0909], [36.3636], [4.5455], [0.0], [0.0001]],
                                                                 [-0.0, 11.3636, 0.8636]))
-    MOIT.linear9test(cached_mock_optimizer, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[5.0], [5.0], [5.0], [0.0]],
-                                                                [-0.0, 1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[2.5], [2.5], [0.0], [5.0]],
-                                                                [-1.0, 0.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[1.0], [1.0], [0.0], [10.0]],
-                                                                [-1.0, -0.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[6.0], [6.0], [10.0], [0.0]],
-                                                                [-0.0, 1.0]))
-    MOIT.linear10test(MOIB.SplitInterval{Float64}(cached_mock_optimizer), config)
+    MOIT.linear9test(bridged, config)
+    # FIXME 5 <= x + y <= 10 is bridged into x + y - z == 0, 5 <= z <= 10 and
+    # then it tries to add two SingleVariable constraints to `z`. We should drop
+    # support for MOI.LessThan once variables bridges works.
+#    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[5.0], [5.0], [5.0], [0.0]],
+#                                                                [-0.0, 1.0]),
+#                                  (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[2.5], [2.5], [0.0], [5.0]],
+#                                                                [-1.0, 0.0]),
+#                                  (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[1.0], [1.0], [0.0], [10.0]],
+#                                                                [-1.0, -0.0]),
+#                                  (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[6.0], [6.0], [10.0], [0.0]],
+#                                                                [-0.0, 1.0]))
+#    MOIT.linear10test(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[1.0], [0.0], [3.2439 0.0; 0.0 2.2439], [3.2439 0.0; 0.0 2.2439]],
                                                                 [0.0, -1.0]),
                                   (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0], [1.0], [1.3765 0.0; 0.0 0.8765], [1.3765 0.0; 0.0 0.8765]],
                                                                 [-1.0, 0.0]))
-    MOIT.linear11test(cached_mock_optimizer, config)
+    MOIT.linear11test(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 MOI.INFEASIBLE,
                                                                 tuple(),
                                                                 [1.0, 3.0]))
-    MOIT.linear12test(cached_mock_optimizer, config)
+    MOIT.linear12test(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[24.0266], [27.6758 0.0; 0.0 22.6705], [27.6758 0.0; 0.0 22.6705]],
                                                                 [0.0, 0.0]))
-    MOIT.linear13test(cached_mock_optimizer, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.5], [1.0], [0.0], [0.0]],
-                                                                [2.0, 1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[1.0], [0.0]],
-                                                                [1.0]))
-    MOIT.linear14test(cached_mock_optimizer, config)
+    MOIT.linear13test(bridged, config)
+    # FIXME z >= 0.0 followed by z <= 1.0. We need to drop support for
+    #       SingleVariable-in-LessThan but we need variable bridge otherwise,
+    #       it creates a slack
+#    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[0.0], [0.5], [1.0], [0.0], [0.0]],
+#                                                                [2.0, 1.0]),
+#                                  (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[1.0], [0.0]],
+#                                                                [1.0]))
+#    MOIT.linear14test(bridged, config)
 end
diff --git a/test/mock_tests_generator.ipynb b/test/mock_tests_generator.ipynb
index 17ba8fc..0b239c2 100644
--- a/test/mock_tests_generator.ipynb
+++ b/test/mock_tests_generator.ipynb
@@ -9,7 +9,7 @@
     "using SemidefiniteOptInterface\n",
     "const SDOI = SemidefiniteOptInterface\n",
     "\n",
-    "using Base.Test\n",
+    "using Test\n",
     "\n",
     "using MathOptInterface\n",
     "const MOI = MathOptInterface\n",
@@ -29,13 +29,15 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "metadata": {
-    "collapsed": true
-   },
+   "metadata": {},
    "outputs": [],
    "source": [
     "const MOIU = MOI.Utilities\n",
-    "MOIU.@model SDModelData () (EqualTo, GreaterThan, LessThan) (Zeros, Nonnegatives, Nonpositives, PositiveSemidefiniteConeTriangle) () (SingleVariable,) (ScalarAffineFunction,) (VectorOfVariables,) (VectorAffineFunction,)"
+    "MOIU.@model(SDModelData,\n",
+    "    (), (MOI.EqualTo, MOI.GreaterThan, MOI.LessThan),\n",
+    "    (MOI.Zeros, MOI.Nonnegatives, MOI.Nonpositives, MOI.PositiveSemidefiniteConeTriangle), (),\n",
+    "    (MOI.SingleVariable,), (MOI.ScalarAffineFunction,),\n",
+    "    (MOI.VectorOfVariables,), ())"
    ]
   },
   {
@@ -45,10 +47,11 @@
    "outputs": [],
    "source": [
     "import CSDP\n",
-    "optimizer = CSDP.CSDPOptimizer(printlevel=0)\n",
+    "optimizer = CSDP.Optimizer(printlevel=0)\n",
     "\n",
-    "cached_optimizer = MOIU.CachingOptimizer(SDModelData{Float64}(), optimizer)\n",
-    "bridged_optimizer = MOIB.SplitInterval{Float64}(MOIB.RootDet{Float64}(MOIB.GeoMean{Float64}(MOIB.RSOCtoPSD{Float64}(MOIB.SOCtoPSD{Float64}(cached_optimizer)))))\n",
+    "cache = MOIU.UniversalFallback(SDModelData{Float64}())\n",
+    "cached = MOIU.CachingOptimizer(cache, optimizer)\n",
+    "bridged = MOIB.full_bridge_optimizer(cached, Float64)\n",
     "\n",
     "config = MOIT.TestConfig(atol=1e-4, rtol=1e-4)"
    ]
@@ -56,7 +59,9 @@
   {
    "cell_type": "code",
    "execution_count": null,
-   "metadata": {},
+   "metadata": {
+    "collapsed": true
+   },
    "outputs": [],
    "source": [
     "function MOI.optimize!(m::SDOI.SOItoMOIBridge)\n",
@@ -64,10 +69,10 @@
     "    X = SDOI.getX(m.sdoptimizer)\n",
     "    println(\"MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,\")\n",
     "    print(  \"                                                            \")\n",
-    "    if MOI.get(m, MOI.DualStatus()) == MOI.InfeasibilityCertificate\n",
+    "    if MOI.get(m, MOI.DualStatus()) == MOI.INFEASIBILITY_CERTIFICATE\n",
     "        print(\"tuple()\")\n",
     "    else\n",
-    "        if MOI.get(m, MOI.PrimalStatus()) == MOI.InfeasibilityCertificate\n",
+    "        if MOI.get(m, MOI.PrimalStatus()) == MOI.INFEASIBILITY_CERTIFICATE\n",
     "            print(\"(MOI.InfeasibilityCertificate, \")\n",
     "        end\n",
     "        print(  \"[\")\n",
@@ -79,11 +84,11 @@
     "            print(SDOI.block(X, blk))\n",
     "        end\n",
     "        print(\"]\")\n",
-    "        if MOI.get(m, MOI.PrimalStatus()) == MOI.InfeasibilityCertificate\n",
+    "        if MOI.get(m, MOI.PrimalStatus()) == MOI.INFEASIBILITY_CERTIFICATE\n",
     "            print(\")\")\n",
     "        end\n",
     "    end\n",
-    "    if MOI.get(m, MOI.PrimalStatus()) != MOI.InfeasibilityCertificate\n",
+    "    if MOI.get(m, MOI.PrimalStatus()) != MOI.INFEASIBILITY_CERTIFICATE\n",
     "        println(\",\")\n",
     "        print(  \"                                                            \")\n",
     "        #print(round.(SDOI.gety(m.sdoptimizer), 4))\n",
@@ -93,18 +98,6 @@
     "end"
    ]
   },
-  {
-   "cell_type": "code",
-   "execution_count": null,
-   "metadata": {},
-   "outputs": [],
-   "source": [
-    "mock = SDOI.MockSDOptimizer{Float64}()\n",
-    "mock_optimizer = SDOI.SDOIOptimizer(mock, Float64)\n",
-    "cached_mock_optimizer = MOIU.CachingOptimizer(SDModelData{Float64}(), mock_optimizer)\n",
-    "config = MOIT.TestConfig(atol=1e-4, rtol=1e-4)"
-   ]
-  },
   {
    "cell_type": "code",
    "execution_count": null,
@@ -112,9 +105,9 @@
    "outputs": [],
    "source": [
     "function generate_mock_test(testfun)\n",
-    "    testfun(bridged_optimizer, config)\n",
-    "    testcall = replace(string(testfun), \"MathOptInterface.Test\", \"MOIT\")\n",
-    "    println(\"$testcall(cached_mock_optimizer, config)\")\n",
+    "    testfun(bridged, config)\n",
+    "    testcall = replace(string(testfun), \"MathOptInterface.Test\" => \"MOIT\")\n",
+    "    println(\"$testcall(bridged, config)\")\n",
     "end"
    ]
   },
@@ -124,7 +117,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "generate_mock_test(MOIT.solve_singlevariable_obj)"
+    "generate_mock_test(MOIT.psdt0ftest)"
    ]
   },
   {
@@ -133,7 +126,7 @@
    "metadata": {},
    "outputs": [],
    "source": [
-    "for testfun in map(p -> p.second, sort(collect(MOIT.psdttests), by=p->p.first))\n",
+    "for testfun in map(p -> p.second, sort(collect(MOIT.lintests), by=p->p.first))\n",
     "    generate_mock_test(testfun)\n",
     "end"
    ]
@@ -146,19 +139,34 @@
    },
    "outputs": [],
    "source": []
+  },
+  {
+   "cell_type": "code",
+   "execution_count": null,
+   "metadata": {
+    "collapsed": true
+   },
+   "outputs": [],
+   "source": [
+    "mock = SDOI.MockSDOptimizer{Float64}()\n",
+    "mock_optimizer = SDOI.SDOIOptimizer(mock, Float64)\n",
+    "cached = MOIU.CachingOptimizer(SDModelData{Float64}(), mock_optimizer)\n",
+    "bridged = MOIB.full_bridge_optimizer(cached, Float64)\n",
+    "config = MOIT.TestConfig(atol=1e-4, rtol=1e-4)"
+   ]
   }
  ],
  "metadata": {
   "kernelspec": {
-   "display_name": "Julia 0.6.3",
+   "display_name": "Julia 1.1.0",
    "language": "julia",
-   "name": "julia-0.6"
+   "name": "julia-1.1"
   },
   "language_info": {
    "file_extension": ".jl",
    "mimetype": "application/julia",
    "name": "julia",
-   "version": "0.6.4"
+   "version": "1.1.0"
   }
  },
  "nbformat": 4,
diff --git a/test/runtests.jl b/test/runtests.jl
index dbd2d74..a94698f 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -21,7 +21,7 @@ MOIU.@model(SDModelData,
             (MOI.SingleVariable,),
             (MOI.ScalarAffineFunction,),
             (MOI.VectorOfVariables,),
-            (MOI.VectorAffineFunction,))
+            ())
 
 mock = SDOI.MockSDOptimizer{Float64}()
 mock_optimizer = SDOI.SDOIOptimizer(mock, Float64)
@@ -29,15 +29,18 @@ mock_optimizer = SDOI.SDOIOptimizer(mock, Float64)
     @test MOIU.supports_allocate_load(mock_optimizer, false)
     @test !MOIU.supports_allocate_load(mock_optimizer, true)
 end
-cached_mock_optimizer = MOIU.CachingOptimizer(SDModelData{Float64}(),
-                                              mock_optimizer)
+cached = MOIU.CachingOptimizer(SDModelData{Float64}(), mock_optimizer)
+bridged = MOIB.full_bridge_optimizer(cached, Float64)
 @testset "SolverName" begin
-    @test MOI.get(       mock,           MOI.SolverName()) == "MockSD"
-    @test MOI.get(       mock_optimizer, MOI.SolverName()) == "MockSD"
-    @test MOI.get(cached_mock_optimizer, MOI.SolverName()) == "MockSD"
+    @test MOI.get(mock,           MOI.SolverName()) == "MockSD"
+    @test MOI.get(mock_optimizer, MOI.SolverName()) == "MockSD"
+    @test MOI.get(cached,         MOI.SolverName()) == "MockSD"
+    @test MOI.get(bridged,        MOI.SolverName()) == "MockSD"
 end
 config = MOIT.TestConfig(atol=1e-4, rtol=1e-4)
 
 include("unit.jl")
 include("contlinear.jl")
-include("contconic.jl")
+@testset "MOI Continuous Conic" begin
+    include("contconic.jl")
+end
diff --git a/test/unit.jl b/test/unit.jl
index aa1a07a..5018507 100644
--- a/test/unit.jl
+++ b/test/unit.jl
@@ -1,13 +1,13 @@
 @testset "Unit" begin
-    MOIT.add_variable(cached_mock_optimizer, config)
-    MOIT.add_variables(cached_mock_optimizer, config)
-    MOIT.delete_variable(cached_mock_optimizer, config)
-    MOIT.delete_variable(cached_mock_optimizer, config)
-    MOIT.feasibility_sense(cached_mock_optimizer, config)
-    MOIT.getconstraint(cached_mock_optimizer, config)
-    MOIT.getvariable(cached_mock_optimizer, config)
-    MOIT.max_sense(cached_mock_optimizer, config)
-    MOIT.min_sense(cached_mock_optimizer, config)
+    MOIT.add_variable(bridged, config)
+    MOIT.add_variables(bridged, config)
+    MOIT.delete_variable(bridged, config)
+    MOIT.delete_variable(bridged, config)
+    MOIT.feasibility_sense(bridged, config)
+    MOIT.getconstraint(bridged, config)
+    MOIT.getvariable(bridged, config)
+    MOIT.max_sense(bridged, config)
+    MOIT.min_sense(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0], [0.0 0; 0 0.0]],
                                                                 [1.0]),
@@ -23,38 +23,44 @@
                                   (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0], [4.47626 0; 0 2.47626]],
                                                                 [1.0]))
-    MOIT.solve_affine_deletion_edge_cases(cached_mock_optimizer, config)
+    MOIT.solve_affine_deletion_edge_cases(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[1.72037 0; 0 1.22037]],
                                                                 [-0.5]))
-    MOIT.solve_affine_equalto(cached_mock_optimizer, config)
+    MOIT.solve_affine_equalto(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0], [2.10102 0; 0 1.60102]],
                                                                 [-0.5]))
-    MOIT.solve_affine_greaterthan(cached_mock_optimizer, config)
+    MOIT.solve_affine_greaterthan(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[3.0], [0.0], [4.88931 0; 0 2.88931]],
                                                                 [0.0, 1.5]))
-    MOIT.solve_affine_interval(MOIB.SplitInterval{Float64}(cached_mock_optimizer), config)
+    MOIT.solve_affine_interval(MOIB.SplitInterval{Float64}(bridged), config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0], [2.06719 0; 0 1.56719]],
                                                                 [0.5]))
-    MOIT.solve_affine_lessthan(cached_mock_optimizer, config)
+    MOIT.solve_affine_lessthan(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0]],
                                                                 [0.0]))
-    MOIT.solve_constant_obj(cached_mock_optimizer, config)
+    MOIT.solve_constant_obj(bridged, config)
     MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
                                                                 [[0.0]],
                                                                 [0.0]))
-    MOIT.solve_singlevariable_obj(cached_mock_optimizer, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [1.0]],
-                                                                [0.0]))
-    MOIT.solve_with_lowerbound(cached_mock_optimizer, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[1.0], [0.0]],
-                                                                [2.0]))
-    MOIT.solve_with_upperbound(cached_mock_optimizer, config)
-    MOIT.variablenames(cached_mock_optimizer, config)
+    MOIT.solve_singlevariable_obj(bridged, config)
+    # FIXME x >= 1.0 followed by x <= 2.0. We need to drop support for
+    #       SingleVariable-in-LessThan but we need variable bridge otherwise,
+    #       it creates a slack
+#    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[0.0], [1.0]],
+#                                                                [0.0]))
+#    MOIT.solve_with_lowerbound(bridged, config)
+    # FIXME x <= 1.0 followed by x >= 0.0. We need to drop support for
+    #       SingleVariable-in-LessThan but we need variable bridge otherwise,
+    #       it creates a slack
+#    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+#                                                                [[1.0], [0.0]],
+#                                                                [2.0]))
+#    MOIT.solve_with_upperbound(bridged, config)
+    MOIT.variablenames(bridged, config)
 end

From 8345da931c4862fca7a2c0f893836e6586b10d6d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Legat?= <benoit.legat@gmail.com>
Date: Sun, 10 Mar 2019 23:39:38 +0100
Subject: [PATCH 2/6] Move testset to runtests.jl

---
 test/contlinear.jl | 192 ++++++++++++++++++++++-----------------------
 test/runtests.jl   |   8 +-
 test/unit.jl       | 113 +++++++++++++-------------
 3 files changed, 157 insertions(+), 156 deletions(-)

diff --git a/test/contlinear.jl b/test/contlinear.jl
index 8380ae3..99d8802 100644
--- a/test/contlinear.jl
+++ b/test/contlinear.jl
@@ -1,6 +1,5 @@
-@testset "MOI Continuous Linear" begin
-    # FIXME `ListOfVariableIndices` is not modified by bridges
-    #       see https://github.com/JuliaOpt/MathOptInterface.jl/issues/693
+# FIXME `ListOfVariableIndices` is not modified by bridges
+#       see https://github.com/JuliaOpt/MathOptInterface.jl/issues/693
 #    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
 #                                                                [[1.0], [0.0], [0.0]],
 #                                                                [1.0]),
@@ -26,81 +25,81 @@
 #                                                                [[0.0], [1.0], [1.0], [0.0]],
 #                                                                [30.9277, 1.5, -0.5]))
 #    MOIT.linear1test(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[1.0], [0.0], [0.0]],
-                                                                [1.0]))
-    MOIT.linear2test(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[3.0], [0.0]],
-                                                                [-1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [3.0]],
-                                                                [-0.0]))
-    MOIT.linear3test(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0]],
-                                                                [-0.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0]],
-                                                                [-0.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0]],
-                                                                [-0.0]))
-    MOIT.linear4test(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[1.3333], [1.3333], [0.0], [0.0]],
-                                                                [0.3333, 0.3333]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[2.0], [0.0], [0.0], [2.0]],
-                                                                [0.5, -0.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[4.0], [0.0], [0.0]],
-                                                                [1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[2.0], [0.0]],
-                                                                [0.5]))
-    MOIT.linear5test(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0], [0.0 0.0; 0.0 0.0], [0.0 0.0; 0.0 0.0]],
-                                                                [-1.0, 1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0], [168.953 0.0; 0.0 68.9528], [107.78 0.0; 0.0 107.78]],
-                                                                [-1.0, 1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0], [250.152 0.0; 0.0 150.152], [150.152 0.0; 0.0 250.152]],
-                                                                [-1.0, 1.0]))
-    MOIT.linear6test(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0], [0.0 0.0; 0.0 0.0], [0.0 0.0; 0.0 0.0]],
-                                                                [-1.0, 1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0], [168.953 0.0; 0.0 68.9528], [107.78 0.0; 0.0 107.78]],
-                                                                [-1.0, 1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0], [250.152 0.0; 0.0 150.152], [150.152 0.0; 0.0 250.152]],
-                                                                [-1.0, 1.0]))
-    MOIT.linear7test(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[1.0], [0.0], [0.0]],
+                                                            [1.0]))
+MOIT.linear2test(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[3.0], [0.0]],
+                                                            [-1.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [3.0]],
+                                                            [-0.0]))
+MOIT.linear3test(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [0.0]],
+                                                            [-0.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [0.0]],
+                                                            [-0.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [0.0]],
+                                                            [-0.0]))
+MOIT.linear4test(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[1.3333], [1.3333], [0.0], [0.0]],
+                                                            [0.3333, 0.3333]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[2.0], [0.0], [0.0], [2.0]],
+                                                            [0.5, -0.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[4.0], [0.0], [0.0]],
+                                                            [1.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[2.0], [0.0]],
+                                                            [0.5]))
+MOIT.linear5test(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [0.0], [0.0 0.0; 0.0 0.0], [0.0 0.0; 0.0 0.0]],
+                                                            [-1.0, 1.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [0.0], [168.953 0.0; 0.0 68.9528], [107.78 0.0; 0.0 107.78]],
+                                                            [-1.0, 1.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [0.0], [250.152 0.0; 0.0 150.152], [150.152 0.0; 0.0 250.152]],
+                                                            [-1.0, 1.0]))
+MOIT.linear6test(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [0.0], [0.0 0.0; 0.0 0.0], [0.0 0.0; 0.0 0.0]],
+                                                            [-1.0, 1.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [0.0], [168.953 0.0; 0.0 68.9528], [107.78 0.0; 0.0 107.78]],
+                                                            [-1.0, 1.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [0.0], [250.152 0.0; 0.0 150.152], [150.152 0.0; 0.0 250.152]],
+                                                            [-1.0, 1.0]))
+MOIT.linear7test(bridged, config)
 
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                MOI.INFEASIBLE,
-                                                                tuple(),
-                                                                [1.0]))
-    MOIT.linear8atest(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                MOI.DUAL_INFEASIBLE,
-                                                                (MOI.INFEASIBILITY_CERTIFICATE, [[0.7709], [0.2291], [0.3126]])))
-    MOIT.linear8btest(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                MOI.DUAL_INFEASIBLE,
-                                                                (MOI.INFEASIBILITY_CERTIFICATE, [[0.5], [0.5]])))
-    MOIT.linear8ctest(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[29.0909], [36.3636], [4.5455], [0.0], [0.0001]],
-                                                                [-0.0, 11.3636, 0.8636]))
-    MOIT.linear9test(bridged, config)
-    # FIXME 5 <= x + y <= 10 is bridged into x + y - z == 0, 5 <= z <= 10 and
-    # then it tries to add two SingleVariable constraints to `z`. We should drop
-    # support for MOI.LessThan once variables bridges works.
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            MOI.INFEASIBLE,
+                                                            tuple(),
+                                                            [1.0]))
+MOIT.linear8atest(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            MOI.DUAL_INFEASIBLE,
+                                                            (MOI.INFEASIBILITY_CERTIFICATE, [[0.7709], [0.2291], [0.3126]])))
+MOIT.linear8btest(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            MOI.DUAL_INFEASIBLE,
+                                                            (MOI.INFEASIBILITY_CERTIFICATE, [[0.5], [0.5]])))
+MOIT.linear8ctest(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[29.0909], [36.3636], [4.5455], [0.0], [0.0001]],
+                                                            [-0.0, 11.3636, 0.8636]))
+MOIT.linear9test(bridged, config)
+# FIXME 5 <= x + y <= 10 is bridged into x + y - z == 0, 5 <= z <= 10 and
+# then it tries to add two SingleVariable constraints to `z`. We should drop
+# support for MOI.LessThan once variables bridges works.
 #    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
 #                                                                [[5.0], [5.0], [5.0], [0.0]],
 #                                                                [-0.0, 1.0]),
@@ -114,25 +113,25 @@
 #                                                                [[6.0], [6.0], [10.0], [0.0]],
 #                                                                [-0.0, 1.0]))
 #    MOIT.linear10test(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[1.0], [0.0], [3.2439 0.0; 0.0 2.2439], [3.2439 0.0; 0.0 2.2439]],
-                                                                [0.0, -1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [1.0], [1.3765 0.0; 0.0 0.8765], [1.3765 0.0; 0.0 0.8765]],
-                                                                [-1.0, 0.0]))
-    MOIT.linear11test(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                MOI.INFEASIBLE,
-                                                                tuple(),
-                                                                [1.0, 3.0]))
-    MOIT.linear12test(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[24.0266], [27.6758 0.0; 0.0 22.6705], [27.6758 0.0; 0.0 22.6705]],
-                                                                [0.0, 0.0]))
-    MOIT.linear13test(bridged, config)
-    # FIXME z >= 0.0 followed by z <= 1.0. We need to drop support for
-    #       SingleVariable-in-LessThan but we need variable bridge otherwise,
-    #       it creates a slack
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[1.0], [0.0], [3.2439 0.0; 0.0 2.2439], [3.2439 0.0; 0.0 2.2439]],
+                                                            [0.0, -1.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [1.0], [1.3765 0.0; 0.0 0.8765], [1.3765 0.0; 0.0 0.8765]],
+                                                            [-1.0, 0.0]))
+MOIT.linear11test(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            MOI.INFEASIBLE,
+                                                            tuple(),
+                                                            [1.0, 3.0]))
+MOIT.linear12test(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[24.0266], [27.6758 0.0; 0.0 22.6705], [27.6758 0.0; 0.0 22.6705]],
+                                                            [0.0, 0.0]))
+MOIT.linear13test(bridged, config)
+# FIXME z >= 0.0 followed by z <= 1.0. We need to drop support for
+#       SingleVariable-in-LessThan but we need variable bridge otherwise,
+#       it creates a slack
 #    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
 #                                                                [[0.0], [0.5], [1.0], [0.0], [0.0]],
 #                                                                [2.0, 1.0]),
@@ -140,4 +139,3 @@
 #                                                                [[1.0], [0.0]],
 #                                                                [1.0]))
 #    MOIT.linear14test(bridged, config)
-end
diff --git a/test/runtests.jl b/test/runtests.jl
index a94698f..bd4b48e 100644
--- a/test/runtests.jl
+++ b/test/runtests.jl
@@ -39,8 +39,12 @@ bridged = MOIB.full_bridge_optimizer(cached, Float64)
 end
 config = MOIT.TestConfig(atol=1e-4, rtol=1e-4)
 
-include("unit.jl")
-include("contlinear.jl")
+@testset "Unit" begin
+    include("unit.jl")
+end
+@testset "MOI Continuous Linear" begin
+    include("contlinear.jl")
+end
 @testset "MOI Continuous Conic" begin
     include("contconic.jl")
 end
diff --git a/test/unit.jl b/test/unit.jl
index 5018507..aa3fddb 100644
--- a/test/unit.jl
+++ b/test/unit.jl
@@ -1,66 +1,65 @@
-@testset "Unit" begin
-    MOIT.add_variable(bridged, config)
-    MOIT.add_variables(bridged, config)
-    MOIT.delete_variable(bridged, config)
-    MOIT.delete_variable(bridged, config)
-    MOIT.feasibility_sense(bridged, config)
-    MOIT.getconstraint(bridged, config)
-    MOIT.getvariable(bridged, config)
-    MOIT.max_sense(bridged, config)
-    MOIT.min_sense(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [0.0 0; 0 0.0]],
-                                                                [1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[1.0], [0.0], [0.624034 0; 0 0.624034]],
-                                                                [0.0, 1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [2.73683 0; 0 1.73683]],
-                                                                [1.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[1.88804e-9], [1.0], [3.25375 0; 0 2.25375]],
-                                                                [1.0, 0.0]),
-                                  (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [4.47626 0; 0 2.47626]],
-                                                                [1.0]))
-    MOIT.solve_affine_deletion_edge_cases(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[1.72037 0; 0 1.22037]],
-                                                                [-0.5]))
-    MOIT.solve_affine_equalto(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [2.10102 0; 0 1.60102]],
-                                                                [-0.5]))
-    MOIT.solve_affine_greaterthan(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[3.0], [0.0], [4.88931 0; 0 2.88931]],
-                                                                [0.0, 1.5]))
-    MOIT.solve_affine_interval(MOIB.SplitInterval{Float64}(bridged), config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0], [2.06719 0; 0 1.56719]],
-                                                                [0.5]))
-    MOIT.solve_affine_lessthan(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0]],
-                                                                [0.0]))
-    MOIT.solve_constant_obj(bridged, config)
-    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
-                                                                [[0.0]],
-                                                                [0.0]))
-    MOIT.solve_singlevariable_obj(bridged, config)
-    # FIXME x >= 1.0 followed by x <= 2.0. We need to drop support for
-    #       SingleVariable-in-LessThan but we need variable bridge otherwise,
-    #       it creates a slack
+MOIT.add_variable(bridged, config)
+MOIT.add_variables(bridged, config)
+MOIT.delete_variable(bridged, config)
+MOIT.delete_variable(bridged, config)
+MOIT.feasibility_sense(bridged, config)
+MOIT.getconstraint(bridged, config)
+MOIT.getvariable(bridged, config)
+MOIT.max_sense(bridged, config)
+MOIT.min_sense(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [0.0 0; 0 0.0]],
+                                                            [1.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[1.0], [0.0], [0.624034 0; 0 0.624034]],
+                                                            [0.0, 1.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [2.73683 0; 0 1.73683]],
+                                                            [1.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[1.88804e-9], [1.0], [3.25375 0; 0 2.25375]],
+                                                            [1.0, 0.0]),
+                              (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [4.47626 0; 0 2.47626]],
+                                                            [1.0]))
+MOIT.solve_affine_deletion_edge_cases(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[1.72037 0; 0 1.22037]],
+                                                            [-0.5]))
+MOIT.solve_affine_equalto(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [2.10102 0; 0 1.60102]],
+                                                            [-0.5]))
+MOIT.solve_affine_greaterthan(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[3.0], [0.0], [4.88931 0; 0 2.88931]],
+                                                            [0.0, 1.5]))
+MOIT.solve_affine_interval(MOIB.SplitInterval{Float64}(bridged), config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0], [2.06719 0; 0 1.56719]],
+                                                            [0.5]))
+MOIT.solve_affine_lessthan(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0]],
+                                                            [0.0]))
+MOIT.solve_constant_obj(bridged, config)
+MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
+                                                            [[0.0]],
+                                                            [0.0]))
+MOIT.solve_singlevariable_obj(bridged, config)
+# FIXME x >= 1.0 followed by x <= 2.0. We need to drop support for
+#       SingleVariable-in-LessThan but we need variable bridge otherwise,
+#       it creates a slack
 #    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
 #                                                                [[0.0], [1.0]],
 #                                                                [0.0]))
 #    MOIT.solve_with_lowerbound(bridged, config)
-    # FIXME x <= 1.0 followed by x >= 0.0. We need to drop support for
-    #       SingleVariable-in-LessThan but we need variable bridge otherwise,
-    #       it creates a slack
+# FIXME x <= 1.0 followed by x >= 0.0. We need to drop support for
+#       SingleVariable-in-LessThan but we need variable bridge otherwise,
+#       it creates a slack
 #    MOIU.set_mock_optimize!(mock, (mock) -> MOIU.mock_optimize!(mock,
 #                                                                [[1.0], [0.0]],
 #                                                                [2.0]))
 #    MOIT.solve_with_upperbound(bridged, config)
-    MOIT.variablenames(bridged, config)
+MOIT.variablenames(bridged, config)
 end

From 710137e9e762bfab97a27f3e50eb8a0e036a8eab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Legat?= <benoit.legat@gmail.com>
Date: Tue, 12 Mar 2019 01:55:29 +0100
Subject: [PATCH 3/6] Remove superfluous end

---
 test/unit.jl | 1 -
 1 file changed, 1 deletion(-)

diff --git a/test/unit.jl b/test/unit.jl
index aa3fddb..4b2e762 100644
--- a/test/unit.jl
+++ b/test/unit.jl
@@ -62,4 +62,3 @@ MOIT.solve_singlevariable_obj(bridged, config)
 #                                                                [2.0]))
 #    MOIT.solve_with_upperbound(bridged, config)
 MOIT.variablenames(bridged, config)
-end

From 0cec4660e0fd3377bd824eab151a8c1755db81e9 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Legat?= <benoit.legat@gmail.com>
Date: Tue, 12 Mar 2019 02:30:21 +0100
Subject: [PATCH 4/6] =?UTF-8?q?=F0=9F=94=A5=20Remove=20dead=20code?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 src/SemidefiniteOptInterface.jl | 16 ----------------
 1 file changed, 16 deletions(-)

diff --git a/src/SemidefiniteOptInterface.jl b/src/SemidefiniteOptInterface.jl
index a9eb9c1..369d419 100644
--- a/src/SemidefiniteOptInterface.jl
+++ b/src/SemidefiniteOptInterface.jl
@@ -288,22 +288,6 @@ end
 function MOI.get(m::SOItoMOIBridge, ::MOI.ConstraintDual, ci::CI)
     return _getattribute(m, ci, getdual)
 end
-function scalevec!(v, c)
-    d = div(isqrt(1+8length(v))-1, 2)
-    @assert div(d*(d+1), 2) == length(v)
-    i = 1
-    for j in 1:d
-        for k in i:(i+j-2)
-            v[k] *= c
-        end
-        i += j
-    end
-    return v
-end
-function MOI.get(m::SOItoMOIBridge{T}, ::MOI.ConstraintDual,
-                 ci::CI{<:SAF{T}, DS}) where T
-    return scalevec!(_getattribute(m, ci, getdual), one(T)/2)
-end
 
 include("sdpa.jl")
 include("mock.jl")

From 9c8fd10ce9589c23e259fafe715210ec510a14b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Legat?= <benoit.legat@gmail.com>
Date: Tue, 12 Mar 2019 03:23:44 +0100
Subject: [PATCH 5/6] Simplify code

---
 src/constraint.jl | 42 +++++++++++++-----------------------------
 src/variable.jl   |  3 +++
 2 files changed, 16 insertions(+), 29 deletions(-)

diff --git a/src/constraint.jl b/src/constraint.jl
index 30ec041..252a73a 100644
--- a/src/constraint.jl
+++ b/src/constraint.jl
@@ -14,40 +14,24 @@ function MOIU.allocate_constraint(m::SOItoMOIBridge, f::SAF, s::SupportedSets)
     _allocate_constraint(m::SOItoMOIBridge, f, s)
 end
 
-output_index(::MOI.ScalarAffineTerm)  = 1
-output_index(t::MOI.VectorAffineTerm) = t.output_index
-scalar_term(t::MOI.ScalarAffineTerm) = t
-scalar_term(t::MOI.VectorAffineTerm) = t.scalar_term
-
-_getconstant(m::SOItoMOIBridge, s::MOI.AbstractScalarSet) = MOIU.getconstant(s)
-_getconstant(m::SOItoMOIBridge{T}, s::MOI.AbstractSet) where T = zero(T)
-
-function loadcoefficients!(m::SOItoMOIBridge, cs::UnitRange, f::SAF, s)
+function loadcoefficients!(m::SOItoMOIBridge, cs::UnitRange,
+                           f::MOI.ScalarAffineFunction, s)
     f = MOIU.canonical(f) # sum terms with same variables and same outputindex
-    if !isempty(cs)
-        rhs = _getconstant(m, s) .- MOI._constant(f)
-        for t in f.terms
-            st = scalar_term(t)
-            if !iszero(st.coefficient)
-                c = cs[output_index(t)]
-                for (blk, i, j, coef, shift) in varmap(m, st.variable_index)
-                    if !iszero(blk)
-                        @assert !iszero(coef)
-                        setconstraintcoefficient!(m.sdoptimizer, st.coefficient*coef, c, blk, i, j)
-                    end
-                    if isa(rhs, Vector)
-                        rhs[output_index(t)] -= st.coefficient * shift
-                    else
-                        rhs -= st.coefficient * shift
-                    end
+    @assert length(cs) == 1
+    c = first(cs)
+    rhs = MOIU.getconstant(s) - MOI._constant(f)
+    for t in f.terms
+        if !iszero(t.coefficient)
+            for (blk, i, j, coef, shift) in varmap(m, t.variable_index)
+                if !iszero(blk)
+                    @assert !iszero(coef)
+                    setconstraintcoefficient!(m.sdoptimizer, t.coefficient*coef, c, blk, i, j)
                 end
+                rhs -= t.coefficient * shift
             end
         end
-        for j in 1:MOI.output_dimension(f)
-            c = cs[j]
-            setconstraintconstant!(m.sdoptimizer, rhs[j], c)
-        end
     end
+    setconstraintconstant!(m.sdoptimizer, rhs, c)
 end
 
 function MOIU.load_constraint(m::SOItoMOIBridge, ci::CI, f::SAF, s::SupportedSets)
diff --git a/src/variable.jl b/src/variable.jl
index 7bcb2df..f38e2de 100644
--- a/src/variable.jl
+++ b/src/variable.jl
@@ -84,6 +84,9 @@ function MOIU.allocate_constraint(m::SOItoMOIBridge{T}, f::VF, s::SupportedSets)
     end
 end
 
+_getconstant(m::SOItoMOIBridge, s::MOI.AbstractScalarSet) = MOIU.getconstant(s)
+_getconstant(m::SOItoMOIBridge{T}, s::MOI.AbstractSet) where T = zero(T)
+
 _var(f::SVF, j) = f.variable
 _var(f::VVF, j) = f.variables[j]
 function MOIU.load_constraint(m::SOItoMOIBridge, ci::CI, f::VF, s::SupportedSets)

From 66bde8349667bd65f3d44c640739c72763708950 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Legat?= <benoit.legat@gmail.com>
Date: Tue, 12 Mar 2019 03:26:21 +0100
Subject: [PATCH 6/6] Remove dead code

---
 src/SemidefiniteOptInterface.jl | 15 ---------------
 1 file changed, 15 deletions(-)

diff --git a/src/SemidefiniteOptInterface.jl b/src/SemidefiniteOptInterface.jl
index 369d419..c225969 100644
--- a/src/SemidefiniteOptInterface.jl
+++ b/src/SemidefiniteOptInterface.jl
@@ -250,21 +250,6 @@ function MOI.get(m::SOItoMOIBridge, a::MOI.ConstraintPrimal,
     end
 end
 
-function getvardual(m::SOItoMOIBridge{T}, vi::VI) where T
-    Z = getZ(m.sdoptimizer)
-    z = zero(T)
-    for (blk, i, j, coef) in varmap(m, vi)
-        if blk != 0
-            z += block(Z, blk)[i, j] * sign(coef)
-        end
-    end
-    return z
-end
-getvardual(m::SOItoMOIBridge, f::SVF) = getvardual(m, f.variable)
-getvardual(m::SOItoMOIBridge, f::VVF) = map(vi -> getvardual(m, vi), f.variables)
-#function MOI.get(m::SOItoMOIBridge, ::MOI.ConstraintDual, ci::CI{<:VF, S})
-#    _getattribute(m, ci, getdual) + getvardual(m, MOI.get(m, MOI.ConstraintFunction(), ci))
-#end
 function MOI.get(m::SOItoMOIBridge, ::MOI.ConstraintDual, ci::CI{<:VF, S}) where S<:SupportedSets
     if ci.value < 0
         return getvardual(m, -ci.value, S)