Repository: OpenRefine/OpenRefine (java)

Issue:
Weird layout for Wikitext importer
The layout of the importer options for the Wikitext format is sub-optimal.

### To Reproduce
Steps to reproduce the behavior:
1. First, use the "Clipboard" panel to create a project from the following text:

```
{| class="wikitable"
|+ Caption text
|-
! Header text !! Header text !! Header text
|-
| Example || Example || Example
|-
| Example || Example || Example
|-
| Example || Example || Example
|}
```


### Current Results
On a sufficiently large screen, the checkboxes for the importing options are very far away from each other:


### Expected Behavior

There shouldn't be such a wide gap between the checkboxes and their associated labels.

### Screenshots

![image](https://github.com/OpenRefine/OpenRefine/assets/309908/f8e25a37-29ad-4a97-a3cc-2518e2a49a7d)

<!-- If applicable, add screenshots to help explain your problem. -->

### Versions<!--  (please complete the following information)-->
 - Operating System: Debian
 - Browser Version: Firefox 115.8.0esr
 - OpenRefine: master branch

### Datasets
<!-- If you are allowed and are OK with making your data public, it would be awesome if you can include or attach the data causing the issue or a URL pointing to where the data is.
If you are concerned about keeping your data private, you can share it selectively by email to developers who work on the issue -->

### Additional context

We probably shouldn't use HTML tables for the layout of importing options, as using HTML tables for layout is a long deprecated practice.


Pull request:
fix: weird layout for wikitext importer
Fixes #6498

Changes proposed in this pull request:
- remove the `width` attribute in the wikidata importer settings HTML to move the labels closer to the check boxes

Although the issue mentions a preference for moving away from using `table` to format the settings, I decided to leave the existing HTML as it's more consistent with the other settings HTML snippets. I think it makes more sense to track the migration of these snippets to more modern styles in a follow-up task.

I've attached a screenshot of the new settings. Given that `Disable auto preview` is below the `Update preview` button, I felt it made sense to leave the indentation for the final checkbox as-is, but I'd be happy to align the button and checkbox with the rest of the settings if others feel that is more appropriate.

![Screenshot from 2025-02-11 10-54-41](https://github.com/user-attachments/assets/e7819ff3-14c0-4747-9435-30a40f6bf87d)


Patch:
diff --git a/benchmark/pom.xml b/benchmark/pom.xml
index 88ee01a56..5b552f99c 100644
--- a/benchmark/pom.xml
+++ b/benchmark/pom.xml
@@ -125,7 +125,7 @@
         </plugin>
         <plugin>
           <artifactId>maven-install-plugin</artifactId>
-          <version>3.1.3</version>
+          <version>3.1.4</version>
         </plugin>
         <plugin>
           <artifactId>maven-jar-plugin</artifactId>
diff --git a/extensions/database/pom.xml b/extensions/database/pom.xml
index ed9948802..25302ef82 100644
--- a/extensions/database/pom.xml
+++ b/extensions/database/pom.xml
@@ -84,7 +84,7 @@
     <dependency>
       <groupId>com.google.http-client</groupId>
       <artifactId>google-http-client-jackson2</artifactId>
-      <version>1.46.2</version>
+      <version>1.46.3</version>
       <exclusions>
         <exclusion>
           <groupId>org.apache.httpcomponents</groupId>
diff --git a/main/src/com/google/refine/operations/cell/KeyValueColumnizeOperation.java b/main/src/com/google/refine/operations/cell/KeyValueColumnizeOperation.java
index ea78ff24d..1fde3c6c4 100644
--- a/main/src/com/google/refine/operations/cell/KeyValueColumnizeOperation.java
+++ b/main/src/com/google/refine/operations/cell/KeyValueColumnizeOperation.java
@@ -116,6 +116,14 @@ public class KeyValueColumnizeOperation extends AbstractOperation {
         return Optional.empty();
     }
 
+    @Override
+    public KeyValueColumnizeOperation renameColumns(Map<String, String> newColumnNames) {
+        return new KeyValueColumnizeOperation(
+                newColumnNames.getOrDefault(_keyColumnName, _keyColumnName),
+                newColumnNames.getOrDefault(_valueColumnName, _valueColumnName),
+                _noteColumnName == null ? null : newColumnNames.getOrDefault(_noteColumnName, _noteColumnName));
+    }
+
     @Override
     protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
         int keyColumnIndex = project.columnModel.getColumnIndexByName(_keyColumnName);
diff --git a/main/src/com/google/refine/operations/cell/MultiValuedCellJoinOperation.java b/main/src/com/google/refine/operations/cell/MultiValuedCellJoinOperation.java
index f5397aeed..9730538f4 100644
--- a/main/src/com/google/refine/operations/cell/MultiValuedCellJoinOperation.java
+++ b/main/src/com/google/refine/operations/cell/MultiValuedCellJoinOperation.java
@@ -35,6 +35,7 @@ package com.google.refine.operations.cell;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
@@ -101,6 +102,14 @@ public class MultiValuedCellJoinOperation extends AbstractOperation {
         return Optional.of(ColumnsDiff.modifySingleColumn(_columnName));
     }
 
+    @Override
+    public MultiValuedCellJoinOperation renameColumns(Map<String, String> newColumnNames) {
+        return new MultiValuedCellJoinOperation(
+                newColumnNames.getOrDefault(_columnName, _columnName),
+                newColumnNames.getOrDefault(_keyColumnName, _keyColumnName),
+                _separator);
+    }
+
     @Override
     protected String getBriefDescription(Project project) {
         return OperationDescription.cell_multivalued_cell_join_brief(_columnName);
diff --git a/main/src/com/google/refine/operations/cell/MultiValuedCellSplitOperation.java b/main/src/com/google/refine/operations/cell/MultiValuedCellSplitOperation.java
index 4dbecdca2..cfba9de77 100644
--- a/main/src/com/google/refine/operations/cell/MultiValuedCellSplitOperation.java
+++ b/main/src/com/google/refine/operations/cell/MultiValuedCellSplitOperation.java
@@ -35,6 +35,7 @@ package com.google.refine.operations.cell;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.regex.Pattern;
@@ -188,6 +189,22 @@ public class MultiValuedCellSplitOperation extends AbstractOperation {
         return Optional.of(ColumnsDiff.modifySingleColumn(_columnName));
     }
 
+    @Override
+    public MultiValuedCellSplitOperation renameColumns(Map<String, String> newColumnNames) {
+        if ("separator".equals(_mode)) {
+            return new MultiValuedCellSplitOperation(
+                    newColumnNames.getOrDefault(_columnName, _columnName),
+                    newColumnNames.getOrDefault(_keyColumnName, _keyColumnName),
+                    _separator,
+                    _regex);
+        } else {
+            return new MultiValuedCellSplitOperation(
+                    newColumnNames.getOrDefault(_columnName, _columnName),
+                    newColumnNames.getOrDefault(_keyColumnName, _keyColumnName),
+                    _fieldLengths);
+        }
+    }
+
     @Override
     protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
         Column column = project.columnModel.getColumnByName(_columnName);
diff --git a/main/src/com/google/refine/operations/cell/TextTransformOperation.java b/main/src/com/google/refine/operations/cell/TextTransformOperation.java
index 27d823f4a..95fb78364 100644
--- a/main/src/com/google/refine/operations/cell/TextTransformOperation.java
+++ b/main/src/com/google/refine/operations/cell/TextTransformOperation.java
@@ -35,6 +35,7 @@ package com.google.refine.operations.cell;
 
 import java.io.Serializable;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Properties;
 import java.util.Set;
@@ -142,6 +143,25 @@ public class TextTransformOperation extends EngineDependentMassCellOperation {
         return Optional.of(ColumnsDiff.modifySingleColumn(_columnName));
     }
 
+    @Override
+    public TextTransformOperation renameColumns(Map<String, String> newColumnNames) {
+        String renamedExpression;
+        try {
+            Evaluable evaluable = MetaParser.parse(_expression);
+            Evaluable renamedEvaluable = evaluable.renameColumnDependencies(newColumnNames);
+            renamedExpression = renamedEvaluable.getFullSource();
+        } catch (ParsingException e) {
+            return this;
+        }
+        return new TextTransformOperation(
+                _engineConfig.renameColumnDependencies(newColumnNames),
+                newColumnNames.getOrDefault(_columnName, _columnName),
+                renamedExpression,
+                _onError,
+                _repeat,
+                _repeatCount);
+    }
+
     @Override
     protected RowVisitor createRowVisitor(Project project, List<CellChange> cellChanges, long historyEntryID) throws Exception {
         Column column = project.columnModel.getColumnByName(_columnName);
diff --git a/main/src/com/google/refine/operations/cell/TransposeColumnsIntoRowsOperation.java b/main/src/com/google/refine/operations/cell/TransposeColumnsIntoRowsOperation.java
index eb68a2cd8..9fec75744 100644
--- a/main/src/com/google/refine/operations/cell/TransposeColumnsIntoRowsOperation.java
+++ b/main/src/com/google/refine/operations/cell/TransposeColumnsIntoRowsOperation.java
@@ -35,6 +35,7 @@ package com.google.refine.operations.cell;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
@@ -203,6 +204,28 @@ public class TransposeColumnsIntoRowsOperation extends AbstractOperation {
         return Optional.empty();
     }
 
+    @Override
+    public TransposeColumnsIntoRowsOperation renameColumns(Map<String, String> newColumnNames) {
+        if (_combinedColumnName != null) {
+            return new TransposeColumnsIntoRowsOperation(
+                    newColumnNames.getOrDefault(_startColumnName, _startColumnName),
+                    _columnCount,
+                    _ignoreBlankCells,
+                    _fillDown,
+                    newColumnNames.getOrDefault(_combinedColumnName, _combinedColumnName),
+                    _prependColumnName,
+                    _separator);
+        } else {
+            return new TransposeColumnsIntoRowsOperation(
+                    newColumnNames.getOrDefault(_startColumnName, _startColumnName),
+                    _columnCount,
+                    _ignoreBlankCells,
+                    _fillDown,
+                    newColumnNames.getOrDefault(_keyColumnName, _keyColumnName),
+                    newColumnNames.getOrDefault(_valueColumnName, _valueColumnName));
+        }
+    }
+
     @Override
     protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
         if (_combinedColumnName != null) {
diff --git a/main/src/com/google/refine/operations/cell/TransposeRowsIntoColumnsOperation.java b/main/src/com/google/refine/operations/cell/TransposeRowsIntoColumnsOperation.java
index d087d34f5..3201a4958 100644
--- a/main/src/com/google/refine/operations/cell/TransposeRowsIntoColumnsOperation.java
+++ b/main/src/com/google/refine/operations/cell/TransposeRowsIntoColumnsOperation.java
@@ -35,6 +35,7 @@ package com.google.refine.operations.cell;
 
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
@@ -95,6 +96,13 @@ public class TransposeRowsIntoColumnsOperation extends AbstractOperation {
         return Optional.empty();
     }
 
+    @Override
+    public TransposeRowsIntoColumnsOperation renameColumns(Map<String, String> newColumnNames) {
+        return new TransposeRowsIntoColumnsOperation(
+                newColumnNames.getOrDefault(_columnName, _columnName),
+                _rowCount);
+    }
+
     @Override
     protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
         List<Column> newColumns = new ArrayList<Column>();
diff --git a/main/src/com/google/refine/operations/column/ColumnAdditionByFetchingURLsOperation.java b/main/src/com/google/refine/operations/column/ColumnAdditionByFetchingURLsOperation.java
index 0d44f7aa5..1ed0a9e06 100644
--- a/main/src/com/google/refine/operations/column/ColumnAdditionByFetchingURLsOperation.java
+++ b/main/src/com/google/refine/operations/column/ColumnAdditionByFetchingURLsOperation.java
@@ -39,6 +39,7 @@ import java.io.IOException;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Properties;
 import java.util.Set;
@@ -227,6 +228,28 @@ public class ColumnAdditionByFetchingURLsOperation extends EngineDependentOperat
         return Optional.of(ColumnsDiff.builder().addColumn(_newColumnName, _baseColumnName).build());
     }
 
+    @Override
+    public ColumnAdditionByFetchingURLsOperation renameColumns(Map<String, String> newColumnNames) {
+        String renamedExpression;
+        try {
+            Evaluable evaluable = MetaParser.parse(_urlExpression);
+            Evaluable renamedEvaluable = evaluable.renameColumnDependencies(newColumnNames);
+            renamedExpression = renamedEvaluable.getFullSource();
+        } catch (ParsingException e) {
+            return this;
+        }
+        return new ColumnAdditionByFetchingURLsOperation(
+                _engineConfig.renameColumnDependencies(newColumnNames),
+                newColumnNames.getOrDefault(_baseColumnName, _baseColumnName),
+                renamedExpression,
+                _onError,
+                newColumnNames.getOrDefault(_newColumnName, _newColumnName),
+                _columnInsertIndex,
+                _delay,
+                _cacheResponses,
+                _httpHeadersJson);
+    }
+
     @Override
     public Process createProcess(Project project, Properties options) throws Exception {
         Engine engine = createEngine(project);
diff --git a/main/src/com/google/refine/operations/column/ColumnMoveOperation.java b/main/src/com/google/refine/operations/column/ColumnMoveOperation.java
index 77e43e915..0ba909930 100644
--- a/main/src/com/google/refine/operations/column/ColumnMoveOperation.java
+++ b/main/src/com/google/refine/operations/column/ColumnMoveOperation.java
@@ -33,6 +33,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 package com.google.refine.operations.column;
 
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
@@ -105,4 +106,9 @@ public class ColumnMoveOperation extends AbstractOperation {
     public Optional<ColumnsDiff> getColumnsDiff() {
         return Optional.of(ColumnsDiff.empty());
     }
+
+    @Override
+    public ColumnMoveOperation renameColumns(Map<String, String> newColumnNames) {
+        return new ColumnMoveOperation(newColumnNames.getOrDefault(_columnName, _columnName), _index);
+    }
 }
diff --git a/main/src/com/google/refine/operations/column/ColumnRemovalOperation.java b/main/src/com/google/refine/operations/column/ColumnRemovalOperation.java
index eb20212aa..d1dcfd793 100644
--- a/main/src/com/google/refine/operations/column/ColumnRemovalOperation.java
+++ b/main/src/com/google/refine/operations/column/ColumnRemovalOperation.java
@@ -33,6 +33,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 package com.google.refine.operations.column;
 
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
@@ -84,6 +85,11 @@ public class ColumnRemovalOperation extends AbstractOperation {
         return Optional.of(ColumnsDiff.builder().deleteColumn(_columnName).build());
     }
 
+    @Override
+    public ColumnRemovalOperation renameColumns(Map<String, String> newColumnNames) {
+        return new ColumnRemovalOperation(newColumnNames.getOrDefault(_columnName, _columnName));
+    }
+
     @Override
     protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
         Column column = project.columnModel.getColumnByName(_columnName);
diff --git a/main/src/com/google/refine/operations/column/ColumnRenameOperation.java b/main/src/com/google/refine/operations/column/ColumnRenameOperation.java
index 69cc04d1a..f80112228 100644
--- a/main/src/com/google/refine/operations/column/ColumnRenameOperation.java
+++ b/main/src/com/google/refine/operations/column/ColumnRenameOperation.java
@@ -33,6 +33,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 package com.google.refine.operations.column;
 
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
@@ -92,6 +93,13 @@ public class ColumnRenameOperation extends AbstractOperation {
         return Optional.of(ColumnsDiff.builder().deleteColumn(_oldColumnName).addColumn(_newColumnName, _oldColumnName).build());
     }
 
+    @Override
+    public ColumnRenameOperation renameColumns(Map<String, String> newColumnNames) {
+        return new ColumnRenameOperation(
+                newColumnNames.getOrDefault(_oldColumnName, _oldColumnName),
+                newColumnNames.getOrDefault(_newColumnName, _newColumnName));
+    }
+
     @Override
     protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
         if (project.columnModel.getColumnByName(_oldColumnName) == null) {
diff --git a/main/src/com/google/refine/operations/column/ColumnReorderOperation.java b/main/src/com/google/refine/operations/column/ColumnReorderOperation.java
index eff3efeef..33d151e4e 100644
--- a/main/src/com/google/refine/operations/column/ColumnReorderOperation.java
+++ b/main/src/com/google/refine/operations/column/ColumnReorderOperation.java
@@ -34,6 +34,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 package com.google.refine.operations.column;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
@@ -84,6 +85,12 @@ public class ColumnReorderOperation extends AbstractOperation {
         return Optional.empty(); // we don't know what columns there were before, so we can't diff them
     }
 
+    @Override
+    public ColumnReorderOperation renameColumns(Map<String, String> newColumnNames) {
+        return new ColumnReorderOperation(
+                _columnNames.stream().map(name -> newColumnNames.getOrDefault(name, name)).collect(Collectors.toList()));
+    }
+
     @Override
     protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
         return new HistoryEntry(
diff --git a/main/src/com/google/refine/operations/column/ColumnSplitOperation.java b/main/src/com/google/refine/operations/column/ColumnSplitOperation.java
index 4bfb3b7c0..fa7406ccb 100644
--- a/main/src/com/google/refine/operations/column/ColumnSplitOperation.java
+++ b/main/src/com/google/refine/operations/column/ColumnSplitOperation.java
@@ -36,6 +36,7 @@ package com.google.refine.operations.column;
 import java.io.Serializable;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 import java.util.regex.Pattern;
@@ -217,6 +218,27 @@ public class ColumnSplitOperation extends EngineDependentOperation {
         return Optional.empty(); // sadly the columns created depend on the data and the name of existing columns
     }
 
+    @Override
+    public ColumnSplitOperation renameColumns(Map<String, String> newColumnNames) {
+        if ("separator".equals(_mode)) {
+            return new ColumnSplitOperation(
+                    _engineConfig.renameColumnDependencies(newColumnNames),
+                    newColumnNames.getOrDefault(_columnName, _columnName),
+                    _guessCellType,
+                    _removeOriginalColumn,
+                    _separator,
+                    _regex,
+                    _maxColumns);
+        } else {
+            return new ColumnSplitOperation(
+                    _engineConfig.renameColumnDependencies(newColumnNames),
+                    newColumnNames.getOrDefault(_columnName, _columnName),
+                    _guessCellType,
+                    _removeOriginalColumn,
+                    _fieldLengths);
+        }
+    }
+
     @Override
     protected HistoryEntry createHistoryEntry(Project project, long historyEntryID) throws Exception {
         Engine engine = createEngine(project);
diff --git a/main/webapp/modules/core/scripts/index/parser-interfaces/wikitext-parser-ui.html b/main/webapp/modules/core/scripts/index/parser-interfaces/wikitext-parser-ui.html
index b0f543ec9..79a6c3b47 100644
--- a/main/webapp/modules/core/scripts/index/parser-interfaces/wikitext-parser-ui.html
+++ b/main/webapp/modules/core/scripts/index/parser-interfaces/wikitext-parser-ui.html
@@ -1,46 +1,46 @@
 <div class="grid-layout layout-tight"><table role="presentation">
       <tr><td colspan="2" id="or-import-colsep"></td></tr>
-         
-      <tr><td width="1%"><input type="checkbox" bind="wikiCheckbox" id="$reconcileWiki" /></td><td><label for="$reconcileWiki" id="or-import-wiki-base-url"></label>
+
+      <tr><td><input type="checkbox" bind="wikiCheckbox" id="$reconcileWiki" /></td><td><label for="$reconcileWiki" id="or-import-wiki-base-url"></label>
         <input bind="wikiUrlInput" spellcheck="false" type="text" class="lightweight" size="30" id="$wikiUrl" /></td></tr>
 
-      <tr><td width="1%"><input type="checkbox" bind="headerLinesCheckbox" id="$headers" /></td>
+      <tr><td><input type="checkbox" bind="headerLinesCheckbox" id="$headers" /></td>
         <td><label for="$headers" id="or-import-parse"></label>
           <input bind="headerLinesInput" type="number" class="lightweight" size="7" value="1" />
           <label for="$headers" id="or-import-header"></label></td></tr>
-      <tr><td width="1%"><input type="checkbox" bind="limitCheckbox" id="$limit" /></td>
+      <tr><td><input type="checkbox" bind="limitCheckbox" id="$limit" /></td>
         <td><label for="$limit" id="or-import-load"></label>
           <input bind="limitInput" type="number" class="lightweight" size="7" value="0" />
           <label for="$limit" id="or-import-rows2"></label></td></tr>
-      <tr><td width="1%"><input type="checkbox" bind="guessCellValueTypesCheckbox" id="$guess" /></td>
+      <tr><td><input type="checkbox" bind="guessCellValueTypesCheckbox" id="$guess" /></td>
         <td><label for="$guess" id="or-import-parseCell"></label></td></tr>
-      <tr><td width="1%"><input type="checkbox" bind="blankSpanningCellsCheckbox" id="$blank-spanning-cells" /></td>
+      <tr><td><input type="checkbox" bind="blankSpanningCellsCheckbox" id="$blank-spanning-cells" /></td>
         <td><label for="$blank-spanning-cells" id="or-import-blankSpanningCells"></label></td></tr>
-      <tr><td width="1%"><input type="checkbox" bind="storeBlankRowsCheckbox" id="$store-blank-rows" /></td>
+      <tr><td><input type="checkbox" bind="storeBlankRowsCheckbox" id="$store-blank-rows" /></td>
         <td colspan="2"><label for="$store-blank-rows" id="or-import-blank"></label></td></tr>
-      <tr><td width="1%"><input type="checkbox" bind="storeBlankColumnsCheckbox" id="$store-blank-columns" /></td>
+      <tr><td><input type="checkbox" bind="storeBlankColumnsCheckbox" id="$store-blank-columns" /></td>
         <td colspan="2"><label for="$store-blank-columns" id="or-import-blank-columns"></label></td></tr>
-      <tr><td width="1%"><input type="checkbox" bind="includeRawTemplatesCheckbox" id="$include-raw-templates" /></td>
+      <tr><td><input type="checkbox" bind="includeRawTemplatesCheckbox" id="$include-raw-templates" /></td>
         <td colspan="2"><label for="$include-raw-templates" id="or-import-includeRawTemplates"></label></td></tr>
-      <tr><td width="1%"><input type="checkbox" bind="parseReferencesCheckbox" id="$parse-references" /></td>
+      <tr><td><input type="checkbox" bind="parseReferencesCheckbox" id="$parse-references" /></td>
         <td colspan="2"><label for="$parse-references" id="or-import-parseReferences"></label></td></tr>
 
-      <tr><td width="1%"><input type="checkbox" bind="storeBlankCellsAsNullsCheckbox" id="$store-blank-cells" /></td>
+      <tr><td><input type="checkbox" bind="storeBlankCellsAsNullsCheckbox" id="$store-blank-cells" /></td>
         <td colspan="2"><label for="$store-blank-cells" id="or-import-null"></label></td></tr>
         
-      <tr><td width="1%"><input type="checkbox" bind="includeFileSourcesCheckbox" id="$include-file-sources" /></td>
+      <tr><td><input type="checkbox" bind="includeFileSourcesCheckbox" id="$include-file-sources" /></td>
         <td><label for="$include-file-sources" id="or-import-source"></label></td></tr>
 
-      <tr><td width="1%"><input type="checkbox" bind="includeArchiveFileCheckbox" id="$include-archive-file" /></td>
+      <tr><td><input type="checkbox" bind="includeArchiveFileCheckbox" id="$include-archive-file" /></td>
         <td><label for="$include-archive-file" id="or-import-archive"></label></td></tr>
 
       <tr>
-        <td width="1%"></td>
+        <td></td>
         <td><button class="button" bind="previewButton"></button></td>
       </tr>
       <tr>
-          <td width="1%"></td>
-          <td width="1%"><input type="checkbox" bind="disableAutoPreviewCheckbox" id="$disable" />
+          <td></td>
+          <td><input type="checkbox" bind="disableAutoPreviewCheckbox" id="$disable" />
             <label for="$disable" id="or-disable-auto-preview"></label></td>
       </tr>
 </table></div>
diff --git a/pom.xml b/pom.xml
index e0daf734e..dc88d31eb 100644
--- a/pom.xml
+++ b/pom.xml
@@ -77,10 +77,10 @@
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
 
     <!-- dependency versions -->
-    <jackson.version>2.18.2</jackson.version>
+    <jackson.version>2.18.3</jackson.version>
     <servlet-api.version>4.0.1</servlet-api.version>
     <butterfly.version>1.2.6</butterfly.version>
-    <slf4j.version>2.0.16</slf4j.version>
+    <slf4j.version>2.0.17</slf4j.version>
     <log4j.version>2.24.3</log4j.version>
     <jetty.version>10.0.16</jetty.version>
     <okhttp.version>4.12.0</okhttp.version>
@@ -113,7 +113,7 @@
     <httpmime.version>4.5.14</httpmime.version>
     <owasp-encoder.version>1.3.1</owasp-encoder.version>
     <jasypt.version>1.9.3</jasypt.version>
-    <mockito.version>5.15.2</mockito.version>
+    <mockito.version>5.16.0</mockito.version>
 
     <!-- plugin versions -->
     <build-helper-maven-plugin.version>3.6.0</build-helper-maven-plugin.version>
@@ -126,7 +126,7 @@
     <maven-jar-plugin.version>3.4.2</maven-jar-plugin.version>
     <maven-clean-plugin.version>3.4.1</maven-clean-plugin.version>
     <git-commit-id-plugin.version>4.9.10</git-commit-id-plugin.version>
-    <maven-deploy-plugin.version>3.1.3</maven-deploy-plugin.version>
+    <maven-deploy-plugin.version>3.1.4</maven-deploy-plugin.version>
     <license-plugin.version>2.5.0</license-plugin.version>
     <org-jvnet-localizer-plugin.version>1.31</org-jvnet-localizer-plugin.version>
   </properties>


Test patch:
diff --git a/main/tests/cypress/package.json b/main/tests/cypress/package.json
index 0ce2986de..df4d291c1 100644
--- a/main/tests/cypress/package.json
+++ b/main/tests/cypress/package.json
@@ -16,14 +16,14 @@
         "lint": "prettier --check . && eslint ."
     },
     "dependencies": {
-        "cypress": "14.0.3",
+        "cypress": "14.1.0",
         "cypress-file-upload": "^5.0.8"
     },
     "devDependencies": {
         "eslint": "^9.21.0",
         "eslint-config-google": "^0.14.0",
-        "eslint-config-prettier": "^10.0.1",
+        "eslint-config-prettier": "^10.0.2",
         "eslint-plugin-cypress": "^4.1.0",
-        "prettier": "3.5.2"
+        "prettier": "3.5.3"
     }
 }
diff --git a/main/tests/cypress/yarn.lock b/main/tests/cypress/yarn.lock
index 924c79ed7..cd1d6ef17 100644
--- a/main/tests/cypress/yarn.lock
+++ b/main/tests/cypress/yarn.lock
@@ -364,10 +364,10 @@ check-more-types@^2.24.0:
   resolved "https://registry.yarnpkg.com/check-more-types/-/check-more-types-2.24.0.tgz"
   integrity sha1-FCD/sQ/URNz8ebQ4kbv//TKoRgA=
 
-ci-info@^4.0.0:
-  version "4.0.0"
-  resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.0.0.tgz#65466f8b280fc019b9f50a5388115d17a63a44f2"
-  integrity sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==
+ci-info@^4.1.0:
+  version "4.1.0"
+  resolved "https://registry.yarnpkg.com/ci-info/-/ci-info-4.1.0.tgz#92319d2fa29d2620180ea5afed31f589bc98cf83"
+  integrity sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==
 
 clean-stack@^2.0.0:
   version "2.2.0"
@@ -461,10 +461,10 @@ cypress-file-upload@^5.0.8:
   resolved "https://registry.yarnpkg.com/cypress-file-upload/-/cypress-file-upload-5.0.8.tgz#d8824cbeaab798e44be8009769f9a6c9daa1b4a1"
   integrity sha512-+8VzNabRk3zG6x8f8BWArF/xA/W0VK4IZNx3MV0jFWrJS/qKn8eHfa5nU73P9fOQAgwHFJx7zjg4lwOnljMO8g==
 
-cypress@14.0.3:
-  version "14.0.3"
-  resolved "https://registry.yarnpkg.com/cypress/-/cypress-14.0.3.tgz#7873d21f61d0559edb9c041316d450cf7ef9d5fa"
-  integrity sha512-yIdvobANw3kS+KF/t5vwjjPNufBA8ux7iQHaWxPTkUw2yCKI72m9mKM24eOwE84Wk4ALPsSvEcGbDrwgmhr4RA==
+cypress@14.1.0:
+  version "14.1.0"
+  resolved "https://registry.yarnpkg.com/cypress/-/cypress-14.1.0.tgz#b2dbe7bbc529dc0c93ffd4e0e9fa59763afba0b8"
+  integrity sha512-pPPj8Uu9NwjaaiXAEcjYZZmgsq6v9Zs1Nw6a+zRF+ANgYSNhH4S32SjFRsvMcuOHR/8dp4GBJhBPqIPSs+TxaA==
   dependencies:
     "@cypress/request" "^3.0.7"
     "@cypress/xvfb" "^1.2.4"
@@ -477,7 +477,7 @@ cypress@14.0.3:
     cachedir "^2.3.0"
     chalk "^4.1.0"
     check-more-types "^2.24.0"
-    ci-info "^4.0.0"
+    ci-info "^4.1.0"
     cli-cursor "^3.1.0"
     cli-table3 "~0.6.1"
     commander "^6.2.1"
@@ -609,10 +609,10 @@ eslint-config-google@^0.14.0:
   resolved "https://registry.yarnpkg.com/eslint-config-google/-/eslint-config-google-0.14.0.tgz"
   integrity sha512-WsbX4WbjuMvTdeVL6+J3rK1RGhCTqjsFjX7UMSMgZiyxxaNLkoJENbrGExzERFeoTpGw3F3FypTiWAP9ZXzkEw==
 
-eslint-config-prettier@^10.0.1:
-  version "10.0.1"
-  resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-10.0.1.tgz#fbb03bfc8db0651df9ce4e8b7150d11c5fe3addf"
-  integrity sha512-lZBts941cyJyeaooiKxAtzoPHTN+GbQTJFAIdQbRhA4/8whaAraEh47Whw/ZFfrjNSnlAxqfm9i0XVAEkULjCw==
+eslint-config-prettier@^10.0.2:
+  version "10.0.2"
+  resolved "https://registry.yarnpkg.com/eslint-config-prettier/-/eslint-config-prettier-10.0.2.tgz#47444de8aa104ce82c2f91ad2a5e96b62c01e20d"
+  integrity sha512-1105/17ZIMjmCOJOPNfVdbXafLCLj3hPmkmB7dLgt7XsQ/zkxSuDerE/xgO3RxoHysR1N1whmquY0lSn2O0VLg==
 
 eslint-plugin-cypress@^4.1.0:
   version "4.1.0"
@@ -1325,10 +1325,10 @@ prelude-ls@^1.2.1:
   resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.2.1.tgz"
   integrity sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==
 
-prettier@3.5.2:
-  version "3.5.2"
-  resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.5.2.tgz#d066c6053200da0234bf8fa1ef45168abed8b914"
-  integrity sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==
+prettier@3.5.3:
+  version "3.5.3"
+  resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.5.3.tgz#4fc2ce0d657e7a02e602549f053b239cb7dfe1b5"
+  integrity sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw==
 
 pretty-bytes@^5.6.0:
   version "5.6.0"
diff --git a/main/tests/server/src/com/google/refine/operations/cell/KeyValueColumnizeTests.java b/main/tests/server/src/com/google/refine/operations/cell/KeyValueColumnizeTests.java
index a0fd572af..f5bb2140d 100644
--- a/main/tests/server/src/com/google/refine/operations/cell/KeyValueColumnizeTests.java
+++ b/main/tests/server/src/com/google/refine/operations/cell/KeyValueColumnizeTests.java
@@ -39,6 +39,7 @@ import static org.testng.Assert.assertThrows;
 import java.io.File;
 import java.io.IOException;
 import java.io.Serializable;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
@@ -140,6 +141,38 @@ public class KeyValueColumnizeTests extends RefineTest {
         assertEquals(new KeyValueColumnizeOperation("foo", "baz", null).getColumnDependencies().get(), Set.of("foo", "baz"));
     }
 
+    @Test
+    public void testRename() {
+        KeyValueColumnizeOperation SUT = new KeyValueColumnizeOperation("foo", "baz", null);
+
+        KeyValueColumnizeOperation renamed = SUT.renameColumns(Map.of("foo", "foo2", "bar", "bar2"));
+
+        TestUtils.isSerializedTo(renamed, "{\n"
+                + "   \"description\" : " + new TextNode(OperationDescription.cell_key_value_columnize_brief("foo2", "baz")).toString()
+                + ",\n"
+                + "   \"keyColumnName\" : \"foo2\",\n"
+                + "   \"noteColumnName\" : null,\n"
+                + "   \"op\" : \"core/key-value-columnize\",\n"
+                + "   \"valueColumnName\" : \"baz\"\n"
+                + "}");
+    }
+
+    @Test
+    public void testRenameNoNotesColumn() {
+        KeyValueColumnizeOperation SUT = new KeyValueColumnizeOperation("foo", "baz", "bar");
+
+        KeyValueColumnizeOperation renamed = SUT.renameColumns(Map.of("foo", "foo2", "bar", "bar2"));
+
+        TestUtils.isSerializedTo(renamed, "{\n"
+                + "   \"description\" : "
+                + new TextNode(OperationDescription.cell_key_value_columnize_note_column_brief("foo2", "baz", "bar2")).toString() + ",\n"
+                + "   \"keyColumnName\" : \"foo2\",\n"
+                + "   \"noteColumnName\" : \"bar2\",\n"
+                + "   \"op\" : \"core/key-value-columnize\",\n"
+                + "   \"valueColumnName\" : \"baz\"\n"
+                + "}");
+    }
+
     /**
      * Test in the case where an ID is available in the first column.
      * 
diff --git a/main/tests/server/src/com/google/refine/operations/cell/MultiValuedCellJoinOperationTests.java b/main/tests/server/src/com/google/refine/operations/cell/MultiValuedCellJoinOperationTests.java
index f5f047184..8a080f030 100644
--- a/main/tests/server/src/com/google/refine/operations/cell/MultiValuedCellJoinOperationTests.java
+++ b/main/tests/server/src/com/google/refine/operations/cell/MultiValuedCellJoinOperationTests.java
@@ -37,6 +37,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertThrows;
 
 import java.io.Serializable;
+import java.util.Map;
 import java.util.Set;
 
 import com.fasterxml.jackson.databind.node.TextNode;
@@ -120,6 +121,20 @@ public class MultiValuedCellJoinOperationTests extends RefineTest {
         assertEquals(new MultiValuedCellJoinOperation("value", "key", "sep").getColumnDependencies().get(), Set.of("value", "key"));
     }
 
+    @Test
+    public void testRename() {
+        var SUT = new MultiValuedCellJoinOperation("value", "key", "sep");
+
+        MultiValuedCellJoinOperation renamed = SUT.renameColumns(Map.of("value", "value2", "key", "key2", "sep", "sep2"));
+
+        String expectedJson = "{\"op\":\"core/multivalued-cell-join\","
+                + "\"description\":" + new TextNode(OperationDescription.cell_multivalued_cell_join_brief("value2")).toString() + ","
+                + "\"columnName\":\"value2\","
+                + "\"keyColumnName\":\"key2\","
+                + "\"separator\":\"sep\"}";
+        TestUtils.isSerializedTo(renamed, expectedJson);
+    }
+
     /*
      * Test to demonstrate the intended behaviour of the function
      */
diff --git a/main/tests/server/src/com/google/refine/operations/cell/MultiValuedCellSplitOperationTests.java b/main/tests/server/src/com/google/refine/operations/cell/MultiValuedCellSplitOperationTests.java
index 4ac3fa1fe..ed1adeb1a 100644
--- a/main/tests/server/src/com/google/refine/operations/cell/MultiValuedCellSplitOperationTests.java
+++ b/main/tests/server/src/com/google/refine/operations/cell/MultiValuedCellSplitOperationTests.java
@@ -37,6 +37,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertThrows;
 
 import java.io.Serializable;
+import java.util.Map;
 import java.util.Set;
 
 import com.fasterxml.jackson.core.JsonProcessingException;
@@ -184,6 +185,28 @@ public class MultiValuedCellSplitOperationTests extends RefineTest {
                 false).getColumnDependencies().get(), Set.of("Value", "Key"));
     }
 
+    @Test
+    public void testRename() {
+        var SUT = new MultiValuedCellSplitOperation(
+                "Value",
+                "Key",
+                ":",
+                false);
+
+        MultiValuedCellSplitOperation renamed = SUT.renameColumns(Map.of("Value", "value2", "key", "Key2"));
+
+        String expectedJson = "{\n"
+                + "  \"columnName\" : \"value2\",\n"
+                + "  \"description\" : " + new TextNode(OperationDescription.cell_multivalued_cell_split_brief("value2")).toString() + ",\n"
+                + "  \"keyColumnName\" : \"Key\",\n"
+                + "  \"mode\" : \"separator\",\n"
+                + "  \"op\" : \"core/multivalued-cell-split\",\n"
+                + "  \"regex\" : false,\n"
+                + "  \"separator\" : \":\"\n"
+                + "}";
+        TestUtils.isSerializedTo(renamed, expectedJson);
+    }
+
     /**
      * Test to demonstrate the intended behaviour of the function, for issue #1268
      * https://github.com/OpenRefine/OpenRefine/issues/1268
diff --git a/main/tests/server/src/com/google/refine/operations/cell/TextTransformOperationTests.java b/main/tests/server/src/com/google/refine/operations/cell/TextTransformOperationTests.java
index 27aea691c..ccf0bcba0 100644
--- a/main/tests/server/src/com/google/refine/operations/cell/TextTransformOperationTests.java
+++ b/main/tests/server/src/com/google/refine/operations/cell/TextTransformOperationTests.java
@@ -5,6 +5,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertThrows;
 
 import java.io.Serializable;
+import java.util.Map;
 import java.util.Set;
 
 import com.fasterxml.jackson.databind.node.TextNode;
@@ -117,6 +118,31 @@ public class TextTransformOperationTests extends RefineTest {
                 false, 0).getColumnDependencies().get(), Set.of("foo", "bar", "facet_1"));
     }
 
+    @Test
+    public void testRename() {
+        var SUT = new TextTransformOperation(
+                engineConfigWithColumnDeps,
+                "bar",
+                "grel:cells[\"foo\"].value+'_'+value",
+                OnError.SetToBlank,
+                false, 0);
+
+        TextTransformOperation renamed = SUT.renameColumns(Map.of("foo", "foo2", "bar", "bar2"));
+        String description = OperationDescription.cell_text_transform_brief("bar2",
+                "grel:cells.get(\"foo2\").value + '_' + value");
+        String expectedJson = "{\n"
+                + "  \"columnName\" : \"bar2\",\n"
+                + "  \"description\" : " + new TextNode(description).toString() + ",\n"
+                + "  \"engineConfig\" : null,\n"
+                + "  \"expression\" : \"grel:cells.get(\\\"foo2\\\").value + '_' + value\",\n"
+                + "  \"onError\" : \"set-to-blank\",\n"
+                + "  \"op\" : \"core/text-transform\",\n"
+                + "  \"repeat\" : false,\n"
+                + "  \"repeatCount\" : 0\n"
+                + "}";
+        TestUtils.isSerializedTo(renamed, expectedJson);
+    }
+
     @Test
     public void testTransformColumnInRowsMode() throws Exception {
         TextTransformOperation operation = new TextTransformOperation(
diff --git a/main/tests/server/src/com/google/refine/operations/cell/TransposeColumnsIntoRowsOperationTest.java b/main/tests/server/src/com/google/refine/operations/cell/TransposeColumnsIntoRowsOperationTest.java
index f26b458d4..5c66ea29a 100644
--- a/main/tests/server/src/com/google/refine/operations/cell/TransposeColumnsIntoRowsOperationTest.java
+++ b/main/tests/server/src/com/google/refine/operations/cell/TransposeColumnsIntoRowsOperationTest.java
@@ -5,6 +5,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertThrows;
 
 import java.io.Serializable;
+import java.util.Map;
 import java.util.Optional;
 
 import com.fasterxml.jackson.databind.node.TextNode;
@@ -66,6 +67,50 @@ public class TransposeColumnsIntoRowsOperationTest extends RefineTest {
                 Optional.empty());
     }
 
+    @Test
+    public void testRename() {
+        var SUT = new TransposeColumnsIntoRowsOperation("num1", -1, true, false, "a", true, ":");
+
+        TransposeColumnsIntoRowsOperation renamed = SUT.renameColumns(Map.of("num1", "num2", "a", "a2"));
+
+        TestUtils.isSerializedTo(renamed, "{\n"
+                + "  \"columnCount\" : -1,\n"
+                + "  \"combinedColumnName\" : \"a2\",\n"
+                + "  \"description\" : "
+                + new TextNode(OperationDescription.cell_transpose_columns_into_rows_combined_neg_brief("num2", "a2")).toString() + ",\n"
+                + "  \"fillDown\" : false,\n"
+                + "  \"ignoreBlankCells\" : true,\n"
+                + "  \"keyColumnName\" : null,\n"
+                + "  \"op\" : \"core/transpose-columns-into-rows\",\n"
+                + "  \"prependColumnName\" : true,\n"
+                + "  \"separator\" : \":\",\n"
+                + "  \"startColumnName\" : \"num2\",\n"
+                + "  \"valueColumnName\" : null\n"
+                + "}");
+    }
+
+    @Test
+    public void testRename2() {
+        var SUT = new TransposeColumnsIntoRowsOperation(
+                "b 1", 2, true, false, "key", "value");
+
+        TransposeColumnsIntoRowsOperation renamed = SUT.renameColumns(Map.of("b 1", "b", "key", "key2"));
+
+        TestUtils.isSerializedTo(renamed, "{\n"
+                + "  \"columnCount\" : 2,\n"
+                + "  \"description\" : " + new TextNode(OperationDescription.cell_transpose_columns_into_rows_not_combined_pos_brief(2, "b",
+                        "key2", "value")).toString()
+                + ",\n"
+                + "  \"fillDown\" : false,\n"
+                + "  \"ignoreBlankCells\" : true,\n"
+                + "  \"keyColumnName\" : \"key2\",\n"
+                + "  \"op\" : \"core/transpose-columns-into-rows\",\n"
+                + "  \"separator\" : null,\n"
+                + "  \"startColumnName\" : \"b\",\n"
+                + "  \"valueColumnName\" : \"value\"\n"
+                + "}");
+    }
+
     @Test
     public void testCreateHistoryEntry_transposeIntoOneColumn_removeRowForNullOrEmptyCell() throws Exception {
         Project project = createProject(
diff --git a/main/tests/server/src/com/google/refine/operations/cell/TransposeRowsIntoColumnsOperationTests.java b/main/tests/server/src/com/google/refine/operations/cell/TransposeRowsIntoColumnsOperationTests.java
index 767ec9e3c..ff00739cf 100644
--- a/main/tests/server/src/com/google/refine/operations/cell/TransposeRowsIntoColumnsOperationTests.java
+++ b/main/tests/server/src/com/google/refine/operations/cell/TransposeRowsIntoColumnsOperationTests.java
@@ -37,6 +37,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertThrows;
 
 import java.io.Serializable;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
@@ -101,6 +102,21 @@ public class TransposeRowsIntoColumnsOperationTests extends RefineTest {
         assertEquals(new TransposeRowsIntoColumnsOperation("b", 2).getColumnDependencies(), Optional.of(Set.of("b")));
     }
 
+    @Test
+    public void testRename() {
+        var SUT = new TransposeRowsIntoColumnsOperation("b", 2);
+
+        TransposeRowsIntoColumnsOperation renamed = SUT.renameColumns(Map.of("b", "c"));
+
+        TestUtils.isSerializedTo(renamed, "{\n"
+                + "  \"columnName\" : \"c\",\n"
+                + "  \"description\" : " + new TextNode(OperationDescription.cell_transpose_rows_into_columns_brief(2, "c")).toString()
+                + ",\n"
+                + "  \"op\" : \"core/transpose-rows-into-columns\",\n"
+                + "  \"rowCount\" : 2\n"
+                + "}");
+    }
+
     @Test
     public void testTransposeRowsIntoColumns() throws Exception {
         TransposeRowsIntoColumnsOperation operation = new TransposeRowsIntoColumnsOperation("b", 2);
diff --git a/main/tests/server/src/com/google/refine/operations/column/ColumnAdditionByFetchingURLsOperationTests.java b/main/tests/server/src/com/google/refine/operations/column/ColumnAdditionByFetchingURLsOperationTests.java
index e02b55b44..c4020c791 100644
--- a/main/tests/server/src/com/google/refine/operations/column/ColumnAdditionByFetchingURLsOperationTests.java
+++ b/main/tests/server/src/com/google/refine/operations/column/ColumnAdditionByFetchingURLsOperationTests.java
@@ -40,6 +40,7 @@ import static org.testng.Assert.assertTrue;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Map;
 import java.util.Properties;
 import java.util.Random;
 import java.util.Set;
@@ -193,6 +194,25 @@ public class ColumnAdditionByFetchingURLsOperationTests extends RefineTest {
         assertThrows(IllegalArgumentException.class, () -> missingExpression.validate());
     }
 
+    @Test
+    public void testRename() {
+        ColumnAdditionByFetchingURLsOperation SUT = new ColumnAdditionByFetchingURLsOperation(engine_config,
+                "fruits",
+                "grel:\"https://example.com/api?city=\"+value",
+                OnError.StoreError,
+                "results",
+                1,
+                5,
+                true,
+                null);
+
+        ColumnAdditionByFetchingURLsOperation renamed = SUT.renameColumns(Map.of("fruits", "vegetables", "results", "json"));
+
+        assertEquals(renamed._baseColumnName, "vegetables");
+        assertEquals(renamed._newColumnName, "json");
+        assertEquals(renamed._urlExpression, "grel:\"https://example.com/api?city=\" + value");
+    }
+
     /**
      * Test for caching
      */
diff --git a/main/tests/server/src/com/google/refine/operations/column/ColumnMoveOperationTests.java b/main/tests/server/src/com/google/refine/operations/column/ColumnMoveOperationTests.java
index 6d22be750..93127e85f 100644
--- a/main/tests/server/src/com/google/refine/operations/column/ColumnMoveOperationTests.java
+++ b/main/tests/server/src/com/google/refine/operations/column/ColumnMoveOperationTests.java
@@ -31,6 +31,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertThrows;
 
 import java.io.Serializable;
+import java.util.Map;
 import java.util.Set;
 
 import com.fasterxml.jackson.databind.node.TextNode;
@@ -149,4 +150,13 @@ public class ColumnMoveOperationTests extends RefineTest {
         assertProjectEquals(project, expected);
     }
 
+    @Test
+    public void testRename() {
+        ColumnMoveOperation SUT = new ColumnMoveOperation("hello", 1);
+
+        ColumnMoveOperation renamed = SUT.renameColumns(Map.of("hello", "world"));
+
+        assertEquals(renamed._columnName, "world");
+    }
+
 }
diff --git a/main/tests/server/src/com/google/refine/operations/column/ColumnRemovalOperationTests.java b/main/tests/server/src/com/google/refine/operations/column/ColumnRemovalOperationTests.java
index 8e9cba6c3..be9fa7721 100644
--- a/main/tests/server/src/com/google/refine/operations/column/ColumnRemovalOperationTests.java
+++ b/main/tests/server/src/com/google/refine/operations/column/ColumnRemovalOperationTests.java
@@ -31,6 +31,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertThrows;
 
 import java.io.Serializable;
+import java.util.Map;
 import java.util.Set;
 
 import com.fasterxml.jackson.databind.node.TextNode;
@@ -103,4 +104,13 @@ public class ColumnRemovalOperationTests extends RefineTest {
                 });
         assertProjectEquals(project, expected);
     }
+
+    @Test
+    public void testRename() {
+        ColumnRemovalOperation SUT = new ColumnRemovalOperation("foo");
+
+        ColumnRemovalOperation renamed = SUT.renameColumns(Map.of("foo", "bar"));
+
+        assertEquals(renamed._columnName, "bar");
+    }
 }
