Upgrade libprotobuf-mutator to 3521f47a2828da9ace403e4ecc4aece1a84feb36

Test: None
Change-Id: Ibb36b20df10d011d8633fb11e659fa651d89974a
diff --git a/METADATA b/METADATA
index 26788ce..358d07c 100644
--- a/METADATA
+++ b/METADATA
@@ -5,11 +5,11 @@
     type: GIT
     value: "https://github.com/google/libprotobuf-mutator"
   }
-  version: "69d93082200bb657f6db9c6b07b71bb94ea7bb47"
+  version: "3521f47a2828da9ace403e4ecc4aece1a84feb36"
   license_type: NOTICE
   last_upgrade_date {
     year: 2020
-    month: 1
-    day: 8
+    month: 2
+    day: 7
   }
 }
diff --git a/README.md b/README.md
index 842214e..4e16fb6 100644
--- a/README.md
+++ b/README.md
@@ -62,11 +62,11 @@
 ```
 class MyProtobufMutator : public protobuf_mutator::Mutator {
  public:
-  MyProtobufMutator(uint32_t seed) : protobuf_mutator::Mutator(seed) {}
   // Optionally redefine the Mutate* methods to perform more sophisticated mutations.
 }
 void Mutate(MyMessage* message) {
-  MyProtobufMutator mutator(my_random_seed);
+  MyProtobufMutator mutator;
+  mutator.Seed(my_random_seed);
   mutator.Mutate(message, 200);
 }
 ```
@@ -94,23 +94,43 @@
 or it may use some fields as checksums. Such constraints are going to be significant bottleneck
 for fuzzer even if it's capable of inserting acceptable values with time.
 
-PostProcessorRegistration can be used to avoid such issue and guide your fuzzer towards interesing
+PostProcessorRegistration can be used to avoid such issue and guide your fuzzer towards interesting
 code. It registers callback which will be called for each message of particular type after each mutation.
 
 ```
 DEFINE_PROTO_FUZZER(const MyMessageType& input) {
   static PostProcessorRegistration reg = {
       [](MyMessageType* message, unsigned int seed) {
-        TweakMyMessageType(message, seed);
+        TweakMyMessage(message, seed);
       }};
 
   // Code which needs to be fuzzed.
   ConsumeMyMessageType(input);
 }
 ```
-
 Optional: Use seed if callback uses random numbers. It may help later with debugging.
 
+Note: You can add callback for any nested message and you can add multiple callbacks for
+the same message type.
+```
+DEFINE_PROTO_FUZZER(const MyMessageType& input) {
+  static PostProcessorRegistration reg1 = {
+      [](MyMessageType* message, unsigned int seed) {
+        TweakMyMessage(message, seed);
+      }};
+  static PostProcessorRegistration reg2 = {
+      [](MyMessageType* message, unsigned int seed) {
+        DifferentTweakMyMessage(message, seed);
+      }};
+  static PostProcessorRegistration reg_nested = {
+      [](MyMessageType::Nested* message, unsigned int seed) {
+        TweakMyNestedMessage(message, seed);
+      }};
+
+  // Code which needs to be fuzzed.
+  ConsumeMyMessageType(input);
+}
+```
 ## UTF-8 strings
 "proto2" and "proto3" handle invalid UTF-8 strings differently. In both cases
 string should be UTF-8, however only "proto3" enforces that. So if fuzzer is
diff --git a/examples/libfuzzer/libfuzzer_bin_example.cc b/examples/libfuzzer/libfuzzer_bin_example.cc
index dae46da..560bcb3 100644
--- a/examples/libfuzzer/libfuzzer_bin_example.cc
+++ b/examples/libfuzzer/libfuzzer_bin_example.cc
@@ -15,6 +15,7 @@
 #include <cmath>
 
 #include "examples/libfuzzer/libfuzzer_example.pb.h"
+#include "port/protobuf.h"
 #include "src/libfuzzer/libfuzzer_macro.h"
 
 protobuf_mutator::protobuf::LogSilencer log_silincer;
@@ -26,15 +27,35 @@
           message->set_optional_uint64(
               std::hash<std::string>{}(message->optional_string()));
         }
+
+        if (message->has_any()) {
+          auto* any = message->mutable_any();
+
+          // Guide mutator to usefull 'Any' types.
+          static const char* const expected_types[] = {
+              "type.googleapis.com/google.protobuf.DescriptorProto",
+              "type.googleapis.com/google.protobuf.FileDescriptorProto",
+          };
+
+          if (!std::count(std::begin(expected_types), std::end(expected_types),
+                          any->type_url())) {
+            const size_t num =
+                (std::end(expected_types) - std::begin(expected_types));
+            any->set_type_url(expected_types[seed % num]);
+          }
+        }
       }};
 
+  protobuf_mutator::protobuf::FileDescriptorProto file;
+
   // Emulate a bug.
   if (message.optional_uint64() ==
           std::hash<std::string>{}(message.optional_string()) &&
       message.optional_string() == "abcdefghijklmnopqrstuvwxyz" &&
       !std::isnan(message.optional_float()) &&
       std::fabs(message.optional_float()) > 1000 &&
-      std::fabs(message.optional_float()) < 1E10) {
+      message.any().UnpackTo(&file) && !file.name().empty()) {
+    std::cerr << message.DebugString() << "\n";
     abort();
   }
 }
diff --git a/examples/libfuzzer/libfuzzer_example.cc b/examples/libfuzzer/libfuzzer_example.cc
index 1520840..6eab362 100644
--- a/examples/libfuzzer/libfuzzer_example.cc
+++ b/examples/libfuzzer/libfuzzer_example.cc
@@ -15,6 +15,7 @@
 #include <cmath>
 
 #include "examples/libfuzzer/libfuzzer_example.pb.h"
+#include "port/protobuf.h"
 #include "src/libfuzzer/libfuzzer_macro.h"
 
 protobuf_mutator::protobuf::LogSilencer log_silincer;
@@ -26,15 +27,35 @@
           message->set_optional_uint64(
               std::hash<std::string>{}(message->optional_string()));
         }
+
+        if (message->has_any()) {
+          auto* any = message->mutable_any();
+
+          // Guide mutator to usefull 'Any' types.
+          static const char* const expected_types[] = {
+              "type.googleapis.com/google.protobuf.DescriptorProto",
+              "type.googleapis.com/google.protobuf.FileDescriptorProto",
+          };
+
+          if (!std::count(std::begin(expected_types), std::end(expected_types),
+                          any->type_url())) {
+            const size_t num =
+                (std::end(expected_types) - std::begin(expected_types));
+            any->set_type_url(expected_types[seed % num]);
+          }
+        }
       }};
 
+  protobuf_mutator::protobuf::FileDescriptorProto file;
+
   // Emulate a bug.
   if (message.optional_uint64() ==
           std::hash<std::string>{}(message.optional_string()) &&
       message.optional_string() == "abcdefghijklmnopqrstuvwxyz" &&
       !std::isnan(message.optional_float()) &&
       std::fabs(message.optional_float()) > 1000 &&
-      std::fabs(message.optional_float()) < 1E10) {
+      message.any().UnpackTo(&file) && !file.name().empty()) {
+    std::cerr << message.DebugString() << "\n";
     abort();
   }
 }
diff --git a/examples/libfuzzer/libfuzzer_example.proto b/examples/libfuzzer/libfuzzer_example.proto
index 71e5fc9..cb25c9d 100644
--- a/examples/libfuzzer/libfuzzer_example.proto
+++ b/examples/libfuzzer/libfuzzer_example.proto
@@ -1,8 +1,11 @@
 syntax = "proto2";
 package libfuzzer_example;
 
+import "google/protobuf/any.proto";
+
 message Msg {
   optional float optional_float = 1;
   optional uint64 optional_uint64 = 2;
   optional string optional_string = 3;
+  optional google.protobuf.Any any = 4;
 }
diff --git a/examples/libfuzzer/libfuzzer_example_test.cc b/examples/libfuzzer/libfuzzer_example_test.cc
index e871d59..2c6fd8c 100644
--- a/examples/libfuzzer/libfuzzer_example_test.cc
+++ b/examples/libfuzzer/libfuzzer_example_test.cc
@@ -25,12 +25,12 @@
 
 TEST_F(LibFuzzerExampleTest, Text) {
   EXPECT_EQ(kDefaultLibFuzzerError,
-            GetError(RunFuzzer("libfuzzer_example", 150, 10000000)));
+            GetError(RunFuzzer("libfuzzer_example", 1000, 10000000)));
 }
 
 TEST_F(LibFuzzerExampleTest, Binary) {
   EXPECT_EQ(kDefaultLibFuzzerError,
-            GetError(RunFuzzer("libfuzzer_bin_example", 150, 10000000)));
+            GetError(RunFuzzer("libfuzzer_bin_example", 1000, 10000000)));
 }
 
 }  // namespace
