diff --git a/src/resourceshrinker/java/com/android/build/shrinker/DummyContent.java b/src/resourceshrinker/java/com/android/build/shrinker/DummyContent.java
new file mode 100644
index 0000000..b9aaa3e
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/DummyContent.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker;
+
+public class DummyContent {
+
+  // A 1x1 pixel PNG of type BufferedImage.TYPE_BYTE_GRAY
+  public static final byte[] TINY_PNG =
+      new byte[] {
+        (byte) -119, (byte) 80, (byte) 78, (byte) 71, (byte) 13, (byte) 10,
+        (byte) 26, (byte) 10, (byte) 0, (byte) 0, (byte) 0, (byte) 13,
+        (byte) 73, (byte) 72, (byte) 68, (byte) 82, (byte) 0, (byte) 0,
+        (byte) 0, (byte) 1, (byte) 0, (byte) 0, (byte) 0, (byte) 1,
+        (byte) 8, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 58,
+        (byte) 126, (byte) -101, (byte) 85, (byte) 0, (byte) 0, (byte) 0,
+        (byte) 10, (byte) 73, (byte) 68, (byte) 65, (byte) 84, (byte) 120,
+        (byte) -38, (byte) 99, (byte) 96, (byte) 0, (byte) 0, (byte) 0,
+        (byte) 2, (byte) 0, (byte) 1, (byte) -27, (byte) 39, (byte) -34,
+        (byte) -4, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 73,
+        (byte) 69, (byte) 78, (byte) 68, (byte) -82, (byte) 66, (byte) 96,
+        (byte) -126
+      };
+
+  public static final long TINY_PNG_CRC = 0x88b2a3b0L;
+
+  // A 3x3 pixel PNG of type BufferedImage.TYPE_INT_ARGB with 9-patch markers
+  public static final byte[] TINY_9PNG =
+      new byte[] {
+        (byte) -119, (byte) 80, (byte) 78, (byte) 71, (byte) 13, (byte) 10,
+        (byte) 26, (byte) 10, (byte) 0, (byte) 0, (byte) 0, (byte) 13,
+        (byte) 73, (byte) 72, (byte) 68, (byte) 82, (byte) 0, (byte) 0,
+        (byte) 0, (byte) 3, (byte) 0, (byte) 0, (byte) 0, (byte) 3,
+        (byte) 8, (byte) 6, (byte) 0, (byte) 0, (byte) 0, (byte) 86,
+        (byte) 40, (byte) -75, (byte) -65, (byte) 0, (byte) 0, (byte) 0,
+        (byte) 20, (byte) 73, (byte) 68, (byte) 65, (byte) 84, (byte) 120,
+        (byte) -38, (byte) 99, (byte) 96, (byte) -128, (byte) -128, (byte) -1,
+        (byte) 12, (byte) 48, (byte) 6, (byte) 8, (byte) -96, (byte) 8,
+        (byte) -128, (byte) 8, (byte) 0, (byte) -107, (byte) -111, (byte) 7,
+        (byte) -7, (byte) -64, (byte) -82, (byte) 8, (byte) 0, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 0, (byte) 73, (byte) 69, (byte) 78,
+        (byte) 68, (byte) -82, (byte) 66, (byte) 96, (byte) -126
+      };
+
+  public static final long TINY_9PNG_CRC = 0x1148f987L;
+
+  // The XML document <x/> as binary-packed with AAPT
+  public static final byte[] TINY_BINARY_XML =
+      new byte[] {
+        (byte) 3, (byte) 0, (byte) 8, (byte) 0, (byte) 104, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 1, (byte) 0, (byte) 28, (byte) 0,
+        (byte) 36, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+        (byte) 0, (byte) 1, (byte) 0, (byte) 0, (byte) 32, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 1,
+        (byte) 120, (byte) 0, (byte) 2, (byte) 1, (byte) 16, (byte) 0,
+        (byte) 36, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 0,
+        (byte) 0, (byte) 0, (byte) -1, (byte) -1, (byte) -1, (byte) -1,
+        (byte) -1, (byte) -1, (byte) -1, (byte) -1, (byte) 0, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 20, (byte) 0, (byte) 20, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 3, (byte) 1, (byte) 16, (byte) 0,
+        (byte) 24, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 0,
+        (byte) 0, (byte) 0, (byte) -1, (byte) -1, (byte) -1, (byte) -1,
+        (byte) -1, (byte) -1, (byte) -1, (byte) -1, (byte) 0, (byte) 0,
+        (byte) 0, (byte) 0
+      };
+
+  public static final long TINY_BINARY_XML_CRC = 0xd7e65643L;
+
+  // The XML document <x/> as a proto packed with AAPT2
+  public static final byte[] TINY_PROTO_XML =
+      new byte[] {0xa, 0x3, 0x1a, 0x1, 0x78, 0x1a, 0x2, 0x8, 0x1};
+  public static final long TINY_PROTO_XML_CRC = 3204905971L;
+
+  // The XML document <x/> as binary-packed with AAPT
+  public static final byte[] TINY_PROTO_CONVERTED_TO_BINARY_XML =
+      new byte[] {
+        (byte) 3, (byte) 0, (byte) 8, (byte) 0, (byte) 112, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 1, (byte) 0, (byte) 28, (byte) 0,
+        (byte) 36, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+        (byte) 0, (byte) 1, (byte) 0, (byte) 0, (byte) 32, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 1, (byte) 1,
+        (byte) 120, (byte) 0, (byte) -128, (byte) 1, (byte) 8, (byte) 0,
+        (byte) 8, (byte) 0, (byte) 0, (byte) 0, (byte) 2, (byte) 1,
+        (byte) 16, (byte) 0, (byte) 36, (byte) 0, (byte) 0, (byte) 0,
+        (byte) 1, (byte) 0, (byte) 0, (byte) 0, (byte) -1, (byte) -1,
+        (byte) -1, (byte) -1, (byte) -1, (byte) -1, (byte) -1, (byte) -1,
+        (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 20, (byte) 0,
+        (byte) 20, (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 0,
+        (byte) 0, (byte) 0, (byte) 0, (byte) 0, (byte) 3, (byte) 1,
+        (byte) 16, (byte) 0, (byte) 24, (byte) 0, (byte) 0, (byte) 0,
+        (byte) 1, (byte) 0, (byte) 0, (byte) 0, (byte) -1, (byte) -1,
+        (byte) -1, (byte) -1, (byte) -1, (byte) -1, (byte) -1, (byte) -1,
+        (byte) 0, (byte) 0, (byte) 0, (byte) 0
+      };
+
+  private DummyContent() {}
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/LinkedResourcesFormat.java b/src/resourceshrinker/java/com/android/build/shrinker/LinkedResourcesFormat.java
new file mode 100644
index 0000000..67b06a8
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/LinkedResourcesFormat.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker;
+
+public enum LinkedResourcesFormat {
+  BINARY,
+  PROTO,
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/PossibleResourcesMarker.java b/src/resourceshrinker/java/com/android/build/shrinker/PossibleResourcesMarker.java
new file mode 100644
index 0000000..5089061
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/PossibleResourcesMarker.java
@@ -0,0 +1,372 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker;
+
+import static com.google.common.collect.ImmutableSet.toImmutableSet;
+import static java.lang.Character.isDigit;
+
+import com.android.annotations.NonNull;
+import com.android.ide.common.resources.usage.ResourceStore;
+import com.android.ide.common.resources.usage.ResourceUsageModel;
+import com.android.ide.common.resources.usage.ResourceUsageModel.Resource;
+import com.android.resources.ResourceType;
+import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.Streams;
+import com.google.common.primitives.Ints;
+import java.util.List;
+import java.util.Set;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.regex.PatternSyntaxException;
+import java.util.stream.Stream;
+
+/** Marks resources which are possibly referenced by string constants as reachable. */
+public class PossibleResourcesMarker {
+
+    // Copied from StringFormatDetector
+    // See java.util.Formatter docs
+    public static final Pattern FORMAT =
+            Pattern.compile(
+                    // Generic format:
+                    //   %[argument_index$][flags][width][.precision]conversion
+                    //
+                    "%"
+                            +
+                            // Argument Index
+                            "(\\d+\\$)?"
+                            +
+                            // Flags
+                            "([-+#, 0(<]*)?"
+                            +
+                            // Width
+                            "(\\d+)?"
+                            +
+                            // Precision
+                            "(\\.\\d+)?"
+                            +
+                            // Conversion. These are all a single character, except date/time
+                            // conversions
+                            // which take a prefix of t/T:
+                            "([tT])?"
+                            +
+                            // The current set of conversion characters are
+                            // b,h,s,c,d,o,x,e,f,g,a,t (as well as all those as upper-case
+                            // characters), plus
+                            // n for newlines and % as a literal %. And then there are all the
+                            // time/date
+                            // characters: HIKLm etc. Just match on all characters here since there
+                            // should
+                            // be at least one.
+                            "([a-zA-Z%])");
+
+    static final String NO_MATCH = "-nomatch-";
+
+    private final ShrinkerDebugReporter debugReporter;
+    private final ResourceStore resourceStore;
+    private final Set<String> strings;
+    private final boolean foundWebContent;
+
+    public PossibleResourcesMarker(ShrinkerDebugReporter debugReporter,
+                                   ResourceStore resourceStore,
+                                   Set<String> strings,
+                                   boolean foundWebContent) {
+        this.debugReporter = debugReporter;
+        this.resourceStore = resourceStore;
+        this.strings = strings;
+        this.foundWebContent = foundWebContent;
+    }
+
+    public void markPossibleResourcesReachable() {
+        Set<String> names =
+                resourceStore.getResources().stream()
+                        .map(resource -> resource.name)
+                        .collect(toImmutableSet());
+
+        int shortest = names.stream().mapToInt(String::length).min().orElse(Integer.MAX_VALUE);
+
+        // Check whether the string looks relevant
+        // We consider four types of strings:
+        //  (1) simple resource names, e.g. "foo" from @layout/foo
+        //      These might be the parameter to a getIdentifier() call, or could
+        //      be composed into a fully qualified resource name for the getIdentifier()
+        //      method. We match these for *all* resource types.
+        //  (2) Relative source names, e.g. layout/foo, from @layout/foo
+        //      These might be composed into a fully qualified resource name for
+        //      getIdentifier().
+        //  (3) Fully qualified resource names of the form package:type/name.
+        //  (4) If foundWebContent is true, look for android_res/ URL strings as well
+        strings.stream()
+                .filter(string -> string.length() >= shortest)
+                .flatMap(
+                        string -> {
+                            int n = string.length();
+                            boolean justName = true;
+                            boolean formatting = false;
+                            boolean haveSlash = false;
+                            for (int i = 0; i < n; i++) {
+                                char c = string.charAt(i);
+                                haveSlash |= c == '/';
+                                formatting |= c == '%';
+                                justName =
+                                        justName && !(c == '.' || c == ':' || c == '%' || c == '/');
+                            }
+
+                            Stream<Resource> reachable = Streams.concat(
+                                    foundWebContent
+                                            ? possibleWebResources(names, string)
+                                            : Stream.empty(),
+                                    justName ? possiblePrefixMatch(string) : Stream.empty(),
+                                    formatting && !haveSlash
+                                            ? possibleFormatting(string)
+                                            : Stream.empty(),
+                                    haveSlash
+                                            ? possibleTypedResource(names, string)
+                                            : Stream.empty(),
+                                    possibleIntResource(string));
+
+                            return reachable
+                                    .peek(resource -> debugReporter.debug(() -> "Marking "
+                                    + resource + " used because it matches string pool constant "
+                                    + string));
+                        })
+                .forEach(ResourceUsageModel::markReachable);
+    }
+
+    private Stream<Resource> possibleWebResources(
+            Set<String> names, String string) {
+        // Look for android_res/ URL strings.
+        List<Resource> resources = resourceStore.getResourcesFromWebUrl(string);
+        if (!resources.isEmpty()) {
+            return resources.stream();
+        }
+
+        int start = Math.max(string.lastIndexOf('/'), 0);
+        int dot = string.indexOf('.', start);
+        String name = string.substring(start, dot != -1 ? dot : string.length());
+
+        if (names.contains(name)) {
+            return resourceStore.getResourceMaps().stream()
+                    .filter(map -> map.containsKey(name))
+                    .flatMap(map -> map.get(name).stream());
+        }
+        return Stream.empty();
+    }
+
+    private Stream<Resource> possiblePrefixMatch(String string) {
+        // Check for a simple prefix match, e.g. as in
+        // getResources().getIdentifier("ic_video_codec_" + codecName, "drawable", ...)
+        return resourceStore.getResources().stream()
+                .filter(resource -> resource.name.startsWith(string));
+    }
+
+    private Stream<Resource> possibleFormatting(String string) {
+        // Possibly a formatting string, e.g.
+        //   String name = String.format("my_prefix_%1d", index);
+        //   int res = getContext().getResources().getIdentifier(name, "drawable", ...)
+        try {
+            Pattern pattern = Pattern.compile(convertFormatStringToRegexp(string));
+            return resourceStore.getResources().stream()
+                    .filter(resource -> pattern.matcher(resource.name).matches());
+        } catch (PatternSyntaxException ignored) {
+            return Stream.empty();
+        }
+    }
+
+    private Stream<Resource> possibleTypedResource(
+            Set<String> names, String string) {
+        // Try to pick out the resource name pieces; if we can find the
+        // resource type unambiguously; if not, just match on names
+        int slash = string.indexOf('/');
+        String name = string.substring(slash + 1);
+        if (name.isEmpty() || !names.contains(name)) {
+            return Stream.empty();
+        }
+        // See if have a known specific resource type
+        if (slash > 0) {
+            int colon = string.indexOf(':');
+            String typeName = string.substring(colon + 1, slash);
+            ResourceType type = ResourceType.fromClassName(typeName);
+            return type != null
+                    ? resourceStore.getResources(type, name).stream()
+                    : Stream.empty();
+        }
+        return resourceStore.getResourceMaps().stream()
+                .filter(map -> map.containsKey(name))
+                .flatMap(map -> map.get(name).stream());
+    }
+
+    private Stream<Resource> possibleIntResource(String string) {
+        // Just a number? There are cases where it calls getIdentifier by
+        // a String number; see for example SuggestionsAdapter in the support
+        // library which reports supporting a string like "2130837524" and
+        // "android.resource://com.android.alarmclock/2130837524".
+        String withoutSlash = string.substring(string.lastIndexOf('/') + 1);
+        if (withoutSlash.isEmpty() || !isDigit(withoutSlash.charAt(0))) {
+            return Stream.empty();
+        }
+        Integer id = Ints.tryParse(withoutSlash);
+        Resource resource = null;
+        if (id != null) {
+            resource = resourceStore.getResource(id);
+        }
+        return resource != null ? Stream.of(resource) : Stream.empty();
+    }
+
+    @VisibleForTesting
+    static String convertFormatStringToRegexp(String formatString) {
+        StringBuilder regexp = new StringBuilder();
+        int from = 0;
+        boolean hasEscapedLetters = false;
+        Matcher matcher = FORMAT.matcher(formatString);
+        int length = formatString.length();
+        while (matcher.find(from)) {
+            int start = matcher.start();
+            int end = matcher.end();
+            if (start == 0 && end == length) {
+                // Don't match if the entire string literal starts with % and ends with
+                // the a formatting character, such as just "%d": this just matches absolutely
+                // everything and is unlikely to be used in a resource lookup
+                return NO_MATCH;
+            }
+            if (start > from) {
+                hasEscapedLetters |= appendEscapedPattern(formatString, regexp, from, start);
+            }
+            String pattern = ".*";
+            String conversion = matcher.group(6);
+            String timePrefix = matcher.group(5);
+
+            //noinspection VariableNotUsedInsideIf,StatementWithEmptyBody: for readability.
+            if (timePrefix != null) {
+                // date notation; just use .* to match these
+            } else if (conversion != null && conversion.length() == 1) {
+                char type = conversion.charAt(0);
+                switch (type) {
+                    case 's':
+                    case 'S':
+                    case 't':
+                    case 'T':
+                        // Match everything
+                        break;
+                    case '%':
+                        pattern = "%";
+                        break;
+                    case 'n':
+                        pattern = "\n";
+                        break;
+                    case 'c':
+                    case 'C':
+                        pattern = ".";
+                        break;
+                    case 'x':
+                    case 'X':
+                        pattern = "\\p{XDigit}+";
+                        break;
+                    case 'd':
+                    case 'o':
+                        pattern = "\\p{Digit}+";
+                        break;
+                    case 'b':
+                        pattern = "(true|false)";
+                        break;
+                    case 'B':
+                        pattern = "(TRUE|FALSE)";
+                        break;
+                    case 'h':
+                    case 'H':
+                        pattern = "(null|\\p{XDigit}+)";
+                        break;
+                    case 'f':
+                        pattern = "-?[\\p{XDigit},.]+";
+                        break;
+                    case 'e':
+                        pattern = "-?\\p{Digit}+[,.]\\p{Digit}+e\\+?\\p{Digit}+";
+                        break;
+                    case 'E':
+                        pattern = "-?\\p{Digit}+[,.]\\p{Digit}+E\\+?\\p{Digit}+";
+                        break;
+                    case 'a':
+                        pattern = "0x[\\p{XDigit},.+p]+";
+                        break;
+                    case 'A':
+                        pattern = "0X[\\p{XDigit},.+P]+";
+                        break;
+                    case 'g':
+                    case 'G':
+                        pattern = "-?[\\p{XDigit},.+eE]+";
+                        break;
+                }
+
+                // Allow space or 0 prefix
+                if (!".*".equals(pattern)) {
+                    String width = matcher.group(3);
+                    //noinspection VariableNotUsedInsideIf
+                    if (width != null) {
+                        String flags = matcher.group(2);
+                        if ("0".equals(flags)) {
+                            pattern = "0*" + pattern;
+                        } else {
+                            pattern = " " + pattern;
+                        }
+                    }
+                }
+
+                // If it's a general .* wildcard which follows a previous .* wildcard,
+                // just skip it (e.g. don't convert %s%s into .*.*; .* is enough.)
+                int regexLength = regexp.length();
+                if (!".*".equals(pattern)
+                        || regexLength < 2
+                        || regexp.charAt(regexLength - 1) != '*'
+                        || regexp.charAt(regexLength - 2) != '.') {
+                    regexp.append(pattern);
+                }
+            }
+            from = end;
+        }
+
+        if (from < length) {
+            hasEscapedLetters |= appendEscapedPattern(formatString, regexp, from, length);
+        }
+
+        if (!hasEscapedLetters) {
+            // If the regexp contains *only* formatting characters, e.g. "%.0f%d", or
+            // if it contains only formatting characters and punctuation, e.g. "%s_%d",
+            // don't treat this as a possible resource name pattern string: it is unlikely
+            // to be intended for actual resource names, and has the side effect of matching
+            // most names.
+            return NO_MATCH;
+        }
+
+        return regexp.toString();
+    }
+
+    /**
+     * Appends the characters in the range [from,to> from formatString as escaped regexp characters
+     * into the given string builder. Returns true if there were any letters in the appended text.
+     */
+    private static boolean appendEscapedPattern(
+            @NonNull String formatString, @NonNull StringBuilder regexp, int from, int to) {
+        regexp.append(Pattern.quote(formatString.substring(from, to)));
+
+        for (int i = from; i < to; i++) {
+            if (Character.isLetter(formatString.charAt(i))) {
+                return true;
+            }
+        }
+
+        return false;
+    }
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/ResourceShrinker.java b/src/resourceshrinker/java/com/android/build/shrinker/ResourceShrinker.java
new file mode 100644
index 0000000..e38056a
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/ResourceShrinker.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker;
+
+import com.android.annotations.NonNull;
+import java.io.File;
+import java.io.IOException;
+import java.util.Map;
+import javax.xml.parsers.ParserConfigurationException;
+import org.xml.sax.SAXException;
+
+/**
+ * Interface for unit that analyzes all resources (after resource merging, compilation and code
+ * shrinking has been completed) and figures out which resources are unused, and replaces them with
+ * dummy content inside zip archive file.
+ */
+public interface ResourceShrinker extends AutoCloseable {
+
+    /**
+     * Analyzes resources and detects unreachable ones. It includes the following steps:
+     *
+     * <ul>
+     *     <li>Gather resources available in project.
+     *     <li>Record resource usages via analyzing compiled code, AndroidManifest etc.
+     *     <li>Build reference graph and connect dependent resources.
+     *     <li>Detects WebView and/or {@code Resources#getIdentifier} usages and guess which
+     *         resources are reachable analyzing string constants available in compiled code.
+     *     <li>Processes resources explicitly asked to keep and discard. &lt;tools:keep&gt; and
+     *         &lt;tools:discard&gt; attribute.
+     *     <li>Based on the root references computes unreachable resources.
+     * </ul>
+     */
+    void analyze() throws IOException, ParserConfigurationException, SAXException;
+
+    /**
+     * Returns count of unused resources. Should be called after {@code ResourceShrinker#analyze}.
+     */
+    int getUnusedResourceCount();
+
+    /**
+     * Replaces entries in {@param source} zip archive that belong to unused resources with dummy
+     * content and produces a new {@param dest} zip archive. Zip archive should contain resources
+     * in 'res/' folder like it is stored in APK.
+     *
+     * <p>For now, doesn't change resource table and applies to file-based resources like layouts,
+     * menus and drawables, not value-based resources like strings and dimensions.
+     *
+     * <p>Should be called after {@code ResourceShrinker#analyze}.
+     */
+    void rewriteResourcesInApkFormat(
+            @NonNull File source,
+            @NonNull File dest,
+            @NonNull LinkedResourcesFormat format
+    ) throws IOException;
+
+    /**
+     * Replaces entries in {@param source} zip archive that belong to unused resources with dummy
+     * content and produces a new {@param dest} zip archive. Zip archive represents App Bundle which
+     * may have multiple modules and each module has its own resource directory: '${module}/res/'.
+     * Package name for each bundle module should be passed as {@param moduleToPackageName}.
+     *
+     * <p>For now, doesn't change resource table and applies to file-based resources like layouts,
+     * menus and drawables, not value-based resources like strings and dimensions.
+     *
+     * <p>Should be called after {@code ResourceShrinker#analyze}.
+     */
+    void rewriteResourcesInBundleFormat(
+            @NonNull File source,
+            @NonNull File dest,
+            @NonNull Map<String, String> moduleToPackageName
+    ) throws IOException;
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/ResourceShrinkerCli.java b/src/resourceshrinker/java/com/android/build/shrinker/ResourceShrinkerCli.java
new file mode 100644
index 0000000..3e30568
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/ResourceShrinkerCli.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker;
+
+import com.android.build.shrinker.gatherer.ProtoResourceTableGatherer;
+import com.android.build.shrinker.gatherer.ResourcesGatherer;
+import com.android.build.shrinker.graph.ProtoResourcesGraphBuilder;
+import com.android.build.shrinker.usages.DexUsageRecorder;
+import com.android.build.shrinker.usages.ProtoAndroidManifestUsageRecorder;
+import com.android.build.shrinker.usages.ResourceUsageRecorder;
+import com.android.build.shrinker.usages.ToolsAttributeUsageRecorder;
+import com.android.utils.FileUtils;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.nio.file.FileSystem;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.zip.ZipFile;
+import javax.xml.parsers.ParserConfigurationException;
+import org.xml.sax.SAXException;
+
+public class ResourceShrinkerCli {
+
+    private static final String INPUT_ARG = "--input";
+    private static final String DEX_INPUT_ARG = "--dex_input";
+    private static final String OUTPUT_ARG = "--output";
+    private static final String RES_ARG = "--raw_resources";
+    private static final String HELP_ARG = "--help";
+    private static final String PRINT_USAGE_LOG = "--print_usage_log";
+
+    private static final String ANDROID_MANIFEST_XML = "AndroidManifest.xml";
+    private static final String RESOURCES_PB = "resources.pb";
+    private static final String RES_FOLDER = "res";
+
+    private static class Options {
+        private String input;
+        private final List<String> dex_inputs = new ArrayList<>();
+        private String output;
+        private String usageLog;
+        private final List<String> rawResources = new ArrayList<>();
+        private boolean help;
+
+        private Options() {}
+
+        public static Options parseOptions(String[] args) {
+            Options options = new Options();
+            for (int i = 0; i < args.length; i++) {
+                String arg = args[i];
+                if (arg.startsWith(INPUT_ARG)) {
+                    i++;
+                    if (i == args.length) {
+                        throw new ResourceShrinkingFailedException("No argument given for input");
+                    }
+                    if (options.input != null) {
+                        throw new ResourceShrinkingFailedException(
+                                "More than one input not supported");
+                    }
+                    options.input = args[i];
+                } else if (arg.startsWith(OUTPUT_ARG)) {
+                    i++;
+                    if (i == args.length) {
+                        throw new ResourceShrinkingFailedException("No argument given for output");
+                    }
+                    if (options.output != null) {
+                        throw new ResourceShrinkingFailedException(
+                                "More than one output not supported");
+                    }
+                    options.output = args[i];
+                } else if (arg.startsWith(DEX_INPUT_ARG)) {
+                    i++;
+                    if (i == args.length) {
+                        throw new ResourceShrinkingFailedException(
+                                "No argument given for dex_input");
+                    }
+                    options.dex_inputs.add(args[i]);
+                } else if (arg.startsWith(PRINT_USAGE_LOG)) {
+                    i++;
+                    if (i == args.length) {
+                        throw new ResourceShrinkingFailedException(
+                                "No argument given for usage log");
+                    }
+                    if (options.usageLog != null) {
+                        throw new ResourceShrinkingFailedException(
+                                "More than usage log not supported");
+                    }
+                    options.usageLog = args[i];
+                } else if (arg.startsWith(RES_ARG)) {
+                    i++;
+                    if (i == args.length) {
+                        throw new ResourceShrinkingFailedException(
+                                "No argument given for raw_resources");
+                    }
+                    options.rawResources.add(args[i]);
+                } else if (arg.equals(HELP_ARG)) {
+                    options.help = true;
+                } else {
+                    throw new ResourceShrinkingFailedException("Unknown argument " + arg);
+                }
+            }
+            return options;
+        }
+
+        public String getInput() {
+            return input;
+        }
+
+        public String getOutput() {
+            return output;
+        }
+
+        public String getUsageLog() {
+            return usageLog;
+        }
+
+        public List<String> getRawResources() {
+            return rawResources;
+        }
+
+        public boolean isHelp() {
+            return help;
+        }
+    }
+
+    public static void main(String[] args) {
+        run(args);
+    }
+
+    protected static ResourceShrinkerImpl run(String[] args) {
+        try {
+            Options options = Options.parseOptions(args);
+            if (options.isHelp()) {
+                printUsage();
+                return null;
+            }
+            validateOptions(options);
+            ResourceShrinkerImpl resourceShrinker = runResourceShrinking(options);
+            return resourceShrinker;
+        } catch (IOException | ParserConfigurationException | SAXException e) {
+            throw new ResourceShrinkingFailedException(
+                    "Failed running resource shrinking: " + e.getMessage(), e);
+        }
+    }
+
+    private static ResourceShrinkerImpl runResourceShrinking(Options options)
+            throws IOException, ParserConfigurationException, SAXException {
+        validateInput(options.getInput());
+        List<ResourceUsageRecorder> resourceUsageRecorders = new ArrayList<>();
+        for (String dexInput : options.dex_inputs) {
+            validateFileExists(dexInput);
+            resourceUsageRecorders.add(
+                    new DexUsageRecorder(
+                            FileUtils.createZipFilesystem(Paths.get(dexInput)).getPath("")));
+        }
+        Path protoApk = Paths.get(options.getInput());
+        Path protoApkOut = Paths.get(options.getOutput());
+        FileSystem fileSystemProto = FileUtils.createZipFilesystem(protoApk);
+        resourceUsageRecorders.add(new DexUsageRecorder(fileSystemProto.getPath("")));
+        resourceUsageRecorders.add(
+                new ProtoAndroidManifestUsageRecorder(
+                        fileSystemProto.getPath(ANDROID_MANIFEST_XML)));
+        // If the apk contains a raw folder, find keep rules in there
+        if (new ZipFile(options.getInput())
+                .stream().anyMatch(zipEntry -> zipEntry.getName().startsWith("res/raw"))) {
+            Path rawPath = fileSystemProto.getPath("res", "raw");
+            resourceUsageRecorders.add(new ToolsAttributeUsageRecorder(rawPath));
+        }
+        ResourcesGatherer gatherer =
+                new ProtoResourceTableGatherer(fileSystemProto.getPath(RESOURCES_PB));
+        ProtoResourcesGraphBuilder res =
+                new ProtoResourcesGraphBuilder(
+                        fileSystemProto.getPath(RES_FOLDER), fileSystemProto.getPath(RESOURCES_PB));
+        ResourceShrinkerImpl resourceShrinker =
+                new ResourceShrinkerImpl(
+                        List.of(gatherer),
+                        null,
+                        resourceUsageRecorders,
+                        List.of(res),
+                        options.usageLog != null
+                                ? new FileReporter(Paths.get(options.usageLog).toFile())
+                                : NoDebugReporter.INSTANCE,
+                        false, // TODO(b/245721267): Add support for bundles
+                        true);
+        resourceShrinker.analyze();
+
+        resourceShrinker.rewriteResourcesInApkFormat(
+                protoApk.toFile(), protoApkOut.toFile(), LinkedResourcesFormat.PROTO);
+        return resourceShrinker;
+    }
+
+    private static void validateInput(String input) throws IOException {
+        ZipFile zipfile = new ZipFile(input);
+        if (zipfile.getEntry(ANDROID_MANIFEST_XML) == null) {
+            throw new ResourceShrinkingFailedException(
+                    "Input must include " + ANDROID_MANIFEST_XML);
+        }
+        if (zipfile.getEntry(RESOURCES_PB) == null) {
+            throw new ResourceShrinkingFailedException(
+                    "Input must include "
+                            + RESOURCES_PB
+                            + ". Did you not convert the input apk"
+                            + " to proto?");
+        }
+        if (zipfile.stream().noneMatch(zipEntry -> zipEntry.getName().startsWith(RES_FOLDER))) {
+            throw new ResourceShrinkingFailedException(
+                    "Input must include a " + RES_FOLDER + " folder");
+        }
+    }
+
+    private static void validateFileExists(String file) {
+        if (!Paths.get(file).toFile().exists()) {
+            throw new RuntimeException("Can't find file: " + file);
+        }
+    }
+
+    private static void validateOptions(Options options) {
+        if (options.getInput() == null) {
+            throw new ResourceShrinkingFailedException("No input given.");
+        }
+        if (options.getOutput() == null) {
+            throw new ResourceShrinkingFailedException("No output destination given.");
+        }
+        validateFileExists(options.getInput());
+        for (String rawResource : options.getRawResources()) {
+            validateFileExists(rawResource);
+        }
+    }
+
+    private static void printUsage() {
+        PrintStream out = System.err;
+        out.println("Usage:");
+        out.println("  resourceshrinker ");
+        out.println("    --input <input-file>, container with manifest, resources table and res");
+        out.println("      folder. May contain dex.");
+        out.println("    --dex_input <input-file> Container with dex files (only dex will be ");
+        out.println("       handled if this contains other files. Several --dex_input arguments");
+        out.println("       are supported");
+        out.println("    --output <output-file>");
+        out.println("    --raw_resource <xml-file or res directory>");
+        out.println("      optional, more than one raw_resoures argument might be given");
+        out.println("    --help prints this help message");
+    }
+
+    private static class ResourceShrinkingFailedException extends RuntimeException {
+        public ResourceShrinkingFailedException(String message) {
+            super(message);
+        }
+
+        public ResourceShrinkingFailedException(String message, Exception e) {
+            super(message, e);
+        }
+    }
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/ResourceShrinkerImpl.kt b/src/resourceshrinker/java/com/android/build/shrinker/ResourceShrinkerImpl.kt
new file mode 100644
index 0000000..1136085
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/ResourceShrinkerImpl.kt
@@ -0,0 +1,316 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker
+
+import com.android.SdkConstants.DOT_9PNG
+import com.android.SdkConstants.DOT_PNG
+import com.android.SdkConstants.DOT_XML
+import com.android.aapt.Resources
+import com.android.build.shrinker.DummyContent.TINY_9PNG
+import com.android.build.shrinker.DummyContent.TINY_9PNG_CRC
+import com.android.build.shrinker.DummyContent.TINY_BINARY_XML
+import com.android.build.shrinker.DummyContent.TINY_BINARY_XML_CRC
+import com.android.build.shrinker.DummyContent.TINY_PNG
+import com.android.build.shrinker.DummyContent.TINY_PNG_CRC
+import com.android.build.shrinker.DummyContent.TINY_PROTO_XML
+import com.android.build.shrinker.DummyContent.TINY_PROTO_XML_CRC
+import com.android.build.shrinker.gatherer.ResourcesGatherer
+import com.android.build.shrinker.graph.ResourcesGraphBuilder
+import com.android.build.shrinker.obfuscation.ObfuscationMappingsRecorder
+import com.android.build.shrinker.usages.ResourceUsageRecorder
+import com.android.ide.common.resources.findUnusedResources
+import com.android.ide.common.resources.usage.ResourceStore
+import com.android.ide.common.resources.usage.ResourceUsageModel.Resource
+import com.android.resources.FolderTypeRelationship
+import com.android.resources.ResourceFolderType
+import com.android.resources.ResourceType
+import com.google.common.io.ByteStreams
+import com.google.common.io.Files
+import java.io.BufferedOutputStream
+import java.io.File
+import java.io.FileOutputStream
+import java.io.IOException
+import java.io.InputStream
+import java.util.jar.JarEntry
+import java.util.jar.JarOutputStream
+import java.util.zip.CRC32
+import java.util.zip.ZipEntry
+import java.util.zip.ZipFile
+
+/**
+ * Unit that analyzes all resources (after resource merging, compilation and code shrinking has
+ * been completed) and figures out which resources are unused, and replaces them with dummy content
+ * inside zip archive file.
+ *
+ * Resource shrinker implementation that allows to customize:
+ * <ul>
+ *     <li>application resource gatherer (from R files, resource tables, etc);
+ *     <li>recorder for mappings from obfuscated class/methods to original class/methods;
+ *     <li>sources from which resource usages are recorded (Dex files, compiled JVM classes,
+ *         AndroidManifests, etc);
+ *     <li>resources graph builder that connects resources dependent on each other (analyzing
+ *         raw resources content in XML, HTML, CSS, JS, analyzing resource content in proto
+ *         compiled format);
+ * </ul>
+ */
+class ResourceShrinkerImpl(
+    private val resourcesGatherers: List<ResourcesGatherer>,
+    private val obfuscationMappingsRecorder: ObfuscationMappingsRecorder?,
+    private val usageRecorders: List<ResourceUsageRecorder>,
+    private val graphBuilders: List<ResourcesGraphBuilder>,
+    private val debugReporter: ShrinkerDebugReporter,
+    val supportMultipackages: Boolean,
+    private val usePreciseShrinking: Boolean
+) : ResourceShrinker {
+    val model = ResourceShrinkerModel(debugReporter, supportMultipackages)
+    private lateinit var unused: List<Resource>
+
+    override fun analyze() {
+        resourcesGatherers.forEach { it.gatherResourceValues(model) }
+        obfuscationMappingsRecorder?.recordObfuscationMappings(model)
+        usageRecorders.forEach { it.recordUsages(model) }
+        graphBuilders.forEach { it.buildGraph(model) }
+
+        model.resourceStore.processToolsAttributes()
+        model.keepPossiblyReferencedResources()
+
+        debugReporter.debug { model.resourceStore.dumpResourceModel() }
+
+        unused = findUnusedResources(model.resourceStore.resources) { roots ->
+            debugReporter.debug { "The root reachable resources are:" }
+            debugReporter.debug { roots.joinToString("\n", transform = { " $it" }) }
+        }
+        debugReporter.debug { "Unused resources are: " }
+        debugReporter.debug { unused.joinToString("\n", transform = { " $it" })}
+
+    }
+
+    override fun close() {
+        debugReporter.close()
+    }
+
+    override fun getUnusedResourceCount(): Int {
+        return unused.size
+    }
+
+    override fun rewriteResourcesInApkFormat(
+        source: File,
+        dest: File,
+        format: LinkedResourcesFormat
+    ) {
+        rewriteResourceZip(source, dest, ApkArchiveFormat(model.resourceStore, format))
+    }
+
+    override fun rewriteResourcesInBundleFormat(
+        source: File,
+        dest: File,
+        moduleNameToPackageNameMap: Map<String, String>
+    ) {
+        rewriteResourceZip(
+            source,
+            dest,
+            BundleArchiveFormat(model.resourceStore, moduleNameToPackageNameMap)
+        )
+    }
+
+    private fun rewriteResourceZip(source: File, dest: File, format: ArchiveFormat) {
+        if (dest.exists() && !dest.delete()) {
+            throw IOException("Could not delete $dest")
+        }
+        JarOutputStream(BufferedOutputStream(FileOutputStream(dest))).use { zos ->
+            ZipFile(source).use { zip ->
+                // Rather than using Deflater.DEFAULT_COMPRESSION we use 9 here,  since that seems
+                // to match the compressed sizes we observe in source .ap_ files encountered by the
+                // resource shrinker:
+                zos.setLevel(9)
+                zip.entries().asSequence().forEach {
+                    if (format.fileIsNotReachable(it)) {
+                        // If we don't use precise shrinking we don't remove the files, see:
+                        // https://b.corp.google.com/issues/37010152
+                        if (!usePreciseShrinking) {
+                            replaceWithDummyEntry(zos, it, format.resourcesFormat)
+                        }
+                    } else if (it.name.endsWith("resources.pb") && usePreciseShrinking) {
+                            removeResourceUnusedTableEntries(zip.getInputStream(it), zos, it)
+                    } else {
+                        copyToOutput(zip.getInputStream(it), zos, it)
+                    }
+                }
+            }
+        }
+        // If net negative, copy original back. This is unusual, but can happen
+        // in some circumstances, such as the one described in
+        // https://plus.google.com/+SaidTahsinDane/posts/X9sTSwoVUhB
+        // "Removed unused resources: Binary resource data reduced from 588KB to 595KB: Removed -1%"
+        // Guard against that, and worst case, just use the original.
+        val before = source.length()
+        val after = dest.length()
+        if (after > before) {
+            debugReporter.info {
+                "Resource shrinking did not work (grew from $before to $after); using original " +
+                "instead"
+            }
+            Files.copy(source, dest)
+        }
+    }
+
+    private fun removeResourceUnusedTableEntries(zis: InputStream,
+                                                 zos: JarOutputStream,
+                                                 srcEntry: ZipEntry) {
+        val resourceIdsToRemove =
+            model.resourceStore.resources.filter { !it.isReachable }.map { it.value }.toList()
+        val shrunkenResourceTable = Resources.ResourceTable.parseFrom(zis)
+                .nullOutEntriesWithIds(resourceIdsToRemove)
+        val bytes = shrunkenResourceTable.toByteArray()
+        val outEntry = JarEntry(srcEntry.name)
+        if (srcEntry.time != -1L) {
+            outEntry.time = srcEntry.time
+        }
+        if (srcEntry.method == JarEntry.STORED) {
+            outEntry.method = JarEntry.STORED
+            outEntry.size = bytes.size.toLong()
+            val crc = CRC32()
+            crc.update(bytes, 0, bytes.size)
+            outEntry.crc = crc.getValue()
+        }
+        zos.putNextEntry(outEntry)
+        zos.write(bytes)
+        zos.closeEntry()
+    }
+
+    /** Replaces the given entry with a minimal valid file of that type.  */
+    private fun replaceWithDummyEntry(
+        zos: JarOutputStream,
+        entry: ZipEntry,
+        format: LinkedResourcesFormat
+    ) {
+        // Create a new entry so that the compressed len is recomputed.
+        val name = entry.name
+        val (bytes, crc) = when {
+            // DOT_9PNG (.9.png) must be always before DOT_PNG (.png)
+            name.endsWith(DOT_9PNG) -> TINY_9PNG to TINY_9PNG_CRC
+            name.endsWith(DOT_PNG) -> TINY_PNG to TINY_PNG_CRC
+            name.endsWith(DOT_XML) && format == LinkedResourcesFormat.BINARY ->
+                TINY_BINARY_XML to TINY_BINARY_XML_CRC
+            name.endsWith(DOT_XML) && format == LinkedResourcesFormat.PROTO ->
+                TINY_PROTO_XML to TINY_PROTO_XML_CRC
+            else -> ByteArray(0) to 0L
+        }
+
+        val outEntry = JarEntry(name)
+        if (entry.time != -1L) {
+            outEntry.time = entry.time
+        }
+        if (entry.method == JarEntry.STORED) {
+            outEntry.method = JarEntry.STORED
+            outEntry.size = bytes.size.toLong()
+            outEntry.crc = crc
+        }
+        zos.putNextEntry(outEntry)
+        zos.write(bytes)
+        zos.closeEntry()
+        debugReporter.info {
+            "Skipped unused resource $name: ${entry.size} bytes (replaced with small dummy file " +
+            "of size ${bytes.size} bytes)"
+        }
+    }
+
+    private fun copyToOutput(zis: InputStream, zos: JarOutputStream, entry: ZipEntry) {
+        // We can't just compress all files; files that are not compressed in the source .ap_ file
+        // must be left uncompressed here, since for example RAW files need to remain uncompressed
+        // in the APK such that they can be mmap'ed at runtime.
+        // Preserve the STORED method of the input entry.
+        val outEntry = when (entry.method) {
+            JarEntry.STORED -> JarEntry(entry)
+            else -> JarEntry(entry.name)
+        }
+        if (entry.time != -1L) {
+            outEntry.time = entry.time
+        }
+        zos.putNextEntry(outEntry)
+        if (!entry.isDirectory) {
+            zos.write(ByteStreams.toByteArray(zis))
+        }
+        zos.closeEntry()
+    }
+}
+
+private interface ArchiveFormat {
+    val resourcesFormat: LinkedResourcesFormat
+    fun fileIsNotReachable(entry: ZipEntry): Boolean
+}
+
+private class ApkArchiveFormat(
+    private val store: ResourceStore,
+    override val resourcesFormat: LinkedResourcesFormat
+) : ArchiveFormat {
+
+    override fun fileIsNotReachable(entry: ZipEntry): Boolean {
+        if (entry.isDirectory || !entry.name.startsWith("res/")) {
+            return false
+        }
+        val (_, folder, name) = entry.name.split('/', limit = 3)
+        return !store.isJarPathReachable(folder, name)
+    }
+}
+
+private class BundleArchiveFormat(
+    private val store: ResourceStore,
+    private val moduleNameToPackageName: Map<String, String>
+) : ArchiveFormat {
+
+    override val resourcesFormat = LinkedResourcesFormat.PROTO
+
+    override fun fileIsNotReachable(entry: ZipEntry): Boolean {
+        val module = entry.name.substringBefore('/')
+        val packageName = moduleNameToPackageName[module]
+        if (entry.isDirectory || packageName == null || !entry.name.startsWith("$module/res/")) {
+            return false
+        }
+        val (_, _, folder, name) = entry.name.split('/', limit = 4)
+        return !store.isJarPathReachable(folder, name)
+    }
+}
+
+private fun ResourceStore.isJarPathReachable(
+    folder: String,
+    name: String
+): Boolean {
+    val folderType = ResourceFolderType.getFolderType(folder) ?: return true
+    val resourceName = name.substringBefore('.')
+    // Bundle format has a restriction: in case the same resource is duplicated in multiple modules
+    // its content should be the same in all of them. This restriction means that we can't replace
+    // resource with dummy content if its duplicate is used in some module.
+    return FolderTypeRelationship.getRelatedResourceTypes(folderType)
+        .filterNot { it == ResourceType.ID }
+        .flatMap { getResources(it, resourceName) }
+        .any { it.isReachable }
+}
+
+private fun ResourceStore.getResourceId(
+    folder: String,
+    name: String
+): Int {
+    val folderType = ResourceFolderType.getFolderType(folder) ?: return -1
+    val resourceName = name.substringBefore('.')
+    return FolderTypeRelationship.getRelatedResourceTypes(folderType)
+        .filterNot { it == ResourceType.ID }
+        .flatMap { getResources(it, resourceName) }
+        .map { it.value }
+        .getOrElse(0) { -1 }
+
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/ResourceShrinkerModel.java b/src/resourceshrinker/java/com/android/build/shrinker/ResourceShrinkerModel.java
new file mode 100644
index 0000000..ce1b39f
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/ResourceShrinkerModel.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker;
+
+import com.android.aapt.Resources.ResourceTable;
+import com.android.annotations.NonNull;
+import com.android.annotations.Nullable;
+import com.android.build.shrinker.obfuscation.ObfuscatedClasses;
+import com.android.ide.common.resources.usage.ResourceStore;
+import com.android.ide.common.resources.usage.ResourceUsageModel.Resource;
+import com.android.resources.ResourceType;
+import com.google.common.collect.Maps;
+import com.google.common.collect.Sets;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Map;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+/**
+ * Represents resource shrinker state that is shared between shrinker stages ResourcesGatherer,
+ * ObfuscationMappingsRecorder, ResourceUsageRecorder, ResourcesGraphBuilder and each stage
+ * contributes an information via changing its state.
+ */
+public class ResourceShrinkerModel {
+
+    private final ShrinkerDebugReporter debugReporter;
+
+    private final ResourceStore resourceStore;
+    private ObfuscatedClasses obfuscatedClasses = ObfuscatedClasses.NO_OBFUSCATION;
+
+    private final Set<String> strings = Sets.newHashSetWithExpectedSize(300);
+
+    private final Map<String, ResourceTable> resourceTableCache = Maps.newHashMap();
+
+    private boolean foundGetIdentifier = false;
+    private boolean foundWebContent = false;
+
+    public ResourceShrinkerModel(
+            ShrinkerDebugReporter debugReporter, boolean supportMultipackages) {
+        this.debugReporter = debugReporter;
+        resourceStore = new ResourceStore(supportMultipackages);
+    }
+
+    @NonNull
+    public ShrinkerDebugReporter getDebugReporter() {
+        return debugReporter;
+    }
+
+    @NonNull
+    public ResourceStore getResourceStore() {
+        return resourceStore;
+    }
+
+    @NonNull
+    public ObfuscatedClasses getObfuscatedClasses() {
+        return obfuscatedClasses;
+    }
+
+    /** Reports recorded mappings from obfuscated classes to original classes */
+    public void setObfuscatedClasses(@NonNull ObfuscatedClasses obfuscatedClasses) {
+        this.obfuscatedClasses = obfuscatedClasses;
+    }
+
+    /** Adds a new gathered resource to model. */
+    @NonNull
+    public Resource addResource(
+            @NonNull ResourceType type,
+            @Nullable String packageName,
+            @NonNull String name,
+            @Nullable String value) {
+        int intValue = -1;
+        try {
+            intValue = value != null ? Integer.decode(value) : -1;
+        } catch (NumberFormatException e) {
+            // ignore
+        }
+        return addResource(type, packageName, name, intValue);
+    }
+
+    /** Adds a new gathered resource to model. */
+    @NonNull
+    public Resource addResource(
+            @NonNull ResourceType type,
+            @Nullable String packageName,
+            @NonNull String name,
+            int value) {
+        return resourceStore.addResource(new Resource(packageName, type, name, value));
+    }
+
+    /** Adds string constant found in code to strings pool. */
+    public void addStringConstant(@NonNull String string) {
+        strings.add(string);
+    }
+
+    /** Returns is reference to {@code Resources#getIdentifier} is found in code. */
+    public boolean isFoundGetIdentifier() {
+        return foundGetIdentifier;
+    }
+
+    /** Reports that reference to {@code Resources#getIdentifier} is found in code. */
+    public void setFoundGetIdentifier(boolean foundGetIdentifier) {
+        this.foundGetIdentifier = foundGetIdentifier;
+    }
+
+    /** Returns is web content is found in code. */
+    public boolean isFoundWebContent() {
+        return foundWebContent;
+    }
+
+    /** Reports that reference to web content is found in code. */
+    public void setFoundWebContent(boolean foundWebContent) {
+        this.foundWebContent = foundWebContent;
+    }
+
+    /** Returns all string constants gathered from compiled classes. */
+    public Set<String> getStrings() {
+        return strings;
+    }
+
+    /**
+     * Mark resources that match string constants as reachable in case invocation of
+     * {@code Resources#getIdentifier} or web content is found in code and safe mode in enabled.
+     */
+    public void keepPossiblyReferencedResources() {
+        if (strings.isEmpty()
+                || !resourceStore.getSafeMode()
+                || (!foundGetIdentifier && !foundWebContent)) {
+            // No calls to android.content.res.Resources#getIdentifier; or user specifically asked
+            // for us not to guess resources to keep
+            return;
+        }
+
+        debugReporter.debug(() -> ""
+                        + "android.content.res.Resources#getIdentifier present: " + foundGetIdentifier + "\n"
+                        + "Web content present: " + foundWebContent + "\n"
+                        + "Referenced Strings:\n"
+                        + strings.stream()
+                            .map(s -> s.trim().replace("\n", "\\n"))
+                            .filter(s -> !s.isEmpty())
+                            .map(s -> s.length() > 40 ? s.substring(0, 37) + "..." : s)
+                            .collect(Collectors.joining("\n"))
+        );
+
+        new PossibleResourcesMarker(debugReporter, resourceStore, strings, foundWebContent)
+                .markPossibleResourcesReachable();
+    }
+
+    /**
+     * Reads resource table from specified path and stores it in cache to be able to reuse it if
+     * the same resource table is requested by another unit.
+     */
+    public ResourceTable readResourceTable(Path resourceTablePath) {
+        return resourceTableCache.computeIfAbsent(resourceTablePath.toString(), (path) -> {
+            try {
+                return ResourceTable.parseFrom(Files.readAllBytes(resourceTablePath));
+            } catch (IOException e) {
+                throw new UncheckedIOException(e);
+            }
+        });
+    }
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/ResourceTableUtil.kt b/src/resourceshrinker/java/com/android/build/shrinker/ResourceTableUtil.kt
new file mode 100644
index 0000000..69952ef
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/ResourceTableUtil.kt
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker
+
+import com.android.aapt.Resources
+
+internal fun Resources.ResourceTable.entriesSequence(): Sequence<EntryWrapper> = sequence {
+    for (resourcePackage in packageList) {
+        for (resourceType in resourcePackage.typeList) {
+            for (resourceEntry in resourceType.entryList) {
+                val id = toIdentifier(resourcePackage, resourceType, resourceEntry)
+                yield(
+                    EntryWrapper(id, resourcePackage.packageName, resourceType.name, resourceEntry)
+                )
+            }
+        }
+    }
+}
+
+internal fun Resources.ResourceTable.nullOutEntriesWithIds(ids: List<Int>)
+    : Resources.ResourceTable {
+    if (ids.isEmpty()) {
+        return this
+    }
+    val packageMappings = calculatePackageMappings(ids)
+    val tableBuilder = this.toBuilder()
+    tableBuilder.packageBuilderList.forEach{
+        val typeMappings = packageMappings[it.packageId.id]
+        if (typeMappings != null) {
+            it.typeBuilderList.forEach { type->
+                val entryList = typeMappings[type.typeId.id]
+                if (entryList != null) {
+                    type.entryBuilderList.forEach { entry ->
+                        if (entryList.contains(entry.entryId.id)) {
+                            entry.clearConfigValue()
+                            if (entry.hasOverlayableItem()) {
+                                entry.clearOverlayableItem()
+                            }
+                        }
+                    }
+                }
+            }
+        }
+    }
+    return tableBuilder.build()
+}
+
+private fun calculatePackageMappings(ids: List<Int>): MutableMap<Int, Map<Int, List<Int>>> {
+    val sortedIds = ids.sorted()
+    val packageMapping = mutableMapOf<Int, Map<Int, List<Int>>>()
+    var typeMapping = mutableMapOf<Int, List<Int>>()
+    var entryList = mutableListOf<Int>()
+    var oldPackageId = -1
+    var oldTypeId = -1
+    for (value in sortedIds) {
+        val packageId = packageIdFromIdentifier(value)
+        val typeId = typeIdFromIdentifier(value)
+        val entryId = entryIdFromIdentifier(value)
+        if (packageId != oldPackageId) {
+            typeMapping = mutableMapOf()
+            packageMapping.put(packageId, typeMapping)
+            oldPackageId = packageId
+            oldTypeId = -1
+        }
+        if (typeId != oldTypeId) {
+            entryList = mutableListOf()
+            typeMapping.put(typeId, entryList)
+            oldTypeId = typeId
+        }
+        entryList.add(entryId)
+    }
+    return packageMapping
+}
+
+internal data class EntryWrapper(
+    val id: Int,
+    val packageName: String,
+    val type: String,
+    val entry: Resources.Entry
+)
+
+private fun toIdentifier(
+    resourcePackage: Resources.Package,
+    type: Resources.Type,
+    entry: Resources.Entry
+): Int =
+    (resourcePackage.packageId.id shl 24) or (type.typeId.id shl 16) or entry.entryId.id
+
+private fun packageIdFromIdentifier(
+    identifier: Int
+): Int =
+    identifier shr 24
+
+private fun typeIdFromIdentifier(
+    identifier: Int
+): Int =
+    (identifier and 0x00FF0000) shr 16
+
+private fun entryIdFromIdentifier(
+    identifier: Int
+): Int =
+    (identifier and 0x0000FFFF)
+
+
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/ShrinkerDebugReporter.kt b/src/resourceshrinker/java/com/android/build/shrinker/ShrinkerDebugReporter.kt
new file mode 100644
index 0000000..b592bb8
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/ShrinkerDebugReporter.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker
+
+import java.io.File
+import java.io.PrintWriter
+
+interface ShrinkerDebugReporter : AutoCloseable {
+    fun debug(f: () -> String)
+    fun info(f: () -> String)
+}
+
+object NoDebugReporter : ShrinkerDebugReporter {
+    override fun debug(f: () -> String) = Unit
+
+    override fun info(f: () -> String) = Unit
+
+    override fun close() = Unit
+}
+
+class FileReporter(
+    reportFile: File
+) : ShrinkerDebugReporter {
+    private val writer: PrintWriter = reportFile.let { PrintWriter(it) }
+    override fun debug(f: () -> String) {
+        writer.println(f())
+    }
+
+    override fun info(f: () -> String) {
+        writer.println(f())
+    }
+
+    override fun close() {
+        writer.close()
+    }
+}
+
+class LoggerAndFileDebugReporter(
+    private val logDebug: (String) -> Unit,
+    private val logInfo: (String) -> Unit,
+    reportFile: File?
+) : ShrinkerDebugReporter {
+    private val writer: PrintWriter? = reportFile?.let { PrintWriter(it) }
+
+    override fun debug(f: () -> String) {
+        val message = f()
+        writer?.println(message)
+        logDebug(message)
+    }
+
+    override fun info(f: () -> String) {
+        val message = f()
+        writer?.println(message)
+        logInfo(message)
+    }
+
+    override fun close() {
+        writer?.close()
+    }
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/gatherer/ProtoResourceTableGatherer.kt b/src/resourceshrinker/java/com/android/build/shrinker/gatherer/ProtoResourceTableGatherer.kt
new file mode 100644
index 0000000..c3c00eb
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/gatherer/ProtoResourceTableGatherer.kt
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker.gatherer
+
+import com.android.build.shrinker.ResourceShrinkerModel
+import com.android.build.shrinker.entriesSequence
+import com.android.ide.common.resources.resourceNameToFieldName
+import com.android.resources.ResourceType
+import java.nio.file.Path
+
+/**
+ * Gathers application resources from proto compiled resource table. Flattens each resource name to
+ * be compatible with field names in R classes.
+ *
+ * @param resourceTablePath path to resource table in proto format.
+ */
+class ProtoResourceTableGatherer(private val resourceTablePath: Path) : ResourcesGatherer {
+
+    override fun gatherResourceValues(model: ResourceShrinkerModel) {
+        model.readResourceTable(resourceTablePath).entriesSequence()
+            .forEach { (id, packageName, type, entry) ->
+                // We need to flatten resource names here to match fields names in R classes via
+                // invoking ResourcesUtil.resourceNameToFieldName because we need to record R fields
+                // usages in code.
+                ResourceType.fromClassName(type)
+                    ?.takeIf { it != ResourceType.STYLEABLE }
+                    ?.let {
+                        model.addResource(it, packageName, resourceNameToFieldName(entry.name), id)
+                    }
+            }
+    }
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/gatherer/ResourcesGatherer.java b/src/resourceshrinker/java/com/android/build/shrinker/gatherer/ResourcesGatherer.java
new file mode 100644
index 0000000..ffe5f5b
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/gatherer/ResourcesGatherer.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker.gatherer;
+
+import com.android.annotations.NonNull;
+import com.android.build.shrinker.ResourceShrinkerModel;
+import java.io.IOException;
+
+/**
+ * Interface for unit that should gather application resources and contribute them to
+ * ResourceShrinkerModel
+ */
+public interface ResourcesGatherer {
+
+  /**
+   * Gathers application resources and contribute them to ResourceShrinkerModel via
+   * ResourceShrinkerModel.addResource
+   */
+  void gatherResourceValues(@NonNull ResourceShrinkerModel model) throws IOException;
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/graph/ProtoResourcesGraphBuilder.kt b/src/resourceshrinker/java/com/android/build/shrinker/graph/ProtoResourcesGraphBuilder.kt
new file mode 100644
index 0000000..130e585
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/graph/ProtoResourcesGraphBuilder.kt
@@ -0,0 +1,302 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker.graph
+
+import com.android.aapt.Resources
+import com.android.aapt.Resources.Entry
+import com.android.aapt.Resources.FileReference
+import com.android.aapt.Resources.FileReference.Type.PROTO_XML
+import com.android.aapt.Resources.Reference
+import com.android.aapt.Resources.XmlAttribute
+import com.android.aapt.Resources.XmlElement
+import com.android.aapt.Resources.XmlNode
+import com.android.build.shrinker.ResourceShrinkerModel
+import com.android.build.shrinker.entriesSequence
+import com.android.ide.common.resources.usage.ResourceUsageModel
+import com.android.ide.common.resources.usage.ResourceUsageModel.Resource
+import com.android.ide.common.resources.usage.WebTokenizers
+import com.android.resources.ResourceType
+import com.android.utils.SdkUtils.IMAGE_EXTENSIONS
+import com.google.common.base.Ascii
+import java.io.IOException
+import java.nio.charset.StandardCharsets
+import java.nio.file.Files
+import java.nio.file.Path
+
+/**
+ * Builds resources graph starting from each resource in resource table in proto format and follow
+ * all references to other resources inside inlined values and external files from res/ folder.
+ *
+ * <p>Supports external files in the following formats:
+ * <ul>
+ *     <li>XML files compiled to proto format;
+ *     <li>HTML, CSS, JS files inside res/raw folder;
+ *     <li>Unknown files inside res/raw folder (only looks for 'android_res/<type>/<name>' pattern);
+ * </ul>
+ *
+ * <p>As ID resources don't specify parent-child relations between resources but are just
+ * identifiers for a resource or some part of the resource we don't gather them as references to
+ * examined resource.
+ *
+ * @param resourceRoot path to <module>/res/ folder.
+ * @param resourceTable path to resource table in proto format.
+ */
+class ProtoResourcesGraphBuilder(
+    private val resourceRoot: Path,
+    private val resourceTable: Path
+) : ResourcesGraphBuilder {
+
+    override fun buildGraph(model: ResourceShrinkerModel) {
+        model.readResourceTable(resourceTable).entriesSequence()
+            .map { (id, _, _, entry) ->
+                model.resourceStore.getResource(id)?.let {
+                    ReferencesForResourceFinder(resourceRoot, model, entry, it)
+                }
+            }
+            .filterNotNull()
+            .forEach { it.findReferences() }
+    }
+}
+
+private class ReferencesForResourceFinder(
+    private val resourcesRoot: Path,
+    private val model: ResourceShrinkerModel,
+    private val entry: Entry,
+    private val current: Resource
+) {
+    companion object {
+        /**
+         * 'android_res/' is a synthetic directory for resource references in URL format. For
+         *  example: file:///android_res/raw/intro_page.
+         */
+        private const val ANDROID_RES = "android_res/"
+
+        private const val CONSTRAINT_REFERENCED_IDS = "constraint_referenced_ids"
+
+        private fun Reference.asItem(): Resources.Item =
+            Resources.Item.newBuilder().setRef(this).build()
+    }
+
+    private val webTokenizers: WebTokenizers by lazy {
+        WebTokenizers(object : WebTokenizers.WebTokensCallback {
+            override fun referencedHtmlAttribute(tag: String?, attribute: String?, value: String) {
+                if (attribute == "href" || attribute == "src") {
+                    referencedUrl(value)
+                }
+            }
+
+            override fun referencedJsString(jsString: String) {
+                referencedStringFromWebContent(jsString)
+            }
+
+            override fun referencedCssUrl(url: String) {
+                referencedUrl(url)
+            }
+
+            private fun referencedUrl(url: String) {
+                // 1. if url contains '/' try to find resources from this web url.
+                // 2. if there is no '/' it might be just relative reference to another resource.
+                val resources = when {
+                    url.contains('/') -> model.resourceStore.getResourcesFromWebUrl(url)
+                    else ->
+                        model.resourceStore.getResources(ResourceType.RAW, url.substringBefore('.'))
+                }
+                if (resources.isNotEmpty()) {
+                    resources.forEach { current.addReference(it) }
+                } else {
+                    // if there is no resources found by provided url just gather this string as
+                    // found inside web content to process it afterwards.
+                    referencedStringFromWebContent(url)
+                }
+            }
+
+            private fun referencedStringFromWebContent(string: String) {
+                if (string.isNotEmpty() && string.length <= 80) {
+                    model.addStringConstant(string)
+                    model.isFoundWebContent = true
+                }
+            }
+        })
+    }
+
+    fun findReferences() {
+        // Walk through all values of the entry and find all Item instances that may reference
+        // other resources in resource table itself or specify external files that should be
+        // analyzed for references.
+        entry.configValueList.asSequence()
+            .map { it.value }
+            .flatMap { value ->
+                val compoundValue = value.compoundValue
+                // compoundValue.attr and compoundValue.styleable are skipped, attr defines
+                // references to ID resources only, but ID and STYLEABLE resources are not supported
+                // by shrinker.
+                when {
+                    value.hasItem() ->
+                        sequenceOf(value.item)
+                    compoundValue.hasStyle() ->
+                        sequenceOf(compoundValue.style.parent.asItem()) +
+                                compoundValue.style.entryList.asSequence().flatMap {
+                                    sequenceOf(
+                                        it.item,
+                                        it.key.asItem()
+                                    )
+                                }
+                    compoundValue.hasArray() ->
+                        compoundValue.array.elementList.asSequence().map { it.item }
+                    compoundValue.hasPlural() ->
+                        compoundValue.plural.entryList.asSequence().map { it.item }
+                    else -> emptySequence()
+                }
+            }
+            .forEach { findFromItem(it) }
+    }
+
+    private fun findFromItem(item: Resources.Item) {
+        try {
+            when {
+                item.hasRef() -> findFromReference(item.ref)
+                item.hasFile() && item.file.path.startsWith("res/") -> findFromFile(item.file)
+            }
+        } catch (e: IOException) {
+            model.debugReporter.debug { "File '${item.file.path}' can not be processed. Skipping." }
+        }
+    }
+
+    private fun findFromReference(reference: Reference) {
+        // Reference object may have id of referenced resource, in this case prefer resolved id.
+        // In case id is not provided try to find referenced resource by name. Name is converted
+        // to resource url here, because name in resource table is not normalized to R style field
+        // and to find it we need normalize it first (for example, in case name in resource table is
+        // MyStyle.Child in R file it is R.style.MyStyle_child).
+        val referencedResources = when {
+            reference.id != 0 -> listOf(model.resourceStore.getResource(reference.id))
+            reference.name.isNotEmpty() ->
+                model.resourceStore.getResourcesFromUrl("@${reference.name}")
+            else -> emptyList()
+        }
+        // IDs are not supported by shrinker for now, just skip it.
+        referencedResources.asSequence()
+            .filterNotNull()
+            .filter { it.type != ResourceType.ID }
+            .forEach { current.addReference(it) }
+    }
+
+    private fun findFromFile(file: FileReference) {
+        val path = resourcesRoot.resolve(file.path.substringAfter("res/"))
+        val bytes: ByteArray by lazy { Files.readAllBytes(path) }
+        val content: String by lazy { String(bytes, StandardCharsets.UTF_8) }
+        val extension = Ascii.toLowerCase(path.fileName.toString()).substringAfter('.')
+        when {
+            file.type == PROTO_XML -> fillFromXmlNode(XmlNode.parseFrom(bytes))
+            extension in listOf("html", "htm") -> webTokenizers.tokenizeHtml(content)
+            extension == "css" -> webTokenizers.tokenizeCss(content)
+            extension == "js" -> webTokenizers.tokenizeJs(content)
+            extension !in IMAGE_EXTENSIONS -> maybeAndroidResUrl(content, markAsReachable = false)
+        }
+    }
+
+    private fun fillFromXmlNode(node: XmlNode) {
+        // Check for possible reference as 'android_res/<type>/<name>' pattern inside element text.
+        if (current.type == ResourceType.XML) {
+            maybeAndroidResUrl(node.text, markAsReachable = true)
+        }
+        // Check special xml element <rawPathResId> which provides reference to res/raw/ apk
+        // resource for wear application. Applies to all XML files for now but might be re-scoped
+        // to only apply to <wearableApp> XMLs.
+        maybeWearAppReference(node.element)
+        node.element.attributeList.forEach { fillFromAttribute(it) }
+        node.element.childList.forEach { fillFromXmlNode(it) }
+    }
+
+    private fun fillFromAttribute(attribute: XmlAttribute) {
+        if (attribute.name == CONSTRAINT_REFERENCED_IDS) {
+            fillFromConstraintReferencedIds(attribute.value)
+        }
+        if (attribute.hasCompiledItem()) {
+            findFromItem(attribute.compiledItem)
+        }
+        // Check for possible reference as 'android_res/<type>/<name>' pattern inside attribute val.
+        if (current.type == ResourceType.XML) {
+            maybeAndroidResUrl(attribute.value, markAsReachable = true)
+        }
+    }
+
+    private fun fillFromConstraintReferencedIds(value: String?) {
+        value
+            ?.split(",")
+            ?.map { it.trim() }
+            ?.forEach {
+                model.resourceStore.getResources(ResourceType.ID, it)
+                    .forEach(ResourceUsageModel::markReachable)
+            }
+    }
+
+    private fun maybeAndroidResUrl(text: String, markAsReachable: Boolean) {
+        findAndroidResReferencesInText(text)
+            .map { it.split('/', limit = 2) }
+            .filter { it.size == 2 }
+            .map { (dir, fileName) ->
+                Pair(
+                    ResourceType.fromFolderName(dir.substringBefore('-')),
+                    fileName.substringBefore('.')
+                )
+            }
+            .filter { (type, _) -> type != null }
+            .flatMap { (type, name) -> model.resourceStore.getResources(type!!, name).asSequence() }
+            .forEach {
+                if (markAsReachable) {
+                    ResourceUsageModel.markReachable(it)
+                } else {
+                    current.addReference(it)
+                }
+            }
+    }
+
+    private fun maybeWearAppReference(element: XmlElement) {
+        if (element.name == "rawPathResId") {
+            val rawResourceName = element.childList
+                .map { it.text }
+                .joinToString(separator = "")
+                .trim()
+
+            model.resourceStore.getResources(ResourceType.RAW, rawResourceName)
+                .forEach { current.addReference(it) }
+        }
+    }
+
+    /**
+     * Splits input text to parts that starts with 'android_res/' and returns sequence of strings
+     * between 'android_res/' occurrences and first whitespace after it. This method is used instead
+     * of {@link CharSequence#splitToSequence} because does not spawn full substrings between
+     * 'android_res/' in memory when text is big enough.
+     */
+    private fun findAndroidResReferencesInText(text: String): Sequence<String> = sequence {
+        var start = 0
+        while (start < text.length) {
+            start = text.indexOf(ANDROID_RES, start)
+            if (start == -1) {
+                break
+            }
+            var end = start + ANDROID_RES.length
+            while (end < text.length && !Character.isWhitespace(text[end])) {
+                end++
+            }
+            yield(text.substring(start + ANDROID_RES.length, end))
+            start = end
+        }
+    }
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/graph/ResourcesGraphBuilder.java b/src/resourceshrinker/java/com/android/build/shrinker/graph/ResourcesGraphBuilder.java
new file mode 100644
index 0000000..e09b0eb
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/graph/ResourcesGraphBuilder.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker.graph;
+
+import com.android.annotations.NonNull;
+import com.android.build.shrinker.ResourceShrinkerModel;
+import java.io.IOException;
+
+/**
+ * Interface for unit that should find references between resources which are gathered inside
+ * ResourceShrinkerModel.
+ */
+public interface ResourcesGraphBuilder {
+
+  /**
+   * Finds references between resources and connects them. May introduce and contribute new
+   * resources to ResourceShrinkerModel.
+   */
+  void buildGraph(@NonNull ResourceShrinkerModel model) throws IOException;
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/obfuscation/ObfuscatedClasses.kt b/src/resourceshrinker/java/com/android/build/shrinker/obfuscation/ObfuscatedClasses.kt
new file mode 100644
index 0000000..3cf757d
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/obfuscation/ObfuscatedClasses.kt
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker.obfuscation
+
+import com.google.common.collect.ImmutableMap
+
+/** Contains mappings between obfuscated classes and methods to original ones. */
+class ObfuscatedClasses private constructor(builder: Builder) {
+
+    companion object {
+        @JvmField
+        val NO_OBFUSCATION = Builder().build()
+    }
+
+    private val obfuscatedClasses = ImmutableMap.copyOf(builder.obfuscatedClasses)
+    private val obfuscatedMethods = ImmutableMap.copyOf(builder.obfuscatedMethods)
+
+    fun resolveOriginalMethod(obfuscatedMethod: ClassAndMethod): ClassAndMethod {
+        return obfuscatedMethods.getOrElse(obfuscatedMethod) {
+            val realClassName = obfuscatedClasses[obfuscatedMethod.className] ?: obfuscatedMethod.className
+            ClassAndMethod(realClassName, obfuscatedMethod.methodName)
+        }
+    }
+
+    fun resolveOriginalClass(obfuscatedClass: String): String {
+        return obfuscatedClasses[obfuscatedClass] ?: obfuscatedClass
+    }
+
+    /**
+     * Builder that allows to build obfuscated mappings in a way when next method mapping is added
+     * to previous class mapping. Example:
+     * builder
+     *   .addClassMapping(Pair(classA, obfuscatedClassA))
+     *   .addMethodMapping(Pair(classAMethod1, obfuscatedClassAMethod1))
+     *   .addMethodMapping(Pair(classAMethod2, obfuscatedClassAMethod2))
+     *   .addClassMapping(Pair(classB, obfuscatedClassB))
+     *   .addMethodMapping(Pair(classBMethod1, obfuscatedClassBMethod1))
+     */
+    class Builder {
+
+        val obfuscatedClasses: MutableMap<String, String> = mutableMapOf()
+        val obfuscatedMethods: MutableMap<ClassAndMethod, ClassAndMethod> = mutableMapOf()
+
+        var currentClassMapping: Pair<String, String>? = null
+
+        /**
+         * Adds class mapping: original class name -> obfuscated class name.
+         *
+         * @param mapping Pair(originalClassName, obfuscatedClassName)
+         */
+        fun addClassMapping(mapping: Pair<String, String>): Builder {
+            currentClassMapping = mapping
+            obfuscatedClasses += Pair(mapping.second, mapping.first)
+            return this
+        }
+
+        /**
+         * Adds method mapping: original method name -> obfuscated method name to the latest added
+         * class mapping.
+         *
+         * @param mapping Pair(originalMethodName, obfuscatedMethodName)
+         */
+        fun addMethodMapping(mapping: Pair<String, String>): Builder {
+            if (currentClassMapping != null) {
+                obfuscatedMethods += Pair(
+                    ClassAndMethod(currentClassMapping!!.second, mapping.second),
+                    ClassAndMethod(currentClassMapping!!.first, mapping.first)
+                )
+            }
+            return this
+        }
+
+        fun build(): ObfuscatedClasses =
+            ObfuscatedClasses(this)
+    }
+}
+
+data class ClassAndMethod(val className: String, val methodName: String)
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/obfuscation/ObfuscationMappingsRecorder.java b/src/resourceshrinker/java/com/android/build/shrinker/obfuscation/ObfuscationMappingsRecorder.java
new file mode 100644
index 0000000..6e76c8d
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/obfuscation/ObfuscationMappingsRecorder.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker.obfuscation;
+
+import com.android.annotations.NonNull;
+import com.android.build.shrinker.ResourceShrinkerModel;
+import java.io.IOException;
+
+/**
+ * Interface for unit that should record obfuscation mappings and contribute it to
+ * ResourceShrinkerModel.obfuscatedClasses.
+ */
+public interface ObfuscationMappingsRecorder {
+
+    /**
+     * Records obfuscation mappings to be able to resolve original class name and original method
+     * name when all references in code are obfuscated. Should create and contribute
+     * ObfuscatedClasses instance to ResourceShrinkerModel.obfuscatedClasses.
+     */
+    void recordObfuscationMappings(@NonNull ResourceShrinkerModel model) throws IOException;
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/obfuscation/ProguardMappingsRecorder.kt b/src/resourceshrinker/java/com/android/build/shrinker/obfuscation/ProguardMappingsRecorder.kt
new file mode 100644
index 0000000..dd538c7
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/obfuscation/ProguardMappingsRecorder.kt
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker.obfuscation
+
+import com.android.build.shrinker.ResourceShrinkerModel
+import java.nio.charset.StandardCharsets
+import java.nio.file.Files
+import java.nio.file.Path
+
+/**
+ * Records obfuscation mappings from single file in proguard format.
+ *
+ * @param mappingsFile path to proguard.map file.
+ */
+class ProguardMappingsRecorder(private val mappingsFile: Path) : ObfuscationMappingsRecorder {
+
+    override fun recordObfuscationMappings(model: ResourceShrinkerModel) {
+        model.obfuscatedClasses = extractObfuscatedResourceClasses()
+    }
+
+    internal fun extractObfuscatedResourceClasses(): ObfuscatedClasses {
+        // Proguard obfuscation mappings file has the following structure:
+        // # comment1
+        // com.package.MainClass -> a.a:
+        //     int field -> a
+        //     boolean getFlag() -> b
+        // com.package.R -> a.b:
+        // com.package.R$style -> a.b.a:
+        //     int Toolbar_android_gravity -> i1
+
+        val builder = ObfuscatedClasses.Builder()
+        Files.readAllLines(mappingsFile, StandardCharsets.UTF_8).forEach { line ->
+            when {
+                isMethodMapping(line) -> builder.addMethodMapping(extractMethodMapping(line))
+                isClassMapping(line) -> builder.addClassMapping(extractClassMapping(line))
+            }
+        }
+        return builder.build()
+    }
+
+    private fun isClassMapping(line: String): Boolean = line.contains("->")
+
+    private fun isMethodMapping(line: String): Boolean =
+        (line.startsWith(" ") || line.startsWith("\t")) && line.contains("->")
+
+    private fun extractClassMapping(line: String): Pair<String, String> {
+        val mapping = line.split("->", limit = 2)
+        return Pair(mapping[0].trim(), mapping[1].trim(' ', '\t', ':'))
+    }
+
+    private fun extractMethodMapping(line: String): Pair<String, String> {
+        val mapping = line.split("->", limit = 2)
+        val originalMethod = mapping[0].trim()
+            .substringBeforeLast('(')
+            .substringAfter(' ')
+        val obfuscatedMethod = mapping[1].trim()
+        return Pair(originalMethod, obfuscatedMethod)
+    }
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/usages/AppCompat.kt b/src/resourceshrinker/java/com/android/build/shrinker/usages/AppCompat.kt
new file mode 100644
index 0000000..bbfea7c
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/usages/AppCompat.kt
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker.usages
+
+import com.android.build.shrinker.obfuscation.ObfuscatedClasses
+
+internal object AppCompat {
+    // Known AppCompat classes which use Resources.getIdentifier but should not trigger mode that
+    // tries to find used resources based on collected strings.
+    internal val APP_COMPAT_CLASSES_ALLOWED_FOR_GET_IDENTIFIER = setOf(
+        "android.support.v7.widget.SuggestionsAdapter",
+        "android.support.v7.internal.widget.ResourcesWrapper",
+        "android.support.v7.widget.ResourcesWrapper",
+        "android.support.v7.widget.TintContextWrapper\$TintResources"
+    )
+
+    internal fun isAppCompatClass(name: String, obfuscation: ObfuscatedClasses): Boolean =
+        APP_COMPAT_CLASSES_ALLOWED_FOR_GET_IDENTIFIER.contains(obfuscation.resolveOriginalClass(name))
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/usages/DexUsageRecorder.kt b/src/resourceshrinker/java/com/android/build/shrinker/usages/DexUsageRecorder.kt
new file mode 100644
index 0000000..3f1a676
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/usages/DexUsageRecorder.kt
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker.usages
+
+import com.android.SdkConstants.DOT_DEX
+import com.android.build.shrinker.ResourceShrinkerModel
+import com.android.build.shrinker.obfuscation.ClassAndMethod
+import com.android.build.shrinker.usages.AppCompat.isAppCompatClass
+import com.android.ide.common.resources.usage.ResourceUsageModel
+import com.android.resources.ResourceType
+import com.android.tools.r8.references.MethodReference
+import java.nio.file.Files
+import java.nio.file.Path
+
+/**
+ * Records resource usages, detects usages of WebViews and {@code Resources#getIdentifier},
+ * gathers string constants from compiled .dex files.
+ *
+ * @param root directory starting from which all .dex files are analyzed.
+ */
+class DexUsageRecorder(val root: Path) : ResourceUsageRecorder {
+
+    override fun recordUsages(model: ResourceShrinkerModel) {
+        // Record resource usages from dex classes. The following cases are covered:
+        // 1. Integer constant which refers to resource id.
+        // 2. Reference to static field in R classes.
+        // 3. Usages of android.content.res.Resources.getIdentifier(...) and
+        //    android.webkit.WebView.load...
+        // 4. All strings which might be used to reference resources by name via
+        //    Resources.getIdentifier.
+
+        Files.walk(root)
+            .filter { Files.isRegularFile(it) }
+            .filter { it.toString().endsWith(DOT_DEX, ignoreCase = true) }
+            .forEach { path ->
+                runResourceShrinkerAnalysis(
+                        Files.readAllBytes(path),
+                        path,
+                        DexFileAnalysisCallback(path, model)
+                )
+            }
+    }
+}
+
+private class DexFileAnalysisCallback(
+        private val path: Path,
+        private val model: ResourceShrinkerModel
+) : AnalysisCallback {
+    companion object {
+        const val ANDROID_RES = "android_res/"
+
+        private fun String.toSourceClassName(): String {
+            return this.replace('/', '.')
+        }
+    }
+
+    // R class methods should only be processed for reachable resource IDs. R class fields that are
+    // not referenced should not be considered since there is no usage in the program.
+    // If the fields have been inlined, the values at the callsite will be recorded when visited.
+    var isRClass: Boolean = false
+
+    // In cases where a value from a method is inlined into a constant, we should still mark the
+    // resource as used.
+    val visitingMethod = MethodVisitingStatus()
+
+    override fun shouldProcess(internalName: String): Boolean {
+        isRClass = isResourceClass(internalName)
+        return true
+    }
+
+    /** Returns whether the given class file name points to an aapt-generated compiled R class. */
+    fun isResourceClass(internalName: String): Boolean {
+        val realClassName =
+            model.obfuscatedClasses.resolveOriginalClass(internalName.toSourceClassName())
+        val lastPart = realClassName.substringAfterLast('.')
+        if (lastPart.startsWith("R$")) {
+            val typeName = lastPart.substring(2)
+            return ResourceType.fromClassName(typeName) != null
+        }
+        return false
+    }
+
+    override fun referencedInt(value: Int) {
+        // Avoid marking R class fields as reachable.
+        if (shouldIgnoreField()) {
+            return
+        }
+        val resource = model.resourceStore.getResource(value)
+        if (ResourceUsageModel.markReachable(resource)) {
+            model.debugReporter.debug {
+                "Marking $resource reachable: referenced from $path"
+            }
+        }
+    }
+
+    override fun referencedStaticField(internalName: String, fieldName: String) {
+        // Avoid marking R class fields as reachable.
+        if (shouldIgnoreField()) {
+            return
+        }
+        val realMethod = model.obfuscatedClasses.resolveOriginalMethod(
+                ClassAndMethod(internalName.toSourceClassName(), fieldName)
+        )
+
+        if (isValidResourceType(realMethod.className)) {
+            val typePart = realMethod.className.substringAfterLast('$')
+            ResourceType.fromClassName(typePart)?.let { type ->
+                model.resourceStore.getResources(type, realMethod.methodName)
+                    .forEach { ResourceUsageModel.markReachable(it) }
+            }
+        }
+    }
+
+    override fun referencedString(value: String) {
+        // Avoid marking R class fields as reachable.
+        if (shouldIgnoreField()) {
+                return
+        }
+        // See if the string is at all eligible; ignore strings that aren't identifiers (has java
+        // identifier chars and nothing but .:/), or are empty or too long.
+        // We also allow "%", used for formatting strings.
+        if (value.isEmpty() || value.length > 80) {
+            return
+        }
+        fun isSpecialCharacter(c: Char) = c == '.' || c == ':' || c == '/' || c == '%'
+
+        if (value.all { Character.isJavaIdentifierPart(it) || isSpecialCharacter(it) } &&
+            value.any { Character.isJavaIdentifierPart(it) }) {
+            model.addStringConstant(value)
+            model.isFoundWebContent = model.isFoundWebContent || value.contains(ANDROID_RES)
+        }
+    }
+
+    override fun referencedMethod(
+            internalName: String,
+            methodName: String,
+            methodDescriptor: String
+    ) {
+        if (isRClass && visitingMethod.isVisiting && visitingMethod.methodName == "<clinit>") {
+            return
+        }
+        if (internalName == "android/content/res/Resources" &&
+            methodName == "getIdentifier" &&
+            methodDescriptor == "(Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;)I"
+        ) {
+            // "benign" usages: don't trigger reflection mode just because the user has included
+            // appcompat
+            if (isAppCompatClass(internalName.toSourceClassName(), model.obfuscatedClasses)) {
+                return
+            }
+            model.isFoundGetIdentifier = true
+            // TODO: Check previous instruction and see if we can find a literal String; if so, we
+            // can more accurately dispatch the resource here rather than having to check the whole
+            // string pool!
+        }
+        if (internalName == "android/webkit/WebView" && methodName.startsWith("load")) {
+            model.isFoundWebContent = true
+        }
+    }
+
+    override fun startMethodVisit(methodReference: MethodReference) {
+        visitingMethod.isVisiting = true
+        visitingMethod.methodName = methodReference.methodName
+    }
+
+    override fun endMethodVisit(methodReference: MethodReference) {
+        visitingMethod.isVisiting = false
+        visitingMethod.methodName = null
+    }
+
+    private fun shouldIgnoreField(): Boolean {
+        val visitingFromStaticInitRClass = (isRClass
+                && visitingMethod.isVisiting
+                && (visitingMethod.methodName == "<clinit>"))
+        return visitingFromStaticInitRClass ||
+                isRClass && !visitingMethod.isVisiting
+    }
+
+    private fun isValidResourceType(className: String): Boolean =
+        className.substringAfterLast('.').startsWith("R$")
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/usages/ProtoAndroidManifestUsageRecorder.kt b/src/resourceshrinker/java/com/android/build/shrinker/usages/ProtoAndroidManifestUsageRecorder.kt
new file mode 100644
index 0000000..4e6aa3e
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/usages/ProtoAndroidManifestUsageRecorder.kt
@@ -0,0 +1,58 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker.usages
+
+import com.android.aapt.Resources.XmlNode
+import com.android.build.shrinker.ResourceShrinkerModel
+import com.android.ide.common.resources.usage.ResourceUsageModel
+import java.nio.file.Files
+import java.nio.file.Path
+
+/**
+ * Records resource usages from AndroidManifest.xml in proto compiled format.
+ *
+ * @param manifest path to AndroidManifest.xml file.
+ */
+class ProtoAndroidManifestUsageRecorder(private val manifest: Path) : ResourceUsageRecorder {
+
+    override fun recordUsages(model: ResourceShrinkerModel) {
+        val root = XmlNode.parseFrom(Files.readAllBytes(manifest))
+        recordUsagesFromNode(root, model)
+    }
+
+    private fun recordUsagesFromNode(node: XmlNode, model: ResourceShrinkerModel) {
+        // Records only resources from element attributes that have reference items with resolved
+        // ids or names.
+        if (!node.hasElement()) {
+            return
+        }
+        node.element.attributeList.asSequence()
+            .filter { it.hasCompiledItem() }
+            .map { it.compiledItem }
+            .filter { it.hasRef() }
+            .map { it.ref }
+            .flatMap {
+                // If resource id is available prefer this id to name.
+                when {
+                    it.id != 0 -> listOfNotNull(model.resourceStore.getResource(it.id))
+                    else -> model.resourceStore.getResourcesFromUrl("@${it.name}")
+                }.asSequence()
+            }
+            .forEach { ResourceUsageModel.markReachable(it) }
+        node.element.childList.forEach { recordUsagesFromNode(it, model) }
+    }
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/usages/ResourceUsageRecorder.java b/src/resourceshrinker/java/com/android/build/shrinker/usages/ResourceUsageRecorder.java
new file mode 100644
index 0000000..46bfddb
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/usages/ResourceUsageRecorder.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker.usages;
+
+import com.android.annotations.NonNull;
+import com.android.build.shrinker.ResourceShrinkerModel;
+import java.io.IOException;
+
+/**
+ * Interface for unit that should record resource usages and contribute this information to
+ * ResourceShrinkerModel.
+ */
+public interface ResourceUsageRecorder {
+
+  /** Records resource usages. */
+  void recordUsages(@NonNull ResourceShrinkerModel model) throws IOException;
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/usages/ToolsAttributeUsageRecorder.kt b/src/resourceshrinker/java/com/android/build/shrinker/usages/ToolsAttributeUsageRecorder.kt
new file mode 100644
index 0000000..3d0dc6f
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/usages/ToolsAttributeUsageRecorder.kt
@@ -0,0 +1,89 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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 com.android.build.shrinker.usages
+
+import com.android.SdkConstants.VALUE_STRICT
+import com.android.build.shrinker.ResourceShrinkerModel
+import com.android.utils.XmlUtils
+import com.google.common.collect.ImmutableMap.copyOf
+import java.io.Reader
+import java.nio.file.Files
+import java.nio.file.Path
+import javax.xml.stream.XMLInputFactory
+
+/**
+ * Records usages of tools:keep, tools:discard and tools:shrinkMode in resources.
+ *
+ * <p>This unit requires to analyze resources in raw XML format because as said in
+ * <a href="https://developer.android.com/studio/write/tool-attributes>documentation</a> these
+ * attributes may appear in any &lt;resources&gt; element and some files that contain such element
+ * are not compiled to proto. For example raw and values resources like res/raw/keep.xml,
+ * res/values/values.xml etc.
+ *
+ * @param rawResourcesPath path to folder with resources in raw format.
+ */
+class ToolsAttributeUsageRecorder(val rawResourcesPath: Path) : ResourceUsageRecorder {
+    companion object {
+        private val TOOLS_NAMESPACE = "http://schemas.android.com/tools"
+    }
+
+    override fun recordUsages(model: ResourceShrinkerModel) {
+        Files.walk(rawResourcesPath)
+            .filter { it.fileName.toString().endsWith(".xml", ignoreCase = true) }
+            .forEach { processRawXml(it, model) }
+    }
+
+    private fun processRawXml(path: Path, model: ResourceShrinkerModel) {
+        processResourceToolsAttributes(path).forEach { key, value ->
+            when (key) {
+                "keep" -> model.resourceStore.recordKeepToolAttribute(value)
+                "discard" -> model.resourceStore.recordDiscardToolAttribute(value)
+                "shrinkMode" ->
+                    if (value == VALUE_STRICT) {
+                        model.resourceStore.safeMode = false
+                    }
+            }
+        }
+    }
+
+    private fun processResourceToolsAttributes(path: Path): Map<String, String> {
+        val toolsAttributes = mutableMapOf<String, String>()
+        XmlUtils.getUtfReader(path).use { reader: Reader ->
+            val factory = XMLInputFactory.newInstance()
+            val xmlStreamReader = factory.createXMLStreamReader(reader)
+
+            var rootElementProcessed = false
+            while (!rootElementProcessed && xmlStreamReader.hasNext()) {
+                xmlStreamReader.next()
+                if (xmlStreamReader.isStartElement) {
+                    if (xmlStreamReader.localName == "resources") {
+                        for (i in 0 until xmlStreamReader.attributeCount) {
+                            if (xmlStreamReader.getAttributeNamespace(i) == TOOLS_NAMESPACE) {
+                                toolsAttributes.put(
+                                    xmlStreamReader.getAttributeLocalName(i),
+                                    xmlStreamReader.getAttributeValue(i)
+                                )
+                            }
+                        }
+                    }
+                    rootElementProcessed = true
+                }
+            }
+        }
+        return copyOf(toolsAttributes)
+    }
+}
diff --git a/src/resourceshrinker/java/com/android/build/shrinker/usages/r8ResourceShrinker.kt b/src/resourceshrinker/java/com/android/build/shrinker/usages/r8ResourceShrinker.kt
new file mode 100644
index 0000000..6bfd90f
--- /dev/null
+++ b/src/resourceshrinker/java/com/android/build/shrinker/usages/r8ResourceShrinker.kt
@@ -0,0 +1,77 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * 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
+ *
+ *      http://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.
+ */
+
+@file:JvmName("R8ResourceShrinker")
+
+package com.android.build.shrinker.usages
+
+import com.android.tools.r8.ProgramResource
+import com.android.tools.r8.ProgramResourceProvider
+import com.android.tools.r8.ResourceShrinker
+import com.android.tools.r8.origin.PathOrigin
+import com.android.tools.r8.references.MethodReference
+import java.nio.file.Path
+
+
+fun runResourceShrinkerAnalysis(bytes: ByteArray, file: Path, callback: AnalysisCallback) {
+    val resource =
+        ProgramResource.fromBytes(PathOrigin(file), ProgramResource.Kind.DEX, bytes, null)
+    val provider = ProgramResourceProvider { listOf(resource) }
+
+    val command = ResourceShrinker.Builder().addProgramResourceProvider(provider).build()
+    ResourceShrinker.run(command, AnalysisAdapter(callback))
+}
+
+/** An adapter so R8 API classes do not leak into other modules. */
+class AnalysisAdapter(val impl: AnalysisCallback) : ResourceShrinker.ReferenceChecker {
+    override fun shouldProcess(internalName: String): Boolean = impl.shouldProcess(internalName)
+
+    override fun referencedStaticField(internalName: String, fieldName: String) =
+        impl.referencedStaticField(internalName, fieldName)
+
+    override fun referencedInt(value: Int) = impl.referencedInt(value)
+
+    override fun referencedString(value: String) = impl.referencedString(value)
+
+    override fun referencedMethod(
+        internalName: String, methodName: String, methodDescriptor: String
+    ) = impl.referencedMethod(internalName, methodName, methodDescriptor)
+
+    override fun startMethodVisit(methodReference: MethodReference
+    ) = impl.startMethodVisit(methodReference)
+
+    override fun endMethodVisit(methodReference: MethodReference
+    ) = impl.endMethodVisit(methodReference)
+}
+
+interface AnalysisCallback {
+
+    fun shouldProcess(internalName: String): Boolean
+
+    fun referencedInt(value: Int)
+
+    fun referencedString(value: String)
+
+    fun referencedStaticField(internalName: String, fieldName: String)
+
+    fun referencedMethod(internalName: String, methodName: String, methodDescriptor: String)
+
+    fun startMethodVisit(methodReference: MethodReference)
+
+    fun endMethodVisit(methodReference: MethodReference)
+}
+
+class MethodVisitingStatus(var isVisiting: Boolean = false, var methodName: String? = null)
