protected void solveConstraints(ContactSolverInfo solverInfo) {
    // sorted version of all btTypedConstraint, based on islandId
    sortedConstraints.clear();
    for (int i = 0; i < constraints.size(); i++) {
      sortedConstraints.add(constraints.getQuick(i));
    }
    // Collections.sort(sortedConstraints, sortConstraintOnIslandPredicate);
    MiscUtil.quickSort(sortedConstraints, sortConstraintOnIslandPredicate);

    ObjectArrayList<TypedConstraint> constraintsPtr =
        getNumConstraints() != 0 ? sortedConstraints : null;

    solverCallback.init(
        solverInfo,
        constraintSolver,
        constraintsPtr,
        sortedConstraints.size(),
        debugDrawer /*,m_stackAlloc*/,
        dispatcher1);

    constraintSolver.prepareSolve(
        getCollisionWorld().getNumCollisionObjects(),
        getCollisionWorld().getDispatcher().getNumManifolds());

    // solve all the constraints for this island
    islandManager.buildAndProcessIslands(
        getCollisionWorld().getDispatcher(),
        getCollisionWorld().getCollisionObjectArray(),
        solverCallback);

    constraintSolver.allSolved(solverInfo, debugDrawer /*, m_stackAlloc*/);
  }
    public void processIsland(
        ObjectArrayList<CollisionObject> bodies,
        int numBodies,
        ObjectArrayList<PersistentManifold> manifolds,
        int manifolds_offset,
        int numManifolds,
        int islandId) {
      if (islandId < 0) {
        // we don't split islands, so all constraints/contact manifolds/bodies are passed into the
        // solver regardless the island id
        solver.solveGroup(
            bodies,
            numBodies,
            manifolds,
            manifolds_offset,
            numManifolds,
            sortedConstraints,
            0,
            numConstraints,
            solverInfo,
            debugDrawer /*,m_stackAlloc*/,
            dispatcher);
      } else {
        // also add all non-contact constraints/joints for this island
        // ObjectArrayList<TypedConstraint> startConstraint = null;
        int startConstraint_idx = -1;
        int numCurConstraints = 0;
        int i;

        // find the first constraint for this island
        for (i = 0; i < numConstraints; i++) {
          if (getConstraintIslandId(sortedConstraints.getQuick(i)) == islandId) {
            // startConstraint = &m_sortedConstraints[i];
            // startConstraint = sortedConstraints.subList(i, sortedConstraints.size());
            startConstraint_idx = i;
            break;
          }
        }
        // count the number of constraints in this island
        for (; i < numConstraints; i++) {
          if (getConstraintIslandId(sortedConstraints.getQuick(i)) == islandId) {
            numCurConstraints++;
          }
        }

        // only call solveGroup if there is some work: avoid virtual function call, its overhead can
        // be excessive
        if ((numManifolds + numCurConstraints) > 0) {
          solver.solveGroup(
              bodies,
              numBodies,
              manifolds,
              manifolds_offset,
              numManifolds,
              sortedConstraints,
              startConstraint_idx,
              numCurConstraints,
              solverInfo,
              debugDrawer /*,m_stackAlloc*/,
              dispatcher);
        }
      }
    }