diff --git a/port/protobuf.h b/port/protobuf.h
index e70d42d..04e0620 100644
--- a/port/protobuf.h
+++ b/port/protobuf.h
@@ -17,6 +17,7 @@
 
 #include <string>
 
+#include "google/protobuf/any.pb.h"
 #include "google/protobuf/descriptor.pb.h"
 #include "google/protobuf/message.h"
 #include "google/protobuf/text_format.h"
diff --git a/src/libfuzzer/libfuzzer_macro.cc b/src/libfuzzer/libfuzzer_macro.cc
index c37276d..b2a5302 100644
--- a/src/libfuzzer/libfuzzer_macro.cc
+++ b/src/libfuzzer/libfuzzer_macro.cc
@@ -14,6 +14,8 @@
 
 #include "src/libfuzzer/libfuzzer_macro.h"
 
+#include <algorithm>
+
 #include "src/binary_format.h"
 #include "src/libfuzzer/libfuzzer_mutator.h"
 #include "src/text_format.h"
@@ -94,13 +96,19 @@
   return &mutator;
 }
 
+size_t GetMaxSize(const InputReader& input, const OutputWriter& output,
+                  const protobuf::Message& message) {
+  size_t max_size = message.ByteSizeLong() + output.size();
+  max_size -= std::min(max_size, input.size());
+  return max_size;
+}
+
 size_t MutateMessage(unsigned int seed, const InputReader& input,
                      OutputWriter* output, protobuf::Message* message) {
   GetMutator()->Seed(seed);
   input.Read(message);
-  GetMutator()->Mutate(message, output->size() > input.size()
-                                    ? (output->size() - input.size())
-                                    : 0);
+  size_t max_size = GetMaxSize(input, *output, *message);
+  GetMutator()->Mutate(message, max_size);
   if (size_t new_size = output->Write(*message)) {
     assert(new_size <= output->size());
     return new_size;
@@ -115,7 +123,8 @@
   GetMutator()->Seed(seed);
   input1.Read(message1);
   input2.Read(message2);
-  GetMutator()->CrossOver(*message2, message1);
+  size_t max_size = GetMaxSize(input1, *output, *message1);
+  GetMutator()->CrossOver(*message2, message1, max_size);
   if (size_t new_size = output->Write(*message1)) {
     assert(new_size <= output->size());
     return new_size;
diff --git a/src/libfuzzer/libfuzzer_mutator.cc b/src/libfuzzer/libfuzzer_mutator.cc
index 979cebf..c8bca64 100644
--- a/src/libfuzzer/libfuzzer_mutator.cc
+++ b/src/libfuzzer/libfuzzer_mutator.cc
@@ -16,6 +16,7 @@
 
 #include <string.h>
 
+#include <algorithm>
 #include <cassert>
 #include <memory>
 #include <string>
@@ -82,13 +83,14 @@
 double Mutator::MutateDouble(double value) { return MutateValue(value); }
 
 std::string Mutator::MutateString(const std::string& value,
-                                  size_t size_increase_hint) {
+                                  int size_increase_hint) {
   // Randomly return empty strings as LLVMFuzzerMutate does not produce them.
   // Use uint16_t because on Windows, uniform_int_distribution does not support
   // any 8 bit types.
   if (!std::uniform_int_distribution<uint16_t>(0, 20)(*random())) return {};
   std::string result = value;
-  result.resize(value.size() + size_increase_hint);
+  result.resize(value.size() +
+                std::max<int>(-value.size(), size_increase_hint));
   if (result.empty()) result.push_back(0);
   result.resize(LLVMFuzzerMutate(reinterpret_cast<uint8_t*>(&result[0]),
                                  value.size(), result.size()));
diff --git a/src/libfuzzer/libfuzzer_mutator.h b/src/libfuzzer/libfuzzer_mutator.h
index 45ea908..04d6604 100644
--- a/src/libfuzzer/libfuzzer_mutator.h
+++ b/src/libfuzzer/libfuzzer_mutator.h
@@ -37,7 +37,7 @@
   float MutateFloat(float value) override;
   double MutateDouble(double value) override;
   std::string MutateString(const std::string& value,
-                           size_t size_increase_hint) override;
+                           int size_increase_hint) override;
 };
 
 }  // namespace libfuzzer
diff --git a/src/mutator.cc b/src/mutator.cc
index e4e0305..45acd48 100644
--- a/src/mutator.cc
+++ b/src/mutator.cc
@@ -15,9 +15,12 @@
 #include "src/mutator.h"
 
 #include <algorithm>
+#include <bitset>
 #include <map>
+#include <memory>
 #include <random>
 #include <string>
+#include <utility>
 #include <vector>
 
 #include "src/field_instance.h"
@@ -26,6 +29,7 @@
 
 namespace protobuf_mutator {
 
+using google::protobuf::Any;
 using protobuf::Descriptor;
 using protobuf::FieldDescriptor;
 using protobuf::FileDescriptor;
@@ -40,17 +44,22 @@
 const int kMaxInitializeDepth = 200;
 const uint64_t kDefaultMutateWeight = 1000000;
 
-enum class Mutation {
+enum class Mutation : uint8_t {
   None,
   Add,     // Adds new field with default value.
   Mutate,  // Mutates field contents.
   Delete,  // Deletes field.
   Copy,    // Copy values copied from another field.
+  Clone,   // Create new field with value copied from another.
 
-  // TODO(vitalybuka):
-  // Clone,  // Adds new field with value copied from another field.
+  Last = Clone,
 };
 
+using MutationBitset = std::bitset<static_cast<size_t>(Mutation::Last)>;
+
+using Messages = std::vector<Message*>;
+using ConstMessages = std::vector<const Message*>;
+
 // Return random integer from [0, count)
 size_t GetRandomIndex(RandomEngine* random, size_t count) {
   assert(count > 0);
@@ -124,14 +133,14 @@
     : public FieldFunction<CanCopyAndDifferentField, bool> {
  public:
   template <class T>
-  bool ForType(const ConstFieldInstance& src,
-               const ConstFieldInstance& dst) const {
+  bool ForType(const ConstFieldInstance& src, const ConstFieldInstance& dst,
+               int size_increase_hint) const {
     T s;
     src.Load(&s);
     if (!dst.CanStore(s)) return false;
     T d;
     dst.Load(&d);
-    return !IsEqual(s, d);
+    return SizeDiff(s, d) <= size_increase_hint && !IsEqual(s, d);
   }
 
  private:
@@ -141,8 +150,8 @@
     return a.index == b.index;
   }
 
-  bool IsEqual(const std::unique_ptr<protobuf::Message>& a,
-               const std::unique_ptr<protobuf::Message>& b) const {
+  bool IsEqual(const std::unique_ptr<Message>& a,
+               const std::unique_ptr<Message>& b) const {
     return MessageDifferencer::Equals(*a, *b);
   }
 
@@ -150,17 +159,31 @@
   bool IsEqual(const T& a, const T& b) const {
     return a == b;
   }
+
+  int64_t SizeDiff(const std::unique_ptr<Message>& src,
+                   const std::unique_ptr<Message>& dst) const {
+    return src->ByteSizeLong() - dst->ByteSizeLong();
+  }
+
+  int64_t SizeDiff(const std::string& src, const std::string& dst) const {
+    return src.size() - dst.size();
+  }
+
+  template <class T>
+  int64_t SizeDiff(const T&, const T&) const {
+    return 0;
+  }
 };
 
 // Selects random field and mutation from the given proto message.
 class MutationSampler {
  public:
-  MutationSampler(bool keep_initialized, RandomEngine* random, Message* message)
-      : keep_initialized_(keep_initialized), random_(random), sampler_(random) {
-    Sample(message);
-    assert(mutation() != Mutation::None ||
-           message->GetDescriptor()->field_count() == 0);
-  }
+  MutationSampler(bool keep_initialized, MutationBitset allowed_mutations,
+                  RandomEngine* random)
+      : keep_initialized_(keep_initialized),
+        allowed_mutations_(allowed_mutations),
+        random_(random),
+        sampler_(random) {}
 
   // Returns selected field.
   const FieldInstance& field() const { return sampler_.selected().field; }
@@ -168,8 +191,15 @@
   // Returns selected mutation.
   Mutation mutation() const { return sampler_.selected().mutation; }
 
- private:
   void Sample(Message* message) {
+    SampleImpl(message);
+    assert(mutation() != Mutation::None ||
+           !allowed_mutations_[static_cast<size_t>(Mutation::Mutate)] ||
+           message->GetDescriptor()->field_count() == 0);
+  }
+
+ private:
+  void SampleImpl(Message* message) {
     const Descriptor* descriptor = message->GetDescriptor();
     const Reflection* reflection = message->GetReflection();
 
@@ -186,59 +216,46 @@
             const FieldDescriptor* add_field =
                 oneof->field(GetRandomIndex(random_, oneof->field_count()));
             if (add_field != current_field) {
-              sampler_.Try(kDefaultMutateWeight,
-                           {{message, add_field}, Mutation::Add});
+              Try({message, add_field}, Mutation::Add);
+              Try({message, add_field}, Mutation::Clone);
               break;
             }
             if (oneof->field_count() < 2) break;
           }
           if (current_field) {
-            if (current_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
-              sampler_.Try(kDefaultMutateWeight,
-                           {{message, current_field}, Mutation::Mutate});
-            }
-            sampler_.Try(kDefaultMutateWeight,
-                         {{message, current_field}, Mutation::Delete});
-            sampler_.Try(kDefaultMutateWeight,
-                         {{message, current_field}, Mutation::Copy});
+            if (current_field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
+              Try({message, current_field}, Mutation::Mutate);
+            Try({message, current_field}, Mutation::Delete);
+            Try({message, current_field}, Mutation::Copy);
           }
         }
       } else {
         if (field->is_repeated()) {
           int field_size = reflection->FieldSize(*message, field);
-          sampler_.Try(
-              kDefaultMutateWeight,
-              {{message, field, GetRandomIndex(random_, field_size + 1)},
-               Mutation::Add});
+          size_t random_index = GetRandomIndex(random_, field_size + 1);
+          Try({message, field, random_index}, Mutation::Add);
+          Try({message, field, random_index}, Mutation::Clone);
 
           if (field_size) {
             size_t random_index = GetRandomIndex(random_, field_size);
-            if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
-              sampler_.Try(kDefaultMutateWeight,
-                           {{message, field, random_index}, Mutation::Mutate});
-            }
-            sampler_.Try(kDefaultMutateWeight,
-                         {{message, field, random_index}, Mutation::Delete});
-            sampler_.Try(kDefaultMutateWeight,
-                         {{message, field, random_index}, Mutation::Copy});
+            if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
+              Try({message, field, random_index}, Mutation::Mutate);
+            Try({message, field, random_index}, Mutation::Delete);
+            Try({message, field, random_index}, Mutation::Copy);
           }
         } else {
           if (reflection->HasField(*message, field) ||
               IsProto3SimpleField(*field)) {
-            if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
-              sampler_.Try(kDefaultMutateWeight,
-                           {{message, field}, Mutation::Mutate});
-            }
+            if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE)
+              Try({message, field}, Mutation::Mutate);
             if (!IsProto3SimpleField(*field) &&
                 (!field->is_required() || !keep_initialized_)) {
-              sampler_.Try(kDefaultMutateWeight,
-                           {{message, field}, Mutation::Delete});
+              Try({message, field}, Mutation::Delete);
             }
-            sampler_.Try(kDefaultMutateWeight,
-                         {{message, field}, Mutation::Copy});
+            Try({message, field}, Mutation::Copy);
           } else {
-            sampler_.Try(kDefaultMutateWeight,
-                         {{message, field}, Mutation::Add});
+            Try({message, field}, Mutation::Add);
+            Try({message, field}, Mutation::Clone);
           }
         }
       }
@@ -247,15 +264,22 @@
         if (field->is_repeated()) {
           const int field_size = reflection->FieldSize(*message, field);
           for (int j = 0; j < field_size; ++j)
-            Sample(reflection->MutableRepeatedMessage(message, field, j));
+            SampleImpl(reflection->MutableRepeatedMessage(message, field, j));
         } else if (reflection->HasField(*message, field)) {
-          Sample(reflection->MutableMessage(message, field));
+          SampleImpl(reflection->MutableMessage(message, field));
         }
       }
     }
   }
 
