gt:                 stmt = connection.prepareStatement(GET_SUBMISSIONS_SQL);
context: package org.lakunu.web.dao.jdbc;
  
  import com.google.common.collect.ImmutableList;
  import org.lakunu.labs.Score;
  import org.lakunu.labs.utils.LabUtils;
  import org.lakunu.web.dao.DAOException;
  import org.lakunu.web.dao.SubmissionDAO;
  import org.lakunu.web.models.*;
  import org.lakunu.web.utils.Security;
  
  import javax.sql.DataSource;
  
  import java.sql.*;
  import java.util.LinkedHashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.stream.Collectors;
  import java.util.stream.IntStream;
  
  import static com.google.common.base.Preconditions.checkNotNull;
  import static com.google.common.base.Preconditions.checkState;
  
  public final class JdbcSubmissionDAO implements SubmissionDAO {
  
      private final DataSource dataSource;
  
      JdbcSubmissionDAO(DataSource dataSource) {
          checkNotNull(dataSource, "DataSource is required");
          this.dataSource = dataSource;
      }
  
      @Override
      public String addSubmission(Submission submission) {
          try {
              return AddSubmissionCommand.execute(dataSource, submission);
          } catch (SQLException e) {
              throw new DAOException("Error while submitting lab", e);
          }
      }
  
      @Override
      public Submission getSubmission(String submissionId) {
          try {
              return GetSubmissionCommand.execute(dataSource, submissionId);
          } catch (SQLException e) {
              throw new DAOException("Error while retrieving submission", e);
          }
      }
  
      @Override
      public ImmutableList<SubmissionView> getOwnedSubmissions(Lab lab, int limit) {
          try {
              return GetOwnedSubmissionsCommand.execute(dataSource, lab.getId(), limit);
          } catch (SQLException e) {
              throw new DAOException("Error while retrieving submissions", e);
          }
      }
  
      @Override
      public ImmutableList<SubmissionView> getSubmissionsByUser(Lab lab, String userId, int limit) {
          try {
              return GetSubmissionsByUserCommand.execute(dataSource, userId, lab.getId(), limit);
          } catch (SQLException e) {
              throw new DAOException("Error while retrieving submissions", e);
          }
      }
  
      @Override
      public ImmutableList<SubmissionView> getAllSubmissions(Lab lab) {
          try {
              return GetAllSubmissionsCommand.execute(dataSource, lab.getId());
          } catch (SQLException e) {
              throw new DAOException("Error while retrieving submissions", e);
          }
      }
  
      @Override
      public void enqueueSubmissions(ImmutableList<String> submissionIds) {
          try {
              EnqueueSubmissionsCommand.execute(dataSource, submissionIds);
          } catch (SQLException e) {
              throw new DAOException("Error while enqueueing submissions", e);
          }
      }
  
      private static final class AddSubmissionCommand extends TxCommand<String> {
  
          private static final String ADD_SUBMISSION_SQL = "INSERT INTO submission (user_id, " +
                  "lab_id, submitted_at, submission_type, submission_data) VALUES (?,?,?,?,?)";
          private static final String ENQUEUE_SUBMISSION_SQL =
                  "INSERT INTO job_queue (submission_id) VALUES (?)";
  
          private final Submission submission;
  
          private AddSubmissionCommand(DataSource dataSource, Submission submission) {
              super(dataSource);
              this.submission = submission;
          }
  
          private static String execute(DataSource dataSource,
                                        Submission submission) throws SQLException {
              return new AddSubmissionCommand(dataSource, submission).run();
          }
  
          @Override
          protected String doTransaction(Connection connection) throws SQLException {
              long submissionId;
              try (PreparedStatement stmt = connection.prepareStatement(ADD_SUBMISSION_SQL,
                      Statement.RETURN_GENERATED_KEYS)) {
                  stmt.setString(1, submission.getUserId());
                  stmt.setLong(2, Long.parseLong(submission.getLabId()));
                  stmt.setTimestamp(3, new Timestamp(submission.getSubmittedAt().getTime()));
                  stmt.setString(4, submission.getType());
                  stmt.setBytes(5, submission.getData());
                  int rows = stmt.executeUpdate();
                  checkState(rows == 1, "Failed to add the lab to database");
                  try (ResultSet rs = stmt.getGeneratedKeys()) {
                      if (rs.next()) {
                          submissionId = rs.getLong(1);
                      } else {
                          throw new IllegalStateException("Failed to retrieve new lab ID");
                      }
                  }
              }
  
              try (PreparedStatement stmt = connection.prepareStatement(ENQUEUE_SUBMISSION_SQL)) {
                  stmt.setLong(1, submissionId);
                  int rows = stmt.executeUpdate();
                  checkState(rows == 1, "Failed to enqueue the submission");
              }
              return String.valueOf(submissionId);
          }
      }
  
      private static final class EnqueueSubmissionsCommand extends Command<Void> {
  
          private final ImmutableList<Long> submissionIds;
  
          private EnqueueSubmissionsCommand(DataSource dataSource, List<String> submissionIds) {
              super(dataSource);
              this.submissionIds = submissionIds.stream().map(Long::parseLong)
                      .collect(LabUtils.immutableList());
          }
  
          private static void execute(DataSource dataSource,
                                      List<String> submissionIds) throws SQLException {
              new EnqueueSubmissionsCommand(dataSource, submissionIds).run();
          }
  
          @Override
          protected Void doRun(Connection connection) throws SQLException {
              if (submissionIds.isEmpty()) {
                  return null;
              }
  
              try (PreparedStatement stmt = connection.prepareStatement(
                      AddSubmissionCommand.ENQUEUE_SUBMISSION_SQL)) {
                  for (long id : submissionIds) {
                      stmt.setLong(1, id);
                      stmt.addBatch();
                  }
                  stmt.executeBatch();
              }
              return null;
          }
      }
  
      private static final class GetSubmissionCommand extends Command<Submission> {
  
          private static final String GET_SUBMISSION_SQL = "SELECT id, user_id, lab_id, submitted_at, " +
                  "submission_type, submission_data FROM submission WHERE id = ?";
  
          private final long submissionId;
  
          private GetSubmissionCommand(DataSource dataSource, String submissionId) {
              super(dataSource);
              this.submissionId = Long.parseLong(submissionId);
          }
  
          private static Submission execute(DataSource dataSource,
                                            String submissionId) throws SQLException {
              return new GetSubmissionCommand(dataSource, submissionId).run();
          }
  
          @Override
          protected Submission doRun(Connection connection) throws SQLException {
              try (PreparedStatement stmt = connection.prepareStatement(GET_SUBMISSION_SQL)) {
                  stmt.setLong(1, submissionId);
                  try (ResultSet rs = stmt.executeQuery()) {
                      if (rs.next()) {
                          return createSubmission(rs);
                      } else {
                          return null;
                      }
                  }
              }
          }
      }
  
      private static String prepareArrayQuery(String sql, int args) {
          String params = IntStream.range(0, args).mapToObj(i -> "?").collect(Collectors.joining(","));
          return String.format(sql, params);
      }
  
      private static class GetAllSubmissionsCommand extends Command<ImmutableList<SubmissionView>> {
  
          private static final String GET_SUBMISSIONS_SQL = "SELECT id, user_id, lab_id, submitted_at, " +
                  "submission_type FROM submission WHERE lab_id = ? ORDER BY submitted_at DESC";
  
          private static final String GET_EVALUATIONS_SQL = "SELECT id, submission_id, " +
                  "started_at, finished_at, finishing_status, log FROM evaluation WHERE " +
                  "submission_id IN (%s) ORDER BY finished_at DESC";
  
          private static final String GET_GRADES_SQL = "SELECT id, evaluation_id, label, score, " +
                  "score_limit FROM grade WHERE evaluation_id IN (%s)";
  
          protected final long labId;
  
          protected GetAllSubmissionsCommand(DataSource dataSource, String labId) {
              super(dataSource);
              this.labId = Long.parseLong(labId);
          }
  
          private static ImmutableList<SubmissionView> execute(DataSource dataSource,
                                                              String labId) throws SQLException {
              return new GetAllSubmissionsCommand(dataSource, labId).run();
          }
  
          protected PreparedStatement getStatement(Connection connection) throws SQLException {
              PreparedStatement stmt = null;
              try {
  