// Copyright 2017 The Bazel Authors. All rights reserved.
//
// 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.google.devtools.build.android;

import static com.google.common.truth.Truth.assertAbout;
import static com.google.common.truth.Truth.assertThat;

import com.android.resources.ResourceType;
import com.google.common.base.Function;
import com.google.common.base.Joiner;
import com.google.common.base.Optional;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.jimfs.Jimfs;
import com.google.common.truth.Subject;
import com.google.devtools.build.android.AndroidResourceMerger.MergingException;
import com.google.devtools.build.android.xml.ArrayXmlResourceValue;
import com.google.devtools.build.android.xml.ArrayXmlResourceValue.ArrayType;
import com.google.devtools.build.android.xml.AttrXmlResourceValue;
import com.google.devtools.build.android.xml.AttrXmlResourceValue.BooleanResourceXmlAttrValue;
import com.google.devtools.build.android.xml.AttrXmlResourceValue.ColorResourceXmlAttrValue;
import com.google.devtools.build.android.xml.AttrXmlResourceValue.DimensionResourceXmlAttrValue;
import com.google.devtools.build.android.xml.AttrXmlResourceValue.EnumResourceXmlAttrValue;
import com.google.devtools.build.android.xml.AttrXmlResourceValue.FlagResourceXmlAttrValue;
import com.google.devtools.build.android.xml.AttrXmlResourceValue.FloatResourceXmlAttrValue;
import com.google.devtools.build.android.xml.AttrXmlResourceValue.FractionResourceXmlAttrValue;
import com.google.devtools.build.android.xml.AttrXmlResourceValue.IntegerResourceXmlAttrValue;
import com.google.devtools.build.android.xml.AttrXmlResourceValue.ReferenceResourceXmlAttrValue;
import com.google.devtools.build.android.xml.AttrXmlResourceValue.StringResourceXmlAttrValue;
import com.google.devtools.build.android.xml.IdXmlResourceValue;
import com.google.devtools.build.android.xml.Namespaces;
import com.google.devtools.build.android.xml.PluralXmlResourceValue;
import com.google.devtools.build.android.xml.PublicXmlResourceValue;
import com.google.devtools.build.android.xml.ResourcesAttribute;
import com.google.devtools.build.android.xml.SimpleXmlResourceValue;
import com.google.devtools.build.android.xml.StyleXmlResourceValue;
import com.google.devtools.build.android.xml.StyleableXmlResourceValue;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.FileSystem;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import javax.xml.stream.XMLStreamException;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

/** Tests for {@link DataResourceXml}. */
@RunWith(JUnit4.class)
public class DataResourceXmlTest {
  static final ImmutableMap<String, String> XLIFF_NAMESPACES =
      ImmutableMap.of("xliff", "urn:oasis:names:tc:xliff:document:1.2");
  static final String END_RESOURCES = new String(AndroidDataWriter.END_RESOURCES);

  private FullyQualifiedName.Factory fqnFactory;
  private FileSystem fs;

  @Before
  public void createCleanEnvironment() {
    fs = Jimfs.newFileSystem();
    fqnFactory = FullyQualifiedName.Factory.from(ImmutableList.<String>of());
  }

  private Path writeResourceXml(String... xml) throws IOException {
    return writeResourceXml(ImmutableMap.<String, String>of(), ImmutableMap.<String, String>of(),
        xml);
  }

  private Path writeResourceXml(Map<String, String> namespaces, Map<String, String> attributes,
      String... xml) throws IOException {
    Path values = fs.getPath("root/values/values.xml");
    Files.createDirectories(values.getParent());
    StringBuilder builder = new StringBuilder();
    builder.append(AndroidDataWriter.PRELUDE).append("<resources");
    for (Entry<String, String> entry : namespaces.entrySet()) {
      builder
          .append(" xmlns:")
          .append(entry.getKey())
          .append("=\"")
          .append(entry.getValue())
          .append("\"");
    }
    for (Entry<String, String> entry : attributes.entrySet()) {
      builder
          .append(" ")
          .append(entry.getKey())
          .append("=\"")
          .append(entry.getValue())
          .append("\"");
    }
    builder.append(">");
    Joiner.on("\n").appendTo(builder, xml);
    builder.append(END_RESOURCES);
    Files.write(values, builder.toString().getBytes(StandardCharsets.UTF_8));
    return values;
  }

  private void parseResourcesFrom(
      Path path, Map<DataKey, DataResource> toOverwrite, Map<DataKey, DataResource> toCombine)
      throws XMLStreamException, IOException {
    DataResourceXml.parse(
        XmlResourceValues.getXmlInputFactory(),
        path,
        fqnFactory,
        new FakeConsumer(toOverwrite),
        new FakeConsumer(toCombine));
  }

  private FullyQualifiedName fqn(String raw) {
    return fqnFactory.parse(raw);
  }