+  void Try(const FieldInstance& field, Mutation mutation) {
+    assert(mutation != Mutation::None);
+    if (!allowed_mutations_[static_cast<size_t>(mutation)]) return;
+    sampler_.Try(kDefaultMutateWeight, {field, mutation});
+  }
+
   bool keep_initialized_ = false;
+  MutationBitset allowed_mutations_;
 
   RandomEngine* random_;
 
@@ -273,10 +297,13 @@
 class DataSourceSampler {
  public:
   DataSourceSampler(const ConstFieldInstance& match, RandomEngine* random,
-                    Message* message)
-      : match_(match), random_(random), sampler_(random) {
-    Sample(message);
-  }
+                    int size_increase_hint)
+      : match_(match),
+        random_(random),
+        size_increase_hint_(size_increase_hint),
+        sampler_(random) {}
+
+  void Sample(const Message& message) { SampleImpl(message); }
 
   // Returns selected field.
   const ConstFieldInstance& field() const {
@@ -287,21 +314,21 @@
   bool IsEmpty() const { return sampler_.IsEmpty(); }
 
  private:
-  void Sample(Message* message) {
-    const Descriptor* descriptor = message->GetDescriptor();
-    const Reflection* reflection = message->GetReflection();
+  void SampleImpl(const Message& message) {
+    const Descriptor* descriptor = message.GetDescriptor();
+    const Reflection* reflection = message.GetReflection();
 
     int field_count = descriptor->field_count();
     for (int i = 0; i < field_count; ++i) {
       const FieldDescriptor* field = descriptor->field(i);
       if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
         if (field->is_repeated()) {
-          const int field_size = reflection->FieldSize(*message, field);
+          const int field_size = reflection->FieldSize(message, field);
           for (int j = 0; j < field_size; ++j) {
-            Sample(reflection->MutableRepeatedMessage(message, field, j));
+            SampleImpl(reflection->GetRepeatedMessage(message, field, j));
           }
-        } else if (reflection->HasField(*message, field)) {
-          Sample(reflection->MutableMessage(message, field));
+        } else if (reflection->HasField(message, field)) {
+          SampleImpl(reflection->GetMessage(message, field));
         }
       }
 
@@ -313,16 +340,16 @@
       }
 
       if (field->is_repeated()) {
-        if (int field_size = reflection->FieldSize(*message, field)) {
-          ConstFieldInstance source(message, field,
+        if (int field_size = reflection->FieldSize(message, field)) {
+          ConstFieldInstance source(&message, field,
                                     GetRandomIndex(random_, field_size));
-          if (CanCopyAndDifferentField()(source, match_))
+          if (CanCopyAndDifferentField()(source, match_, size_increase_hint_))
             sampler_.Try(field_size, source);
         }
       } else {
-        if (reflection->HasField(*message, field)) {
-          ConstFieldInstance source(message, field);
-          if (CanCopyAndDifferentField()(source, match_))
+        if (reflection->HasField(message, field)) {
+          ConstFieldInstance source(&message, field);
+          if (CanCopyAndDifferentField()(source, match_, size_increase_hint_))
             sampler_.Try(1, source);
         }
       }
@@ -331,19 +358,162 @@
 
   ConstFieldInstance match_;
   RandomEngine* random_;
+  int size_increase_hint_;
 
   WeightedReservoirSampler<ConstFieldInstance, RandomEngine> sampler_;
 };
 
+using UnpackedAny =
+    std::unordered_map<const Message*, std::unique_ptr<Message>>;
+
+const Descriptor* GetAnyTypeDescriptor(const Any& any) {
+  std::string type_name;
+  if (!Any::ParseAnyTypeUrl(std::string(any.type_url()), &type_name))
+    return nullptr;
+  return any.descriptor()->file()->pool()->FindMessageTypeByName(type_name);
+}
+
+std::unique_ptr<Message> UnpackAny(const Any& any) {
+  const Descriptor* desc = GetAnyTypeDescriptor(any);
+  if (!desc) return {};
+  std::unique_ptr<Message> message(
+      any.GetReflection()->GetMessageFactory()->GetPrototype(desc)->New());
+  message->ParsePartialFromString(std::string(any.value()));
+  return message;
+}
+
+const Any* CastToAny(const Message* message) {
+  return Any::GetDescriptor() == message->GetDescriptor()
+             ? static_cast<const Any*>(message)
+             : nullptr;
+}
+
+Any* CastToAny(Message* message) {
+  return Any::GetDescriptor() == message->GetDescriptor()
+             ? static_cast<Any*>(message)
+             : nullptr;
+}
+
+std::unique_ptr<Message> UnpackIfAny(const Message& message) {
+  if (const Any* any = CastToAny(&message)) return UnpackAny(*any);
+  return {};
+}
+
+void UnpackAny(const Message& message, UnpackedAny* result) {
+  if (std::unique_ptr<Message> any = UnpackIfAny(message)) {
+    UnpackAny(*any, result);
+    result->emplace(&message, std::move(any));
+    return;
+  }
+
+  const Descriptor* descriptor = message.GetDescriptor();
+  const Reflection* reflection = message.GetReflection();
+
+  for (int i = 0; i < descriptor->field_count(); ++i) {
+    const FieldDescriptor* field = descriptor->field(i);
+    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
+      if (field->is_repeated()) {
+        const int field_size = reflection->FieldSize(message, field);
+        for (int j = 0; j < field_size; ++j) {
+          UnpackAny(reflection->GetRepeatedMessage(message, field, j), result);
+        }
+      } else if (reflection->HasField(message, field)) {
+        UnpackAny(reflection->GetMessage(message, field), result);
+      }
+    }
+  }
+}
+
+class PostProcessing {
+ public:
+  using PostProcessors =
+      std::unordered_multimap<const Descriptor*, Mutator::PostProcess>;
+
+  PostProcessing(bool keep_initialized, const PostProcessors& post_processors,
+                 const UnpackedAny& any, RandomEngine* random)
+      : keep_initialized_(keep_initialized),
+        post_processors_(post_processors),
+        any_(any),
+        random_(random) {}
+
+  void Run(Message* message, int max_depth) {
+    --max_depth;
+    const Descriptor* descriptor = message->GetDescriptor();
+
+    // Apply custom mutators in nested messages before packing any.
+    const Reflection* reflection = message->GetReflection();
+    for (int i = 0; i < descriptor->field_count(); i++) {
+      const FieldDescriptor* field = descriptor->field(i);
+      if (keep_initialized_ &&
+          (field->is_required() || descriptor->options().map_entry()) &&
+          !reflection->HasField(*message, field)) {
+        CreateDefaultField()(FieldInstance(message, field));
+      }
+
+      if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) continue;
+
+      if (max_depth < 0 && !field->is_required()) {
+        // Clear deep optional fields to avoid stack overflow.
+        reflection->ClearField(message, field);
+        if (field->is_repeated())
+          assert(!reflection->FieldSize(*message, field));
+        else
+          assert(!reflection->HasField(*message, field));
+        continue;
+      }
+
+      if (field->is_repeated()) {
+        const int field_size = reflection->FieldSize(*message, field);
+        for (int j = 0; j < field_size; ++j) {
+          Message* nested_message =
+              reflection->MutableRepeatedMessage(message, field, j);
+          Run(nested_message, max_depth);
+        }
+      } else if (reflection->HasField(*message, field)) {
+        Message* nested_message = reflection->MutableMessage(message, field);
+        Run(nested_message, max_depth);
+      }
+    }
+
+    if (Any* any = CastToAny(message)) {
+      if (max_depth < 0) {
+        // Clear deep Any fields to avoid stack overflow.
+        any->Clear();
+      } else {
+        auto It = any_.find(message);
+        if (It != any_.end()) {
+          Run(It->second.get(), max_depth);
+          std::string value;
+          It->second->SerializePartialToString(&value);
+          *any->mutable_value() = value;
+        }
+      }
+    }
+
+    // Call user callback after message trimmed, initialized and packed.
+    auto range = post_processors_.equal_range(descriptor);
+    for (auto it = range.first; it != range.second; ++it)
+      it->second(message, (*random_)());
+  }
+
+ private:
+  bool keep_initialized_;
+  const PostProcessors& post_processors_;
+  const UnpackedAny& any_;
+  RandomEngine* random_;
+};
+
 }  // namespace
 
 class FieldMutator {
  public:
-  FieldMutator(size_t size_increase_hint, bool enforce_changes,
-               bool enforce_utf8_strings, Mutator* mutator)
+  FieldMutator(int size_increase_hint, bool enforce_changes,
+               bool enforce_utf8_strings, const ConstMessages& sources,
+               Mutator* mutator)
       : size_increase_hint_(size_increase_hint),
         enforce_changes_(enforce_changes),
         enforce_utf8_strings_(enforce_utf8_strings),
+        sources_(sources),
         mutator_(mutator) {}
 
   void Mutate(int32_t* value) const {
@@ -395,7 +565,8 @@
     assert(*message);
     if (GetRandomBool(mutator_->random(), mutator_->random_to_default_ratio_))
       return;
-    mutator_->MutateImpl(message->get(), size_increase_hint_);
+    mutator_->MutateImpl(sources_, {message->get()}, false,
+                         size_increase_hint_);
   }
 
  private:
@@ -412,9 +583,10 @@
     }
   }
 
