diff --git a/synthtool/languages/java.py b/synthtool/languages/java.py
index 82f2c56b1..fefc9e0db 100644
--- a/synthtool/languages/java.py
+++ b/synthtool/languages/java.py
@@ -15,6 +15,7 @@
 import glob
 import os
 import xml.etree.ElementTree as ET
+import re
 import requests
 import synthtool as s
 import synthtool.gcp as gcp
@@ -398,3 +399,64 @@ def custom_templates(files: List[str], **kwargs) -> None:
     for file in files:
         template = gcp.CommonTemplates().render(file, **kwargs)
         s.copy([template])
+
+
+def remove_method(filename: str, signature: str):
+    """Helper to remove an entire method.
+
+    Goes line-by-line to detect the start of the block. Determines
+    the end of the block by a closing brace at the same indentation
+    level. This requires the file to be correctly formatted.
+
+    Example: consider the following class:
+
+        class Example {
+            public void main(String[] args) {
+                System.out.println("Hello World");
+            }
+
+            public String foo() {
+                return "bar";
+            }
+        }
+
+    To remove the `main` method above, use:
+
+        remove_method('path/to/file', 'public void main(String[] args)')
+
+    Args:
+        filename (str): Path to source file
+        signature (str): Full signature of the method to remove. Example:
+            `public void main(String[] args)`.
+    """
+    lines = []
+    leading_regex = None
+    with open(filename, "r") as fp:
+        line = fp.readline()
+        while line:
+            # for each line, try to find the matching
+            regex = re.compile("(\\s*)" + re.escape(signature) + ".*")
+            match = regex.match(line)
+            if match:
+                leading_regex = re.compile(match.group(1) + "}")
+                line = fp.readline()
+                continue
+
+            # not in a ignore block - preserve the line
+            if not leading_regex:
+                lines.append(line)
+                line = fp.readline()
+                continue
+
+            # detect the closing tag based on the leading spaces
+            match = leading_regex.match(line)
+            if match:
+                # block is closed, resume capturing content
+                leading_regex = None
+
+            line = fp.readline()
+
+    with open(filename, "w") as fp:
+        for line in lines:
+            # print(line)
+            fp.write(line)
diff --git a/tests/test_language_java.py b/tests/test_language_java.py
index 7d97c58fd..f7e10cac6 100644
--- a/tests/test_language_java.py
+++ b/tests/test_language_java.py
@@ -113,3 +113,30 @@ def assert_valid_yaml(file):
                         assert_valid_yaml(os.path.join(dirpath, file))
         finally:
             os.chdir(cwd)
+
+
+def test_remove_method():
+    with tempfile.TemporaryDirectory() as tempdir:
+        shutil.copyfile(
+            "tests/testdata/SampleClass.java", tempdir + "/SampleClass.java"
+        )
+
+        java.remove_method(tempdir + "/SampleClass.java", "public static void foo()")
+        java.remove_method(tempdir + "/SampleClass.java", "public void asdf()")
+        assert_matches_golden(
+            "tests/testdata/SampleClassGolden.java", tempdir + "/SampleClass.java"
+        )
+
+
+def assert_matches_golden(expected, actual):
+    matching_lines = 0
+    with open(actual, "rt") as fp:
+        with open(expected, "rt") as golden:
+            while True:
+                matching_lines += 1
+                log_line = fp.readline()
+                expected = golden.readline()
+                assert log_line == expected
+                if not log_line:
+                    break
+    assert matching_lines > 0
diff --git a/tests/testdata/SampleClass.java b/tests/testdata/SampleClass.java
new file mode 100644
index 000000000..849548b9d
--- /dev/null
+++ b/tests/testdata/SampleClass.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * 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
+ *
+ *      https://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.
+ */
+
+package dlp;
+
+class ExampleClass {
+  public static void foo() {
+    System.out.println("bar");
+  }
+
+  public static class InnerClass {
+    public void asdf() {
+      System.out.println("qwer");
+    }
+  }
+}
diff --git a/tests/testdata/SampleClassGolden.java b/tests/testdata/SampleClassGolden.java
new file mode 100644
index 000000000..dbe1fe9d1
--- /dev/null
+++ b/tests/testdata/SampleClassGolden.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2020 Google LLC
+ *
+ * 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
+ *
+ *      https://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.
+ */
+
+package dlp;
+
+class ExampleClass {
+
+  public static class InnerClass {
+  }
+}