text: """
  Copyright 2016 Sascha-Dominic Schnug
  
  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at
  
      http://www.apache.org/licenses/LICENSE-2.0
  
  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.
  """
  
  import cvxpy.settings as s
  from cvxpy.constraints import NonPos, Zero
  from cvxpy.problems.problem_data.problem_data import ProblemData
  from cvxpy.reductions.solution import Solution
  import numpy as np
  
  from .conic_solver import ConicSolver
  
  
  class CBC(ConicSolver):
      """ An interface to the CBC solver
      """
  
      # Solver capabilities.
      MIP_CAPABLE = True
  
      # Map of GLPK MIP status to CVXPY status.
      STATUS_MAP_MIP = {'solution': s.OPTIMAL,
                        'relaxation infeasible': s.INFEASIBLE,
                        'stopped on user event': s.SOLVER_ERROR}
  
      STATUS_MAP_LP = {'optimal': s.OPTIMAL,
                       'primal infeasible': s.INFEASIBLE,
                       'stopped due to errors': s.SOLVER_ERROR,
                       'stopped by event handler (virtual int '
                       'ClpEventHandler::event())': s.SOLVER_ERROR}
  
      def name(self):
          """The name of the solver.
          """
          return s.CBC
  
      def import_solver(self):
          """Imports the solver.
          """
          from cylp.cy import CyClpSimplex
          CyClpSimplex  # For flake8
  
      def accepts(self, problem):
          """Can Cbc solve the problem?
          """
          # TODO check if is matrix stuffed.
          if not problem.objective.args[0].is_affine():
              return False
          for constr in problem.constraints:
              if type(constr) not in CBC.SUPPORTED_CONSTRAINTS:
                  return False
              for arg in constr.args:
                  if not arg.is_affine():
                      return False
          return True
  
      def apply(self, problem):
          """Returns a new problem and data for inverting the new solution.
  
          Returns
          -------
          tuple
              (dict of arguments needed for the solver, inverse data)
          """
          data = {}
          objective, _ = problem.objective.canonical_form
          constraints = [con for c in problem.constraints for con in c.canonical_form[1]]
          data["objective"] = objective
          data["constraints"] = constraints
          variables = problem.variables()[0]
          data[s.BOOL_IDX] = [int(t[0]) for t in variables.boolean_idx]
          data[s.INT_IDX] = [int(t[0]) for t in variables.integer_idx]
  
          # Order and group constraints.
          inv_data = {self.VAR_ID: problem.variables()[0].id}
          eq_constr = [c for c in problem.constraints if type(c) == Zero]
          inv_data[self.EQ_CONSTR] = eq_constr
          leq_constr = [c for c in problem.constraints if type(c) == NonPos]
          inv_data[self.NEQ_CONSTR] = leq_constr
          return data, inv_data
  
      def invert(self, solution, inverse_data):
          """Returns the solution to the original problem given the inverse_data.
          """
          status = solution['status']
  
          if status in s.SOLUTION_PRESENT:
              opt_val = solution['value']
              primal_vars = {inverse_data[self.VAR_ID]: solution['primal']}
          else:
              if status == s.INFEASIBLE:
                  opt_val = np.inf
              elif status == s.UNBOUNDED:
                  opt_val = -np.inf
              else:
                  opt_val = None
              primal_vars = None
          dual_vars = None
  
          return Solution(status, opt_val, primal_vars, dual_vars, {})
  
      def solve_via_data(self, data, warm_start, verbose, solver_opts, solver_cache=None):
          from cvxpy.problems.solvers.cbc_intf import CBC as CBC_OLD
          solver = CBC_OLD()
          solver_opts[s.BOOL_IDX] = data[s.BOOL_IDX]
          solver_opts[s.INT_IDX] = data[s.INT_IDX]
          return solver.solve(
              data["objective"],
              data["constraints"],
              {self.name(): ProblemData()},
              warm_start,
              verbose,
              solver_opts)
  