-  size_t size_increase_hint_;
+  int size_increase_hint_;
   size_t enforce_changes_;
   bool enforce_utf8_strings_;
+  const ConstMessages& sources_;
   Mutator* mutator_;
 };
 
@@ -422,11 +594,12 @@
 
 struct MutateField : public FieldFunction<MutateField> {
   template <class T>
-  void ForType(const FieldInstance& field, size_t size_increase_hint,
-               Mutator* mutator) const {
+  void ForType(const FieldInstance& field, int size_increase_hint,
+               const ConstMessages& sources, Mutator* mutator) const {
     T value;
     field.Load(&value);
-    FieldMutator(size_increase_hint, true, field.EnforceUtf8(), mutator)
+    FieldMutator(size_increase_hint, true, field.EnforceUtf8(), sources,
+                 mutator)
         .Mutate(&value);
     field.Store(value);
   }
@@ -435,13 +608,13 @@
 struct CreateField : public FieldFunction<CreateField> {
  public:
   template <class T>
-  void ForType(const FieldInstance& field, size_t size_increase_hint,
-               Mutator* mutator) const {
+  void ForType(const FieldInstance& field, int size_increase_hint,
+               const ConstMessages& sources, Mutator* mutator) const {
     T value;
     field.GetDefault(&value);
     FieldMutator field_mutator(size_increase_hint,
                                false /* defaults could be useful */,
-                               field.EnforceUtf8(), mutator);
+                               field.EnforceUtf8(), sources, mutator);
     field_mutator.Mutate(&value);
     field.Create(value);
   }
@@ -451,210 +624,116 @@
 
 void Mutator::Seed(uint32_t value) { random_.seed(value); }
 
-void Mutator::Mutate(Message* message, size_t size_increase_hint) {
-  MutateImpl(message, size_increase_hint);
+void Mutator::Mutate(Message* message, size_t max_size_hint) {
+  UnpackedAny any;
+  UnpackAny(*message, &any);
 
-  InitializeAndTrim(message, kMaxInitializeDepth);
-  assert(!keep_initialized_ || message->IsInitialized());
+  Messages messages;
+  messages.reserve(any.size() + 1);
+  messages.push_back(message);
+  for (const auto& kv : any) messages.push_back(kv.second.get());
 
-  if (!post_processors_.empty()) {
-    ApplyPostProcessing(message);
-  }
+  ConstMessages sources(messages.begin(), messages.end());
+  MutateImpl(sources, messages, false,
+             static_cast<int>(max_size_hint) -
+                 static_cast<int>(message->ByteSizeLong()));
+
+  PostProcessing(keep_initialized_, post_processors_, any, &random_)
+      .Run(message, kMaxInitializeDepth);
+  assert(IsInitialized(*message));
 }
 
-void Mutator::RegisterPostProcessor(const protobuf::Descriptor* desc,
+void Mutator::CrossOver(const Message& message1, Message* message2,
+                        size_t max_size_hint) {
+  UnpackedAny any;
+  UnpackAny(*message2, &any);
+
+  Messages messages;
+  messages.reserve(any.size() + 1);
+  messages.push_back(message2);
+  for (auto& kv : any) messages.push_back(kv.second.get());
+
+  UnpackAny(message1, &any);
+
+  ConstMessages sources;
+  sources.reserve(any.size() + 2);
+  sources.push_back(&message1);
+  sources.push_back(message2);
+  for (const auto& kv : any) sources.push_back(kv.second.get());
+
+  MutateImpl(sources, messages, true,
+             static_cast<int>(max_size_hint) -
+                 static_cast<int>(message2->ByteSizeLong()));
+
+  PostProcessing(keep_initialized_, post_processors_, any, &random_)
+      .Run(message2, kMaxInitializeDepth);
+  assert(IsInitialized(*message2));
+}
+
+void Mutator::RegisterPostProcessor(const Descriptor* desc,
                                     PostProcess callback) {
   post_processors_.emplace(desc, callback);
 }
 
-void Mutator::ApplyPostProcessing(Message* message) {
-  const Descriptor* descriptor = message->GetDescriptor();
-
-  auto it = post_processors_.find(descriptor);
-  if (it != post_processors_.end()) {
-    it->second(message, random_());
+bool Mutator::MutateImpl(const ConstMessages& sources, const Messages& messages,
+                         bool copy_clone_only, int size_increase_hint) {
+  MutationBitset mutations;
+  if (copy_clone_only) {
+    mutations[static_cast<size_t>(Mutation::Copy)] = true;
+    mutations[static_cast<size_t>(Mutation::Clone)] = true;
+  } else if (size_increase_hint <= 16) {
+    mutations[static_cast<size_t>(Mutation::Delete)] = true;
+  } else {
+    mutations.set();
+    mutations[static_cast<size_t>(Mutation::Copy)] = false;
+    mutations[static_cast<size_t>(Mutation::Clone)] = false;
   }
+  while (mutations.any()) {
+    MutationSampler mutation(keep_initialized_, mutations, &random_);
+    for (Message* message : messages) mutation.Sample(message);
 
-  // Now recursively apply custom mutators.
-  const Reflection* reflection = message->GetReflection();
-  for (int i = 0; i < descriptor->field_count(); i++) {
-    const FieldDescriptor* field = descriptor->field(i);
-    if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
-      continue;
-    }
-    if (field->is_repeated()) {
-      const int field_size = reflection->FieldSize(*message, field);
-      for (int j = 0; j < field_size; ++j) {
-        Message* nested_message =
-            reflection->MutableRepeatedMessage(message, field, j);
-        ApplyPostProcessing(nested_message);
-      }
-    } else if (reflection->HasField(*message, field)) {
-      Message* nested_message = reflection->MutableMessage(message, field);
-      ApplyPostProcessing(nested_message);
-    }
-  }
-}
-
-void Mutator::MutateImpl(Message* message, size_t size_increase_hint) {
-  for (;;) {
-    MutationSampler mutation(keep_initialized_, &random_, message);
     switch (mutation.mutation()) {
       case Mutation::None:
-        return;
+        return true;
       case Mutation::Add:
-        CreateField()(mutation.field(), size_increase_hint / 2, this);
-        return;
+        CreateField()(mutation.field(), size_increase_hint, sources, this);
+        return true;
       case Mutation::Mutate:
-        MutateField()(mutation.field(), size_increase_hint / 2, this);
-        return;
+        MutateField()(mutation.field(), size_increase_hint, sources, this);
+        return true;
       case Mutation::Delete:
         DeleteField()(mutation.field());
-        return;
+        return true;
+      case Mutation::Clone: {
+        CreateDefaultField()(mutation.field());
+        DataSourceSampler source_sampler(mutation.field(), &random_,
+                                         size_increase_hint);
+        for (const Message* source : sources) source_sampler.Sample(*source);
+        if (source_sampler.IsEmpty()) {
+          if (!IsProto3SimpleField(*mutation.field().descriptor()))
+            return true;  // CreateField is enough for proto2.
+          break;
+        }
+        CopyField()(source_sampler.field(), mutation.field());
+        return true;
+      }
       case Mutation::Copy: {
-        DataSourceSampler source(mutation.field(), &random_, message);
-        if (source.IsEmpty()) break;
-        CopyField()(source.field(), mutation.field());
-        return;
+        DataSourceSampler source_sampler(mutation.field(), &random_,
+                                         size_increase_hint);
+        for (const Message* source : sources) source_sampler.Sample(*source);
+        if (source_sampler.IsEmpty()) break;
+        CopyField()(source_sampler.field(), mutation.field());
+        return true;
       }
       default:
         assert(false && "unexpected mutation");
-        return;
-    }
-  }
-}
-
-void Mutator::CrossOver(const protobuf::Message& message1,
-                        protobuf::Message* message2) {
-  // CrossOver can produce result which still equals to inputs. So we backup
-  // message2 to later comparison. message1 is already constant.
-  std::unique_ptr<protobuf::Message> message2_copy(message2->New());
-  message2_copy->CopyFrom(*message2);
-
-  CrossOverImpl(message1, message2);
-
-  InitializeAndTrim(message2, kMaxInitializeDepth);
-  assert(!keep_initialized_ || message2->IsInitialized());
-
-  if (!post_processors_.empty()) {
-    ApplyPostProcessing(message2);
-  }
-
-  // Can't call mutate from crossover because of a bug in libFuzzer.
-  // if (MessageDifferencer::Equals(*message2_copy, *message2) ||
-  //     MessageDifferencer::Equals(message1, *message2)) {
-  //   Mutate(message2, 0);
-  // }
-}
-
-void Mutator::CrossOverImpl(const protobuf::Message& message1,
-                            protobuf::Message* message2) {
-  const Descriptor* descriptor = message2->GetDescriptor();
-  const Reflection* reflection = message2->GetReflection();
-  assert(message1.GetDescriptor() == descriptor);
-  assert(message1.GetReflection() == reflection);
-
-  for (int i = 0; i < descriptor->field_count(); ++i) {
-    const FieldDescriptor* field = descriptor->field(i);
-
-    if (field->is_repeated()) {
-      const int field_size1 = reflection->FieldSize(message1, field);
-      int field_size2 = reflection->FieldSize(*message2, field);
-      for (int j = 0; j < field_size1; ++j) {
-        ConstFieldInstance source(&message1, field, j);
-        FieldInstance destination(message2, field, field_size2++);
-        AppendField()(source, destination);
-      }
-
-      assert(field_size2 == reflection->FieldSize(*message2, field));
-
-      // Shuffle
-      for (int j = 0; j < field_size2; ++j) {
-        if (int k = GetRandomIndex(&random_, field_size2 - j)) {
-          reflection->SwapElements(message2, field, j, j + k);
-        }
-      }
-
-      int keep = GetRandomIndex(&random_, field_size2 + 1);
-
-      if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
-        int remove = field_size2 - keep;
-        // Cross some message to keep with messages to remove.
-        int cross = GetRandomIndex(&random_, std::min(keep, remove) + 1);
-        for (int j = 0; j < cross; ++j) {
-          int k = GetRandomIndex(&random_, keep);
-          int r = keep + GetRandomIndex(&random_, remove);
-          assert(k != r);
-          CrossOverImpl(reflection->GetRepeatedMessage(*message2, field, r),
-                        reflection->MutableRepeatedMessage(message2, field, k));
-        }
-      }
-
-      for (int j = keep; j < field_size2; ++j)
-        reflection->RemoveLast(message2, field);
-      assert(keep == reflection->FieldSize(*message2, field));
-
-    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
-      if (!reflection->HasField(message1, field)) {
-        if (GetRandomBool(&random_))
-          DeleteField()(FieldInstance(message2, field));
-      } else if (!reflection->HasField(*message2, field)) {
-        if (GetRandomBool(&random_)) {
-          ConstFieldInstance source(&message1, field);
-          CopyField()(source, FieldInstance(message2, field));
-        }
-      } else {
-        CrossOverImpl(reflection->GetMessage(message1, field),
-                      reflection->MutableMessage(message2, field));
-      }
-    } else {
-      if (GetRandomBool(&random_)) {
-        if (reflection->HasField(message1, field)) {
-          ConstFieldInstance source(&message1, field);
-          CopyField()(source, FieldInstance(message2, field));
-        } else {
-          DeleteField()(FieldInstance(message2, field));
-        }
-      }
-    }
-  }
-}
-
-void Mutator::InitializeAndTrim(Message* message, int max_depth) {
-  const Descriptor* descriptor = message->GetDescriptor();
-  const Reflection* reflection = message->GetReflection();
-  for (int i = 0; i < descriptor->field_count(); ++i) {
-    const FieldDescriptor* field = descriptor->field(i);
-    if (keep_initialized_ &&
-        (field->is_required() || descriptor->options().map_entry()) &&
-        !reflection->HasField(*message, field)) {
-      CreateDefaultField()(FieldInstance(message, field));
+        return false;
     }
 
-    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
-      if (max_depth <= 0 && !field->is_required()) {
-        // Clear deep optional fields to avoid stack overflow.
-        reflection->ClearField(message, field);
-        if (field->is_repeated())
-          assert(!reflection->FieldSize(*message, field));
-        else
-          assert(!reflection->HasField(*message, field));
-        continue;
-      }
-
-      if (field->is_repeated()) {
-        const int field_size = reflection->FieldSize(*message, field);
-        for (int j = 0; j < field_size; ++j) {
-          Message* nested_message =
-              reflection->MutableRepeatedMessage(message, field, j);
-          InitializeAndTrim(nested_message, max_depth - 1);
-        }
-      } else if (reflection->HasField(*message, field)) {
-        Message* nested_message = reflection->MutableMessage(message, field);
-        InitializeAndTrim(nested_message, max_depth - 1);
-      }
-    }
+    // Don't try same mutation next time.
+    mutations[static_cast<size_t>(mutation.mutation())] = false;
   }
+  return false;
 }
 
 int32_t Mutator::MutateInt32(int32_t value) { return FlipBit(value, &random_); }
@@ -681,14 +760,16 @@
 }
 
 std::string Mutator::MutateString(const std::string& value,
-                                  size_t size_increase_hint) {
+                                  int size_increase_hint) {
   std::string result = value;
 
   while (!result.empty() && GetRandomBool(&random_)) {
     result.erase(GetRandomIndex(&random_, result.size()), 1);
   }
 
-  while (result.size() < size_increase_hint && GetRandomBool(&random_)) {
+  while (size_increase_hint > 0 &&
+         result.size() < static_cast<size_t>(size_increase_hint) &&
+         GetRandomBool(&random_)) {
     size_t index = GetRandomIndex(&random_, result.size() + 1);
     result.insert(result.begin() + index, GetRandomIndex(&random_, 1 << 8));
   }
@@ -706,10 +787,16 @@
 }
 
 std::string Mutator::MutateUtf8String(const std::string& value,
-                                      size_t size_increase_hint) {
+                                      int size_increase_hint) {
   std::string str = MutateString(value, size_increase_hint);
   FixUtf8String(&str, &random_);
   return str;
 }
 
+bool Mutator::IsInitialized(const Message& message) const {
+  if (!keep_initialized_ || message.IsInitialized()) return true;
+  std::cerr << "Uninitialized: " << message.DebugString() << "\n";
+  return false;
+}
+
 }  // namespace protobuf_mutator
diff --git a/src/mutator.h b/src/mutator.h
index 7af7b38..57c7c47 100644
--- a/src/mutator.h
+++ b/src/mutator.h
@@ -52,15 +52,13 @@
   void Seed(uint32_t value);
 
   // message: message to mutate.
-  // size_increase_hint: approximate number of bytes which can be added to the
-  // message. Method does not guarantee that real result size increase will be
-  // less than the value. It only changes probabilities of mutations which can
-  // cause size increase. Caller could repeat mutation if result was larger than
-  // requested.
-  void Mutate(protobuf::Message* message, size_t size_increase_hint);
+  // max_size_hint: approximate max ByteSize() of resulting message. Method does
+  // not guarantee that real result will be strictly smaller than value. Caller
+  // could repeat mutation if result was larger than expected.
+  void Mutate(protobuf::Message* message, size_t max_size_hint);
 
-  void CrossOver(const protobuf::Message& message1,
-                 protobuf::Message* message2);
+  void CrossOver(const protobuf::Message& message1, protobuf::Message* message2,
+                 size_t max_size_hint);
 
   // Callback to postprocess mutations.
   // Implementation should use seed to initialize random number generators.
@@ -84,25 +82,25 @@
   virtual bool MutateBool(bool value);
   virtual size_t MutateEnum(size_t index, size_t item_count);
   virtual std::string MutateString(const std::string& value,
-                                   size_t size_increase_hint);
-
-  std::unordered_map<const protobuf::Descriptor*, PostProcess> post_processors_;
+                                   int size_increase_hint);
 
   RandomEngine* random() { return &random_; }
 
  private:
   friend class FieldMutator;
   friend class TestMutator;
-  void InitializeAndTrim(protobuf::Message* message, int max_depth);
-  void MutateImpl(protobuf::Message* message, size_t size_increase_hint);
-  void CrossOverImpl(const protobuf::Message& message1,
-                     protobuf::Message* message2);
+  bool MutateImpl(const std::vector<const protobuf::Message*>& sources,
+                  const std::vector<protobuf::Message*>& messages,
+                  bool copy_clone_only, int size_increase_hint);
   std::string MutateUtf8String(const std::string& value,
-                               size_t size_increase_hint);
-  void ApplyPostProcessing(protobuf::Message* message);
+                               int size_increase_hint);
+  bool IsInitialized(const protobuf::Message& message) const;
   bool keep_initialized_ = true;
   size_t random_to_default_ratio_ = 100;
   RandomEngine random_;
+  using PostProcessors =
+      std::unordered_multimap<const protobuf::Descriptor*, PostProcess>;
+  PostProcessors post_processors_;
 };
 
 }  // namespace protobuf_mutator
