private void syncTable(Connection scon, Connection dcon, Table srcTable, Table dstTable,
                                  Map<String, List<Object>> filters, boolean delete) throws Exception {
        Table lcd = findLcd(srcTable, dstTable);
        String sql = lcd.writeHashedQuery(filters);
        //int i = 0; // TODO: Threading and progress indicator
        try (PreparedStatement stmt = scon.prepareStatement(sql); PreparedStatement dtmt = dcon.prepareStatement(sql)) {
            // Set filter parameters
            if(lcd.hasAllColumns(filters.keySet())) {
                setFilterParams(stmt, filters);
                setFilterParams(dtmt, filters);
            }

            // Make changes
            try (ResultSet srs = stmt.executeQuery(); ResultSet drs = dtmt.executeQuery()) {
                srs.next();
                drs.next();
                Map<ChangeType, Set<Key>> changes = new HashMap<>();
                changes.put(ChangeType.INSERT, new HashSet<>());
                changes.put(ChangeType.UPDATE, new HashSet<>());
                changes.put(ChangeType.DELETE, new HashSet<>());
                while (srs.getRow() > 0 || drs.getRow() > 0) {
                    ChangeType change = lcd.detectChange(srs, drs);

                    Key key = lcd.getPk(srs, drs);
                    Set<Key> changeset = changes.get(change);
                    if (changeset != null) {
                        changeset.add(key);
                    }
                    advance(srcTable, dstTable, srs, drs);
                    currentRow.incrementAndGet();
                }

                // Update stats
                currentMod.set(0);
                modCount.set(0);
                if(delete) {
                    modCount.addAndGet(changes.get(ChangeType.DELETE).size());
                }
                modCount.addAndGet(changes.get(ChangeType.INSERT).size());
                modCount.addAndGet(changes.get(ChangeType.UPDATE).size());

                // Sync
                if(delete) {
                    lcd.deleteRows(dcon, changes.get(ChangeType.DELETE), currentMod);
                }
                lcd.insertRows(scon, dcon, changes.get(ChangeType.INSERT), currentMod);
                lcd.updateRows(scon, dcon, changes.get(ChangeType.UPDATE), currentMod);
            } catch (Exception ex) {
                throw new RuntimeException("Error selecting hashed rows: " + sql, ex);
            }
        }
    }