diff --git a/tools/gn/BUILD.gn b/tools/gn/BUILD.gn
index b77d2af..510c178 100644
--- a/tools/gn/BUILD.gn
+++ b/tools/gn/BUILD.gn
@@ -58,8 +58,6 @@
     "create_bundle_target_generator.h",
     "deps_iterator.cc",
     "deps_iterator.h",
-    "desc_builder.cc",
-    "desc_builder.h",
     "eclipse_writer.cc",
     "eclipse_writer.h",
     "err.cc",
@@ -103,8 +101,6 @@
     "input_file_manager.h",
     "item.cc",
     "item.h",
-    "json_project_writer.cc",
-    "json_project_writer.h",
     "label.cc",
     "label.h",
     "label_pattern.cc",
diff --git a/tools/gn/command_desc.cc b/tools/gn/command_desc.cc
index 72525e9..ea1bab3 100644
--- a/tools/gn/command_desc.cc
+++ b/tools/gn/command_desc.cc
@@ -9,14 +9,18 @@
 #include <sstream>
 
 #include "base/command_line.h"
-#include "base/json/json_writer.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string_util.h"
+#include "build/build_config.h"
 #include "tools/gn/commands.h"
 #include "tools/gn/config.h"
-#include "tools/gn/desc_builder.h"
+#include "tools/gn/config_values_extractors.h"
+#include "tools/gn/deps_iterator.h"
+#include "tools/gn/filesystem_utils.h"
+#include "tools/gn/item.h"
+#include "tools/gn/label.h"
+#include "tools/gn/runtime_deps.h"
 #include "tools/gn/setup.h"
 #include "tools/gn/standard_out.h"
+#include "tools/gn/substitution_writer.h"
 #include "tools/gn/switches.h"
 #include "tools/gn/target.h"
 #include "tools/gn/variables.h"
@@ -28,258 +32,725 @@
 // Desc-specific command line switches.
 const char kBlame[] = "blame";
 const char kTree[] = "tree";
-const char kAll[] = "all";
 