diff --git a/src/mutator_test.cc b/src/mutator_test.cc
index a86760a..fe93181 100644
--- a/src/mutator_test.cc
+++ b/src/mutator_test.cc
@@ -46,6 +46,17 @@
     repeated_msg { required_int32: 67 }
     repeated_msg {}
   }
+  any {
+    [type.googleapis.com/protobuf_mutator.Msg] {
+      optional_msg {}
+      repeated_msg {}
+      any {
+        [type.googleapis.com/protobuf_mutator.Msg3.SubMsg] {
+          optional_int64: -5
+        }
+      }
+    }
+  }
 )";
 
 const char kMessagesProto3[] = R"(
@@ -59,6 +70,17 @@
     repeated_msg { optional_int32: 67 }
     repeated_msg {}
   }
+  any {
+    [type.googleapis.com/protobuf_mutator.Msg] {
+      optional_msg {}
+      repeated_msg {}
+      any {
+        [type.googleapis.com/protobuf_mutator.Msg3.SubMsg] {
+          optional_int64: -5
+        }
+      }
+    }
+  }
 )";
 
 const char kRequiredFields[] = R"(
@@ -154,6 +176,18 @@
   }
 )";
 
+const char kRequiredInAnyFields[] = R"(
+  any {
+    [type.googleapis.com/protobuf_mutator.Msg] {
+      required_uint32: 14486213
+      required_uint64: 520229415
+      required_sint64: -6057486163525532641
+      required_string: "qwert"
+      required_bytes: "asdf"
+    }
+  }
+)";
+
 const char kOptionalNestedFields[] = R"(
   optional_int32: 123
   optional_msg {
@@ -176,6 +210,18 @@
   }
 )";
 