diff --git a/main/tests/server/src/com/google/refine/operations/column/ColumnRenameOperationTests.java b/main/tests/server/src/com/google/refine/operations/column/ColumnRenameOperationTests.java
index 0b0d73acc..f81175128 100644
--- a/main/tests/server/src/com/google/refine/operations/column/ColumnRenameOperationTests.java
+++ b/main/tests/server/src/com/google/refine/operations/column/ColumnRenameOperationTests.java
@@ -31,6 +31,7 @@ import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertThrows;
 
 import java.io.Serializable;
+import java.util.Map;
 import java.util.Set;
 
 import com.fasterxml.jackson.databind.node.TextNode;
@@ -108,4 +109,14 @@ public class ColumnRenameOperationTests extends RefineTest {
                 });
         assertProjectEquals(project, expected);
     }
+
+    @Test
+    public void testRenameDependencies() throws Exception {
+        ColumnRenameOperation SUT = new ColumnRenameOperation("foo", "newfoo");
+
+        ColumnRenameOperation renamed = SUT.renameColumns(Map.of("foo", "foo2", "newfoo", "newfoo2"));
+
+        assertEquals(renamed._oldColumnName, "foo2");
+        assertEquals(renamed._newColumnName, "newfoo2");
+    }
 }
diff --git a/main/tests/server/src/com/google/refine/operations/column/ColumnReorderOperationTests.java b/main/tests/server/src/com/google/refine/operations/column/ColumnReorderOperationTests.java
index ad4752669..c5b1480d7 100644
--- a/main/tests/server/src/com/google/refine/operations/column/ColumnReorderOperationTests.java
+++ b/main/tests/server/src/com/google/refine/operations/column/ColumnReorderOperationTests.java
@@ -32,6 +32,8 @@ import static org.testng.Assert.assertThrows;
 
 import java.io.Serializable;
 import java.util.Arrays;