  @Test
  public void simpleXmlResources() throws Exception {
    Path path =
        writeResourceXml(
            "<string name='exit' description=\"&amp; egress -&gt; &quot;\">way out</string>",
            "<bool name='canExit'>false</bool>",
            "<color name='exitColor'>#FF000000</color>",
            "<dimen name='exitSize'>20sp</dimen>",
            "<integer name='exitInt'>20</integer>",
            "<fraction name='exitFraction'>%20</fraction>",
            "<drawable name='exitBackground'>#99000000</drawable>",
            "<item name='some_id' type='id'/>",
            "<item name='reference_id' type='id'>@id/some_id</item>");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("string/exit"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                SimpleXmlResourceValue.of(
                    SimpleXmlResourceValue.Type.STRING,
                    ImmutableMap.of("description", "&amp; egress -&gt; &quot;"),
                    "way out")), // Value
            fqn("bool/canExit"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                SimpleXmlResourceValue.createWithValue(
                    SimpleXmlResourceValue.Type.BOOL, "false")), // Value
            fqn("color/exitColor"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                SimpleXmlResourceValue.createWithValue(
                    SimpleXmlResourceValue.Type.COLOR, "#FF000000")), // Value
            fqn("dimen/exitSize"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                SimpleXmlResourceValue.createWithValue(
                    SimpleXmlResourceValue.Type.DIMEN, "20sp")), // Value
            fqn("integer/exitInt"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                SimpleXmlResourceValue.createWithValue(
                    SimpleXmlResourceValue.Type.INTEGER, "20")), // Value
            fqn("fraction/exitFraction"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                SimpleXmlResourceValue.createWithValue(
                    SimpleXmlResourceValue.Type.FRACTION, "%20")), // Value
            fqn("drawable/exitBackground"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                SimpleXmlResourceValue.createWithValue(
                    SimpleXmlResourceValue.Type.DRAWABLE, "#99000000")) // Value
            );
    assertThat(toCombine)
        .containsExactly(
            fqn("id/some_id"), // Key
            DataResourceXml.createWithNoNamespace(path, IdXmlResourceValue.of()), // Value
            fqn("id/reference_id"), // Key
            DataResourceXml.createWithNoNamespace(
                path, IdXmlResourceValue.of("@id/some_id")) // Value
            );
  }

  @Test
  public void skipIgnored() throws Exception {
    Path path = writeResourceXml("<skip/>");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite).isEmpty();
    assertThat(toCombine).isEmpty();
  }

  @Test
  public void eatCommentIgnored() throws Exception {
    Path path = writeResourceXml("<eat-comment/>");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite).isEmpty();
    assertThat(toCombine).isEmpty();
  }

  @Test
  public void itemSimpleXmlResources() throws Exception {
    Path path =
        writeResourceXml(
            "<item type='dimen' name='exitSizePercent'>20%</item>",
            "<item type='dimen' format='float' name='exitSizeFloat'>20.0</item>",
            "<item type='fraction' name='denom'>%5</item>",
            "<item name='subtype_id' type='id'>0x6f972360</item>",
            "<item type='array' name='oboes'/>",
            "<item type='drawable' name='placeholder'/>");
    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("dimen/exitSizePercent"), // Key
            DataResourceXml.createWithNoNamespace(
                path, SimpleXmlResourceValue.itemWithValue(ResourceType.DIMEN, "20%")), // Value
            fqn("dimen/exitSizeFloat"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                SimpleXmlResourceValue.itemWithFormattedValue(
                    ResourceType.DIMEN, "float", "20.0")), // Value
            fqn("drawable/placeholder"), // Key
            DataResourceXml.createWithNoNamespace(
                path, SimpleXmlResourceValue.itemPlaceHolderFor(ResourceType.DRAWABLE)), // Value
            fqn("array/oboes"), // Key
            DataResourceXml.createWithNoNamespace(
                path, SimpleXmlResourceValue.itemPlaceHolderFor(ResourceType.ARRAY)), // Value
            fqn("fraction/denom"), // Key
            DataResourceXml.createWithNoNamespace(
                path, SimpleXmlResourceValue.itemWithValue(ResourceType.FRACTION, "%5")) // Value
            );
  }

  @Test
  public void styleableXmlResourcesEnum() throws Exception {
    Path path =
        writeResourceXml(
            "<declare-styleable name='Theme'>",
            "  <attr name=\"labelPosition\" format=\"enum\">",
            "    <enum name=\"left\" value=\"0\"/>",
            "    <enum name=\"right\" value=\"1\"/>",
            "  </attr>",
            "</declare-styleable>");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("attr/labelPosition"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                AttrXmlResourceValue.fromFormatEntries(
                    EnumResourceXmlAttrValue.asEntryOf("left", "0", "right", "1"))) // Value
            );
    assertThat(toCombine)
        .containsExactly(
            fqn("styleable/Theme"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                StyleableXmlResourceValue.createAllAttrAsDefinitions(
                    fqnFactory.parse("attr/labelPosition"))) // Value
            );
  }

  @Test
  public void styleableXmlResourcesString() throws Exception {
    Path path =
        writeResourceXml(
            "<declare-styleable name='UnusedStyleable'>",
            "  <attr name='attribute1'/>",
            "  <attr name='attribute2'/>",
            "</declare-styleable>",
            "<attr name='attribute1' format='string'/>",
            "<attr name='attribute2' format='string'/>");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("attr/attribute1"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                AttrXmlResourceValue.fromFormatEntries(
                    StringResourceXmlAttrValue.asEntry())), // Value
            fqn("attr/attribute2"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                AttrXmlResourceValue.fromFormatEntries(
                    StringResourceXmlAttrValue.asEntry())) // Value
            );
    assertThat(toCombine)
        .containsExactly(
            fqn("styleable/UnusedStyleable"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                StyleableXmlResourceValue.createAllAttrAsReferences(
                    fqnFactory.parse("attr/attribute1"),
                    fqnFactory.parse("attr/attribute2"))) // Value
            );
  }

  @Test
  public void pluralXmlResources() throws Exception {
    Path path =
        writeResourceXml(
            "<plurals name='numberOfSongsAvailable'>",
            "  <item quantity='one'>%d song found.</item>",
            "  <item quantity='other'>%d songs found.</item>",
            "</plurals>");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("plurals/numberOfSongsAvailable"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                PluralXmlResourceValue.createWithoutAttributes(
                    ImmutableMap.of(
                        "one", "%d song found.",
                        "other", "%d songs found."))) // Value
            );
  }

  @Test
  public void pluralXmlResourcesWithTrailingCharacters() throws Exception {
    Path path =
        writeResourceXml(
            "<plurals name='numberOfSongsAvailable'>",
            "  <item quantity='one'>%d song found.</item> // this is an invalid comment.",
            "  <item quantity='other'>%d songs found.</item>typo",
            "</plurals>");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("plurals/numberOfSongsAvailable"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                PluralXmlResourceValue.createWithoutAttributes(
                    ImmutableMap.of(
                        "one", "%d song found.",
                        "other", "%d songs found."))) // Value
            );
  }

  @Test
  public void styleResources() throws Exception {
    Path path =
        writeResourceXml(
            "<style name=\"candlestick_maker\" parent=\"@style/wax_maker\">\n"
                + "  <item name=\"texture\">waxy</item>\n"
                + "</style>");
    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("style/candlestick_maker"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                StyleXmlResourceValue.of(
                    "@style/wax_maker", ImmutableMap.of("texture", "waxy"))) // Value
            );
  }

  @Test
  public void styleResourcesNoParent() throws Exception {
    Path path =
        writeResourceXml(
            "<style name=\"CandlestickMaker\">\n"
                + "  <item name=\"texture\">waxy</item>\n"
                + "</style>");
    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("style/CandlestickMaker"), // Key
            DataResourceXml.createWithNoNamespace(
                path, StyleXmlResourceValue.of(null, ImmutableMap.of("texture", "waxy"))) // Value
            );
  }

  @Test
  public void styleResourcesForceNoParent() throws Exception {
    Path path =
        writeResourceXml(
            // using a '.' implies a parent Candlestick, parent='' corrects to no parent.
            "<style name=\"Candlestick.Maker\" parent=\"\">\n"
                + "  <item name=\"texture\">waxy</item>\n"
                + "</style>");
    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("style/Candlestick.Maker"), // Key
            DataResourceXml.createWithNoNamespace(
                path, StyleXmlResourceValue.of("", ImmutableMap.of("texture", "waxy"))) // Value
            );
  }

  @Test
  public void styleResourcesLazyReference() throws Exception {
    Path path =
        writeResourceXml(
            "<style name=\"candlestick_maker\" parent=\"AppTheme\">\n"
                + "  <item name=\"texture\">waxy</item>\n"
                + "</style>");
    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("style/candlestick_maker"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                StyleXmlResourceValue.of("AppTheme", ImmutableMap.of("texture", "waxy"))) // Value
            );
  }

  @Test
  public void arrayXmlResources() throws Exception {
    Path path =
        writeResourceXml(
            "<array name='icons'>",
            "  <item>@drawable/home</item>",
            "  <item>@drawable/settings</item>",
            "  <item>@drawable/logout</item>",
            "</array>",
            "<array name='colors'>",
            "  <item>#FFFF0000</item>",
            "  <item>#FF00FF00</item>",
            "  <item>#FF0000FF</item>",
            "</array>");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("array/icons"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                ArrayXmlResourceValue.of(
                    ArrayType.ARRAY,
                    "@drawable/home",
                    "@drawable/settings",
                    "@drawable/logout")), // Value
            fqn("array/colors"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                ArrayXmlResourceValue.of(
                    ArrayType.ARRAY, "#FFFF0000", "#FF00FF00", "#FF0000FF")) // Value
            );
  }

  @Test
  public void stringArrayXmlResources() throws Exception {
    Path path =
        writeResourceXml(
            "<string-array name='characters'>",
            "  <item>boojum</item>",
            "  <item>snark</item>",
            "  <item>bellman</item>",
            "  <item>barrister</item>",
            "  <item>\\\"billiard-marker\\\"</item>",
            "</string-array>");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("array/characters"),
            DataResourceXml.createWithNoNamespace(
                path,
                ArrayXmlResourceValue.of(
                    ArrayType.STRING_ARRAY,
                    "boojum",
                    "snark",
                    "bellman",
                    "barrister",
                    "\\\"billiard-marker\\\"")));
    assertThat(toCombine).isEmpty();
  }

  @Test
  public void integerArrayXmlResources() throws Exception {
    Path path =
        writeResourceXml(
            "<integer-array name='bits'>",
            "  <item>4</item>",
            "  <item>8</item>",
            "  <item>16</item>",
            "  <item>32</item>",
            "</integer-array>");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("array/bits"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                ArrayXmlResourceValue.of(ArrayType.INTEGER_ARRAY, "4", "8", "16", "32")) // Value
            );
  }

  @Test
  public void attrFlagXmlResources() throws Exception {
    Path path =
        writeResourceXml(
            "  <attr name=\"labelPosition\">",
            "    <flag name=\"left\" value=\"0\"/>",
            "    <flag name=\"right\" value=\"1\"/>",
            "  </attr>");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("attr/labelPosition"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                AttrXmlResourceValue.fromFormatEntries(
                    FlagResourceXmlAttrValue.asEntryOf(
                        "left", "0",
                        "right", "1"))) // Value
            );
  }

  @Test
  public void attrMultiFormatImplicitFlagXmlResources() throws Exception {
    Path path =
        writeResourceXml(
            "  <attr name='labelPosition' format='reference'>",
            "    <flag name='left' value='0'/>",
            "    <flag name='right' value='1'/>",
            "  </attr>");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("attr/labelPosition"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                AttrXmlResourceValue.fromFormatEntries(
                    ReferenceResourceXmlAttrValue.asEntry(),
                    FlagResourceXmlAttrValue.asEntryOf(
                        "left", "0",
                        "right", "1"))) // Value
            );
  }

  @Test
  public void attrMultiFormatResources() throws Exception {
    Path path =
        writeResourceXml(
            "<attr name='labelPosition' ",
            "format='color|boolean|dimension|float|integer|string|fraction|reference' />");

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    assertThat(toOverwrite)
        .containsExactly(
            fqn("attr/labelPosition"), // Key
            DataResourceXml.createWithNoNamespace(
                path,
                AttrXmlResourceValue.fromFormatEntries(
                    ColorResourceXmlAttrValue.asEntry(),
                    BooleanResourceXmlAttrValue.asEntry(),
                    ReferenceResourceXmlAttrValue.asEntry(),
                    DimensionResourceXmlAttrValue.asEntry(),
                    FloatResourceXmlAttrValue.asEntry(),
                    IntegerResourceXmlAttrValue.asEntry(),
                    StringResourceXmlAttrValue.asEntry(),
                    FractionResourceXmlAttrValue.asEntry())) // Value
            );
  }

  @Test
  public void publicXmlResource() throws Exception {
    Path path =
        writeResourceXml(
            "<string name='exit'>way out</string>",
            "<public type='string' name='exit' id='0x123'/>");
    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);
    assertThat(toOverwrite)
        .containsExactly(
            fqn("string/exit"),
            DataResourceXml.createWithNoNamespace(
                path,
                SimpleXmlResourceValue.createWithValue(
                    SimpleXmlResourceValue.Type.STRING, "way out")));
    assertThat(toCombine)
        .containsExactly(
            fqn("public/exit"),
            DataResourceXml.createWithNoNamespace(
                path, PublicXmlResourceValue.create(ResourceType.STRING, Optional.of(0x123))));
  }

  @Test
  public void resourcesAttribute() throws Exception {
    Namespaces namespaces = Namespaces.from(
        ImmutableMap.of("tools", "http://schemas.android.com/tools"));

    Path path = writeResourceXml(
        namespaces.asMap(),
        ImmutableMap.of("tools:foo", "fooVal", "tools:ignore", "ignoreVal"));

    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);

    FullyQualifiedName fooFqn = fqn("<resources>/{http://schemas.android.com/tools}foo");
    assertThat(toOverwrite)
        .containsExactly(
            fooFqn,
            DataResourceXml.createWithNamespaces(
                path,
                ResourcesAttribute.of(fooFqn, "tools:foo", "fooVal"),
                namespaces)
            );

    FullyQualifiedName ignoreFqn = fqn("<resources>/{http://schemas.android.com/tools}ignore");
    assertThat(toCombine)
        .containsExactly(
            ignoreFqn,
            DataResourceXml.createWithNamespaces(
                path,
                ResourcesAttribute.of(ignoreFqn, "tools:ignore", "ignoreVal"),
                namespaces)
            );

  }

  @Test
  public void writeSimpleXmlResources() throws Exception {
    Path source =
        writeResourceXml(
            "<string name='exit'>way <a href=\"out.html\">out</a></string>",
            "<bool name='canExit'>false</bool>",
            "<color name='exitColor'>#FF000000</color>",
            "<integer name='exitInt'>5</integer>",
            "<drawable name='reference'/>");
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("string/exit")))
        .xmlContentsIsEqualTo(
            resourcesXmlFrom(
                source, "<string name='exit'>way <a href=\"out.html\">out</a></string>"));
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("bool/canExit")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, "<bool name='canExit'>false</bool>"));
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("color/exitColor")))
        .xmlContentsIsEqualTo(
            resourcesXmlFrom(source, "<color name='exitColor'>#FF000000</color>"));
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("integer/exitInt")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, "<integer name='exitInt'>5</integer>"));
  }

  @Test
  public void writeItemResources() throws Exception {
    Path source =
        writeResourceXml(
            "<item type='dimen' name='exitSizePercent'>20%</item>",
            "<item type='dimen' format='float' name='exitSizeFloat'>20.0</item>",
            "<item name='exitId' type='id'/>",
            "<item name='frac' type='fraction'>5%</item>");
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("dimen/exitSizePercent")))
        .xmlContentsIsEqualTo(
            resourcesXmlFrom(source, "<item type='dimen' name='exitSizePercent'>20%</item>"));
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("dimen/exitSizeFloat")))
        .xmlContentsIsEqualTo(
            resourcesXmlFrom(
                source, "<item type='dimen' format='float' name='exitSizeFloat'>20.0</item>"));
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("fraction/frac")))
        .xmlContentsIsEqualTo(
            resourcesXmlFrom(source, "<item name='frac' type='fraction'>5%</item>"));
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("id/exitId")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, "<item name='exitId' type='id'/>"));
  }

  @Test
  public void writeStringResourceWithXliffNamespace() throws Exception {
    Path source = fs.getPath("root/values/values.xml");
    Files.createDirectories(source.getParent());
    Files.write(
        source,
        ("<resources xmlns:xliff=\"urn:oasis:names:tc:xliff:document:1.2\">"
                + "<string name=\"star_rating\">Check out our 5\n"
                + "    <xliff:g id=\"star\">\\u2605</xliff:g>\n"
                + "</string>"
                + "</resources>")
            .getBytes(StandardCharsets.UTF_8));
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("string/star_rating")))
        .xmlContentsIsEqualTo(
            resourcesXmlFrom(
                XLIFF_NAMESPACES,
                ImmutableMap.<String, String>of(),
                source,
                "<string name=\"star_rating\">Check out our 5",
                "    <xliff:g id=\"star\">\\u2605</xliff:g>",
                "</string>"));
  }

  @Test
  public void writeStringResourceCData() throws Exception {
    String[] xml = {
      "<string name='cdata'><![CDATA[<b>Jabber, Jabber</b><br><br>\n Wock!]]></string>"
    };
    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("string/cdata")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, xml));
  }

  @Test
  public void writeStringResourceWithNamespace() throws Exception {
    Path source = fs.getPath("root/values/values.xml");
    Files.createDirectories(source.getParent());
    Files.write(
        source,
        ("<resources xmlns:ns1=\"urn:oasis:names:tc:xliff:document:1.2\">"
                + "<string name=\"star_rating\">Check out our 5\n"
                + "    <ns1:g xmlns:foglebert=\"defogle\" foglebert:id=\"star\">\\u2605</ns1:g>\n"
                + "</string>"
                + "</resources>")
            .getBytes(StandardCharsets.UTF_8));
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("string/star_rating")))
        .xmlContentsIsEqualTo(
            resourcesXmlFrom(
                ImmutableMap.of("ns1", "urn:oasis:names:tc:xliff:document:1.2"),
                ImmutableMap.<String, String>of(),
                source,
                "<string name=\"star_rating\">Check out our 5    ",
                "<ns1:g xmlns:foglebert=\"defogle\" " + "foglebert:id=\"star\">\\u2605</ns1:g>",
                "</string>"));
  }

  @Test
  public void writeStringResourceWithUnusedNamespace() throws Exception {
    Path source = fs.getPath("root/values/values.xml");
    Files.createDirectories(source.getParent());
    Files.write(
        source,
        ("<resources xmlns:ns1=\"urn:oasis:names:tc:xliff:document:1.2\">"
                + "<string name=\"star_rating\">"
                + "not yet implemented\n"
                + "</string>"
                + "</resources>")
            .getBytes(StandardCharsets.UTF_8));
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("string/star_rating")))
        .xmlContentsIsEqualTo(
            resourcesXmlFrom(
                source, "<string name=\"star_rating\">", "not yet implemented\n", "</string>"));
  }

  @Test
  public void writeStringResourceWithEscapedValues() throws Exception {
    String[] xml = {
      "<string name=\"AAP_SUGGEST_ACCEPT_SUGGESTION\">",
      "        &lt;b&gt;<xliff:g id=\"name\" example=\"Pizza hut\">%1$s</xliff:g>&lt;/b&gt; "
      + "already exists at &lt;b&gt;<xliff:g id=\"address\" "
      + "example=\"123 main street\">%2$s</xliff:g>&lt;/b&gt;&lt;br&gt;",
      "        &lt;br&gt;",
      "        Is this the place you\\'re trying to add?\n",
      "</string>"
    };

    Path source = writeResourceXml(XLIFF_NAMESPACES, ImmutableMap.<String, String>of(), xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("string/AAP_SUGGEST_ACCEPT_SUGGESTION")))
        .xmlContentsIsEqualTo(
            resourcesXmlFrom(XLIFF_NAMESPACES, ImmutableMap.<String, String>of(), source, xml));
  }

  @Test
  public void writeStyleableXmlResource() throws Exception {
    String[] xml = {
      "<declare-styleable name='Theme'>",
      "  <attr name=\"labelPosition\" />",
      "</declare-styleable>"
    };

    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("styleable/Theme")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, xml));
  }

  @Test
  public void writeStyleableXmlResourceReference() throws Exception {
    String[] xml = {
      "<declare-styleable name='Theme'>",
      "  <attr name=\"labelColor\" format=\"color\" />",
      "</declare-styleable>"
    };

    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("styleable/Theme"), fqn("attr/labelColor")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, xml));
  }

  @Test
  public void writePluralXmlResources() throws Exception {
    String[] xml = {
      "<plurals name='numberOfSongsAvailable' format='none'>",
      "  <item quantity='one'>%d song found.</item>",
      "  <item quantity='other'>%d songs found.</item>",
      "</plurals>"
    };
    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("plurals/numberOfSongsAvailable")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, xml));
  }

  @Test
  public void writePublicXmlResources() throws Exception {
    String[] xml = {
        "<public name='bar' type='dimen' id='0x7f030003' />",
        "<public name='foo' type='dimen' />",
    };
    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("public/bar"), fqn("public/foo")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, xml));
  }

  @Test
  public void writeArrayXmlResources() throws Exception {
    String[] xml = {
      "<array name='icons'>",
      "  <item>@drawable/home</item>",
      "  <item>@drawable/settings</item>",
      "  <item>@drawable/logout</item>",
      "</array>",
    };

    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("array/icons")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, xml));
  }

  @Test
  public void writeStringArrayXmlResources() throws Exception {
    String[] xml = {
      "<string-array name='rosebud' translatable='false'>",
      "  <item>Howard Hughes</item>",
      "  <item>Randolph Hurst</item>",
      "</string-array>",
    };

    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("array/rosebud")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, xml));
  }

  @Test
  public void writeIntegerArrayXmlResources() throws Exception {
    String[] xml = {
      "<integer-array name='bits'>",
      "  <item>4</item>",
      "  <item>8</item>",
      "  <item>16</item>",
      "  <item>32</item>",
      "</integer-array>"
    };
    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("array/bits")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, xml));
  }

  @Test
  public void writeAttrFlagXmlResources() throws Exception {
    String[] xml = {
      "  <attr name=\"labelPosition\">",
      "    <flag name=\"left\" value=\"0\"/>",
      "    <flag name=\"right\" value=\"1\"/>",
      "  </attr>"
    };
    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("attr/labelPosition")))
        .xmlContentsIsEqualTo(
            resourcesXmlFrom(
                source,
                "  <attr name=\"labelPosition\">",
                "    <flag name=\"left\" value=\"0\"/>",
                "    <flag name=\"right\" value=\"1\"/>",
                "  </attr>"));
  }

  @Test
  public void writeAttrMultiFormatImplicitFlagXmlResources() throws Exception {
    String[] xml = {
      "  <attr name='labelPosition' format='reference'>",
      "    <flag name='left' value='0'/>",
      "    <flag name='right' value='1'/>",
      "  </attr>"
    };
    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("attr/labelPosition")))
        .xmlContentsIsEqualTo(
            resourcesXmlFrom(
                source,
                "  <attr name='labelPosition' format='reference'>",
                "    <flag name='left' value='0'/>",
                "    <flag name='right' value='1'/>",
                "  </attr>"));
  }

  @Test
  public void writeAttrMultiFormatResources() throws Exception {
    String[] xml = {
      "<attr name='labelPosition' ",
      "format='boolean|color|dimension|float|fraction|integer|reference|string'/>"
    };
    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("attr/labelPosition")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, xml));
  }

  @Test
  public void writeStyle() throws Exception {
    String[] xml = {
      "<style name='candlestick_maker' parent='@style/wax_maker'>\n"
          + "  <item name='texture'>waxy</item>\n"
          + "</style>"
    };

    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("style/candlestick_maker")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, xml));
  }

  @Test
  public void writeForceNoParentStyle() throws Exception {
    String[] xml = {
      "<style name='candlestick_maker' parent=''>\n",
      "  <item name='texture'>waxy</item>\n",
      "</style>"
    };

    Path source = writeResourceXml(xml);
    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("style/candlestick_maker")))
        .xmlContentsIsEqualTo(resourcesXmlFrom(source, xml));
  }

  @Test
  public void writeResourceAttributes() throws Exception {
    Path source = writeResourceXml(
        ImmutableMap.of("tools", "http://schemas.android.com/tools"),
        ImmutableMap.of("tools:foo", "fooVal"));

    assertAbout(resourcePaths)
        .that(parsedAndWritten(source, fqn("<resources>/{http://schemas.android.com/tools}foo")))
        .xmlContentsIsEqualTo(
            resourcesXmlFrom(
                ImmutableMap.of("tools", "http://schemas.android.com/tools"),
                ImmutableMap.of("tools:foo", "fooVal"),
                null));
  }

  @Test
  public void serializeMultipleSimpleXmlResources() throws Exception {
    Path serialized = fs.getPath("out/out.bin");
    Path source = fs.getPath("res/values/values.xml");
    FullyQualifiedName stringKey = fqn("string/exit");
    DataResourceXml stringValue =
        DataResourceXml.createWithNoNamespace(
            source,
            SimpleXmlResourceValue.createWithValue(SimpleXmlResourceValue.Type.STRING, "way out"));
    FullyQualifiedName nullStringKey = fqn("string/nullexit");
    DataResourceXml nullStringValue =
        DataResourceXml.createWithNoNamespace(
            source,
            SimpleXmlResourceValue.createWithValue(SimpleXmlResourceValue.Type.STRING, null));
    FullyQualifiedName boolKey = fqn("bool/canExit");
    DataResourceXml boolValue =
        DataResourceXml.createWithNoNamespace(
            source,
            SimpleXmlResourceValue.createWithValue(SimpleXmlResourceValue.Type.BOOL, "false"));
    FullyQualifiedName colorKey = fqn("color/exitColor");
    DataResourceXml colorValue =
        DataResourceXml.createWithNoNamespace(
            source,
            SimpleXmlResourceValue.createWithValue(SimpleXmlResourceValue.Type.COLOR, "#FF000000"));
    FullyQualifiedName dimenKey = fqn("dimen/exitSize");
    DataResourceXml dimenValue =
        DataResourceXml.createWithNoNamespace(
            source,
            SimpleXmlResourceValue.createWithValue(SimpleXmlResourceValue.Type.DIMEN, "20sp"));

    AndroidDataSerializer serializer = AndroidDataSerializer.create();
    serializer.queueForSerialization(stringKey, stringValue);
    serializer.queueForSerialization(nullStringKey, nullStringValue);
    serializer.queueForSerialization(boolKey, boolValue);
    serializer.queueForSerialization(colorKey, colorValue);
    serializer.queueForSerialization(dimenKey, dimenValue);
    serializer.flushTo(serialized);

    AndroidDataDeserializer deserializer = AndroidDataDeserializer.create();
    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    deserializer.read(
        serialized,
        KeyValueConsumers.of(new FakeConsumer(toOverwrite), new FakeConsumer(toCombine), null));
    assertThat(toOverwrite)
        .containsExactly(
            stringKey, stringValue,
            boolKey, boolValue,
            colorKey, colorValue,
            nullStringKey, nullStringValue,
            dimenKey, dimenValue);
    assertThat(toCombine).isEmpty();
  }

  @Test
  public void serializeItemXmlResources() throws Exception {
    Path source = fs.getPath("res/values/values.xml");
    assertSerialization(
        fqn("dimen/exitSizePercent"),
        DataResourceXml.createWithNoNamespace(
            source, SimpleXmlResourceValue.itemWithValue(ResourceType.DIMEN, "20%")));
    assertSerialization(
        fqn("dimen/exitSizeFloat"),
        DataResourceXml.createWithNoNamespace(
            source,
            SimpleXmlResourceValue.itemWithFormattedValue(ResourceType.DIMEN, "float", "20.0")));
    assertSerialization(
        fqn("fraction/denom"),
        DataResourceXml.createWithNoNamespace(
            source,
            SimpleXmlResourceValue.createWithValue(SimpleXmlResourceValue.Type.COLOR, "5%")));
    assertSerialization(
        fqn("id/subtype_afrikaans"),
        DataResourceXml.createWithNoNamespace(
            source, SimpleXmlResourceValue.itemWithValue(ResourceType.ID, "0x6f972360")));
  }

  @Test
  public void serializeStyleableXmlResource() throws Exception {
    Path serialized = fs.getPath("out/out.bin");
    Path source = fs.getPath("res/values/values.xml");
    FullyQualifiedName attrKey = fqn("attr/labelPosition");
    DataResourceXml attrValue =
        DataResourceXml.createWithNoNamespace(
            source,
            AttrXmlResourceValue.fromFormatEntries(
                EnumResourceXmlAttrValue.asEntryOf("left", "0", "right", "1")));
    FullyQualifiedName themeKey = fqn("styleable/Theme");
    DataResourceXml themeValue =
        DataResourceXml.createWithNoNamespace(
            source,
            StyleableXmlResourceValue.createAllAttrAsReferences(
                fqnFactory.parse("attr/labelPosition")));

    AndroidDataSerializer serializer = AndroidDataSerializer.create();
    serializer.queueForSerialization(attrKey, attrValue);
    serializer.queueForSerialization(themeKey, themeValue);
    serializer.flushTo(serialized);

    AndroidDataDeserializer deserializer = AndroidDataDeserializer.create();
    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    deserializer.read(
        serialized,
        KeyValueConsumers.of(new FakeConsumer(toOverwrite), new FakeConsumer(toCombine), null));
    assertThat(toOverwrite).containsEntry(attrKey, attrValue);
    assertThat(toCombine).containsEntry(themeKey, themeValue);
  }

  @Test
  public void serializePlurals() throws Exception {
    Path path = fs.getPath("res/values/values.xml");
    assertSerialization(
        fqn("plurals/numberOfSongsAvailable"),
        DataResourceXml.createWithNoNamespace(
            path,
            PluralXmlResourceValue.createWithoutAttributes(
                ImmutableMap.of(
                    "one", "%d song found.",
                    "other", "%d songs found."))));
  }

  @Test
  public void serializeArrays() throws Exception {
    Path path = fs.getPath("res/values/values.xml");
    assertSerialization(
        fqn("plurals/numberOfSongsAvailable"),
        DataResourceXml.createWithNoNamespace(
            path,
            PluralXmlResourceValue.createWithoutAttributes(
                ImmutableMap.of(
                    "one", "%d song found.",
                    "other", "%d songs found."))));
    assertSerialization(
        fqn("array/icons"),
        DataResourceXml.createWithNoNamespace(
            path,
            ArrayXmlResourceValue.of(
                ArrayType.ARRAY, "@drawable/home", "@drawable/settings", "@drawable/logout")));
    assertSerialization(
        fqn("array/colors"),
        DataResourceXml.createWithNoNamespace(
            path,
            ArrayXmlResourceValue.of(ArrayType.ARRAY, "#FFFF0000", "#FF00FF00", "#FF0000FF")));
    assertSerialization(
        fqn("array/characters"),
        DataResourceXml.createWithNoNamespace(
            path,
            ArrayXmlResourceValue.of(
                ArrayType.STRING_ARRAY,
                "boojum",
                "snark",
                "bellman",
                "barrister",
                "\\\"billiard-marker\\\"")));
  }

  @Test
  public void serializeAttrFlag() throws Exception {
    assertSerialization(
        fqn("attr/labelPosition"),
        DataResourceXml.createWithNoNamespace(
            fs.getPath("res/values/values.xml"),
            AttrXmlResourceValue.fromFormatEntries(
                FlagResourceXmlAttrValue.asEntryOf(
                    "left", "0",
                    "right", "1"))));
  }

  @Test
  public void serializeId() throws Exception {
    assertSerialization(
        fqn("id/squark"),
        DataResourceXml.createWithNoNamespace(
            fs.getPath("res/values/values.xml"), IdXmlResourceValue.of()));
  }

  @Test
  public void serializePublic() throws Exception {
    assertSerialization(
        fqn("public/park"),
        DataResourceXml.createWithNoNamespace(
            fs.getPath("res/values/public.xml"), PublicXmlResourceValue.of(
                ImmutableMap.of(
                    ResourceType.DIMEN, Optional.of(0x7f040000),
                    ResourceType.STRING, Optional.of(0x7f050000))
            )));
  }

  @Test
  public void serializeStyle() throws Exception {
    assertSerialization(
        fqn("style/snark"),
        DataResourceXml.createWithNoNamespace(
            fs.getPath("res/values/styles.xml"),
            StyleXmlResourceValue.of(null, ImmutableMap.of("look", "boojum"))));
  }

  @Test
  public void assertMultiFormatAttr() throws Exception {
    assertSerialization(
        fqn("attr/labelPosition"),
        DataResourceXml.createWithNoNamespace(
            fs.getPath("res/values/values.xml"),
            AttrXmlResourceValue.fromFormatEntries(
                ColorResourceXmlAttrValue.asEntry(),
                BooleanResourceXmlAttrValue.asEntry(),
                ReferenceResourceXmlAttrValue.asEntry(),
                DimensionResourceXmlAttrValue.asEntry(),
                FloatResourceXmlAttrValue.asEntry(),
                IntegerResourceXmlAttrValue.asEntry(),
                StringResourceXmlAttrValue.asEntry(),
                FractionResourceXmlAttrValue.asEntry())));
  }

  private void assertSerialization(FullyQualifiedName key, DataValue value) throws Exception {
    Path serialized = fs.getPath("out/out.bin");
    Files.deleteIfExists(serialized);
    Path manifestPath = fs.getPath("AndroidManifest.xml");
    Files.deleteIfExists(manifestPath);
    Files.createFile(manifestPath);
    AndroidDataSerializer serializer = AndroidDataSerializer.create();
    serializer.queueForSerialization(key, value);
    serializer.flushTo(serialized);

    AndroidDataDeserializer deserializer = AndroidDataDeserializer.create();
    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    deserializer.read(
        serialized,
        KeyValueConsumers.of(new FakeConsumer(toOverwrite), new FakeConsumer(toCombine), null));
    if (key.isOverwritable()) {
      assertThat(toOverwrite).containsEntry(key, value);
      assertThat(toCombine).isEmpty();
    } else {
      assertThat(toCombine).containsEntry(key, value);
      assertThat(toOverwrite).isEmpty();
    }
  }

  private String[] resourcesXmlFrom(Path source, String... lines) {
    return resourcesXmlFrom(ImmutableMap.<String, String>of(), ImmutableMap.<String, String>of(),
        source, lines);
  }

  private String[] resourcesXmlFrom(Map<String, String> namespaces, Map<String, String> attributes,
      Path source, String... lines) {
    FluentIterable<String> xml = FluentIterable.of(new String(AndroidDataWriter.PRELUDE))
        .append("<resources")
        .append(
            FluentIterable.from(namespaces.entrySet())
                .transform(
                    new Function<Entry<String, String>, String>() {
                      @Override
                      public String apply(Entry<String, String> input) {
                        return String.format(" xmlns:%s=\"%s\"", input.getKey(), input.getValue());
                      }
                    })
                .join(Joiner.on("")))
        .append(
            FluentIterable.from(attributes.entrySet())
                .transform(
                    new Function<Entry<String, String>, String>() {
                      @Override
                      public String apply(Entry<String, String> input) {
                        return String.format(" %s=\"%s\"", input.getKey(), input.getValue());
                      }
                    })
                .join(Joiner.on("")));
    if (source == null && (lines == null || lines.length == 0)) {
      xml = xml.append("/>");
    } else {
      xml = xml.append(">");
      if (source != null) {
        xml = xml.append(String.format("<!-- %s --> <eat-comment/>", source));
      }
      if (lines != null) {
        xml = xml.append(lines);
      }
      xml = xml.append(END_RESOURCES);
    }
    return xml.toArray(String.class);
  }

  private Path parsedAndWritten(Path path, FullyQualifiedName... fqns)
      throws XMLStreamException, IOException, MergingException {
    final Map<DataKey, DataResource> toOverwrite = new HashMap<>();
    final Map<DataKey, DataResource> toCombine = new HashMap<>();
    parseResourcesFrom(path, toOverwrite, toCombine);
    Path out = fs.getPath("out");
    if (Files.exists(out)) {
      Files.walkFileTree(
          out,
          new SimpleFileVisitor<Path>() {
            @Override
            public FileVisitResult visitFile(Path file, BasicFileAttributes attrs)
                throws IOException {
              Files.delete(file);
              return FileVisitResult.CONTINUE;
            }

            @Override
            public FileVisitResult postVisitDirectory(Path directory, IOException e)
                throws IOException {
              if (e != null) {
                throw e;
              }
              Files.delete(directory);
              return FileVisitResult.CONTINUE;
            }
          });
    }
    // find and write the resource -- the categorization is tested during parsing.
    AndroidDataWriter mergedDataWriter = AndroidDataWriter.createWithDefaults(out);
    for (FullyQualifiedName fqn : fqns) {
      if (toOverwrite.containsKey(fqn)) {
        toOverwrite.get(fqn).writeResource(fqn, mergedDataWriter);
      } else if (toCombine.containsKey(fqn)) {
        toCombine.get(fqn).writeResource(fqn, mergedDataWriter);
      }
    }
    mergedDataWriter.flush();
    return mergedDataWriter.resourceDirectory().resolve("values/values.xml");
  }

  private static final Subject.Factory<PathsSubject, Path> resourcePaths = PathsSubject::new;

  private static class FakeConsumer
      implements ParsedAndroidData.KeyValueConsumer<DataKey, DataResource> {
    private final Map<DataKey, DataResource> target;

    FakeConsumer(Map<DataKey, DataResource> target) {
      this.target = target;
    }

    @Override
    public void accept(DataKey key, DataResource value) {
      target.put(key, value);
    }
  }
}