+const char kOptionalInAnyFields[] = R"(
+  any {
+    [type.googleapis.com/protobuf_mutator.Msg] {
+      optional_uint32: 440
+      optional_uint64: 1559
+      optional_sint32: 440615
+      optional_string: "XYZ"
+      optional_enum: ENUM_4
+    }
+  }
+)";
+
 const char kRepeatedNestedFields[] = R"(
   optional_int32: 123
   optional_msg {
@@ -214,6 +260,39 @@
   }
 )";
 
+const char kRepeatedInAnyFields[] = R"(
+  any {
+    [type.googleapis.com/protobuf_mutator.Msg] {
+      repeated_double: 1.931778501556e-31
+      repeated_double: 1.26685288449177e-31
+      repeated_float: 4.739759e-41
+      repeated_float: 5.98038e-39
+      repeated_int32: 400201
+      repeated_int32: 673
+      repeated_int64: 104
+      repeated_int64: 52850685
+    }
+  }
+)";
+
+const char kOptionalInDeepAnyFields[] = R"(
+  any {
+    [type.googleapis.com/protobuf_mutator.Msg] {
+      any {
+        [type.googleapis.com/protobuf_mutator.Msg] {
+          any {
+            [type.googleapis.com/protobuf_mutator.Msg] {
+              optional_double: 1.9317850152856e-314
+              optional_sint64: 1743625000076
+              optional_string: "XYZ"
+            }
+          }
+        }
+      }
+    }
+  }
+)";
+
 class TestMutator : public Mutator {
  public:
   explicit TestMutator(bool keep_initialized,
@@ -224,12 +303,6 @@
     keep_initialized_ = keep_initialized;
   }
 
-  // Avoids dedup logic for some tests.
-  void NoDeDupCrossOver(const protobuf::Message& message1,
-                        protobuf::Message* message2) {
-    CrossOverImpl(message1, message2);
-  }
-
  private:
   RandomEngine random_;
 };
@@ -258,7 +331,7 @@
   float MutateFloat(float value) override { return GetRandomValue(); }
   double MutateDouble(double value) override { return GetRandomValue(); }
   std::string MutateString(const std::string& value,
-                           size_t size_increase_hint) override {
+                           int size_increase_hint) override {
     return strings_[std::uniform_int_distribution<>(
         0, strings_.size() - 1)(*random())];
   }
@@ -282,7 +355,8 @@
   return result;
 }
 
-using TestParams = std::tuple<const protobuf::Message*, const char*, size_t>;
+using TestParams =
+    std::tuple<const protobuf::Message*, const char*, size_t, std::string>;
 
 template <class T>
 std::vector<TestParams> GetFieldTestParams(
@@ -292,7 +366,8 @@
     auto lines = Split(t);
     for (size_t i = 0; i != lines.size(); ++i) {
       if (lines[i].find(':') != std::string::npos)
-        results.push_back(std::make_tuple(&T::default_instance(), t, i));
+        results.push_back(
+            std::make_tuple(&T::default_instance(), t, i, lines[i]));
     }
   }
   return results;
@@ -306,26 +381,42 @@
     auto lines = Split(t);
     for (size_t i = 0; i != lines.size(); ++i) {
       if (lines[i].find("{}") != std::string::npos)
-        results.push_back(std::make_tuple(&T::default_instance(), t, i));
+        results.push_back(
+            std::make_tuple(&T::default_instance(), t, i, lines[i]));
     }
   }
   return results;
 }
 