+import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
@@ -125,4 +127,13 @@ public class ColumnReorderOperationTests extends RefineTest {
                 });
         assertProjectEquals(project, expected);
     }
+
+    @Test
+    public void testRename() {
+        ColumnReorderOperation SUT = new ColumnReorderOperation(Arrays.asList("c", "b"));
+
+        ColumnReorderOperation renamed = SUT.renameColumns(Map.of("a", "a2", "b", "b2"));
+
+        assertEquals(renamed._columnNames, List.of("c", "b2"));
+    }
 }
diff --git a/main/tests/server/src/com/google/refine/operations/column/ColumnSplitOperationTests.java b/main/tests/server/src/com/google/refine/operations/column/ColumnSplitOperationTests.java
index b2cc93592..125049c09 100644
--- a/main/tests/server/src/com/google/refine/operations/column/ColumnSplitOperationTests.java
+++ b/main/tests/server/src/com/google/refine/operations/column/ColumnSplitOperationTests.java
@@ -32,6 +32,7 @@ import static org.testng.Assert.assertThrows;
 
 import java.io.Serializable;
 import java.util.Collections;
+import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
 
@@ -258,4 +259,48 @@ public class ColumnSplitOperationTests extends RefineTest {
                 });
         assertProjectEquals(project, expected);
     }