-// Prints value with specified indentation level
-void PrintValue(const base::Value* value, int indentLevel) {
-  std::string indent(indentLevel * 2, ' ');
-  const base::ListValue* list_value = nullptr;
-  const base::DictionaryValue* dict_value = nullptr;
-  std::string string_value;
-  bool bool_value = false;
-  if (value->GetAsList(&list_value)) {
-    for (const auto& v : *list_value) {
-      PrintValue(v.get(), indentLevel);
+// Prints the given directory in a nice way for the user to view.
+std::string FormatSourceDir(const SourceDir& dir) {
+#if defined(OS_WIN)
+  // On Windows we fix up system absolute paths to look like native ones.
+  // Internally, they'll look like "/C:\foo\bar/"
+  if (dir.is_system_absolute()) {
+    std::string buf = dir.value();
+    if (buf.size() > 3 && buf[2] == ':') {
+      buf.erase(buf.begin());  // Erase beginning slash.
+      return buf;
     }
-  } else if (value->GetAsString(&string_value)) {
-    OutputString(indent);
-    OutputString(string_value);
-    OutputString("\n");
-  } else if (value->GetAsBoolean(&bool_value)) {
-    OutputString(indent);
-    OutputString(bool_value ? "true" : "false");
-    OutputString("\n");
-  } else if (value->GetAsDictionary(&dict_value)) {
-    base::DictionaryValue::Iterator iter(*dict_value);
-    while (!iter.IsAtEnd()) {
-      OutputString(indent + iter.key() + "\n");
-      PrintValue(&iter.value(), indentLevel + 1);
-      iter.Advance();
+  }
+#endif
+  return dir.value();
+}
+
+void RecursiveCollectChildDeps(const Target* target,
+                               std::set<const Target*>* result);
+
+void RecursiveCollectDeps(const Target* target,
+                          std::set<const Target*>* result) {
+  if (result->find(target) != result->end())
+    return;  // Already did this target.
+  result->insert(target);
+
+  RecursiveCollectChildDeps(target, result);
+}
+
+void RecursiveCollectChildDeps(const Target* target,
+                               std::set<const Target*>* result) {
+  for (const auto& pair : target->GetDeps(Target::DEPS_ALL))
+    RecursiveCollectDeps(pair.ptr, result);
+}
+
+// Prints dependencies of the given target (not the target itself). If the
+// set is non-null, new targets encountered will be added to the set, and if
+// a dependency is in the set already, it will not be recused into. When the
+// set is null, all dependencies will be printed.
+void RecursivePrintDeps(const Target* target,
+                        const Label& default_toolchain,
+                        std::set<const Target*>* seen_targets,
+                        int indent_level) {
+  // Combine all deps into one sorted list.
+  std::vector<LabelTargetPair> sorted_deps;
+  for (const auto& pair : target->GetDeps(Target::DEPS_ALL))
+    sorted_deps.push_back(pair);
+  std::sort(sorted_deps.begin(), sorted_deps.end(),
+            LabelPtrLabelLess<Target>());
+
+  std::string indent(indent_level * 2, ' ');
+  for (const auto& pair : sorted_deps) {
+    const Target* cur_dep = pair.ptr;
+
+    OutputString(indent +
+        cur_dep->label().GetUserVisibleName(default_toolchain));
+    bool print_children = true;
+    if (seen_targets) {
+      if (seen_targets->find(cur_dep) == seen_targets->end()) {
+        // New target, mark it visited.
+        seen_targets->insert(cur_dep);
+      } else {
+        // Already seen.
+        print_children = false;
+        // Only print "..." if something is actually elided, which means that
+        // the current target has children.
+        if (!cur_dep->public_deps().empty() ||
+            !cur_dep->private_deps().empty() ||
+            !cur_dep->data_deps().empty())
+          OutputString("...");
+      }
     }
-  } else if (value->IsType(base::Value::TYPE_NULL)) {
-    OutputString(indent + "<null>\n");
+
+    OutputString("\n");
+    if (print_children) {
+      RecursivePrintDeps(cur_dep, default_toolchain, seen_targets,
+                         indent_level + 1);
+    }
   }
 }
 
-// Default handler for property
-void DefaultHandler(const std::string& name, const base::Value* value) {
-  OutputString("\n");
-  OutputString(name);
-  OutputString("\n");
-  PrintValue(value, 1);
-}
+void PrintDeps(const Target* target, bool display_header) {
+  const base::CommandLine* cmdline = base::CommandLine::ForCurrentProcess();
+  Label toolchain_label = target->label().GetToolchainLabel();
 
-// Specific handler for properties that need different treatment
+  // Tree mode is separate.
+  if (cmdline->HasSwitch(kTree)) {
+    if (display_header)
+      OutputString("\nDependency tree\n");
 
-// Prints label and property value on one line, capitalizing the label.
-void LabelHandler(std::string name, const base::Value* value) {
-  name[0] = base::ToUpperASCII(name[0]);
-  std::string string_value;
-  if (value->GetAsString(&string_value)) {
-    OutputString(name + ": ", DECORATION_YELLOW);
-    OutputString(string_value + "\n");
-  }
-}
-
-void VisibilityHandler(const std::string& name, const base::Value* value) {
-  const base::ListValue* list;
-  if (value->GetAsList(&list)) {
-    if (list->empty()) {
-      base::StringValue str("(no visibility)");
-      DefaultHandler(name, &str);
+    if (cmdline->HasSwitch("all")) {
+      // Show all tree deps with no eliding.
+      RecursivePrintDeps(target, toolchain_label, nullptr, 1);
     } else {
-      DefaultHandler(name, value);
+      // Don't recurse into duplicates.
+      std::set<const Target*> seen_targets;
+      RecursivePrintDeps(target, toolchain_label, &seen_targets, 1);
     }
+    return;
   }
-}
 
-void PublicHandler(const std::string& name, const base::Value* value) {
-  std::string p;
-  if (value->GetAsString(&p)) {
-    if (p == "*") {
-      base::StringValue str("[All headers listed in the sources are public.]");
-      DefaultHandler(name, &str);
-      return;
-    }
-  }
-  DefaultHandler(name, value);
-}
+  // Collect the deps to display.
+  if (cmdline->HasSwitch("all")) {
+    // Show all dependencies.
+    if (display_header)
+      OutputString("\nAll recursive dependencies\n");
 
-void ConfigsHandler(const std::string& name, const base::Value* value) {
-  bool tree = base::CommandLine::ForCurrentProcess()->HasSwitch(kTree);
-  if (tree)
-    DefaultHandler(name + " tree (in order applying)", value);
-  else
-    DefaultHandler(name + " (in order applying, try also --tree)", value);
-}
-
-void DepsHandler(const std::string& name, const base::Value* value) {
-  bool tree = base::CommandLine::ForCurrentProcess()->HasSwitch(kTree);
-  bool all = base::CommandLine::ForCurrentProcess()->HasSwitch(kTree);
-  if (tree) {
-    DefaultHandler("Dependency tree", value);
+    std::set<const Target*> all_deps;
+    RecursiveCollectChildDeps(target, &all_deps);
+    FilterAndPrintTargetSet(display_header, all_deps);
   } else {
-    if (!all) {
-      DefaultHandler(
-          "Direct dependencies "
-          "(try also \"--all\", \"--tree\", or even \"--all --tree\")",
-          value);
-    } else {
-      DefaultHandler("All recursive dependencies", value);
+    std::vector<const Target*> deps;
+    // Show direct dependencies only.
+    if (display_header) {
+      OutputString(
+          "\nDirect dependencies "
+          "(try also \"--all\", \"--tree\", or even \"--all --tree\")\n");
     }
+    for (const auto& pair : target->GetDeps(Target::DEPS_ALL))
+      deps.push_back(pair.ptr);
+    std::sort(deps.begin(), deps.end());
+    FilterAndPrintTargets(display_header, &deps);
   }
 }
 
-// Outputs need special processing when output patterns are present.
-void ProcessOutputs(base::DictionaryValue* target) {
-  base::ListValue* patterns = nullptr;
-  base::ListValue* outputs = nullptr;
-  target->GetList("output_patterns", &patterns);
-  target->GetList(variables::kOutputs, &outputs);
+// libs and lib_dirs are special in that they're inherited. We don't currently
+// implement a blame feature for this since the bottom-up inheritance makes
+// this difficult.
+void PrintLibDirs(const Target* target, bool display_header) {
+  const OrderedSet<SourceDir>& lib_dirs = target->all_lib_dirs();
+  if (lib_dirs.empty())
+    return;
 
-  if (outputs || patterns) {
+  if (display_header)
+    OutputString("\nlib_dirs\n");
+
+  for (size_t i = 0; i < lib_dirs.size(); i++)
+    OutputString("    " + FormatSourceDir(lib_dirs[i]) + "\n");
+}
+
+void PrintLibs(const Target* target, bool display_header) {
+  const OrderedSet<LibFile>& libs = target->all_libs();
+  if (libs.empty())
+    return;
+
+  if (display_header)
+    OutputString("\nlibs\n");
+
+  for (size_t i = 0; i < libs.size(); i++)
+    OutputString("    " + libs[i].value() + "\n");
+}
+
+void PrintPublic(const Target* target, bool display_header) {
+  if (display_header)
+    OutputString("\npublic\n");
+
+  if (target->all_headers_public()) {
+    OutputString("  [All headers listed in the sources are public.]\n");
+    return;
+  }
+
+  Target::FileList public_headers = target->public_headers();
+  std::sort(public_headers.begin(), public_headers.end());
+  for (const auto& hdr : public_headers)
+    OutputString("  " + hdr.value() + "\n");
+}
+
+void PrintCheckIncludes(const Target* target, bool display_header) {
+  if (display_header)
+    OutputString("\ncheck_includes\n");
+
+  if (target->check_includes())
+    OutputString("  true\n");
+  else
+    OutputString("  false\n");
+}
+
+void PrintAllowCircularIncludesFrom(const Target* target, bool display_header) {
+  if (display_header)
+    OutputString("\nallow_circular_includes_from\n");
+
+  Label toolchain_label = target->label().GetToolchainLabel();
+  for (const auto& cur : target->allow_circular_includes_from())
+    OutputString("  " + cur.GetUserVisibleName(toolchain_label) + "\n");
+}
+
+void PrintVisibility(const Target* target, bool display_header) {
+  if (display_header)
+    OutputString("\nvisibility\n");
+
+  OutputString(target->visibility().Describe(2, false));
+}
+
+void PrintTestonly(const Target* target, bool display_header) {
+  if (display_header)
+    OutputString("\ntestonly\n");
+
+  if (target->testonly())
+    OutputString("  true\n");
+  else
+    OutputString("  false\n");
+}
+
+// Recursively prints subconfigs of a config.
+void PrintSubConfigs(const Config* config, int indent_level) {
+  if (config->configs().empty())
+    return;
+
+  std::string indent(indent_level * 2, ' ');
+  Label toolchain_label = config->label().GetToolchainLabel();
+  for (const auto& pair : config->configs()) {
+    OutputString(
+        indent + pair.label.GetUserVisibleName(toolchain_label) + "\n");
+    PrintSubConfigs(pair.ptr, indent_level + 1);
+  }
+}
+
+// This allows configs stored as either std::vector<LabelConfigPair> or
+// UniqueVector<LabelConfigPair> to be printed.
+template <class VectorType>
+void PrintConfigsVector(const Item* item,
+                        const VectorType& configs,
+                        const std::string& heading,
+                        bool display_header) {
+  if (configs.empty())
+    return;
+
+  bool tree = base::CommandLine::ForCurrentProcess()->HasSwitch(kTree);
+
+  // Don't sort since the order determines how things are processed.
+  if (display_header) {
+    if (tree)
+      OutputString("\n" + heading + " tree (in order applying)\n");
+    else
+      OutputString("\n" + heading + " (in order applying, try also --tree)\n");
+  }
+
+  Label toolchain_label = item->label().GetToolchainLabel();
+  for (const auto& config : configs) {
+    OutputString("  " + config.label.GetUserVisibleName(toolchain_label) +
+                 "\n");
+    if (tree)
+      PrintSubConfigs(config.ptr, 2);  // 2 = start with double-indent.
+  }
+}
+
+void PrintConfigs(const Target* target, bool display_header) {
+  PrintConfigsVector(target, target->configs().vector(), "configs",
+                     display_header);
+}
+
+void PrintConfigs(const Config* config, bool display_header) {
+  PrintConfigsVector(config, config->configs().vector(), "configs",
+                     display_header);
+}
+
+void PrintPublicConfigs(const Target* target, bool display_header) {
+  PrintConfigsVector(target, target->public_configs(),
+                     "public_configs", display_header);
+}
+
+void PrintAllDependentConfigs(const Target* target, bool display_header) {
+  PrintConfigsVector(target, target->all_dependent_configs(),
+                     "all_dependent_configs", display_header);
+}
+
+void PrintFileList(const Target::FileList& files,
+                   const std::string& header,
+                   bool indent_extra,
+                   bool display_header) {
+  if (files.empty())
+    return;
+
+  if (display_header)
+    OutputString("\n" + header + "\n");
+
+  std::string indent = indent_extra ? "    " : "  ";
+
+  Target::FileList sorted = files;
+  std::sort(sorted.begin(), sorted.end());
+  for (const auto& elem : sorted)
+    OutputString(indent + elem.value() + "\n");
+}
+
+void PrintSources(const Target* target, bool display_header) {
+  PrintFileList(target->sources(), "sources", false, display_header);
+}
+
+void PrintInputs(const Target* target, bool display_header) {
+  PrintFileList(target->inputs(), "inputs", false, display_header);
+}
+
+void PrintOutputs(const Target* target, bool display_header) {
+  if (display_header)
     OutputString("\noutputs\n");
-    int indent = 1;
-    if (patterns) {
-      OutputString("  Output patterns\n");
-      indent = 2;
-      PrintValue(patterns, indent);
+
+  if (target->output_type() == Target::ACTION) {
+    // Action, print out outputs, don't apply sources to it.
+    for (const auto& elem : target->action_values().outputs().list()) {
+      OutputString("  " + elem.AsString() + "\n");
+    }
+  } else if (target->output_type() == Target::CREATE_BUNDLE) {
+    std::vector<SourceFile> output_files;
+    target->bundle_data().GetOutputsAsSourceFiles(target->settings(),
+                                                  &output_files);
+    PrintFileList(output_files, std::string(), true, false);
+  } else if (target->output_type() == Target::ACTION_FOREACH) {
+    const SubstitutionList& outputs = target->action_values().outputs();
+    if (!outputs.required_types().empty()) {
+      // Display the pattern and resolved pattern separately, since there are
+      // subtitutions used.
+      OutputString("  Output pattern\n");
+      for (const auto& elem : outputs.list())
+        OutputString("    " + elem.AsString() + "\n");
+
+      // Now display what that resolves to given the sources.
       OutputString("\n  Resolved output file list\n");
     }
-    if (outputs)
-      PrintValue(outputs, indent);
 
-    target->Remove("output_patterns", nullptr);
-    target->Remove(variables::kOutputs, nullptr);
+    // Resolved output list.
+    std::vector<SourceFile> output_files;
+    SubstitutionWriter::ApplyListToSources(target->settings(), outputs,
+                                           target->sources(), &output_files);
+    PrintFileList(output_files, std::string(), true, false);
+  } else {
+    DCHECK(target->IsBinary());
+    const Tool* tool = target->toolchain()->GetToolForTargetFinalOutput(target);
+
+    std::vector<OutputFile> output_files;
+    SubstitutionWriter::ApplyListToLinkerAsOutputFile(
+        target, tool, tool->outputs(), &output_files);
+
+    std::vector<SourceFile> output_files_as_source_file;
+    for (const OutputFile& output_file : output_files) {
+      output_files_as_source_file.push_back(
+          output_file.AsSourceFile(target->settings()->build_settings()));
+    }
+
+    PrintFileList(output_files_as_source_file, std::string(), true, false);
   }
 }
 
+void PrintScript(const Target* target, bool display_header) {
+  if (display_header)
+    OutputString("\nscript\n");
+  OutputString("  " + target->action_values().script().value() + "\n");
+}
+
+void PrintArgs(const Target* target, bool display_header) {
+  if (display_header)
+    OutputString("\nargs\n");
+  for (const auto& elem : target->action_values().args().list()) {
+    OutputString("  " + elem.AsString() + "\n");
+  }
+}
+
+void PrintDepfile(const Target* target, bool display_header) {
+  if (target->action_values().depfile().empty())
+    return;
+  if (display_header)
+    OutputString("\ndepfile\n");
+  OutputString("  " + target->action_values().depfile().AsString() + "\n");
+}
+
+// Attribute the origin for attributing from where a target came from. Does
+// nothing if the input is null or it does not have a location.
+void OutputSourceOfDep(const ParseNode* origin, std::ostream& out) {
+  if (!origin)
+    return;
+  Location location = origin->GetRange().begin();
+  out << "       (Added by " + location.file()->name().value() << ":"
+      << location.line_number() << ")\n";
+}
+
+// Templatized writer for writing out different config value types.
+template<typename T> struct DescValueWriter {};
+template<> struct DescValueWriter<std::string> {
+  void operator()(const std::string& str, std::ostream& out) const {
+    out << "    " << str << "\n";
+  }
+};
+
+template<> struct DescValueWriter<SourceDir> {
+  void operator()(const SourceDir& dir, std::ostream& out) const {
+    out << "    " << FormatSourceDir(dir) << "\n";
+  }
+};
+
+template<> struct DescValueWriter<LibFile> {
+  void operator()(const LibFile& lib, std::ostream& out) const {
+    if (lib.is_source_file())
+      out << "    " << lib.source_file().value() << "\n";
+    else
+      out << "    " << lib.value() << "\n";
+  }
+};
+
+// Writes a given config value type to the string, optionally with attribution.
+// This should match RecursiveTargetConfigToStream in the order it traverses.
+template<typename T> void OutputRecursiveTargetConfig(
+    const Target* target,
+    const char* header_name,
+    const std::vector<T>& (ConfigValues::* getter)() const) {
+  bool display_blame =
+      base::CommandLine::ForCurrentProcess()->HasSwitch(kBlame);
+
+  DescValueWriter<T> writer;
+  std::ostringstream out;
+
+  for (ConfigValuesIterator iter(target); !iter.done(); iter.Next()) {
+    if ((iter.cur().*getter)().empty())
+      continue;
+
+    // Optional blame sub-head.
+    if (display_blame) {
+      const Config* config = iter.GetCurrentConfig();
+      if (config) {
+        // Source of this value is a config.
+        out << "  From " << config->label().GetUserVisibleName(false) << "\n";
+        OutputSourceOfDep(iter.origin(), out);
+      } else {
+        // Source of this value is the target itself.
+        out << "  From " << target->label().GetUserVisibleName(false) << "\n";
+      }
+    }
+
+    // Actual values.
+    ConfigValuesToStream(iter.cur(), getter, writer, out);
+  }
+
+  std::string out_str = out.str();
+  if (!out_str.empty()) {
+    if (header_name)
+      OutputString("\n" + std::string(header_name) + "\n");
+    OutputString(out_str);
+  }
+}
+
+template<typename T> void OutputConfigValueArray(
+    const ConfigValues& values,
+    const char* header_name,
+    const std::vector<T>& (ConfigValues::* getter)() const) {
+  std::ostringstream out;
+
+  DescValueWriter<T> writer;
+  for (const T& cur : (values.*getter)())
+    writer(cur, out);
+
+  std::string out_str = out.str();
+  if (!out_str.empty()) {
+    if (header_name)
+      OutputString("\n" + std::string(header_name) + "\n");
+    OutputString(out_str);
+  }
+}
+
+void PrintRuntimeDeps(const Target* target) {
+  bool display_blame =
+      base::CommandLine::ForCurrentProcess()->HasSwitch(kBlame);
+  Label toolchain = target->label().GetToolchainLabel();
+
+  const Target* previous_from = NULL;
+  for (const auto& pair : ComputeRuntimeDeps(target)) {
+    if (display_blame) {
+      // Generally a target's runtime deps will be listed sequentially, so
+      // group them and don't duplicate the "from" label for two in a row.
+      if (previous_from == pair.second) {
+        OutputString("  ");  // Just indent.
+      } else {
+        previous_from = pair.second;
+        OutputString("From ");
+        OutputString(pair.second->label().GetUserVisibleName(toolchain));
+        OutputString("\n  ");  // Make the file name indented.
+      }
+    }
+    OutputString(pair.first.value());
+    OutputString("\n");
+  }
+}
+
+// If "what" is empty, prints all PCH info. If "what" is nonempty, prints only
+// the things that match (if any). Returns true if anything was printed.
+bool PrintPrecompiledHeaderInfo(const ConfigValues& values,
+                                const std::string& what,
+                                bool display_headers) {
+  bool found_match = false;
+  if (what == variables::kPrecompiledHeader || what.empty()) {
+    if (!values.precompiled_header().empty()) {
+      if (display_headers)
+        OutputString("\nprecompiled_header\n");
+      OutputString(values.precompiled_header() + "\n");
+    }
+    found_match = true;
+  }
+  if (what == variables::kPrecompiledSource || what.empty()) {
+    if (!values.precompiled_source().is_null()) {
+      if (display_headers)
+        OutputString("\nprecompiled_source\n");
+      OutputString(values.precompiled_source().value() + "\n");
+    }
+    found_match = true;
+  }
+  return found_match;
+}
+
 bool PrintTarget(const Target* target,
                  const std::string& what,
-                 bool single_target,
-                 bool all,
-                 bool tree,
-                 bool blame) {
-  std::unique_ptr<base::DictionaryValue> dict =
-      DescBuilder::DescriptionForTarget(target, what, all, tree, blame);
-  if (!what.empty() && dict->empty()) {
+                 bool display_target_header) {
+  if (display_target_header) {
+    OutputString("Target: ", DECORATION_YELLOW);
+    OutputString(target->label().GetUserVisibleName(false) + "\n");
+    OutputString("Type: ", DECORATION_YELLOW);
+    OutputString(std::string(
+        Target::GetStringForOutputType(target->output_type())) + "\n");
+    OutputString("Toolchain: ", DECORATION_YELLOW);
+    OutputString(
+        target->label().GetToolchainLabel().GetUserVisibleName(false) + "\n");
+  }
+
+  // Display headers when outputting everything.
+  bool display_headers = what.empty();
+  bool is_binary_output = target->IsBinary();
+
+  bool found_match = false;
+
+  // General target meta variables.
+  if (what.empty() || what == variables::kVisibility) {
+    PrintVisibility(target, display_headers);
+    found_match = true;
+  }
+  if (what.empty() || what == variables::kTestonly) {
+    PrintTestonly(target, display_headers);
+    found_match  = true;
+  }
+
+  // Binary target meta variables.
+  if (is_binary_output) {
+    if (what.empty() || what == variables::kCheckIncludes) {
+      PrintCheckIncludes(target, display_headers);
+      found_match = true;
+    }
+    if (what.empty() || what == variables::kAllowCircularIncludesFrom) {
+      PrintAllowCircularIncludesFrom(target, display_headers);
+      found_match = true;
+    }
+  }
+
+  // Sources and inputs.
+  if (what.empty() || what == variables::kSources) {
+    PrintSources(target, display_headers);
+    found_match = true;
+  }
+  if (what.empty() || what == variables::kPublic) {
+    PrintPublic(target, display_headers);
+    found_match = true;
+  }
+  if (what.empty() || what == variables::kInputs) {
+    PrintInputs(target, display_headers);
+    found_match = true;
+  }
+
+  // Configs. Configs set directly on a target are only relevant for binary
+  // targets
+  if (is_binary_output && (what.empty() || what == variables::kConfigs)) {
+    PrintConfigs(target, display_headers);
+    found_match = true;
+  }
+
+  // Dependent/public configs can be applied to anything.
+  if (what.empty() || what == variables::kPublicConfigs) {
+    PrintPublicConfigs(target, display_headers);
+    found_match = true;
+  }
+  if (what.empty() || what == variables::kAllDependentConfigs) {
+    PrintAllDependentConfigs(target, display_headers);
+    found_match = true;
+  }
+
+  // Action values.
+  if (target->output_type() == Target::ACTION ||
+      target->output_type() == Target::ACTION_FOREACH) {
+    if (what.empty() || what == variables::kScript) {
+      PrintScript(target, display_headers);
+      found_match = true;
+    }
+    if (what.empty() || what == variables::kArgs) {
+      PrintArgs(target, display_headers);
+      found_match = true;
+    }
+    if (what.empty() || what == variables::kDepfile) {
+      PrintDepfile(target, display_headers);
+      found_match = true;
+    }
+  }
+
+  // Outputs.
+  if (target->output_type() != Target::SOURCE_SET &&
+      target->output_type() != Target::GROUP) {
+    if (what.empty() || what == variables::kOutputs) {
+      PrintOutputs(target, display_headers);
+      found_match = true;
+    }
+  }
+
+  // Values from configs only apply to binary targets.
+  if (is_binary_output) {
+    #define CONFIG_VALUE_ARRAY_HANDLER(name, type) \
+      if (what.empty() || what == #name) { \
+        OutputRecursiveTargetConfig<type>( \
+            target, display_headers ? #name : nullptr, &ConfigValues::name); \
+        found_match = true; \
+      }
+
+    CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(defines, std::string)
+    CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir)
+    CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string)
+    // Libs and lib_dirs are handled specially below.
+
+    #undef CONFIG_VALUE_ARRAY_HANDLER
+
+    found_match |= PrintPrecompiledHeaderInfo(target->config_values(),
+                                              what, display_headers);
+  }
+
+  // Deps
+  if (what.empty() || what == "deps") {
+    PrintDeps(target, display_headers);
+    found_match = true;
+  }
+
+  // Runtime deps are special, print only when explicitly asked for and not in
+  // overview mode.
+  if (what == "runtime_deps") {
+    PrintRuntimeDeps(target);
+    found_match = true;
+  }
+
+  // Libs can be part of any target and get recursively pushed up the chain,
+  // so display them regardless of target type.
+  if (what.empty() || what == variables::kLibs) {
+    PrintLibs(target, display_headers);
+    found_match = true;
+  }
+  if (what.empty() || what == variables::kLibDirs) {
+    PrintLibDirs(target, display_headers);
+    found_match = true;
+  }
+
+  if (!found_match) {
     OutputString("Don't know how to display \"" + what + "\" for \"" +
-                 Target::GetStringForOutputType(target->output_type()) +
-                 "\".\n");
+        Target::GetStringForOutputType(target->output_type()) + "\".\n");
     return false;
   }
-  // Print single value, without any headers
-  if (!what.empty() && dict->size() == 1 && single_target) {
-    base::DictionaryValue::Iterator iter(*dict);
-    PrintValue(&iter.value(), 0);
-    return true;
-  }
-
-  OutputString("Target ", DECORATION_YELLOW);
-  OutputString(target->label().GetUserVisibleName(false));
-  OutputString("\n");
-
-  std::unique_ptr<base::Value> v;
-#define HANDLER(property, handler_name) \
-  if (dict->Remove(property, &v)) {     \
-    handler_name(property, v.get());    \
-  }
-
-  // Entries with DefaultHandler are present to enforce order
-  HANDLER("type", LabelHandler);
-  HANDLER("toolchain", LabelHandler);
-  HANDLER(variables::kVisibility, VisibilityHandler);
-  HANDLER(variables::kTestonly, DefaultHandler);
-  HANDLER(variables::kCheckIncludes, DefaultHandler);
-  HANDLER(variables::kAllowCircularIncludesFrom, DefaultHandler);
-  HANDLER(variables::kSources, DefaultHandler);
-  HANDLER(variables::kPublic, PublicHandler);
-  HANDLER(variables::kInputs, DefaultHandler);
-  HANDLER(variables::kConfigs, ConfigsHandler);
-  HANDLER(variables::kPublicConfigs, ConfigsHandler);
-  HANDLER(variables::kAllDependentConfigs, ConfigsHandler);
-  HANDLER(variables::kScript, DefaultHandler);
-  HANDLER(variables::kArgs, DefaultHandler);
-  HANDLER(variables::kDepfile, DefaultHandler);
-  ProcessOutputs(dict.get());
-  HANDLER("bundle_data", DefaultHandler);
-  HANDLER(variables::kArflags, DefaultHandler);
-  HANDLER(variables::kAsmflags, DefaultHandler);
-  HANDLER(variables::kCflags, DefaultHandler);
-  HANDLER(variables::kCflagsC, DefaultHandler);
-  HANDLER(variables::kCflagsCC, DefaultHandler);
-  HANDLER(variables::kCflagsObjC, DefaultHandler);
-  HANDLER(variables::kCflagsObjCC, DefaultHandler);
-  HANDLER(variables::kDefines, DefaultHandler);
-  HANDLER(variables::kIncludeDirs, DefaultHandler);
-  HANDLER(variables::kLdflags, DefaultHandler);
-  HANDLER(variables::kPrecompiledHeader, DefaultHandler);
-  HANDLER(variables::kPrecompiledSource, DefaultHandler);
-  HANDLER(variables::kDeps, DepsHandler);
-  HANDLER(variables::kLibs, DefaultHandler);
-  HANDLER(variables::kLibDirs, DefaultHandler);
-
-#undef HANDLER
-
-  // Process the rest (if any)
-  base::DictionaryValue::Iterator iter(*dict);
-  while (!iter.IsAtEnd()) {
-    DefaultHandler(iter.key(), &iter.value());
-    iter.Advance();
-  }
-
   return true;
 }
 
 bool PrintConfig(const Config* config,
                  const std::string& what,
-                 bool single_config) {
-  std::unique_ptr<base::DictionaryValue> dict =
-      DescBuilder::DescriptionForConfig(config, what);
-  if (!what.empty() && dict->empty()) {
+                 bool display_config_header) {
+  const ConfigValues& values = config->resolved_values();
+
+  if (display_config_header) {
+    OutputString("Config: ", DECORATION_YELLOW);
+    OutputString(config->label().GetUserVisibleName(false) + "\n");
+    OutputString("Toolchain: ", DECORATION_YELLOW);
+    OutputString(
+        config->label().GetToolchainLabel().GetUserVisibleName(false) + "\n");
+    if (what.empty() && !config->configs().empty()) {
+      OutputString(
+          "(This is a composite config, the values below are after the\n"
+          "expansion of the child configs.)\n");
+    }
+  }
+
+  // Display headers when outputting everything.
+  bool display_headers = what.empty();
+
+  if (what.empty() || what == variables::kConfigs)
+    PrintConfigs(config, display_headers);
+
+#define CONFIG_VALUE_ARRAY_HANDLER(name, type) \
+  if (what.empty() || what == #name) { \
+    OutputConfigValueArray<type>(values, display_headers ? #name : nullptr, \
+                                 &ConfigValues::name); \
+    found_match = true; \
+  }
+
+  bool found_match = false;
+
+  CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string)
+  CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string)
+  CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string)
+  CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string)
+  CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string)
+  CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string)
+  CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string)
+  CONFIG_VALUE_ARRAY_HANDLER(defines, std::string)
+  CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir)
+  CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string)
+  CONFIG_VALUE_ARRAY_HANDLER(lib_dirs, SourceDir)
+  CONFIG_VALUE_ARRAY_HANDLER(libs, LibFile)
+
+#undef CONFIG_VALUE_ARRAY_HANDLER
+
+  // Handles all PCH-related variables.
+  found_match |= PrintPrecompiledHeaderInfo(config->resolved_values(),
+                                            what, display_headers);
+
+  if (!found_match) {
     OutputString("Don't know how to display \"" + what + "\" for a config.\n");
     return false;
   }
-  // Print single value, without any headers
-  if (!what.empty() && dict->size() == 1 && single_config) {
-    base::DictionaryValue::Iterator iter(*dict);
-    PrintValue(&iter.value(), 0);
-    return true;
-  }
-
-  OutputString("Config: ", DECORATION_YELLOW);
-  OutputString(config->label().GetUserVisibleName(false));
-  OutputString("\n");
-
-  std::unique_ptr<base::Value> v;
-#define HANDLER(property, handler_name) \
-  if (dict->Remove(property, &v)) {     \
-    handler_name(property, v.get());    \
-  }
-
-  HANDLER("toolchain", LabelHandler);
-  if (!config->configs().empty()) {
-    OutputString(
-        "(This is a composite config, the values below are after the\n"
-        "expansion of the child configs.)\n");
-  }
-  HANDLER(variables::kArflags, DefaultHandler);
-  HANDLER(variables::kAsmflags, DefaultHandler);
-  HANDLER(variables::kCflags, DefaultHandler);
-  HANDLER(variables::kCflagsC, DefaultHandler);
-  HANDLER(variables::kCflagsCC, DefaultHandler);
-  HANDLER(variables::kCflagsObjC, DefaultHandler);
-  HANDLER(variables::kCflagsObjCC, DefaultHandler);
-  HANDLER(variables::kDefines, DefaultHandler);
-  HANDLER(variables::kIncludeDirs, DefaultHandler);
-  HANDLER(variables::kLdflags, DefaultHandler);
-  HANDLER(variables::kLibs, DefaultHandler);
-  HANDLER(variables::kLibDirs, DefaultHandler);
-  HANDLER(variables::kPrecompiledHeader, DefaultHandler);
-  HANDLER(variables::kPrecompiledSource, DefaultHandler);
-
-#undef HANDLER
-
   return true;
 }
 
@@ -291,8 +762,7 @@
 const char kDesc_HelpShort[] =
     "desc: Show lots of insightful information about a target or config.";
 const char kDesc_Help[] =
-    "gn desc <out_dir> <label or pattern> [<what to show>] [--blame] "
-    "[--format=json]\n"
+    "gn desc <out_dir> <label or pattern> [<what to show>] [--blame]\n"
     "\n"
     "  Displays information about a given target or config. The build\n"
     "  build parameters will be taken for the build in the given <out_dir>.\n"
@@ -344,9 +814,6 @@
     "\n"
     ALL_TOOLCHAINS_SWITCH_HELP
     "\n"
-    "  --format=json\n"
-    "      Format the output as JSON instead of text.\n"
-    "\n"
     "Target flags\n"
     "\n"
     "  --blame\n"
@@ -455,52 +922,28 @@
   if (args.size() == 3)
     what_to_print = args[2];
 
-  bool json = cmdline->GetSwitchValueASCII("format") == "json";
+  bool multiple_outputs = (target_matches.size() + config_matches.size()) > 1;
 
-  if (json) {
-    // Convert all targets/configs to JSON, serialize and print them
-    auto res = base::WrapUnique(new base::DictionaryValue());
-    if (!target_matches.empty()) {
-      for (const auto* target : target_matches) {
-        res->Set(target->label().GetUserVisibleName(
-                     target->settings()->default_toolchain_label()),
-                 DescBuilder::DescriptionForTarget(
-                     target, what_to_print, cmdline->HasSwitch(kAll),
-                     cmdline->HasSwitch(kTree), cmdline->HasSwitch(kBlame)));
-      }
-    } else if (!config_matches.empty()) {
-      for (const auto* config : config_matches) {
-        res->Set(config->label().GetUserVisibleName(false),
-                 DescBuilder::DescriptionForConfig(config, what_to_print));
-      }
-    }
-    std::string s;
-    base::JSONWriter::WriteWithOptions(
-        *res.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &s);
-    OutputString(s);
-  } else {
-    // Regular (non-json) formatted output
-    bool multiple_outputs = (target_matches.size() + config_matches.size()) > 1;
+  // Display headers for each target when printing all values, or when printing
+  // multiple targets or configs.
+  bool display_item_header = multiple_outputs || what_to_print.empty();
 
-    bool printed_output = false;
-    for (const Target* target : target_matches) {
-      if (printed_output)
-        OutputString("\n\n");
-      printed_output = true;
+  bool printed_output = false;
+  for (const Target* target : target_matches) {
+    if (printed_output)
+      OutputString("\n\n");
+    printed_output = true;
 
-      if (!PrintTarget(target, what_to_print, !multiple_outputs,
-                       cmdline->HasSwitch(kAll), cmdline->HasSwitch(kTree),
-                       cmdline->HasSwitch(kBlame)))
-        return 1;
-    }
-    for (const Config* config : config_matches) {
-      if (printed_output)
-        OutputString("\n\n");
-      printed_output = true;
+    if (!PrintTarget(target, what_to_print, display_item_header))
+      return 1;
+  }
+  for (const Config* config : config_matches) {
+    if (printed_output)
+      OutputString("\n\n");
+    printed_output = true;
 
-      if (!PrintConfig(config, what_to_print, !multiple_outputs))
-        return 1;
-    }
+    if (!PrintConfig(config, what_to_print, display_item_header))
+      return 1;
   }
 
   return 0;
diff --git a/tools/gn/command_gen.cc b/tools/gn/command_gen.cc
index 06b99ca..3d44274 100644
--- a/tools/gn/command_gen.cc
+++ b/tools/gn/command_gen.cc
@@ -11,7 +11,6 @@
 #include "tools/gn/build_settings.h"
 #include "tools/gn/commands.h"
 #include "tools/gn/eclipse_writer.h"
-#include "tools/gn/json_project_writer.h"
 #include "tools/gn/ninja_target_writer.h"
 #include "tools/gn/ninja_writer.h"
 #include "tools/gn/qt_creator_writer.h"
@@ -37,14 +36,10 @@
 const char kSwitchIdeValueVs2013[] = "vs2013";
 const char kSwitchIdeValueVs2015[] = "vs2015";
 const char kSwitchIdeValueXcode[] = "xcode";
-const char kSwitchIdeValueJson[] = "json";
 const char kSwitchNinjaExtraArgs[] = "ninja-extra-args";
 const char kSwitchRootTarget[] = "root-target";
 const char kSwitchSln[] = "sln";
 const char kSwitchWorkspace[] = "workspace";
-const char kSwitchJsonFileName[] = "json-file-name";
-const char kSwitchJsonIdeScript[] = "json-ide-script";
-const char kSwitchJsonIdeScriptArgs[] = "json-ide-script-args";
 
 // Called on worker thread to write the ninja file.
 void BackgroundDoWrite(const Target* target) {
@@ -118,7 +113,7 @@
 
   if (generator) {
     err += "but this file was not generated by any dependencies of the " +
-           target_str + ". The target\nthat generates the file is:\n  ";
+        target_str + ". The target\nthat generates the file is:\n  ";
     err += generator->label().GetUserVisibleName(show_toolchains);
   } else {
     err += "but no targets in the build generate that file.";
@@ -171,12 +166,11 @@
                   Err* err) {
   const base::CommandLine* command_line =
       base::CommandLine::ForCurrentProcess();
-  bool quiet = command_line->HasSwitch(switches::kQuiet);
   base::ElapsedTimer timer;
 
   if (ide == kSwitchIdeValueEclipse) {
     bool res = EclipseWriter::RunAndWriteFile(build_settings, builder, err);
-    if (res && !quiet) {
+    if (res && !command_line->HasSwitch(switches::kQuiet)) {
       OutputString("Generating Eclipse settings took " +
                    base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                    "ms\n");
@@ -195,7 +189,7 @@
       filters = command_line->GetSwitchValueASCII(kSwitchFilters);
     bool res = VisualStudioWriter::RunAndWriteFiles(
         build_settings, builder, version, sln_name, filters, err);
-    if (res && !quiet) {
+    if (res && !command_line->HasSwitch(switches::kQuiet)) {
       OutputString("Generating Visual Studio projects took " +
                    base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                    "ms\n");
@@ -208,7 +202,7 @@
         command_line->GetSwitchValueASCII(kSwitchNinjaExtraArgs),
         command_line->GetSwitchValueASCII(kSwitchFilters), build_settings,
         builder, err);
-    if (res && !quiet) {
+    if (res && !command_line->HasSwitch(switches::kQuiet)) {
       OutputString("Generating Xcode projects took " +
                    base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                    "ms\n");
@@ -220,32 +214,12 @@
       root_target = command_line->GetSwitchValueASCII(kSwitchRootTarget);
     bool res = QtCreatorWriter::RunAndWriteFile(build_settings, builder, err,
                                                 root_target);
-    if (res && !quiet) {
+    if (res && !command_line->HasSwitch(switches::kQuiet)) {
       OutputString("Generating QtCreator projects took " +
                    base::Int64ToString(timer.Elapsed().InMilliseconds()) +
                    "ms\n");
     }
     return res;
-  } else if (ide == kSwitchIdeValueJson) {
-    std::string file_name =
-        command_line->GetSwitchValueASCII(kSwitchJsonFileName);
-    if (file_name.empty())
-      file_name = "project.json";
-    std::string exec_script =
-        command_line->GetSwitchValueASCII(kSwitchJsonIdeScript);
-    std::string exec_script_extra_args =
-        command_line->GetSwitchValueASCII(kSwitchJsonIdeScriptArgs);
-    std::string filters = command_line->GetSwitchValueASCII(kSwitchFilters);
-
-    bool res = JSONProjectWriter::RunAndWriteFiles(
-        build_settings, builder, file_name, exec_script, exec_script_extra_args,
-        filters, quiet, err);
-    if (res && !quiet) {
-      OutputString("Generating JSON projects took " +
-                   base::Int64ToString(timer.Elapsed().InMilliseconds()) +
-                   "ms\n");
-    }
-    return res;
   }
 
   *err = Err(Location(), "Unknown IDE: " + ide);
@@ -255,7 +229,8 @@
 }  // namespace
 
 const char kGen[] = "gen";
-const char kGen_HelpShort[] = "gen: Generate ninja files.";
+const char kGen_HelpShort[] =
+    "gen: Generate ninja files.";
 const char kGen_Help[] =
     "gn gen: Generate ninja files.\n"
     "\n"
@@ -284,13 +259,12 @@
     "      \"vs2015\" - Visual Studio 2015 project/solution files.\n"
     "      \"xcode\" - Xcode workspace/solution files.\n"
     "      \"qtcreator\" - QtCreator project files.\n"
-    "      \"json\" - JSON file containing target information\n"
     "\n"
     "  --filters=<path_prefixes>\n"
     "      Semicolon-separated list of label patterns used to limit the set\n"
     "      of generated projects (see \"gn help label_pattern\"). Only\n"
     "      matching targets and their dependencies will be included in the\n"
-    "      solution. Only used for Visual Studio, Xcode and JSON.\n"
+    "      solution. Only used for Visual Studio and Xcode.\n"
     "\n"
     "Visual Studio Flags\n"
     "\n"
@@ -331,27 +305,7 @@
     "  properly define includes/defines for each file individually.\n"
     "  Instead, one set of includes/defines is generated for the entire\n"
     "  project. This works fairly well but may still result in a few indexer\n"
-    "  issues here and there.\n"
-    "\n"
-    "Generic JSON Output\n"
-    "\n"
-    "  Dumps target information to JSON file and optionally invokes python\n"
-    "  script on generated file. \n"
-    "  See comments at the beginning of json_project_writer.cc and\n"
-    "  desc_builder.cc for overview of JSON file format.\n"
-    "\n"
-    "  --json-file-name=<json_file_name>\n"
-    "      Overrides default file name (project.json) of generated JSON file.\n"
-    "\n"
-    "  --json-ide-script=<path_to_python_script>\n"
-    "      Executes python script after the JSON file is generated.\n"
-    "      Path can be project absolute (//), system absolute (/) or\n"
-    "      relative, in which case the output directory will be base.\n"
-    "      Path to generated JSON file will be first argument when invoking\n"
-    "      script.\n"
-    "\n"
-    "  --json-ide-script-args=<argument>\n"
-    "      Optional second argument that will passed to executed script.\n";
+    "  issues here and there.\n";
 
 int RunGen(const std::vector<std::string>& args) {
   base::ElapsedTimer timer;
diff --git a/tools/gn/commands.cc b/tools/gn/commands.cc
index 492b74f..a646679 100644
--- a/tools/gn/commands.cc
+++ b/tools/gn/commands.cc
@@ -6,7 +6,6 @@
 
 #include "base/command_line.h"
 #include "base/strings/string_split.h"
-#include "base/values.h"
 #include "tools/gn/builder.h"
 #include "tools/gn/filesystem_utils.h"
 #include "tools/gn/item.h"
@@ -281,20 +280,22 @@
   return item->defined_from()->GetRange().begin().file()->physical_name();
 }
 
-void PrintTargetsAsBuildfiles(const std::vector<const Target*>& targets,
-                              base::ListValue* out) {
+void PrintTargetsAsBuildfiles(bool indent,
+                              const std::vector<const Target*>& targets) {
   // Output the set of unique source files.
   std::set<std::string> unique_files;
   for (const Target* target : targets)
     unique_files.insert(FilePathToUTF8(BuildFileForItem(target)));
 
   for (const std::string& file : unique_files) {
-    out->AppendString(file);
+    if (indent)
+      OutputString("  ");
+    OutputString(file + "\n");
   }
 }
 
-void PrintTargetsAsLabels(const std::vector<const Target*>& targets,
-                          base::ListValue* out) {
+void PrintTargetsAsLabels(bool indent,
+                          const std::vector<const Target*>& targets) {
   // Putting the labels into a set automatically sorts them for us.
   std::set<Label> unique_labels;
   for (auto* target : targets)
@@ -306,13 +307,16 @@
 
   for (const Label& label : unique_labels) {
     // Print toolchain only for ones not in the default toolchain.
-    out->AppendString(label.GetUserVisibleName(label.GetToolchainLabel() !=
-                                               default_tc_label));
+    if (indent)
+      OutputString("  ");
+    OutputString(label.GetUserVisibleName(
+        label.GetToolchainLabel() != default_tc_label));
+    OutputString("\n");
   }
 }
 
-void PrintTargetsAsOutputs(const std::vector<const Target*>& targets,
-                           base::ListValue* out) {
+void PrintTargetsAsOutputs(bool indent,
+                           const std::vector<const Target*>& targets) {
   if (targets.empty())
     return;
 
@@ -332,7 +336,10 @@
     std::string result = RebasePath(output_as_source.value(),
                                     build_settings->build_dir(),
                                     build_settings->root_path_utf8());
-    out->AppendString(result);
+    if (indent)
+      OutputString("  ");
+    OutputString(result);
+    OutputString("\n");
   }
 }
 
@@ -483,8 +490,7 @@
   return true;
 }
 
-void FilterAndPrintTargets(std::vector<const Target*>* targets,
-                           base::ListValue* out) {
+void FilterAndPrintTargets(bool indent, std::vector<const Target*>* targets) {
   if (targets->empty())
     return;
 
@@ -498,40 +504,21 @@
     return;
   switch (printing_mode) {
     case TARGET_PRINT_BUILDFILE:
-      PrintTargetsAsBuildfiles(*targets, out);
+      PrintTargetsAsBuildfiles(indent, *targets);
       break;
     case TARGET_PRINT_LABEL:
-      PrintTargetsAsLabels(*targets, out);
+      PrintTargetsAsLabels(indent, *targets);
       break;
     case TARGET_PRINT_OUTPUT:
-      PrintTargetsAsOutputs(*targets, out);
+      PrintTargetsAsOutputs(indent, *targets);
       break;
   }
 }
 
-void FilterAndPrintTargets(bool indent, std::vector<const Target*>* targets) {
-  base::ListValue tmp;
-  FilterAndPrintTargets(targets, &tmp);
-  for (const auto& value : tmp) {
-    std::string string;
-    value->GetAsString(&string);
-    if (indent)
-      OutputString("  ");
-    OutputString(string);
-    OutputString("\n");
-  }
-}
-
 void FilterAndPrintTargetSet(bool indent,
                              const std::set<const Target*>& targets) {
   std::vector<const Target*> target_vector(targets.begin(), targets.end());
   FilterAndPrintTargets(indent, &target_vector);
 }
 
-void FilterAndPrintTargetSet(const std::set<const Target*>& targets,
-                             base::ListValue* out) {
-  std::vector<const Target*> target_vector(targets.begin(), targets.end());
-  FilterAndPrintTargets(&target_vector, out);
-}
-
 }  // namespace commands
diff --git a/tools/gn/commands.h b/tools/gn/commands.h
index 01bf0ee..fdd10fc 100644
--- a/tools/gn/commands.h
+++ b/tools/gn/commands.h
@@ -11,7 +11,6 @@
 #include <vector>
 
 #include "base/strings/string_piece.h"
-#include "base/values.h"
 #include "tools/gn/target.h"
 #include "tools/gn/unique_vector.h"
 
@@ -180,13 +179,8 @@
 //
 // The vector will be modified so that only the printed targets will remain.
 void FilterAndPrintTargets(bool indent, std::vector<const Target*>* targets);
-void FilterAndPrintTargets(std::vector<const Target*>* targets,
-                           base::ListValue* out);
-
 void FilterAndPrintTargetSet(bool indent,
                              const std::set<const Target*>& targets);
-void FilterAndPrintTargetSet(const std::set<const Target*>& targets,
-                             base::ListValue* out);
 
 // Extra help from command_check.cc
 extern const char kNoGnCheck_Help[];
diff --git a/tools/gn/desc_builder.cc b/tools/gn/desc_builder.cc
deleted file mode 100644
index bc8f02a..0000000
--- a/tools/gn/desc_builder.cc
+++ /dev/null
@@ -1,694 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include <set>
-
-#include "base/memory/ptr_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "tools/gn/commands.h"
-#include "tools/gn/config.h"
-#include "tools/gn/config_values_extractors.h"
-#include "tools/gn/deps_iterator.h"
-#include "tools/gn/desc_builder.h"
-#include "tools/gn/input_file.h"
-#include "tools/gn/parse_tree.h"
-#include "tools/gn/runtime_deps.h"
-#include "tools/gn/settings.h"
-#include "tools/gn/substitution_writer.h"
-#include "tools/gn/variables.h"
-
-// Example structure of Value for single target
-// (not applicable or empty fields will be ommitted depending on target type)
-//
-// target_properties = {
-//   "type" : "output_type", // matching Target::GetStringForOutputType
-//   "toolchain" : "toolchain_name",
-//   "visibility" : [ list of visibility pattern descriptions ],
-//   "test_only" : true or false,
-//   "check_includes": true or false,
-//   "allow_circular_includes_from": [ list of target names ],
-//   "sources" : [ list of source files ],
-//   "public" : either "*" or [ list of public headers],
-//   "inputs" : [ list of inputs for target ],
-//   "configs" : [ list of configs for this target ],
-//   "public_configs" : [ list of public configs for this taget],
-//   "all_dependent_configs", [ list of all dependent configs for this target],
-//   "script" : "script for action targets",
-//   "args" : [ argument list for action targets ],
-//   "depfile : "file name for action input dependencies",
-//   "outputs" : [ list of target outputs ],
-//   "arflags", "asmflags", "cflags", "cflags_c",
-//   "clfags_cc", "cflags_objc", "clfags_objcc" : [ list of flags],
-//   "defines" : [ list of preprocessor definitions ],
-//   "include_dirs" : [ list of include directories ],
-//   "precompiled_header" : "name of precompiled header file",
-//   "precompiled_source" : "path to precompiled source",
-//   "deps : [ list of target dependencies ],
-//   "libs" : [ list of libraries ],
-//   "lib_dirs" : [ list of library directories ]
-// }
-//
-// Optionally, if "what" is specified while generating description, two other
-// properties can be requested that are not included by default
-//
-// "runtime_deps" : [list of computed runtime dependencies]
-// "source_outputs" : {
-//    "source_file x" : [ list of outputs for source file x ]
-//    "source_file y" : [ list of outputs for source file y ]
-//    ...
-// }
-
-namespace {
-
-std::string FormatSourceDir(const SourceDir& dir) {
-#if defined(OS_WIN)
-  // On Windows we fix up system absolute paths to look like native ones.
-  // Internally, they'll look like "/C:\foo\bar/"
-  if (dir.is_system_absolute()) {
-    std::string buf = dir.value();
-    if (buf.size() > 3 && buf[2] == ':') {
-      buf.erase(buf.begin());  // Erase beginning slash.
-      return buf;
-    }
-  }
-#endif
-  return dir.value();
-}
-
-void RecursiveCollectChildDeps(const Target* target,
-                               std::set<const Target*>* result);
-
-void RecursiveCollectDeps(const Target* target,
-                          std::set<const Target*>* result) {
-  if (result->find(target) != result->end())
-    return;  // Already did this target.
-  result->insert(target);
-
-  RecursiveCollectChildDeps(target, result);
-}
-
-void RecursiveCollectChildDeps(const Target* target,
-                               std::set<const Target*>* result) {
-  for (const auto& pair : target->GetDeps(Target::DEPS_ALL))
-    RecursiveCollectDeps(pair.ptr, result);
-}
-
-// Common functionality for target and config description builder
-class BaseDescBuilder {
- public:
-  typedef std::unique_ptr<base::Value> ValuePtr;
-
-  BaseDescBuilder(const std::set<std::string>& what,
-                  bool all,
-                  bool tree,
-                  bool blame)
-      : what_(what), all_(all), tree_(tree), blame_(blame) {}
-
- protected:
-  virtual Label GetToolchainLabel() const = 0;
-
-  bool what(const std::string& w) const {
-    return what_.empty() || what_.find(w) != what_.end();
-  }
-
-  template <typename T>
-  ValuePtr RenderValue(const std::vector<T>& vector) {
-    auto res = base::WrapUnique(new base::ListValue());
-    for (const auto& v : vector)
-      res->Append(RenderValue(v));
-
-    return std::move(res);
-  }
-
-  ValuePtr RenderValue(const std::string& s, bool optional = false) {
-    return (s.empty() && optional) ? base::Value::CreateNullValue()
-                                   : ValuePtr(new base::StringValue(s));
-  }
-
-  ValuePtr RenderValue(const SourceDir& d) {
-    return d.is_null() ? base::Value::CreateNullValue()
-                       : ValuePtr(new base::StringValue(FormatSourceDir(d)));
-  }
-
-  ValuePtr RenderValue(const SourceFile& f) {
-    return f.is_null() ? base::Value::CreateNullValue()
-                       : ValuePtr(new base::StringValue(f.value()));
-  }
-
-  ValuePtr RenderValue(const LibFile& lib) {
-    if (lib.is_source_file())
-      return RenderValue(lib.source_file());
-    return RenderValue(lib.value());
-  }
-
-  template <class VectorType>
-  void FillInConfigVector(base::ListValue* out,
-                          const VectorType& configs,
-                          int indent = 0) {
-    for (const auto& config : configs) {
-      std::string name(indent * 2, ' ');
-      name.append(config.label.GetUserVisibleName(GetToolchainLabel()));
-      out->AppendString(name);
-      if (tree_)
-        FillInConfigVector(out, config.ptr->configs(), indent + 1);
-    }
-  }
-
-  void FillInPrecompiledHeader(base::DictionaryValue* out,
-                               const ConfigValues& values) {
-    if (what(variables::kPrecompiledHeader) &&
-        !values.precompiled_header().empty()) {
-      out->Set(variables::kPrecompiledHeader,
-               RenderValue(values.precompiled_header(), true));
-    }
-    if (what(variables::kPrecompiledSource) &&
-        !values.precompiled_source().is_null()) {
-      out->Set(variables::kPrecompiledSource,
-               RenderValue(values.precompiled_source()));
-    }
-  }
-
-  std::set<std::string> what_;
-  bool all_;
-  bool tree_;
-  bool blame_;
-};
-
-class ConfigDescBuilder : public BaseDescBuilder {
- public:
-  ConfigDescBuilder(const Config* config, const std::set<std::string>& what)
-      : BaseDescBuilder(what, false, false, false), config_(config) {}
-
-  std::unique_ptr<base::DictionaryValue> BuildDescription() {
-    auto res = base::WrapUnique(new base::DictionaryValue());
-    const ConfigValues& values = config_->resolved_values();
-
-    if (what_.empty())
-      res->SetString(
-          "toolchain",
-          config_->label().GetToolchainLabel().GetUserVisibleName(false));
-
-    if (what(variables::kConfigs) && !config_->configs().empty()) {
-      auto configs = base::WrapUnique(new base::ListValue());
-      FillInConfigVector(configs.get(), config_->configs().vector());
-      res->Set(variables::kConfigs, std::move(configs));
-    }
-
-#define CONFIG_VALUE_ARRAY_HANDLER(name, type)                        \
-  if (what(#name)) {                                                  \
-    ValuePtr ptr =                                                    \
-        render_config_value_array<type>(values, &ConfigValues::name); \
-    if (ptr) {                                                        \
-      res->Set(#name, std::move(ptr));                                \
-    }                                                                 \
-  }
-    CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(defines, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir)
-    CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string)
-    CONFIG_VALUE_ARRAY_HANDLER(lib_dirs, SourceDir)
-    CONFIG_VALUE_ARRAY_HANDLER(libs, LibFile)
-
-#undef CONFIG_VALUE_ARRAY_HANDLER
-
-    FillInPrecompiledHeader(res.get(), values);
-
-    return res;
-  }
-
- protected:
-  Label GetToolchainLabel() const override {
-    return config_->label().GetToolchainLabel();
-  }
-
- private:
-  template <typename T>
-  ValuePtr render_config_value_array(
-      const ConfigValues& values,
-      const std::vector<T>& (ConfigValues::*getter)() const) {
-    auto res = base::WrapUnique(new base::ListValue());
-
-    for (const T& cur : (values.*getter)())
-      res->Append(RenderValue(cur));
-
-    return res->empty() ? nullptr : std::move(res);
-  }
-
-  const Config* config_;
-};
-
-class TargetDescBuilder : public BaseDescBuilder {
- public:
-  TargetDescBuilder(const Target* target,
-                    const std::set<std::string>& what,
-                    bool all,
-                    bool tree,
-                    bool blame)
-      : BaseDescBuilder(what, all, tree, blame), target_(target) {}
-
-  std::unique_ptr<base::DictionaryValue> BuildDescription() {
-    auto res = base::WrapUnique(new base::DictionaryValue());
-    bool is_binary_output = target_->IsBinary();
-
-    if (what_.empty()) {
-      res->SetString("type",
-                     Target::GetStringForOutputType(target_->output_type()));
-      res->SetString(
-          "toolchain",
-          target_->label().GetToolchainLabel().GetUserVisibleName(false));
-    }
-
-    // General target meta variables.
-    if (what(variables::kVisibility))
-      res->Set(variables::kVisibility, target_->visibility().AsValue());
-
-    if (what(variables::kTestonly))
-      res->SetBoolean(variables::kTestonly, target_->testonly());
-
-    if (is_binary_output) {
-      if (what(variables::kCheckIncludes))
-        res->SetBoolean(variables::kCheckIncludes, target_->check_includes());
-
-      if (what(variables::kAllowCircularIncludesFrom)) {
-        auto labels = base::WrapUnique(new base::ListValue());
-        for (const auto& cur : target_->allow_circular_includes_from())
-          labels->AppendString(cur.GetUserVisibleName(GetToolchainLabel()));
-
-        res->Set(variables::kAllowCircularIncludesFrom, std::move(labels));
-      }
-    }
-
-    if (what(variables::kSources) && !target_->sources().empty())
-      res->Set(variables::kSources, RenderValue(target_->sources()));
-
-    if (what(variables::kOutputName) && !target_->output_name().empty())
-      res->SetString(variables::kOutputName, target_->output_name());
-
-    if (what(variables::kOutputDir) && !target_->output_dir().is_null())
-      res->Set(variables::kOutputDir, RenderValue(target_->output_dir()));
-
-    if (what(variables::kOutputExtension) && target_->output_extension_set())
-      res->SetString(variables::kOutputExtension, target_->output_extension());
-
-    if (what(variables::kPublic)) {
-      if (target_->all_headers_public())
-        res->SetString(variables::kPublic, "*");
-      else
-        res->Set(variables::kPublic, RenderValue(target_->public_headers()));
-    }
-
-    if (what(variables::kInputs) && !target_->inputs().empty())
-      res->Set(variables::kInputs, RenderValue(target_->inputs()));
-
-    if (is_binary_output && what(variables::kConfigs) &&
-        !target_->configs().empty()) {
-      auto configs = base::WrapUnique(new base::ListValue());
-      FillInConfigVector(configs.get(), target_->configs().vector());
-      res->Set(variables::kConfigs, std::move(configs));
-    }
-
-    if (what(variables::kPublicConfigs) && !target_->public_configs().empty()) {
-      auto configs = base::WrapUnique(new base::ListValue());
-      FillInConfigVector(configs.get(), target_->public_configs());
-      res->Set(variables::kPublicConfigs, std::move(configs));
-    }
-
-    if (what(variables::kAllDependentConfigs) &&
-        !target_->all_dependent_configs().empty()) {
-      auto configs = base::WrapUnique(new base::ListValue());
-      FillInConfigVector(configs.get(), target_->all_dependent_configs());
-      res->Set(variables::kAllDependentConfigs, std::move(configs));
-    }
-
-    // Action
-    if (target_->output_type() == Target::ACTION ||
-        target_->output_type() == Target::ACTION_FOREACH) {
-      if (what(variables::kScript))
-        res->SetString(variables::kScript,
-                       target_->action_values().script().value());
-
-      if (what(variables::kArgs)) {
-        auto args = base::WrapUnique(new base::ListValue());
-        for (const auto& elem : target_->action_values().args().list())
-          args->AppendString(elem.AsString());
-
-        res->Set(variables::kArgs, std::move(args));
-      }
-      if (what(variables::kDepfile) &&
-          !target_->action_values().depfile().empty()) {
-        res->SetString(variables::kDepfile,
-                       target_->action_values().depfile().AsString());
-      }
-    }
-
-    if (target_->output_type() != Target::SOURCE_SET &&
-        target_->output_type() != Target::GROUP &&
-        target_->output_type() != Target::BUNDLE_DATA) {
-      if (what(variables::kOutputs))
-        FillInOutputs(res.get());
-    }
-
-    // Source outputs are only included when specifically asked for it
-    if (what_.find("source_outputs") != what_.end())
-      FillInSourceOutputs(res.get());
-
-    if (target_->output_type() == Target::CREATE_BUNDLE && what("bundle_data"))
-      FillInBundle(res.get());
-
-    if (is_binary_output) {
-#define CONFIG_VALUE_ARRAY_HANDLER(name, type)                    \
-  if (what(#name)) {                                              \
-    ValuePtr ptr = RenderConfigValues<type>(&ConfigValues::name); \
-    if (ptr) {                                                    \
-      res->Set(#name, std::move(ptr));                            \
-    }                                                             \
-  }
-      CONFIG_VALUE_ARRAY_HANDLER(arflags, std::string)
-      CONFIG_VALUE_ARRAY_HANDLER(asmflags, std::string)
-      CONFIG_VALUE_ARRAY_HANDLER(cflags, std::string)
-      CONFIG_VALUE_ARRAY_HANDLER(cflags_c, std::string)
-      CONFIG_VALUE_ARRAY_HANDLER(cflags_cc, std::string)
-      CONFIG_VALUE_ARRAY_HANDLER(cflags_objc, std::string)
-      CONFIG_VALUE_ARRAY_HANDLER(cflags_objcc, std::string)
-      CONFIG_VALUE_ARRAY_HANDLER(defines, std::string)
-      CONFIG_VALUE_ARRAY_HANDLER(include_dirs, SourceDir)
-      CONFIG_VALUE_ARRAY_HANDLER(ldflags, std::string)
-#undef CONFIG_VALUE_ARRAY_HANDLER
-
-      // Libs and lib_dirs are handled specially below.
-
-      FillInPrecompiledHeader(res.get(), target_->config_values());
-    }
-
-    if (what(variables::kDeps))
-      res->Set(variables::kDeps, RenderDeps());
-
-    // Runtime deps are special, print only when explicitly asked for and not in
-    // overview mode.
-    if (what_.find("runtime_deps") != what_.end())
-      res->Set("runtime_deps", RenderRuntimeDeps());
-
-    // libs and lib_dirs are special in that they're inherited. We don't
-    // currently
-    // implement a blame feature for this since the bottom-up inheritance makes
-    // this difficult.
-
-    // Libs can be part of any target and get recursively pushed up the chain,
-    // so display them regardless of target type.
-    if (what(variables::kLibs)) {
-      const OrderedSet<LibFile>& all_libs = target_->all_libs();
-      if (!all_libs.empty()) {
-        auto libs = base::WrapUnique(new base::ListValue());
-        for (size_t i = 0; i < all_libs.size(); i++)
-          libs->AppendString(all_libs[i].value());
-        res->Set(variables::kLibs, std::move(libs));
-      }
-    }
-
-    if (what(variables::kLibDirs)) {
-      const OrderedSet<SourceDir>& all_lib_dirs = target_->all_lib_dirs();
-      if (!all_lib_dirs.empty()) {
-        auto lib_dirs = base::WrapUnique(new base::ListValue());
-        for (size_t i = 0; i < all_lib_dirs.size(); i++)
-          lib_dirs->AppendString(FormatSourceDir(all_lib_dirs[i]));
-        res->Set(variables::kLibDirs, std::move(lib_dirs));
-      }
-    }
-
-    return res;
-  }
-
- private:
-  // Prints dependencies of the given target (not the target itself). If the
-  // set is non-null, new targets encountered will be added to the set, and if
-  // a dependency is in the set already, it will not be recused into. When the
-  // set is null, all dependencies will be printed.
-  void RecursivePrintDeps(base::ListValue* out,
-                          const Target* target,
-                          std::set<const Target*>* seen_targets,
-                          int indent_level) {
-    // Combine all deps into one sorted list.
-    std::vector<LabelTargetPair> sorted_deps;
-    for (const auto& pair : target->GetDeps(Target::DEPS_ALL))
-      sorted_deps.push_back(pair);
-    std::sort(sorted_deps.begin(), sorted_deps.end(),
-              LabelPtrLabelLess<Target>());
-
-    std::string indent(indent_level * 2, ' ');
-
-    for (const auto& pair : sorted_deps) {
-      const Target* cur_dep = pair.ptr;
-      std::string str =
-          indent + cur_dep->label().GetUserVisibleName(GetToolchainLabel());
-
-      bool print_children = true;
-      if (seen_targets) {
-        if (seen_targets->find(cur_dep) == seen_targets->end()) {
-          // New target, mark it visited.
-          seen_targets->insert(cur_dep);
-        } else {
-          // Already seen.
-          print_children = false;
-          // Only print "..." if something is actually elided, which means that
-          // the current target has children.
-          if (!cur_dep->public_deps().empty() ||
-              !cur_dep->private_deps().empty() || !cur_dep->data_deps().empty())
-            str += "...";
-        }
-      }
-
-      out->AppendString(str);
-
-      if (print_children)
-        RecursivePrintDeps(out, cur_dep, seen_targets, indent_level + 1);
-    }
-  }
-
-  ValuePtr RenderDeps() {
-    auto res = base::WrapUnique(new base::ListValue());
-
-    // Tree mode is separate.
-    if (tree_) {
-      if (all_) {
-        // Show all tree deps with no eliding.
-        RecursivePrintDeps(res.get(), target_, nullptr, 0);
-      } else {
-        // Don't recurse into duplicates.
-        std::set<const Target*> seen_targets;
-        RecursivePrintDeps(res.get(), target_, &seen_targets, 0);
-      }
-    } else {  // not tree
-
-      // Collect the deps to display.
-      if (all_) {
-        // Show all dependencies.
-        std::set<const Target*> all_deps;
-        RecursiveCollectChildDeps(target_, &all_deps);
-        commands::FilterAndPrintTargetSet(all_deps, res.get());
-      } else {
-        // Show direct dependencies only.
-        std::vector<const Target*> deps;
-        for (const auto& pair : target_->GetDeps(Target::DEPS_ALL))
-          deps.push_back(pair.ptr);
-        std::sort(deps.begin(), deps.end());
-        commands::FilterAndPrintTargets(&deps, res.get());
-      }
-    }
-
-    return std::move(res);
-  }
-
-  ValuePtr RenderRuntimeDeps() {
-    auto res = base::WrapUnique(new base::ListValue());
-
-    const Target* previous_from = NULL;
-    for (const auto& pair : ComputeRuntimeDeps(target_)) {
-      std::string str;
-      if (blame_) {
-        // Generally a target's runtime deps will be listed sequentially, so
-        // group them and don't duplicate the "from" label for two in a row.
-        if (previous_from == pair.second) {
-          str = "  ";
-        } else {
-          previous_from = pair.second;
-          res->AppendString(
-              str + "From " +
-              pair.second->label().GetUserVisibleName(GetToolchainLabel()));
-          str = "  ";
-        }
-      }
-
-      res->AppendString(str + pair.first.value());
-    }
-
-    return std::move(res);
-  }
-
-  void FillInSourceOutputs(base::DictionaryValue* res) {
-    auto dict = base::WrapUnique(new base::DictionaryValue());
-    for (const auto& source : target_->sources()) {
-      std::vector<OutputFile> outputs;
-      Toolchain::ToolType tool_type = Toolchain::TYPE_NONE;
-      if (target_->GetOutputFilesForSource(source, &tool_type, &outputs)) {
-        auto list = base::WrapUnique(new base::ListValue());
-        for (const auto& output : outputs)
-          list->AppendString(output.value());
-
-        dict->SetWithoutPathExpansion(source.value(), std::move(list));
-      }
-    }
-    res->Set("source_outputs", std::move(dict));
-  }
-
-  void FillInBundle(base::DictionaryValue* res) {
-    auto data = base::WrapUnique(new base::DictionaryValue());
-    const BundleData& bundle_data = target_->bundle_data();
-    const Settings* settings = target_->settings();
-    BundleData::SourceFiles sources;
-    bundle_data.GetSourceFiles(&sources);
-    data->Set("source_files", RenderValue(sources));
-    data->SetString("root_dir_output",
-                    bundle_data.GetBundleRootDirOutput(settings).value());
-    data->Set("root_dir", RenderValue(bundle_data.root_dir()));
-    data->Set("resources_dir", RenderValue(bundle_data.resources_dir()));
-    data->Set("executable_dir", RenderValue(bundle_data.executable_dir()));
-    data->Set("plugins_dir", RenderValue(bundle_data.plugins_dir()));
-    data->SetString("product_type", bundle_data.product_type());
-
-    auto deps = base::WrapUnique(new base::ListValue());
-    for (const auto* dep : bundle_data.bundle_deps())
-      deps->AppendString(dep->label().GetUserVisibleName(GetToolchainLabel()));
-
-    data->Set("deps", std::move(deps));
-    res->Set("bundle_data", std::move(data));
-  }
-
-  void FillInOutputs(base::DictionaryValue* res) {
-    if (target_->output_type() == Target::ACTION) {
-      auto list = base::WrapUnique(new base::ListValue());
-      for (const auto& elem : target_->action_values().outputs().list())
-        list->AppendString(elem.AsString());
-
-      res->Set(variables::kOutputs, std::move(list));
-    } else if (target_->output_type() == Target::CREATE_BUNDLE) {
-      std::vector<SourceFile> output_files;
-      target_->bundle_data().GetOutputsAsSourceFiles(target_->settings(),
-                                                     &output_files);
-      res->Set(variables::kOutputs, RenderValue(output_files));
-    } else if (target_->output_type() == Target::ACTION_FOREACH ||
-               target_->output_type() == Target::COPY_FILES) {
-      const SubstitutionList& outputs = target_->action_values().outputs();
-      if (!outputs.required_types().empty()) {
-        auto patterns = base::WrapUnique(new base::ListValue());
-        for (const auto& elem : outputs.list())
-          patterns->AppendString(elem.AsString());
-
-        res->Set("output_patterns", std::move(patterns));
-      }
-      std::vector<SourceFile> output_files;
-      SubstitutionWriter::ApplyListToSources(target_->settings(), outputs,
-                                             target_->sources(), &output_files);
-      res->Set(variables::kOutputs, RenderValue(output_files));
-    } else {
-      DCHECK(target_->IsBinary());
-      const Tool* tool =
-          target_->toolchain()->GetToolForTargetFinalOutput(target_);
-
-      std::vector<OutputFile> output_files;
-      SubstitutionWriter::ApplyListToLinkerAsOutputFile(
-          target_, tool, tool->outputs(), &output_files);
-      std::vector<SourceFile> output_files_as_source_file;
-      for (const OutputFile& output_file : output_files)
-        output_files_as_source_file.push_back(
-            output_file.AsSourceFile(target_->settings()->build_settings()));
-
-      res->Set(variables::kOutputs, RenderValue(output_files_as_source_file));
-    }
-  }
-
-  // Writes a given config value type to the string, optionally with
-  // attribution.
-  // This should match RecursiveTargetConfigToStream in the order it traverses.
-  template <class T>
-  ValuePtr RenderConfigValues(const std::vector<T>& (ConfigValues::*getter)()
-                                  const) {
-    auto res = base::WrapUnique(new base::ListValue());
-    for (ConfigValuesIterator iter(target_); !iter.done(); iter.Next()) {
-      const std::vector<T>& vec = (iter.cur().*getter)();
-
-      if (vec.empty())
-        continue;
-
-      if (blame_) {
-        const Config* config = iter.GetCurrentConfig();
-        if (config) {
-          // Source of this value is a config.
-          std::string from =
-              "From " + config->label().GetUserVisibleName(false);
-          res->AppendString(from);
-          if (iter.origin()) {
-            Location location = iter.origin()->GetRange().begin();
-            from = "     (Added by " + location.file()->name().value() + ":" +
-                   base::IntToString(location.line_number()) + ")";
-            res->AppendString(from);
-          }
-        } else {
-          // Source of this value is the target itself.
-          std::string from =
-              "From " + target_->label().GetUserVisibleName(false);
-          res->AppendString(from);
-        }
-      }
-
-      for (const T& val : vec) {
-        ValuePtr rendered = RenderValue(val);
-        std::string str;
-        // Indent string values in blame mode
-        if (blame_ && rendered->GetAsString(&str)) {
-          str = "  " + str;
-          rendered = base::WrapUnique(new base::StringValue(str));
-        }
-        res->Append(std::move(rendered));
-      }
-    }
-    return res->empty() ? nullptr : std::move(res);
-  }
-
-  Label GetToolchainLabel() const override {
-    return target_->label().GetToolchainLabel();
-  }
-
-  const Target* target_;
-};
-
-}  // namespace
-
-std::unique_ptr<base::DictionaryValue> DescBuilder::DescriptionForTarget(
-    const Target* target,
-    const std::string& what,
-    bool all,
-    bool tree,
-    bool blame) {
-  std::set<std::string> w;
-  if (!what.empty())
-    w.insert(what);
-  TargetDescBuilder b(target, w, all, tree, blame);
-  return b.BuildDescription();
-}
-
-std::unique_ptr<base::DictionaryValue> DescBuilder::DescriptionForConfig(
-    const Config* config,
-    const std::string& what) {
-  std::set<std::string> w;
-  if (!what.empty())
-    w.insert(what);
-  ConfigDescBuilder b(config, w);
-  return b.BuildDescription();
-}
diff --git a/tools/gn/desc_builder.h b/tools/gn/desc_builder.h
deleted file mode 100644
index 1f0c395..0000000
--- a/tools/gn/desc_builder.h
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef TOOLS_GN_DESC_BUILDER_H_
-#define TOOLS_GN_DESC_BUILDER_H_
-
-#include "base/values.h"
-#include "tools/gn/target.h"
-
-class DescBuilder {
- public:
-  // Creates Dictionary representation for given target
-  static std::unique_ptr<base::DictionaryValue> DescriptionForTarget(
-      const Target* target,
-      const std::string& what,
-      bool all,
-      bool tree,
-      bool blame);
-
-  // Creates Dictionary representation for given config
-  static std::unique_ptr<base::DictionaryValue> DescriptionForConfig(
-      const Config* config,
-      const std::string& what);
-};
-
-#endif
diff --git a/tools/gn/json_project_writer.cc b/tools/gn/json_project_writer.cc
deleted file mode 100644
index 272a288..0000000
--- a/tools/gn/json_project_writer.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "tools/gn/json_project_writer.h"
-
-#include <iostream>
-
-#include "base/command_line.h"
-#include "base/json/json_writer.h"
-#include "base/memory/ptr_util.h"
-#include "base/strings/string_number_conversions.h"
-#include "tools/gn/builder.h"
-#include "tools/gn/commands.h"
-#include "tools/gn/deps_iterator.h"
-#include "tools/gn/desc_builder.h"
-#include "tools/gn/exec_process.h"
-#include "tools/gn/filesystem_utils.h"
-#include "tools/gn/settings.h"
-
-// Structure of JSON output file
-// {
-//   "build_settings" = {
-//     "root_path" : "absolute path of project root",
-//     "build_dir" : "build directory (project relative)",
-//     "default_toolchain" : "name of default toolchain"
-//   }
-//   "targets" = {
-//      "target x name" : { target x properties },
-//      "target y name" : { target y properties },
-//      ...
-//    }
-// }
-// See desc_builder.cc for overview of target properties
-
-namespace {
-
-void AddTargetDependencies(const Target* target,
-                           std::set<const Target*>* deps) {
-  for (const auto& pair : target->GetDeps(Target::DEPS_LINKED)) {
-    if (deps->find(pair.ptr) == deps->end()) {
-      deps->insert(pair.ptr);
-      AddTargetDependencies(pair.ptr, deps);
-    }
-  }
-}
-
-// Filters targets according to filter string; Will also recursively
-// add dependent targets.
-bool FilterTargets(const BuildSettings* build_settings,
-                   std::vector<const Target*>& all_targets,
-                   std::vector<const Target*>* targets,
-                   const std::string& dir_filter_string,
-                   Err* err) {
-  if (dir_filter_string.empty()) {
-    *targets = all_targets;
-  } else {
-    targets->reserve(all_targets.size());
-    std::vector<LabelPattern> filters;
-    if (!commands::FilterPatternsFromString(build_settings, dir_filter_string,
-                                            &filters, err)) {
-      return false;
-    }
-    commands::FilterTargetsByPatterns(all_targets, filters, targets);
-
-    std::set<const Target*> target_set(targets->begin(), targets->end());
-    for (const auto* target : *targets)
-      AddTargetDependencies(target, &target_set);
-
-    targets->clear();
-    targets->insert(targets->end(), target_set.begin(), target_set.end());
-  }
-
-  // Sort the list of targets per-label to get a consistent ordering of them
-  // in the generated project (and thus stability of the file generated).
-  std::sort(targets->begin(), targets->end(),
-            [](const Target* a, const Target* b) {
-              return a->label().name() < b->label().name();
-            });
-
-  return true;
-}
-
-std::string RenderJSON(const BuildSettings* build_settings,
-                       const Builder* builder,
-                       std::vector<const Target*>& all_targets) {
-  Label default_toolchain_label;
-
-  auto targets = base::WrapUnique(new base::DictionaryValue());
-  for (const auto* target : all_targets) {
-    if (default_toolchain_label.is_null())
-      default_toolchain_label = target->settings()->default_toolchain_label();
-    auto description =
-        DescBuilder::DescriptionForTarget(target, "", false, false, false);
-    // Outputs need to be asked for separately.
-    auto outputs = DescBuilder::DescriptionForTarget(target, "source_outputs",
-                                                     false, false, false);
-    base::DictionaryValue* outputs_value = nullptr;
-    if (outputs->GetDictionary("source_outputs", &outputs_value) &&
-        !outputs_value->empty()) {
-      description->MergeDictionary(outputs.get());
-    }
-    targets->Set(target->label().GetUserVisibleName(default_toolchain_label),
-                 std::move(description));
-  }
-
-  auto settings = base::WrapUnique(new base::DictionaryValue());
-  settings->SetString("root_path", build_settings->root_path_utf8());
-  settings->SetString("build_dir", build_settings->build_dir().value());
-  settings->SetString("default_toolchain",
-                      default_toolchain_label.GetUserVisibleName(false));
-
-  auto output = base::WrapUnique(new base::DictionaryValue());
-  output->Set("targets", std::move(targets));
-  output->Set("build_settings", std::move(settings));
-
-  std::string s;
-  base::JSONWriter::WriteWithOptions(
-      *output.get(), base::JSONWriter::OPTIONS_PRETTY_PRINT, &s);
-  return s;
-}
-
-bool InvokePython(const BuildSettings* build_settings,
-                  const base::FilePath& python_script_path,
-                  const std::string& python_script_extra_args,
-                  const base::FilePath& output_path,
-                  bool quiet,
-                  Err* err) {
-  const base::FilePath& python_path = build_settings->python_path();
-  base::CommandLine cmdline(python_path);
-  cmdline.AppendArg("--");
-  cmdline.AppendArgPath(python_script_path);
-  cmdline.AppendArgPath(output_path);
-  if (!python_script_extra_args.empty()) {
-    cmdline.AppendArg(python_script_extra_args);
-  }
-  base::FilePath startup_dir =
-      build_settings->GetFullPath(build_settings->build_dir());
-
-  std::string output;
-  std::string stderr_output;
-
-  int exit_code = 0;
-  if (!internal::ExecProcess(cmdline, startup_dir, &output, &stderr_output,
-                             &exit_code)) {
-    *err =
-        Err(Location(), "Could not execute python.",
-            "I was trying to execute \"" + FilePathToUTF8(python_path) + "\".");
-    return false;
-  }
-
-  if (!quiet) {
-    std::cout << output;
-    std::cerr << stderr_output;
-  }
-
-  if (exit_code != 0) {
-    *err = Err(Location(), "Python has quit with exit code " +
-                               base::IntToString(exit_code) + ".");
-    return false;
-  }
-
-  return true;
-}
-
-}  // namespace
-
-bool JSONProjectWriter::RunAndWriteFiles(
-    const BuildSettings* build_settings,
-    const Builder* builder,
-    const std::string& file_name,
-    const std::string& exec_script,
-    const std::string& exec_script_extra_args,
-    const std::string& dir_filter_string,
-    bool quiet,
-    Err* err) {
-  SourceFile output_file = build_settings->build_dir().ResolveRelativeFile(
-      Value(nullptr, file_name), err);
-  if (output_file.is_null()) {
-    return false;
-  }
-
-  base::FilePath output_path = build_settings->GetFullPath(output_file);
-
-  std::vector<const Target*> all_targets = builder->GetAllResolvedTargets();
-  std::vector<const Target*> targets;
-  if (!FilterTargets(build_settings, all_targets, &targets, dir_filter_string,
-                     err)) {
-    return false;
-  }
-
-  std::string json = RenderJSON(build_settings, builder, targets);
-  if (!ContentsEqual(output_path, json)) {
-    if (!WriteFileIfChanged(output_path, json, err)) {
-      return false;
-    }
-
-    if (!exec_script.empty()) {
-      SourceFile script_file;
-      if (exec_script[0] != '/') {
-        // Relative path, assume the base is in build_dir.
-        script_file = build_settings->build_dir().ResolveRelativeFile(
-            Value(nullptr, exec_script), err);
-        if (script_file.is_null()) {
-          return false;
-        }
-      } else {
-        script_file = SourceFile(exec_script);
-      }
-      base::FilePath script_path = build_settings->GetFullPath(script_file);
-      return InvokePython(build_settings, script_path, exec_script_extra_args,
-                          output_path, quiet, err);
-    }
-  }
-
-  return true;
-}
diff --git a/tools/gn/json_project_writer.h b/tools/gn/json_project_writer.h
deleted file mode 100644
index e69dc3a..0000000
--- a/tools/gn/json_project_writer.h
+++ /dev/null
@@ -1,26 +0,0 @@
-// Copyright (c) 2016 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef TOOLS_GN_JSON_WRITER_H_
-#define TOOLS_GN_JSON_WRITER_H_
-
-#include "tools/gn/err.h"
-#include "tools/gn/target.h"
-
-class Builder;
-class BuildSettings;
-
-class JSONProjectWriter {
- public:
-  static bool RunAndWriteFiles(const BuildSettings* build_setting,
-                               const Builder* builder,
-                               const std::string& file_name,
-                               const std::string& exec_script,
-                               const std::string& exec_script_extra_args,
-                               const std::string& dir_filter_string,
-                               bool quiet,
-                               Err* err);
-};
-
-#endif
diff --git a/tools/gn/target.cc b/tools/gn/target.cc
index 9851035..aa1fcf6 100644
--- a/tools/gn/target.cc
+++ b/tools/gn/target.cc
@@ -14,7 +14,6 @@
 #include "tools/gn/config_values_extractors.h"
 #include "tools/gn/deps_iterator.h"
 #include "tools/gn/filesystem_utils.h"
-#include "tools/gn/functions.h"
 #include "tools/gn/scheduler.h"
 #include "tools/gn/source_file_type.h"
 #include "tools/gn/substitution_writer.h"
@@ -216,29 +215,29 @@
 const char* Target::GetStringForOutputType(OutputType type) {
   switch (type) {
     case UNKNOWN:
-      return "unknown";
+      return "Unknown";
     case GROUP:
-      return functions::kGroup;
+      return "Group";
     case EXECUTABLE:
-      return functions::kExecutable;
+      return "Executable";
     case LOADABLE_MODULE:
-      return functions::kLoadableModule;
+      return "Loadable module";
     case SHARED_LIBRARY:
-      return functions::kSharedLibrary;
+      return "Shared library";
     case STATIC_LIBRARY:
-      return functions::kStaticLibrary;
+      return "Static library";
     case SOURCE_SET:
-      return functions::kSourceSet;
+      return "Source set";
     case COPY_FILES:
-      return functions::kCopy;
+      return "Copy";
     case ACTION:
-      return functions::kAction;
+      return "Action";
     case ACTION_FOREACH:
-      return functions::kActionForEach;
+      return "ActionForEach";
     case BUNDLE_DATA:
-      return functions::kBundleData;
+      return "Bundle data";
     case CREATE_BUNDLE:
-      return functions::kCreateBundle;
+      return "Create bundle";
     default:
       return "";
   }
diff --git a/tools/gn/visibility.cc b/tools/gn/visibility.cc
index b32586c..a61a5cd 100644
--- a/tools/gn/visibility.cc
+++ b/tools/gn/visibility.cc
@@ -4,10 +4,8 @@
 
 #include "tools/gn/visibility.h"
 
-#include "base/memory/ptr_util.h"
 #include "base/strings/string_piece.h"
 #include "base/strings/string_util.h"
-#include "base/values.h"
 #include "tools/gn/err.h"
 #include "tools/gn/filesystem_utils.h"
 #include "tools/gn/item.h"
@@ -85,14 +83,6 @@
   return result;
 }
 
-std::unique_ptr<base::Value> Visibility::AsValue() const {
-  auto* res = new base::ListValue();
-  for (const auto& pattern : patterns_)
-    res->AppendString(pattern.Describe());
-
-  return WrapUnique(res);
-}
-
 // static
 bool Visibility::CheckItemVisibility(const Item* from,
                                      const Item* to,
@@ -103,7 +93,7 @@
         "The item " + from->label().GetUserVisibleName(false) + "\n"
         "can not depend on " + to_label + "\n"
         "because it is not in " + to_label + "'s visibility list: " +
-                   to->visibility().Describe(0, true));
+        to->visibility().Describe(0, true));
     return false;
   }
   return true;
diff --git a/tools/gn/visibility.h b/tools/gn/visibility.h
index 4228f9d..d6d7f1f 100644
--- a/tools/gn/visibility.h
+++ b/tools/gn/visibility.h
@@ -5,17 +5,12 @@
 #ifndef TOOLS_GN_VISIBILITY_H_
 #define TOOLS_GN_VISIBILITY_H_
 
-#include <memory>
 #include <vector>
 
 #include "base/macros.h"
 #include "tools/gn/label_pattern.h"
 #include "tools/gn/source_dir.h"
 
-namespace base {
-class Value;
-}
-
 class Err;
 class Item;
 class Label;
@@ -48,9 +43,6 @@
   // result will end in a newline.
   std::string Describe(int indent, bool include_brackets) const;
 
-  // Returns value representation of this visibility
-  std::unique_ptr<base::Value> AsValue() const;
-
   // Helper function to check visibility between the given two items. If
   // to is invisible to from, returns false and sets the error.
   static bool CheckItemVisibility(const Item* from, const Item* to, Err* err);