-bool Mutate(const protobuf::Message& from, const protobuf::Message& to) {
+bool Mutate(const protobuf::Message& from, const protobuf::Message& to,
+            int iterations = 100000) {
   EXPECT_FALSE(MessageDifferencer::Equals(from, to));
   ReducedTestMutator mutator;
   std::unique_ptr<protobuf::Message> message(from.New());
   EXPECT_FALSE(MessageDifferencer::Equals(from, to));
-  for (int j = 0; j < 1000000; ++j) {
+  for (int j = 0; j < iterations; ++j) {
     message->CopyFrom(from);
-    mutator.Mutate(message.get(), 1000);
+    mutator.Mutate(message.get(), 1500);
     if (MessageDifferencer::Equals(*message, to)) return true;
   }
 
   ADD_FAILURE() << "Failed to get from:\n"
-                << SaveMessageAsText(from) << "\nto:\n"
-                << SaveMessageAsText(to);
+                << from.DebugString() << "\nto:\n"
+                << to.DebugString();
+  return false;
+}
+
+bool CrossOver(const protobuf::Message& from, const protobuf::Message& with,
+               const protobuf::Message& to, int iterations = 100000) {
+  EXPECT_FALSE(MessageDifferencer::Equals(from, to));
+  ReducedTestMutator mutator;
+  std::unique_ptr<protobuf::Message> message(from.New());
+  EXPECT_FALSE(MessageDifferencer::Equals(from, to));
+  for (int j = 0; j < iterations; ++j) {
+    message->CopyFrom(from);
+    mutator.CrossOver(with, message.get(), 1000);
+    if (MessageDifferencer::Equals(*message, to)) return true;
+  }
   return false;
 }
 
@@ -389,8 +480,10 @@
 INSTANTIATE_TEST_SUITE_P(Proto2, MutatorFieldInsDelTest,
                          ValuesIn(GetFieldTestParams<Msg>(
                              {kRequiredFields, kOptionalFields, kRepeatedFields,
-                              kRequiredNestedFields, kOptionalNestedFields,
-                              kRepeatedNestedFields})));
+                              kRequiredNestedFields, kRequiredInAnyFields,
+                              kOptionalNestedFields, kOptionalInAnyFields,
+                              kRepeatedNestedFields, kRepeatedInAnyFields,
+                              kOptionalInDeepAnyFields})));
 
 TEST_P(MutatorFieldInsDelTest, DeleteField) {
   LoadMessage(m1_.get());
@@ -398,106 +491,85 @@
   EXPECT_TRUE(Mutate(*m1_, *m2_));
 }
 
-TEST_P(MutatorFieldInsDelTest, InsertField) {
-  LoadWithoutLine(m1_.get());
-  LoadWithChangedLine(m2_.get(), 0);
-  EXPECT_TRUE(Mutate(*m1_, *m2_));
-}
-
-class MutatorFieldTest : public MutatorTest {
- public:
-  template <class Msg>
-  void TestCopyField();
-};
-INSTANTIATE_TEST_SUITE_P(Proto2, MutatorFieldTest,
+INSTANTIATE_TEST_SUITE_P(Proto2, MutatorTest,
                          ValuesIn(GetFieldTestParams<Msg>(
                              {kRequiredFields, kOptionalFields, kRepeatedFields,
-                              kRequiredNestedFields, kOptionalNestedFields,
-                              kRepeatedNestedFields})));
-INSTANTIATE_TEST_SUITE_P(Proto3, MutatorFieldTest,
+                              kRequiredNestedFields, kRequiredInAnyFields,
+                              kOptionalNestedFields, kOptionalInAnyFields,
+                              kRepeatedNestedFields, kRepeatedInAnyFields,
+                              kOptionalInDeepAnyFields})));
+INSTANTIATE_TEST_SUITE_P(Proto3, MutatorTest,
                          ValuesIn(GetFieldTestParams<Msg3>(
                              {kOptionalFields, kRepeatedFields,
-                              kOptionalNestedFields, kRepeatedNestedFields})));
+                              kOptionalNestedFields, kOptionalInAnyFields,
+                              kRepeatedNestedFields, kRepeatedInAnyFields,
+                              kOptionalInDeepAnyFields})));
 