+
+    @Test
+    public void testRenameLengths() {
+        ColumnSplitOperation SUT = new ColumnSplitOperation(EngineConfig.defaultRowBased(), "hello", false,
+                false, new int[] { 1, 2 });
+
+        ColumnSplitOperation renamed = SUT.renameColumns(Map.of("hello", "world"));
+        TestUtils.isSerializedTo(renamed, "{\n"
+                + "       \"columnName\" : \"world\",\n"
+                + "       \"description\" : " + new TextNode(OperationDescription.column_split_brief("world")).toString() + ",\n"
+                + "       \"engineConfig\" : {\n"
+                + "         \"facets\" : [ ],\n"
+                + "         \"mode\" : \"row-based\"\n"
+                + "       },\n"
+                + "       \"fieldLengths\" : [ 1, 2 ],\n"
+                + "       \"guessCellType\" : false,\n"
+                + "       \"mode\" : \"lengths\",\n"
+                + "       \"op\" : \"core/column-split\",\n"
+                + "       \"removeOriginalColumn\" : false\n"
+                + "     }");
+    }
+
+    @Test
+    public void testRenameSeparator() {
+        ColumnSplitOperation SUT = new ColumnSplitOperation(EngineConfig.defaultRowBased(), "foo", true, true, ",",
+                false, 2);
+
+        ColumnSplitOperation renamed = SUT.renameColumns(Map.of("foo", "bar"));
+        TestUtils.isSerializedTo(renamed, "{\n"
+                + "       \"columnName\" : \"bar\",\n"
+                + "       \"description\" : " + new TextNode(OperationDescription.column_split_separator_brief("bar")).toString() + ",\n"
+                + "       \"engineConfig\" : {\n"
+                + "         \"facets\" : [ ],\n"
+                + "         \"mode\" : \"row-based\"\n"
+                + "       },\n"
+                + "       \"guessCellType\" : true,\n"
+                + "       \"maxColumns\": 2,\n"
+                + "       \"regex\": false,\n"
+                + "       \"mode\" : \"separator\",\n"
+                + "       \"separator\": \",\",\n"
+                + "       \"op\" : \"core/column-split\",\n"
+                + "       \"removeOriginalColumn\" : true\n"
+                + "     }");
+    }
 }