-TEST_P(MutatorFieldTest, Initialized) {
+TEST_P(MutatorTest, Initialized) {
   LoadWithoutLine(m1_.get());
   TestMutator mutator(true);
   mutator.Mutate(m1_.get(), 1000);
   EXPECT_TRUE(m1_->IsInitialized());
 }
 
-TEST_P(MutatorFieldTest, ChangeField) {
-  LoadWithChangedLine(m1_.get(), 0);
+TEST_P(MutatorTest, InsertField) {
+  LoadWithoutLine(m1_.get());
   LoadWithChangedLine(m2_.get(), 1);
   EXPECT_TRUE(Mutate(*m1_, *m2_));
-  EXPECT_TRUE(Mutate(*m2_, *m1_));
 }
 
-template <class Msg>
-void MutatorFieldTest::TestCopyField() {
-  LoadWithChangedLine(m1_.get(), 7);
-  LoadWithChangedLine(m2_.get(), 0);
-
-  Msg from;
-  from.add_repeated_msg()->CopyFrom(*m1_);
-  from.add_repeated_msg()->CopyFrom(*m2_);
-
-  Msg to;
-  to.add_repeated_msg()->CopyFrom(*m1_);
-  to.add_repeated_msg()->CopyFrom(*m1_);
-  EXPECT_TRUE(Mutate(from, to));
-
-  to.Clear();
-  to.add_repeated_msg()->CopyFrom(*m2_);
-  to.add_repeated_msg()->CopyFrom(*m2_);
-  EXPECT_TRUE(Mutate(from, to));
+TEST_P(MutatorTest, ChangeField) {
+  LoadWithChangedLine(m1_.get(), 0);
+  LoadWithChangedLine(m2_.get(), 1);
+  EXPECT_TRUE(Mutate(*m1_, *m2_, 1000000));
+  EXPECT_TRUE(Mutate(*m2_, *m1_, 1000000));
 }
 
-TEST_P(MutatorFieldTest, CopyField) {
-  if (m1_->GetDescriptor() == Msg::descriptor())
-    TestCopyField<Msg>();
-  else
-    TestCopyField<Msg3>();
-}
-
-class MutatorSingleFieldTest : public MutatorTest {};
-INSTANTIATE_TEST_SUITE_P(Proto2, MutatorSingleFieldTest,
-                         ValuesIn(GetFieldTestParams<Msg>({
-                             kRequiredFields,
-                             kOptionalFields,
-                             kRequiredNestedFields,
-                             kOptionalNestedFields,
-                         })));
-INSTANTIATE_TEST_SUITE_P(Proto3, MutatorSingleFieldTest,
-                         ValuesIn(GetFieldTestParams<Msg3>({
-                             kOptionalFields,
-                             kOptionalNestedFields,
-                         })));
-
-TEST_P(MutatorSingleFieldTest, CrossOver) {
+TEST_P(MutatorTest, CrossOver) {
   LoadWithoutLine(m1_.get());
   LoadMessage(m2_.get());
 
   EXPECT_FALSE(MessageDifferencer::Equals(*m1_, *m2_));
   TestMutator mutator(false);
 
-  int match_m1_ = 0;
-  int match_m2_ = 0;
-  int iterations = 1000;
-  std::unique_ptr<protobuf::Message> message(m1_->New());
-  for (int j = 0; j < iterations; ++j) {
-    message->CopyFrom(*m1_);
-    mutator.NoDeDupCrossOver(*m2_, message.get());
-    if (MessageDifferencer::Equals(*message, *m2_)) ++match_m2_;
-    if (MessageDifferencer::Equals(*message, *m1_)) ++match_m1_;
-  }
-
-  EXPECT_LT(iterations * .4, match_m1_);
-  EXPECT_GE(iterations * .6, match_m1_);
-  EXPECT_LT(iterations * .4, match_m2_);
-  EXPECT_GE(iterations * .6, match_m2_);
+  EXPECT_TRUE(CrossOver(*m1_, *m2_, *m2_));
 }
 
+template <class Msg>
+void RunCrossOver(const protobuf::Message& m1, const protobuf::Message& m2) {
+  Msg from;
+  from.add_repeated_msg()->CopyFrom(m1);
+  from.add_repeated_msg()->CopyFrom(m2);
+  from.mutable_repeated_msg(1)->add_repeated_string("repeated_string");
+
+  Msg to;
+  to.add_repeated_msg()->CopyFrom(m1);
+  to.add_repeated_msg()->CopyFrom(m1);
+  to.mutable_repeated_msg(1)->add_repeated_string("repeated_string");
+  EXPECT_TRUE(CrossOver(from, from, to));
+}
+
+TEST_P(MutatorTest, CopyField) {
+  LoadWithChangedLine(m1_.get(), 7);
+  LoadWithChangedLine(m2_.get(), 0);
+
+  if (m1_->GetDescriptor() == Msg::descriptor())
+    RunCrossOver<Msg>(*m1_, *m2_);
+  else
+    RunCrossOver<Msg3>(*m1_, *m2_);
+}
+
+TEST_P(MutatorTest, CloneField) {
+  LoadWithChangedLine(m1_.get(), 7);
+  LoadWithoutLine(m2_.get());
+
+  if (m1_->GetDescriptor() == Msg::descriptor())
+    RunCrossOver<Msg>(*m1_, *m2_);
+  else
+    RunCrossOver<Msg3>(*m1_, *m2_);
+}
+
+class MutatorSingleFieldTest : public MutatorTest {};
 template <typename T>
 class MutatorTypedTest : public ::testing::Test {
  public:
@@ -507,58 +579,6 @@
 using MutatorTypedTestTypes = testing::Types<Msg, Msg3>;
 TYPED_TEST_SUITE(MutatorTypedTest, MutatorTypedTestTypes);
 
-TYPED_TEST(MutatorTypedTest, CrossOverRepeated) {
-  typename TestFixture::Message m1;
-  m1.add_repeated_int32(1);
-  m1.add_repeated_int32(2);
-  m1.add_repeated_int32(3);
-
-  typename TestFixture::Message m2;
-  m2.add_repeated_int32(4);
-  m2.add_repeated_int32(5);
-  m2.add_repeated_int32(6);
-
-  int iterations = 10000;
-  std::set<std::set<int>> sets;
-  TestMutator mutator(false);
-  for (int j = 0; j < iterations; ++j) {
-    typename TestFixture::Message message;
-    message.CopyFrom(m1);
-    mutator.NoDeDupCrossOver(m2, &message);
-    sets.insert(
-        {message.repeated_int32().begin(), message.repeated_int32().end()});
-  }
-
-  EXPECT_EQ(1u << 6, sets.size());
-}
-
-TYPED_TEST(MutatorTypedTest, CrossOverRepeatedMessages) {
-  typename TestFixture::Message m1;
-  auto* rm1 = m1.add_repeated_msg();
-  rm1->add_repeated_int32(1);
-  rm1->add_repeated_int32(2);
-
-  typename TestFixture::Message m2;
-  auto* rm2 = m2.add_repeated_msg();
-  rm2->add_repeated_int32(3);
-  rm2->add_repeated_int32(4);
-  rm2->add_repeated_int32(5);
-  rm2->add_repeated_int32(6);
-
-  int iterations = 10000;
-  std::set<std::set<int>> sets;
-  TestMutator mutator(false);
-  for (int j = 0; j < iterations; ++j) {
-    typename TestFixture::Message message;
-    message.CopyFrom(m1);
-    mutator.NoDeDupCrossOver(m2, &message);
-    for (const auto& msg : message.repeated_msg())
-      sets.insert({msg.repeated_int32().begin(), msg.repeated_int32().end()});
-  }
-
-  EXPECT_EQ(1u << 6, sets.size());
-}
-
 TYPED_TEST(MutatorTypedTest, FailedMutations) {
   TestMutator mutator(false);
   size_t crossovers = 0;
@@ -575,47 +595,59 @@
     }
 
     tmp.CopyFrom(messages[1]);
-    mutator.CrossOver(messages[0], &tmp);
+    mutator.CrossOver(messages[0], &tmp, 1000);
     if (MessageDifferencer::Equals(tmp, messages[1]) ||
         MessageDifferencer::Equals(tmp, messages[0]))
       ++crossovers;
   }
 
   // CrossOver may fail but very rare.
-  EXPECT_LT(crossovers, 10u);
+  EXPECT_LT(crossovers, 100u);
 }
 
 TYPED_TEST(MutatorTypedTest, RegisterPostProcessor) {
-  constexpr char kInitialString[] = " ";
-  constexpr char kIndicatorString[] = "0123456789abcdef";
-  bool custom_mutation = false;
-  bool regular_mutation = false;
-
+  std::set<std::string> top_mutations = {"0123456789abcdef",
+                                         "abcdef0123456789"};
   TestMutator mutator(false);
-  mutator.RegisterPostProcessor(
-      TestFixture::Message::descriptor(),
-      [kIndicatorString](protobuf::Message* message, unsigned int seed) {
-        typename TestFixture::Message* test_message =
-            static_cast<typename TestFixture::Message*>(message);
-        if (seed % 2) test_message->set_optional_string(kIndicatorString);
-      });
+  for (auto& v : top_mutations) {
+    mutator.RegisterPostProcessor(
+        TestFixture::Message::descriptor(),
+        [=](protobuf::Message* message, unsigned int seed) {
+          auto test_message =
+              static_cast<typename TestFixture::Message*>(message);
+          if (seed % 2) test_message->set_optional_string(v);
+        });
+  }
+
+  std::set<int64_t> nested_mutations = {1234567, 567890};
+  for (auto& v : nested_mutations) {
+    mutator.RegisterPostProcessor(
+        TestFixture::Message::SubMsg::descriptor(),
+        [=](protobuf::Message* message, unsigned int seed) {
+          auto test_message =
+              static_cast<typename TestFixture::Message::SubMsg*>(message);
+          if (seed % 2) test_message->set_optional_int64(v);
+        });
+  }
+
+  bool regular_mutation = false;
 
   for (int j = 0; j < 100000; ++j) {
     // Include this field to increase the probability of mutation.
     typename TestFixture::Message message;
-    message.set_optional_string(kInitialString);
+    message.set_optional_string("a");
     mutator.Mutate(&message, 1000);
 
-    if (message.optional_string() == kIndicatorString) {
-      custom_mutation = true;
-    } else if (message.optional_string() != kInitialString) {
-      regular_mutation = true;
-    }
+    top_mutations.erase(message.optional_string());
+    nested_mutations.erase(message.mutable_sub_message()->optional_int64());
+    if (message.optional_string().empty()) regular_mutation = true;
 
-    if (custom_mutation && regular_mutation) break;
+    if (top_mutations.empty() && nested_mutations.empty() && regular_mutation)
+      break;
   }
 
-  EXPECT_TRUE(custom_mutation);
+  EXPECT_TRUE(top_mutations.empty());
+  EXPECT_TRUE(nested_mutations.empty());
   EXPECT_TRUE(regular_mutation);
 }
 
@@ -709,6 +741,25 @@
   EXPECT_TRUE(Mutate(*m1_, *m2_));
 }
 
+class MutatorMessagesSizeTest : public TestWithParam<size_t> {};
+
+static const size_t kMaxSizes[] = {100, 256, 777, 10101};
+INSTANTIATE_TEST_SUITE_P(Proto, MutatorMessagesSizeTest, ValuesIn(kMaxSizes));
+
+TEST_P(MutatorMessagesSizeTest, MaxSize) {
+  TestMutator mutator(false);
+  size_t over_sized_count = 0;
+  Msg message;
+  const size_t kMaxSize = GetParam();
+  const int kIterations = 10000;
+  for (int i = 0; i < kIterations; ++i) {
+    mutator.Mutate(&message, kMaxSize);
+    if (message.ByteSizeLong() > kMaxSize) ++over_sized_count;
+    EXPECT_LT(message.ByteSizeLong(), 1.1 * kMaxSize);
+  }
+  EXPECT_LT(over_sized_count, kIterations * .1);
+}
+
 // TODO(vitalybuka): Special tests for oneof.
 
 TEST(MutatorMessagesTest, NeverCopyUnknownEnum) {
diff --git a/src/mutator_test_proto2.proto b/src/mutator_test_proto2.proto
index 0927775..44d4757 100644
--- a/src/mutator_test_proto2.proto
+++ b/src/mutator_test_proto2.proto
@@ -1,6 +1,9 @@
 syntax = "proto2";
+
 package protobuf_mutator;
 
+import "google/protobuf/any.proto";
+
 message Msg {
   enum Enum {
     ENUM_0 = 0;
@@ -93,6 +96,8 @@
     Msg oneof_msg = 68;
   }
 
+  optional SubMsg sub_message = 69;
+
   required group Group = 70 {
     required bool required_bool = 1;
     optional bool optional_bool = 2;
@@ -122,6 +127,7 @@
     map<string, int32> map1 = 1;
     map<int32, Msg> map2 = 2;
   }
-}
 
+  optional google.protobuf.Any any = 90;
+}
 
diff --git a/src/mutator_test_proto3.proto b/src/mutator_test_proto3.proto
index 5fd7507..f40fe2b 100644
--- a/src/mutator_test_proto3.proto
+++ b/src/mutator_test_proto3.proto
@@ -1,6 +1,9 @@
 syntax = "proto3";
+
 package protobuf_mutator;
 
+import "google/protobuf/any.proto";
+
 message Msg3 {
   enum Enum {
     ENUM_0 = 0;
@@ -15,6 +18,10 @@
     ENUM_9 = 9;
   }
 
+  message SubMsg {
+    int64 optional_int64 = 1;
+  }
+
   double optional_double = 18;
   float optional_float = 19;
   int32 optional_int32 = 20;
@@ -71,6 +78,8 @@
     Msg3 oneof_msg = 68;
   }
 
+  SubMsg sub_message = 69;
+
   message EmptyMessage {}
 
   message RegressionMessage {
@@ -94,4 +103,6 @@
     map<string, int32> map1 = 1;
     map<int32, Msg3> map2 = 2;
   }
+
+  google.protobuf.Any any = 90;
 }