[
  {
    "path": ".gitignore",
    "content": ".idea*\n*.iml\ntarget\n\n"
  },
  {
    "path": "CHANGELOG.md",
    "content": "v0.5.0: Oct 07 2011\n===================\n\n* Added `canSerialize` and `canDeserialize`.\n* Upgraded Jackson to 1.9.0.\n* Dropped support for Scala 2.8.1, added support for 2.8.2. Upgrade.\n* Dropped support for 2.9.0-1. Upgrade.\n\nv0.4.2: Sep 16 2011\n===================\n\n* Added support for case classes with multiple constructors.\n* Added support for `snake_cased` JSON field names via the `@JsonSnakeCase`\n  annotation.\n\nv0.4.1: Sep 13 2011\n===================\n\n* Added `@JsonIgnoreProperties` support.\n* No longer serializing `transient` members of case classes.\n* Upgraded to Jackson 1.8.x. (Jerkson will now track the highest available\n  version in the 1.8.x series.)\n\n\nv0.4.0: Jul 25 2011\n===================\n\n* Upgraded to Jackson 1.8.3.\n* Fixed deserialization of empty JSON objects as `JValue` instances.\n* Fixed deserialization of `Map[java.lang.Integer, A]` and\n  `Map[java.lang.Long, A]` instances.\n* Fixed deserialization of case classes in weird bytecode environments like\n  Play.\n* Added support for case classes nested in objects.\n* Allowed for deserializing `BigInt` and `BigDecimal` instances from anything\n  those classes can parse as text.\n* Added a cache for type manifests.\n\n\nv0.3.2: Jun 09 2011\n===================\n\n* Added `Json.stream[A](Reader)`.\n* Fix `NullPointerException` when deserializing `Map` instances from weird JSON\n  values.\n\n\nv0.3.1: Jun 05 2011\n===================\n\n* Added support for deserializing `Map[Int, _]` and `Map[Long, _]` instances.\n\n\nv0.3.0: Jun 04 2011\n===================\n* Added a very comprehensive set of tests, refactored around support for various\n  types. (h/t Daniel Brown)\n* Added support for `StringBuilder`, `Array[A]`, `immutable._`, `mutable._`,\n  `collection._` classes, `AST` classes, and others.\n* Fixed error messages when parsing empty JSON objects as case classes.\n* Enabled caching of all serializers and deserializers.\n* Switched to Maven for builds.\n* Removed the deprecated `Parser#parseStreamOf`.\n\n\nv0.2.2: May 18 2011\n===================\n\n* Upgraded to Jackson 1.7.7.\n* Fixed bugs in parsing case classes with other specially-namespaced types.\n\n\nv0.2.1: May 12 2011\n===================\n\n* Fixed bug in parsing case classes with `List[A]` members (and anything else\n  which is typed in the `scala` package.\n\n\nv0.2.0: May 12 2011\n===================\n\n* Now cross-built for Scala 2.9.0.\n* Changed to parse the embedded Scala signature in case classes by using an\n  embedded version of `scalap`. No longer depends on Paranamer.\n* Serializing a case class with a `None` field now elides the entire field\n  instead of serializing the `Option[A]` as `null`.\n* Removed explicit flushes to output.\n\n\nv0.1.8: May 05 2011\n===================\n\n* Upgraded to Jackson 1.7.6.\n* Added selectors to `JValue` and friends.\n* Extracted out the `Json` trait for extensibility.\n* Added support for `Iterator` and `Set` instances.\n* Fixed deserialization of empty `Map`s.\n\n\nv0.1.7: Mar 31 2011\n===================\n\n* Upgraded to Jackson 1.7.4.\n\n\nv0.1.6: Feb 18 2011\n===================\n\n* Serialize `None` instances to `null`. (h/t Alex Cruise again)\n\n\nv0.1.5: Feb 18 2011\n===================\n\n* Added ability to actually serialize `Option` instances. (h/t Alex Cruise)\n\n\nv0.1.4: Jan 17 2011\n===================\n\n* Upgraded to Jackson 1.7.1, which fixes the buffer overruns\n* Handle empty JSON documents w/o resorting to `EOFException`\n\n\nv0.1.3: Jan 12 2011\n===================\n\n* Quick fix for potential buffer overrun errors in huge case classes (JACKSON-462).\n\n\nv0.1.2: Jan 07 2011\n===================\n\n* Upgraded to [Jackson 1.7.0](http://jackson.codehaus.org/1.7.0/release-notes/VERSION).\n* Added support for `Either[A, B]` instances.\n* Internal refactoring of `Json`.\n\n\nv0.1.1: Dec 09 2010\n===================\n\n* Upgraded to [Jackson 1.6.3](http://jackson.codehaus.org/1.6.3/release-notes/VERSION).\n* Added `StreamingIterator`, `Json.stream`, and deprecated `Json.parseStreamOf`.\n* Fixed support for `lazy` `val` and `var` members of case classes.\n* Added support for `@JsonIgnore` for case classes.\n\n\nv0.1.0: Dec 03 2010\n===================\n\n* Initial release. Totally awesome.\n"
  },
  {
    "path": "LICENSE.md",
    "content": "Copyright (c) 2010-2011 Coda Hale\n\nPermission is hereby granted, free of charge, to any person obtaining\na copy of this software and associated documentation files (the\n\"Software\"), to deal in the Software without restriction, including\nwithout limitation the rights to use, copy, modify, merge, publish,\ndistribute, sublicense, and/or sell copies of the Software, and to\npermit persons to whom the Software is furnished to do so, subject to\nthe following conditions:\n\nThe above copyright notice and this permission notice shall be\nincluded in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\nEXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\nMERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\nNONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\nLIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\nOF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\nWITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "Jerkson\n-------\n\n*Because I think you should use JSON.*\n\nJerkson is a Scala wrapper for [Jackson](http://jackson.codehaus.org/) which\nbrings Scala's ease-of-use to Jackson's features.\n\n\nRequirements\n------------\n\n* Scala 2.8.2 or 2.9.1\n* Jackson 1.9.x\n\n\nSetting Up Your Project\n-----------------------\n\nGo ahead and add Jerkson as a dependency:\n\n```xml\n<repositories>\n  <repository>\n    <id>repo.codahale.com</id>\n    <url>http://repo.codahale.com</url>\n  </repository>\n</repositories>\n\n<dependencies>\n  <dependency>\n    <groupId>com.codahale</groupId>\n    <artifactId>jerkson_${scala.version}</artifactId>\n    <version>0.5.0</version>\n  </dependency>\n</dependencies>\n```\n\n\nParsing JSON\n------------\n\n```scala\nimport com.codahale.jerkson.Json._\n\n// Parse JSON arrays\nparse[List[Int]](\"[1,2,3]\") //=> List(1,2,3)\n\n// Parse JSON objects\nparse[Map[String, Int]](\"\"\"{\"one\":1,\"two\":2}\"\"\") //=> Map(\"one\"->1,\"two\"->2)\n\n// Parse JSON objects as case classes\n// (Parsing case classes isn't supported in the REPL.)\ncase class Person(id: Long, name: String)\nparse[Person](\"\"\"{\"id\":1,\"name\":\"Coda\"}\"\"\") //=> Person(1,\"Coda\")\n\n// Parse streaming arrays of things\nfor (person <- stream[Person](inputStream)) {\n  println(\"New person: \" + person)\n}\n```\n\nFor more examples, check out the [specs](https://github.com/codahale/jerkson/blob/master/src/test/scala/com/codahale/jerkson/tests/).\n\n\nGenerating JSON\n---------------\n\n```scala\n// Generate JSON arrays\ngenerate(List(1, 2, 3)) //=> [1,2,3]\n\n// Generate JSON objects\ngenerate(Map(\"one\"->1, \"two\"->\"dos\")) //=> {\"one\":1,\"two\":\"dos\"}\n```\n\nFor more examples, check out the [specs](https://github.com/codahale/jerkson/blob/master/src/test/scala/com/codahale/jerkson/tests/).\n\n\nHandling `snake_case` Field Names\n=================================\n\n```scala\ncase class Person(firstName: String, lastName: String)\n\n@JsonSnakeCase\ncase class Snake(firstName: String, lastName: String)\n\ngenerate(Person(\"Coda\", \"Hale\"))   //=> {\"firstName\": \"Coda\",\"lastName\":\"Hale\"}\ngenerate(Snake(\"Windey\", \"Mover\")) //=> {\"first_name\": \"Windey\",\"last_name\":\"Mover\"}\n```\n\n\nLicense\n-------\n\nCopyright (c) 2010-2011 Coda Hale\n\nPublished under The MIT License, see LICENSE\n"
  },
  {
    "path": "pom.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project xmlns=\"http://maven.apache.org/POM/4.0.0\"\n         xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n         xsi:schemaLocation=\"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd\">\n    <modelVersion>4.0.0</modelVersion>\n\n    <prerequisites>\n        <maven>3.0.0</maven>\n    </prerequisites>\n\n    <groupId>com.codahale</groupId>\n    <artifactId>jerkson_2.9.1</artifactId>\n    <version>0.6.0-SNAPSHOT</version>\n    <name>Jerkson for Scala</name>\n\n    <properties>\n        <scala.version>2.9.1</scala.version>\n        <jackson.version>2.0.2</jackson.version>\n    </properties>\n\n    <developers>\n        <developer>\n            <name>Coda Hale</name>\n            <email>coda.hale@gmail.com</email>\n            <timezone>-8</timezone>\n        </developer>\n    </developers>\n\n    <licenses>\n        <license>\n            <url>http://codahale.com/mit.txt</url>\n            <name>The MIT License</name>\n            <distribution>repo</distribution>\n        </license>\n    </licenses>\n\n    <repositories>\n        <repository>\n            <id>repo.codahale.com</id>\n            <url>http://repo.codahale.com</url>\n        </repository>\n        <repository>\n            <id>nativelibs4java</id>\n            <url>http://nativelibs4java.sourceforge.net/maven</url>\n        </repository>\n    </repositories>\n\n    <distributionManagement>\n        <repository>\n            <id>repo.codahale.com</id>\n            <url>scp://codahale.com/home/codahale/repo.codahale.com</url>\n        </repository>\n    </distributionManagement>\n\n    <dependencies>\n        <dependency>\n            <groupId>org.scala-lang</groupId>\n            <artifactId>scala-library</artifactId>\n            <version>${scala.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.core</groupId>\n            <artifactId>jackson-core</artifactId>\n            <version>${jackson.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.fasterxml.jackson.core</groupId>\n            <artifactId>jackson-databind</artifactId>\n            <version>${jackson.version}</version>\n        </dependency>\n        <dependency>\n            <groupId>com.codahale</groupId>\n            <artifactId>simplespec_${scala.version}</artifactId>\n            <version>0.5.2</version>\n            <scope>test</scope>\n        </dependency>\n    </dependencies>\n\n    <profiles>\n        <profile>\n            <id>release-sign-artifacts</id>\n            <activation>\n                <property>\n                    <name>performRelease</name>\n                    <value>true</value>\n                </property>\n            </activation>\n            <build>\n                <plugins>\n                    <plugin>\n                        <groupId>org.apache.maven.plugins</groupId>\n                        <artifactId>maven-gpg-plugin</artifactId>\n                        <version>1.2</version>\n                        <executions>\n                            <execution>\n                                <id>sign-artifacts</id>\n                                <phase>verify</phase>\n                                <goals>\n                                    <goal>sign</goal>\n                                </goals>\n                            </execution>\n                        </executions>\n                    </plugin>\n                </plugins>\n            </build>\n        </profile>\n    </profiles>\n\n    <build>\n        <plugins>\n            <plugin>\n                <groupId>org.scala-tools</groupId>\n                <artifactId>maven-scala-plugin</artifactId>\n                <version>2.15.2</version>\n                <executions>\n                    <execution>\n                        <goals>\n                            <goal>compile</goal>\n                            <goal>testCompile</goal>\n                        </goals>\n                    </execution>\n                </executions>\n                <configuration>\n                    <args>\n                        <arg>-optimise</arg>\n                        <arg>-unchecked</arg>\n                        <arg>-deprecation</arg>\n                    </args>\n                    <compilerPlugins>\n                        <compilerPlugin>\n                            <groupId>com.nativelibs4java</groupId>\n                            <artifactId>scalacl-compiler-plugin</artifactId>\n                            <version>0.2</version>\n                        </compilerPlugin>\n                    </compilerPlugins>\n                    <charset>UTF-8</charset>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-compiler-plugin</artifactId>\n                <version>2.3.2</version>\n                <configuration>\n                    <source>1.6</source>\n                    <target>1.6</target>\n                    <encoding>UTF-8</encoding>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-source-plugin</artifactId>\n                <version>2.1.2</version>\n                <executions>\n                    <execution>\n                        <id>attach-sources</id>\n                        <goals>\n                            <goal>jar</goal>\n                        </goals>\n                    </execution>\n                </executions>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-resources-plugin</artifactId>\n                <version>2.5</version>\n                <configuration>\n                    <encoding>UTF-8</encoding>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-surefire-plugin</artifactId>\n                <version>2.8.1</version>\n                <configuration>\n                    <useSystemClassLoader>false</useSystemClassLoader>\n                    <argLine>-Xmx1024m</argLine>\n                    <includes>\n                        <include>**/*Spec.java</include>\n                    </includes>\n                    <excludes>\n                        <exclude>**/*Test.java</exclude>\n                    </excludes>\n                </configuration>\n            </plugin>\n            <plugin>\n                <groupId>org.apache.maven.plugins</groupId>\n                <artifactId>maven-release-plugin</artifactId>\n                <version>2.2.1</version>\n                <configuration>\n                    <autoVersionSubmodules>true</autoVersionSubmodules>\n                    <mavenExecutorId>forked-path</mavenExecutorId>\n                    <tagNameFormat>v@{project.version}</tagNameFormat>\n                    <preparationGoals>clean test</preparationGoals>\n                </configuration>\n            </plugin>\n        </plugins>\n        <extensions>\n            <extension>\n                <groupId>org.apache.maven.wagon</groupId>\n                <artifactId>wagon-ssh</artifactId>\n                <version>2.2</version>\n            </extension>\n        </extensions>\n    </build>\n</project>\n"
  },
  {
    "path": "src/main/java/com/codahale/jerkson/JsonSnakeCase.java",
    "content": "package com.codahale.jerkson;\n\nimport com.fasterxml.jackson.annotation.JacksonAnnotation;\n\nimport java.lang.annotation.ElementType;\nimport java.lang.annotation.Retention;\nimport java.lang.annotation.RetentionPolicy;\nimport java.lang.annotation.Target;\n\n/**\n * Marker annotation which indicates that the annotated case class should be\n * serialized and deserialized using {@code snake_case} JSON field names instead\n * of {@code camelCase} field names.\n */\n@Target({ElementType.TYPE})\n@Retention(RetentionPolicy.RUNTIME)\n@JacksonAnnotation\npublic @interface JsonSnakeCase {\n    \n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/AST.scala",
    "content": "package com.codahale.jerkson\n\nobject AST {\n  sealed trait JValue {\n    def value: Any\n    \n    def valueAs[A]: A = value.asInstanceOf[A]\n    \n    def \\(fieldName: String): JValue = JNull\n    \n    def apply(idx: Int): JValue = JNull\n    \n    def \\\\(fieldName: String): Seq[JValue] = Nil\n  }\n\n  case object JNull extends JValue {\n    def value = null\n  }\n\n  case class JBoolean(value: Boolean) extends JValue\n\n  case class JInt(value: BigInt) extends JValue\n\n  case class JFloat(value: Double) extends JValue\n\n  case class JString(value: String) extends JValue\n\n  case class JArray(elements: List[JValue]) extends JValue {\n    def value = null\n    \n    override def apply(index: Int): JValue = {\n      try {\n        elements(index)\n      } catch {\n        case _ => JNull\n      }\n    }\n  }\n\n  case class JField(name: String, value: JValue) extends JValue\n\n  case class JObject(fields: List[JField]) extends JValue {\n    def value = null\n    \n    override def \\(fieldName: String): JValue = {\n      fields.find { case JField(name, _) =>\n        name == fieldName\n      }.map { case JField(_, value) =>\n        value\n      }.getOrElse(JNull)\n    }\n    \n    override def \\\\(fieldName: String): Seq[JValue] = {\n      fields.flatMap { \n        case JField(name, value) if name == fieldName => Seq(value) ++ (value \\\\ fieldName)\n        case JField(_, value) => value \\\\ fieldName\n      }\n    }\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/Factory.scala",
    "content": "package com.codahale.jerkson\n\nimport com.fasterxml.jackson.core.JsonFactory\nimport com.fasterxml.jackson.databind.ObjectMapper\n\ntrait Factory {\n  /**\n   * The ObjectMapper to be used by {@link Parser} and {@link Generator}.\n   */\n  protected val mapper: ObjectMapper\n\n  /**\n   * The JsonFactory to be used by {@link Parser} and {@link Generator}.\n   */\n  protected val factory: JsonFactory\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/Generator.scala",
    "content": "package com.codahale.jerkson\n\nimport java.io.{File, OutputStream, Writer, StringWriter}\nimport com.fasterxml.jackson.core.{JsonGenerator, JsonEncoding}\n\ntrait Generator extends Factory {\n  /**\n   * Generate JSON from the given object and return it as a string.\n   */\n  def generate[A](obj: A): String = {\n    val writer = new StringWriter\n    generate(obj, writer)\n    writer.toString\n  }\n\n  /**\n   * Generate JSON from the given object and write to the given Writer.\n   */\n  def generate[A](obj: A, output: Writer) {\n    generate(obj, factory.createJsonGenerator(output))\n  }\n\n  /**\n   * Generate JSON from the given object and write it to the given OutputStream.\n   */\n  def generate[A](obj: A, output: OutputStream) {\n    generate(obj, factory.createJsonGenerator(output, JsonEncoding.UTF8))\n  }\n\n  /**\n   * Generate JSON from the given object and write it to the given File.\n   */\n  def generate[A](obj: A, output: File) {\n    generate(obj, factory.createJsonGenerator(output, JsonEncoding.UTF8))\n  }\n\n  /**\n   * Returns true if the given class is serializable.\n   */\n  def canSerialize[A](implicit mf: Manifest[A]) = mapper.canSerialize(mf.erasure)\n\n  private def generate[A](obj: A, generator: JsonGenerator) {\n    generator.writeObject(obj)\n    generator.close()\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/Json.scala",
    "content": "package com.codahale.jerkson\n\nimport com.fasterxml.jackson.databind.{MappingJsonFactory, ObjectMapper}\nimport com.fasterxml.jackson.core.{JsonGenerator, JsonParser => JacksonParser}\n\nobject Json extends Json\n\ntrait Json extends Parser with Generator {\n  protected val classLoader = Thread.currentThread().getContextClassLoader\n\n  protected val mapper = new ObjectMapper\n  mapper.registerModule(new ScalaModule(classLoader))\n\n  protected val factory = new MappingJsonFactory(mapper)\n  factory.enable(JsonGenerator.Feature.AUTO_CLOSE_JSON_CONTENT)\n  factory.enable(JsonGenerator.Feature.AUTO_CLOSE_TARGET)\n  factory.enable(JsonGenerator.Feature.QUOTE_FIELD_NAMES)\n  factory.enable(JacksonParser.Feature.ALLOW_COMMENTS)\n  factory.enable(JacksonParser.Feature.AUTO_CLOSE_SOURCE)\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/Parser.scala",
    "content": "package com.codahale.jerkson\n\nimport io.Source\nimport java.net.URL\nimport com.codahale.jerkson.AST.{JValue, JNull}\nimport com.fasterxml.jackson.core.{JsonParser, JsonProcessingException}\nimport com.fasterxml.jackson.databind.JsonNode\nimport com.fasterxml.jackson.databind.node.TreeTraversingParser\nimport java.io.{EOFException, Reader, File, InputStream}\n\ntrait Parser extends Factory {\n  /**\n   * Parse a JSON string as a particular type.\n   */\n  def parse[A](input: String)(implicit mf: Manifest[A]): A = parse[A](factory.createJsonParser(input), mf)\n\n  /**\n   * Parse a JSON input stream as a particular type.\n   */\n  def parse[A](input: InputStream)(implicit mf: Manifest[A]): A = parse[A](factory.createJsonParser(input), mf)\n\n  /**\n   * Parse a JSON file as a particular type.\n   */\n  def parse[A](input: File)(implicit mf: Manifest[A]): A = parse[A](factory.createJsonParser(input), mf)\n\n  /**\n   * Parse a JSON URL as a particular type.\n   */\n  def parse[A](input: URL)(implicit mf: Manifest[A]): A = parse[A](factory.createJsonParser(input), mf)\n\n  /**\n   * Parse a JSON Reader as a particular type.\n   */\n  def parse[A](input: Reader)(implicit mf: Manifest[A]): A = parse[A](factory.createJsonParser(input), mf)\n\n  /**\n   * Parse a JSON byte array as a particular type.\n   */\n  def parse[A](input: Array[Byte])(implicit mf: Manifest[A]): A = parse[A](factory.createJsonParser(input), mf)\n\n  /**\n   * Parse a JSON Source as a particular type.\n   */\n  def parse[A](input: Source)(implicit mf: Manifest[A]): A = parse[A](input.mkString)\n\n  /**\n   * Parse a JSON node as a particular type.\n   */\n  def parse[A](input: JsonNode)(implicit mf: Manifest[A]): A = {\n    val parser = new TreeTraversingParser(input, mapper)\n    parse(parser, mf)\n  }\n\n  /**\n   * Parse a streaming JSON array of particular types, returning an iterator\n   * of the elements of the stream.\n   */\n  def stream[A](input: InputStream)(implicit mf: Manifest[A]): Iterator[A] = {\n    val parser = factory.createJsonParser(input)\n    new StreamingIterator[A](parser, mf)\n  }\n\n  /**\n   * Parse a streaming JSON array of particular types, returning an iterator\n   * of the elements of the stream.\n   */\n  def stream[A](input: Reader)(implicit mf: Manifest[A]): Iterator[A] = {\n    val parser = factory.createJsonParser(input)\n    new StreamingIterator[A](parser, mf)\n  }\n\n  /**\n   * Returns true if the given class is deserializable.\n   */\n  def canDeserialize[A](implicit mf: Manifest[A]) = mapper.canDeserialize(Types.build(mapper.getTypeFactory, mf))\n\n  private[jerkson] def parse[A](parser: JsonParser, mf: Manifest[A]): A = {\n    try {\n      if (mf.erasure == classOf[JValue] || mf.erasure == JNull.getClass) {\n        val value: A = parser.getCodec.readValue(parser, Types.build(mapper.getTypeFactory, mf))\n        if (value == null) JNull.asInstanceOf[A] else value\n      } else {\n        parser.getCodec.readValue(parser, Types.build(mapper.getTypeFactory, mf))\n      }\n    } catch {\n      case e: JsonProcessingException => throw ParsingException(e)\n      case e: EOFException => throw new ParsingException(\"JSON document ended unexpectedly.\", e)\n    }\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/ParsingException.scala",
    "content": "package com.codahale.jerkson\n\nimport java.io.IOException\nimport com.fasterxml.jackson.databind.JsonMappingException\nimport com.fasterxml.jackson.core.{JsonParseException, JsonProcessingException}\n\nobject ParsingException {\n  def apply(cause: JsonProcessingException): ParsingException = {\n    val message = cause match {\n      case e: JsonMappingException => e.getMessage\n      case e: JsonParseException => {\n        val fake = new JsonParseException(\"\", e.getLocation)\n        val msg = e.getMessage.replace(fake.getMessage, \"\").replaceAll(\"\"\" (\\(from.*\\))\"\"\", \"\")\n        \"Malformed JSON. %s at character offset %d.\".format(msg, e.getLocation.getCharOffset)\n      }\n    }\n    new ParsingException(message, cause)\n  }\n}\n\nclass ParsingException(message: String, cause: Throwable)\n        extends IOException(message, cause)\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/ScalaModule.scala",
    "content": "package com.codahale.jerkson\n\nimport deser.ScalaDeserializers\nimport com.fasterxml.jackson.databind.Module.SetupContext\nimport com.fasterxml.jackson.core.Version\nimport com.fasterxml.jackson.databind.Module\nimport ser.ScalaSerializers\n\nclass ScalaModule(classLoader: ClassLoader) extends Module {\n  def version = new Version(0, 6, 0, \"SNAPSHOT\", \"com.codahale\", \"jerkson\")\n  def getModuleName = \"jerkson\"\n\n  def setupModule(context: SetupContext) {\n    context.addDeserializers(new ScalaDeserializers(classLoader, context))\n    context.addSerializers(new ScalaSerializers)\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/StreamingIterator.scala",
    "content": "package com.codahale.jerkson\n\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\n\nclass StreamingIterator[A](parser: JsonParser, mf: Manifest[A])\n        extends Iterator[A] {\n\n  import Json._\n\n  if (parser.getCurrentToken == null) {\n    parser.nextToken()\n  }\n  require(parser.getCurrentToken == JsonToken.START_ARRAY)\n  parser.nextToken()\n\n  def hasNext = parser.getCurrentToken != JsonToken.END_ARRAY && !parser.isClosed\n\n  def next() = if (hasNext) {\n    val value = parse[A](parser, mf)\n    parser.nextToken()\n    value\n  } else Iterator.empty.next()\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/Types.scala",
    "content": "package com.codahale.jerkson\n\nimport com.fasterxml.jackson.databind.JavaType\nimport com.fasterxml.jackson.databind.`type`.{TypeFactory, ArrayType}\nimport scala.collection.JavaConversions.asScalaConcurrentMap\nimport java.util.concurrent.ConcurrentHashMap\n\nprivate[jerkson] object Types {\n  private val cachedTypes = asScalaConcurrentMap(new ConcurrentHashMap[Manifest[_], JavaType]())\n\n  def build(factory: TypeFactory, manifest: Manifest[_]): JavaType =\n    cachedTypes.getOrElseUpdate(manifest, constructType(factory, manifest))\n\n  private def constructType(factory: TypeFactory, manifest: Manifest[_]): JavaType = {\n    if (manifest.erasure.isArray) {\n      ArrayType.construct(factory.constructType(manifest.erasure.getComponentType), null, null)\n    } else {\n      factory.constructParametricType(\n        manifest.erasure,\n        manifest.typeArguments.map {m => build(factory, m)}.toArray: _*)\n    }\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/Util.scala",
    "content": "package com.codahale.jerkson\n\nprivate[jerkson] object Util {\n  /**\n   * Convert a string from camelCase to snake_case.\n   */\n  def snakeCase(word: String) = {\n    val len = word.length()\n    val builder = new StringBuilder(len)\n    if (len > 0) {\n      var idx = if (word(0) == '_') {\n        // preserve the first underscore\n        builder += '_'\n        1\n      } else 0\n      while (idx < len) {\n        val char = word(idx)\n        if (Character.isUpperCase(char)) {\n          builder += '_'\n          builder += Character.toLowerCase(char)\n        } else {\n          builder += char\n        }\n        idx += 1\n      }\n    }\n    builder.toString()\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/BigDecimalDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}\nimport com.fasterxml.jackson.core.JsonParser\n\nclass BigDecimalDeserializer extends JsonDeserializer[Object] {\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext) = {\n    if (jp.getCurrentToken == null) {\n      jp.nextToken()\n    }\n\n    try {\n      BigDecimal(jp.getText)\n    } catch {\n      case e: NumberFormatException =>\n        throw ctxt.mappingException(classOf[BigDecimal])\n    }\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/BigIntDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}\nimport com.fasterxml.jackson.core.JsonParser\n\nclass BigIntDeserializer extends JsonDeserializer[Object] {\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext) = {\n    if (jp.getCurrentToken == null) {\n      jp.nextToken()\n    }\n\n    try {\n      BigInt(jp.getText)\n    } catch {\n      case e: NumberFormatException =>\n        throw ctxt.mappingException(classOf[BigInt])\n    }\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/BitSetDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport scala.collection.generic.BitSetFactory\nimport scala.collection.{BitSetLike, BitSet}\nimport com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\n\nclass BitSetDeserializer[Coll <: BitSet with BitSetLike[Coll]](factory: BitSetFactory[Coll])\n  extends JsonDeserializer[Coll] {\n\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext) = {\n    val builder = factory.newBuilder\n\n    if (jp.getCurrentToken != JsonToken.START_ARRAY) {\n      throw ctxt.mappingException(classOf[BitSet])\n    }\n\n    while (jp.nextToken() != JsonToken.END_ARRAY) {\n      builder += jp.getIntValue\n    }\n\n    builder.result()\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/CaseClassDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport scala.collection.JavaConversions._\nimport scala.collection.mutable.ArrayBuffer\nimport com.codahale.jerkson.JsonSnakeCase\nimport com.codahale.jerkson.util._\nimport com.codahale.jerkson.Util._\nimport com.fasterxml.jackson.databind._\nimport com.fasterxml.jackson.databind.node.{ObjectNode, NullNode, TreeTraversingParser}\nimport com.fasterxml.jackson.databind.JavaType\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\n\nclass CaseClassDeserializer(config: DeserializationConfig,\n                            javaType: JavaType,\n                            classLoader: ClassLoader) extends JsonDeserializer[Object] {\n  private val isSnakeCase = javaType.getRawClass.isAnnotationPresent(classOf[JsonSnakeCase])\n  private val params = CaseClassSigParser.parse(javaType.getRawClass, config.getTypeFactory, classLoader).map {\n    case (name, jt) => (if (isSnakeCase) snakeCase(name) else name, jt)\n  }.toArray\n  private val paramTypes = params.map { _._2.getRawClass }.toList\n  private val constructor = javaType.getRawClass.getConstructors.find { c =>\n    val constructorTypes = c.getParameterTypes.toList.map { t =>\n      t.toString match {\n        case \"byte\" => classOf[java.lang.Byte]\n        case \"short\" => classOf[java.lang.Short]\n        case \"int\" => classOf[java.lang.Integer]\n        case \"long\" => classOf[java.lang.Long]\n        case \"float\" => classOf[java.lang.Float]\n        case \"double\" => classOf[java.lang.Double]\n        case \"char\" => classOf[java.lang.Character]\n        case \"boolean\" => classOf[java.lang.Boolean]\n        case _ => t\n      }\n    }\n    constructorTypes == paramTypes\n  }.getOrElse { throw new JsonMappingException(\"Unable to find a case accessor for \" + javaType.getRawClass.getName) }\n\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext): Object = {\n    if (jp.getCurrentToken == JsonToken.START_OBJECT) {\n      jp.nextToken()\n    }\n\n    if (jp.getCurrentToken != JsonToken.FIELD_NAME &&\n      jp.getCurrentToken != JsonToken.END_OBJECT) {\n      throw ctxt.mappingException(javaType.getRawClass)\n    }\n\n    val node = jp.readValueAsTree[JsonNode]\n\n    val values = new ArrayBuffer[AnyRef]\n    for ((paramName, paramType) <- params) {\n      val field = node.get(paramName)\n      val tp = new TreeTraversingParser(if (field == null) NullNode.getInstance else field, jp.getCodec)\n      val value = if (paramType.getRawClass == classOf[Option[_]]) {\n        // thanks again for special-casing VALUE_NULL\n        Option(tp.getCodec.readValue[Object](tp, paramType.containedType(0)))\n      } else {\n        tp.getCodec.readValue[Object](tp, paramType)\n      }\n\n      if (field != null || value != null) {\n        values += value\n      }\n\n\n      if (values.size == params.size) {\n        return constructor.newInstance(values.toArray: _*).asInstanceOf[Object]\n      }\n    }\n\n    throw new JsonMappingException(errorMessage(node))\n  }\n\n  private def errorMessage(node: JsonNode) = {\n    val names = params.map { _._1 }.mkString(\"[\", \", \", \"]\")\n    val existing = node match {\n      case obj: ObjectNode => obj.fieldNames.mkString(\"[\", \", \", \"]\")\n      case _: NullNode => \"[]\" // this is what Jackson deserializes the inside of an empty object to\n      case unknown => \"a non-object\"\n    }\n    \"Invalid JSON. Needed %s, but found %s.\".format(names, existing)\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/EitherDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.core.JsonParser\nimport com.fasterxml.jackson.databind.node.TreeTraversingParser\nimport com.fasterxml.jackson.databind._\n\nclass EitherDeserializer(config: DeserializationConfig,\n                         javaType: JavaType) extends JsonDeserializer[Object] {\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext) = {\n    val node = jp.readValueAsTree[JsonNode]\n    val tp = new TreeTraversingParser(node, jp.getCodec)\n\n    try {\n      Left(tp.getCodec.readValue[Object](tp, javaType.containedType(0)))\n    } catch {\n      case _ => Right(tp.getCodec.readValue[Object](tp, javaType.containedType(1)))\n    }\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/ImmutableMapDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.databind.JavaType\nimport com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\nimport collection.generic.MapFactory\nimport collection.MapLike\nimport com.fasterxml.jackson.databind.deser.ResolvableDeserializer\n\nclass ImmutableMapDeserializer[CC[A, B] <: Map[A, B] with MapLike[A, B, CC[A, B]]](companion: MapFactory[CC],\n                                                                          valueType: JavaType)\n  extends JsonDeserializer[Object] with ResolvableDeserializer {\n\n  var valueDeserializer: JsonDeserializer[Object] = _\n\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext): CC[String, Object] = {\n    val builder = companion.newBuilder[String, Object]\n\n    if (jp.getCurrentToken == JsonToken.START_OBJECT) {\n      jp.nextToken()\n    }\n\n    if (jp.getCurrentToken != JsonToken.FIELD_NAME &&\n        jp.getCurrentToken != JsonToken.END_OBJECT) {\n      throw ctxt.mappingException(valueType.getRawClass)\n    }\n\n    while (jp.getCurrentToken != JsonToken.END_OBJECT) {\n      val name = jp.getCurrentName\n      jp.nextToken()\n      builder += ((name, valueDeserializer.deserialize(jp, ctxt)))\n      jp.nextToken()\n    }\n\n    builder.result()\n  }\n\n  def resolve(ctxt: DeserializationContext) {\n    valueDeserializer = ctxt.findRootValueDeserializer(valueType)\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/IntMapDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\nimport com.fasterxml.jackson.databind.JavaType\nimport scala.collection.immutable.IntMap\nimport com.fasterxml.jackson.databind.deser.ResolvableDeserializer\n\nclass IntMapDeserializer(valueType: JavaType) extends JsonDeserializer[Object] with ResolvableDeserializer {\n  var valueDeserializer: JsonDeserializer[Object] = _\n\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext) = {\n    var map = IntMap.empty[Object]\n\n    if (jp.getCurrentToken == JsonToken.START_OBJECT) {\n      jp.nextToken()\n    }\n\n    if (jp.getCurrentToken != JsonToken.FIELD_NAME &&\n        jp.getCurrentToken != JsonToken.END_OBJECT) {\n      throw ctxt.mappingException(valueType.getRawClass)\n    }\n\n    while (jp.getCurrentToken != JsonToken.END_OBJECT) {\n      try {\n        val name = jp.getCurrentName.toInt\n        jp.nextToken()\n        map += ((name, valueDeserializer.deserialize(jp, ctxt)))\n        jp.nextToken()\n      } catch {\n        case e: IllegalArgumentException => throw ctxt.mappingException(classOf[IntMap[_]])\n      }\n    }\n\n    map\n  }\n\n  def resolve(ctxt: DeserializationContext) {\n    valueDeserializer = ctxt.findRootValueDeserializer(valueType)\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/IteratorDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.databind.JavaType\nimport com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\nimport com.fasterxml.jackson.databind.deser.ResolvableDeserializer\n\nclass IteratorDeserializer(elementType: JavaType) extends JsonDeserializer[Object] with ResolvableDeserializer {\n  var elementDeserializer: JsonDeserializer[Object] = _\n\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext) = {\n    val builder = Seq.newBuilder[Object]\n\n    if (jp.getCurrentToken != JsonToken.START_ARRAY) {\n      throw ctxt.mappingException(elementType.getRawClass)\n    }\n\n    while (jp.nextToken() != JsonToken.END_ARRAY) {\n      builder += elementDeserializer.deserialize(jp, ctxt)\n    }\n\n    builder.result().iterator.buffered\n  }\n\n  def resolve(ctxt: DeserializationContext) {\n    elementDeserializer = ctxt.findRootValueDeserializer(elementType)\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/JValueDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\nimport com.codahale.jerkson.AST._\nimport collection.mutable.ArrayBuffer\nimport com.fasterxml.jackson.databind.`type`.TypeFactory\nimport com.codahale.jerkson.Types\n\nclass JValueDeserializer(factory: TypeFactory, klass: Class[_]) extends JsonDeserializer[Object] {\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext): Object = {\n    if (jp.getCurrentToken == null) {\n      jp.nextToken()\n    }\n\n    val value = jp.getCurrentToken match {\n      case JsonToken.VALUE_NUMBER_INT => JInt(BigInt(jp.getText))\n      case JsonToken.VALUE_NUMBER_FLOAT => JFloat(jp.getDoubleValue)\n      case JsonToken.VALUE_STRING => JString(jp.getText)\n      case JsonToken.VALUE_TRUE => JBoolean(true)\n      case JsonToken.VALUE_FALSE => JBoolean(false)\n      case JsonToken.START_ARRAY => {\n        JArray(jp.getCodec.readValue(jp, Types.build(factory, manifest[List[JValue]])))\n      }\n      case JsonToken.START_OBJECT => {\n        jp.nextToken()\n        deserialize(jp, ctxt)\n      }\n      case JsonToken.FIELD_NAME | JsonToken.END_OBJECT => {\n        val fields = new ArrayBuffer[JField]\n        while (jp.getCurrentToken != JsonToken.END_OBJECT) {\n          val name = jp.getCurrentName\n          jp.nextToken()\n          fields += JField(name, jp.getCodec.readValue(jp, Types.build(factory, manifest[JValue])))\n          jp.nextToken()\n        }\n        JObject(fields.toList)\n      }\n      case _ => throw ctxt.mappingException(classOf[JValue])\n    }\n\n    if (!klass.isAssignableFrom(value.getClass)) {\n      throw ctxt.mappingException(klass)\n    }\n\n    value\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/LongMapDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\nimport com.fasterxml.jackson.databind.JavaType\nimport scala.collection.immutable.LongMap\nimport com.fasterxml.jackson.databind.deser.ResolvableDeserializer\n\nclass LongMapDeserializer(valueType: JavaType) extends JsonDeserializer[Object] with ResolvableDeserializer {\n  var valueDeserializer: JsonDeserializer[Object] = _\n\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext) = {\n    var map = LongMap.empty[Object]\n\n    if (jp.getCurrentToken == JsonToken.START_OBJECT) {\n      jp.nextToken()\n    }\n\n    if (jp.getCurrentToken != JsonToken.FIELD_NAME &&\n        jp.getCurrentToken != JsonToken.END_OBJECT) {\n      throw ctxt.mappingException(valueType.getRawClass)\n    }\n\n    while (jp.getCurrentToken != JsonToken.END_OBJECT) {\n      try {\n        val name = jp.getCurrentName.toLong\n        jp.nextToken()\n        map += ((name, valueDeserializer.deserialize(jp, ctxt)))\n        jp.nextToken()\n      } catch {\n        case e: IllegalArgumentException => throw ctxt.mappingException(classOf[LongMap[_]])\n      }\n    }\n    map\n  }\n\n  def resolve(ctxt: DeserializationContext) {\n    valueDeserializer = ctxt.findRootValueDeserializer(valueType)\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/MutableLinkedHashMapDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.databind.JavaType\nimport com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}\nimport scala.collection.mutable\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\nimport com.fasterxml.jackson.databind.deser.ResolvableDeserializer\n\nclass MutableLinkedHashMapDeserializer(valueType: JavaType) extends JsonDeserializer[Object] with ResolvableDeserializer {\n  var valueDeserializer: JsonDeserializer[Object] = _\n\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext) = {\n    val builder = mutable.LinkedHashMap.newBuilder[String, Object]\n\n    if (jp.getCurrentToken == JsonToken.START_OBJECT) {\n      jp.nextToken()\n    }\n\n    while (jp.getCurrentToken != JsonToken.END_OBJECT) {\n      val name = jp.getCurrentName\n      jp.nextToken()\n      builder += ((name, valueDeserializer.deserialize(jp, ctxt)))\n      jp.nextToken()\n    }\n\n    builder.result()\n  }\n\n  def resolve(ctxt: DeserializationContext) {\n    valueDeserializer = ctxt.findRootValueDeserializer(valueType)\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/MutableMapDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.databind.JavaType\nimport com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\nimport scala.collection.mutable\nimport com.fasterxml.jackson.databind.deser.ResolvableDeserializer\n\nclass MutableMapDeserializer(valueType: JavaType) extends JsonDeserializer[Object] with ResolvableDeserializer {\n  var valueDeserializer: JsonDeserializer[Object] = _\n\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext) = {\n    val builder = mutable.HashMap.newBuilder[String, Object]\n\n    if (jp.getCurrentToken == JsonToken.START_OBJECT) {\n      jp.nextToken()\n    }\n\n    if (jp.getCurrentToken != JsonToken.FIELD_NAME &&\n        jp.getCurrentToken != JsonToken.END_OBJECT) {\n      throw ctxt.mappingException(valueType.getRawClass)\n    }\n\n    while (jp.getCurrentToken != JsonToken.END_OBJECT) {\n      val name = jp.getCurrentName\n      jp.nextToken()\n      builder += ((name, valueDeserializer.deserialize(jp, ctxt)))\n      jp.nextToken()\n    }\n\n    builder.result()\n  }\n\n  def resolve(ctxt: DeserializationContext) {\n    valueDeserializer = ctxt.findRootValueDeserializer(valueType)\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/OptionDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.databind.JavaType\nimport com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\nimport com.fasterxml.jackson.databind.deser.ResolvableDeserializer\n\nclass OptionDeserializer(elementType: JavaType)\n  extends JsonDeserializer[Object] with ResolvableDeserializer {\n\n  var elementDeserializer: JsonDeserializer[Object] = _\n\n  override def getEmptyValue = None\n\n  override def getNullValue = None\n\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext) = {\n    if (jp.getCurrentToken == JsonToken.VALUE_NULL) {\n      None\n    } else {\n      Some(elementDeserializer.deserialize(jp, ctxt))\n    }\n  }\n\n  def resolve(ctxt: DeserializationContext) {\n    elementDeserializer = ctxt.findRootValueDeserializer(elementType)\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/RangeDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport collection.JavaConversions._\nimport com.fasterxml.jackson.databind.JsonNode\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\nimport com.fasterxml.jackson.databind.{JsonMappingException, DeserializationContext, JsonDeserializer}\nimport com.fasterxml.jackson.databind.node.{IntNode, BooleanNode, NullNode, ObjectNode}\n\nclass RangeDeserializer extends JsonDeserializer[Object] {\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext) = {\n    if (jp.getCurrentToken == JsonToken.START_OBJECT) {\n      jp.nextToken()\n    }\n\n    if (jp.getCurrentToken != JsonToken.FIELD_NAME &&\n      jp.getCurrentToken != JsonToken.END_OBJECT) {\n      throw ctxt.mappingException(classOf[Range])\n    }\n\n    val node = jp.readValueAsTree[JsonNode]\n    val inclusiveNode  = node.get(\"inclusive\")\n    val stepNode = node.get(\"step\")\n    val startNode = node.get(\"start\")\n    val endNode = node.get(\"end\")\n\n    if (startNode == null || !classOf[IntNode].isAssignableFrom(startNode.getClass) ||\n        endNode == null || !classOf[IntNode].isAssignableFrom(endNode.getClass)) {\n      throw new JsonMappingException(errorMessage(node))\n    }\n\n    val step = if (stepNode == null || !classOf[IntNode].isAssignableFrom(stepNode.getClass)) {\n      1\n    } else {\n      stepNode.intValue\n    }\n\n    val start = startNode.asInstanceOf[IntNode].intValue\n    val end = endNode.asInstanceOf[IntNode].intValue\n\n    if (inclusiveNode == null || inclusiveNode == BooleanNode.FALSE) {\n      Range(start, end, step)\n    } else {\n      Range.inclusive(start, end, step)\n    }\n  }\n\n  private def errorMessage(node: JsonNode) = {\n    val existing = node match {\n      case obj: ObjectNode => obj.fieldNames.mkString(\"[\", \", \", \"]\")\n      case _: NullNode => \"[]\" // this is what Jackson deserializes the inside of an empty object to\n      case unknown => \"a non-object\"\n    }\n    \"Invalid JSON. Needed [start, end, <step>, <inclusive>], but found %s.\".format(existing)\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/ScalaDeserializers.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.databind._\nimport scala.collection.{Traversable, MapLike, immutable, mutable}\nimport com.codahale.jerkson.AST.{JNull, JValue}\nimport scala.collection.generic.{MapFactory, GenericCompanion}\nimport com.fasterxml.jackson.databind.deser.Deserializers\nimport com.fasterxml.jackson.databind.Module.SetupContext\n\nclass ScalaDeserializers(classLoader: ClassLoader, context: SetupContext) extends Deserializers.Base {\n  override def findBeanDeserializer(javaType: JavaType, config: DeserializationConfig,\n                            beanDesc: BeanDescription) = {\n    val klass = javaType.getRawClass\n    if (klass == classOf[Range] || klass == classOf[immutable.Range]) {\n      new RangeDeserializer\n    } else if (klass == classOf[StringBuilder]) {\n      new StringBuilderDeserializer\n    } else if (klass == classOf[List[_]] || klass == classOf[immutable.List[_]]) {\n      createSeqDeserializer(config, javaType, List)\n    } else if (klass == classOf[Seq[_]] || klass == classOf[immutable.Seq[_]] ||\n               klass == classOf[Iterable[_]] || klass == classOf[Traversable[_]] ||\n               klass == classOf[immutable.Traversable[_]]) {\n      createSeqDeserializer(config, javaType, Seq)\n    } else if (klass == classOf[Stream[_]] || klass == classOf[immutable.Stream[_]]) {\n      createSeqDeserializer(config, javaType, Stream)\n    } else if (klass == classOf[immutable.Queue[_]]) {\n      createSeqDeserializer(config, javaType, immutable.Queue)\n    } else if (klass == classOf[Vector[_]]) {\n      createSeqDeserializer(config, javaType, Vector)\n    } else if (klass == classOf[IndexedSeq[_]] || klass == classOf[immutable.IndexedSeq[_]]) {\n      createSeqDeserializer(config, javaType, IndexedSeq)\n    } else if (klass == classOf[mutable.ResizableArray[_]]) {\n      createSeqDeserializer(config, javaType, mutable.ResizableArray)\n    } else if (klass == classOf[mutable.ArraySeq[_]]) {\n      createSeqDeserializer(config, javaType, mutable.ArraySeq)\n    } else if (klass == classOf[mutable.MutableList[_]]) {\n      createSeqDeserializer(config, javaType, mutable.MutableList)\n    } else if (klass == classOf[mutable.Queue[_]]) {\n      createSeqDeserializer(config, javaType, mutable.Queue)\n    } else if (klass == classOf[mutable.ListBuffer[_]]) {\n      createSeqDeserializer(config, javaType, mutable.ListBuffer)\n    } else if (klass == classOf[mutable.ArrayBuffer[_]] || klass == classOf[mutable.Traversable[_]]) {\n      createSeqDeserializer(config, javaType, mutable.ArrayBuffer)\n    } else if (klass == classOf[collection.BitSet] || klass == classOf[immutable.BitSet]) {\n      new BitSetDeserializer(immutable.BitSet)\n    } else if (klass == classOf[mutable.BitSet]) {\n      new BitSetDeserializer(mutable.BitSet)\n    } else if (klass == classOf[immutable.HashSet[_]]) {\n      createSeqDeserializer(config, javaType, immutable.HashSet)\n    } else if (klass == classOf[Set[_]] || klass == classOf[immutable.Set[_]] || klass == classOf[collection.Set[_]]) {\n      createSeqDeserializer(config, javaType, Set)\n    } else if (klass == classOf[mutable.HashSet[_]]) {\n      createSeqDeserializer(config, javaType, mutable.HashSet)\n    } else if (klass == classOf[mutable.LinkedHashSet[_]]) {\n      createSeqDeserializer(config, javaType, mutable.LinkedHashSet)\n    } else if (klass == classOf[Iterator[_]] || klass == classOf[BufferedIterator[_]]) {\n      val elementType = javaType.containedType(0)\n      new IteratorDeserializer(elementType)\n    } else if (klass == classOf[immutable.HashMap[_, _]] || klass == classOf[Map[_, _]] || klass == classOf[collection.Map[_, _]]) {\n      createImmutableMapDeserializer(config, javaType, immutable.HashMap)\n    } else if (klass == classOf[immutable.IntMap[_]]) {\n      val valueType = javaType.containedType(0)\n      new IntMapDeserializer(valueType)\n    } else if (klass == classOf[immutable.LongMap[_]]) {\n      val valueType = javaType.containedType(0)\n      new LongMapDeserializer(valueType)\n    } else if (klass == classOf[mutable.HashMap[_, _]] || klass == classOf[mutable.Map[_, _]]) {\n      if (javaType.containedType(0).getRawClass == classOf[String]) {\n        val valueType = javaType.containedType(1)\n        new MutableMapDeserializer(valueType)\n      } else {\n        null\n      }\n    } else if (klass == classOf[mutable.LinkedHashMap[_, _]]) {\n      if (javaType.containedType(0).getRawClass == classOf[String]) {\n        val valueType = javaType.containedType(1)\n        new MutableLinkedHashMapDeserializer(valueType)\n      } else {\n        null\n      }\n    } else if (klass == classOf[Option[_]]) {\n      createOptionDeserializer(config, javaType)\n    } else if (classOf[JValue].isAssignableFrom(klass) || klass == JNull.getClass) {\n      new JValueDeserializer(config.getTypeFactory, klass)\n    } else if (klass == classOf[BigInt]) {\n      new BigIntDeserializer\n    } else if (klass == classOf[BigDecimal]) {\n      new BigDecimalDeserializer\n    } else if (klass == classOf[Either[_,_]]) {\n      new EitherDeserializer(config, javaType)\n    } else if (classOf[Product].isAssignableFrom(klass)) {\n      new CaseClassDeserializer(config, javaType, classLoader)\n    } else null\n  }\n\n  private def createSeqDeserializer[CC[X] <: Traversable[X]](config: DeserializationConfig,\n                                                             javaType: JavaType,\n                                                             companion: GenericCompanion[CC]) = {\n    val elementType = javaType.containedType(0)\n    new SeqDeserializer[CC](companion, elementType)\n  }\n\n  private def createOptionDeserializer(config: DeserializationConfig,\n                                       javaType: JavaType) = {\n    val elementType = javaType.containedType(0)\n    new OptionDeserializer(elementType)\n  }\n\n  private def createImmutableMapDeserializer[CC[A, B] <: Map[A, B] with MapLike[A, B, CC[A, B]]](config: DeserializationConfig,\n                                                                                        javaType: JavaType,\n                                                                                        companion: MapFactory[CC]) = {\n    val keyType = javaType.containedType(0)\n    val valueType = javaType.containedType(1)\n    if (keyType.getRawClass == classOf[String]) {\n      new ImmutableMapDeserializer[CC](companion, valueType)\n    } else if (keyType.getRawClass == classOf[Int] || keyType.getRawClass == classOf[java.lang.Integer]) {\n      new IntMapDeserializer(valueType)\n    } else if (keyType.getRawClass == classOf[Long] || keyType.getRawClass == classOf[java.lang.Long]) {\n      new LongMapDeserializer(valueType)\n    } else {\n      null\n    }\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/SeqDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\nimport com.fasterxml.jackson.databind.JavaType\nimport com.fasterxml.jackson.databind.{JsonDeserializer, DeserializationContext}\nimport collection.generic.GenericCompanion\nimport com.fasterxml.jackson.databind.deser.ResolvableDeserializer\n\nclass SeqDeserializer[+CC[X] <: Traversable[X]](companion: GenericCompanion[CC],\n                                                elementType: JavaType)\n  extends JsonDeserializer[Object] with ResolvableDeserializer {\n\n  var elementDeserializer: JsonDeserializer[Object] = _\n\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext): CC[Object] = {\n    val builder = companion.newBuilder[Object]\n\n    if (jp.getCurrentToken != JsonToken.START_ARRAY) {\n      throw ctxt.mappingException(elementType.getRawClass)\n    }\n\n    while (jp.nextToken() != JsonToken.END_ARRAY) {\n      builder += elementDeserializer.deserialize(jp, ctxt)\n    }\n\n    builder.result()\n  }\n\n  def resolve(ctxt: DeserializationContext) {\n    elementDeserializer = ctxt.findRootValueDeserializer(elementType)\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/deser/StringBuilderDeserializer.scala",
    "content": "package com.codahale.jerkson.deser\n\nimport com.fasterxml.jackson.databind.{DeserializationContext, JsonDeserializer}\nimport com.fasterxml.jackson.core.{JsonToken, JsonParser}\n\nclass StringBuilderDeserializer extends JsonDeserializer[Object] {\n  def deserialize(jp: JsonParser, ctxt: DeserializationContext) = {\n    if (jp.getCurrentToken != JsonToken.VALUE_STRING) {\n      throw ctxt.mappingException(classOf[StringBuilder])\n    }\n\n    new StringBuilder(jp.getText)\n  }\n\n  override def isCachable = true\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/ser/CaseClassSerializer.scala",
    "content": "package com.codahale.jerkson.ser\n\nimport java.lang.reflect.Modifier\nimport com.codahale.jerkson.JsonSnakeCase\nimport com.codahale.jerkson.Util._\nimport com.fasterxml.jackson.core.JsonGenerator\nimport com.fasterxml.jackson.annotation.{JsonIgnore, JsonIgnoreProperties}\nimport com.fasterxml.jackson.databind.{SerializerProvider, JsonSerializer}\n\nclass CaseClassSerializer[A <: Product](klass: Class[_]) extends JsonSerializer[A] {\n  private val isSnakeCase = klass.isAnnotationPresent(classOf[JsonSnakeCase])\n  private val ignoredFields = if (klass.isAnnotationPresent(classOf[JsonIgnoreProperties])) {\n    klass.getAnnotation(classOf[JsonIgnoreProperties]).value().toSet\n  } else Set.empty[String]\n  \n  private val nonIgnoredFields = klass.getDeclaredFields.filterNot { f =>\n    f.getAnnotation(classOf[JsonIgnore]) != null ||\n    ignoredFields(f.getName) ||\n      (f.getModifiers & Modifier.TRANSIENT) != 0 ||\n      f.getName.contains(\"$\")\n  }\n\n  private val methods = klass.getDeclaredMethods\n                                .filter { _.getParameterTypes.isEmpty }\n                                .map { m => m.getName -> m }.toMap\n  \n  def serialize(value: A, json: JsonGenerator, provider: SerializerProvider) {\n    json.writeStartObject()\n    for (field <- nonIgnoredFields) {\n      val methodOpt = methods.get(field.getName)\n      val fieldValue: Object = methodOpt.map { _.invoke(value) }.getOrElse(field.get(value))\n      if (fieldValue != None) {\n        val fieldName = methodOpt.map { _.getName }.getOrElse(field.getName)\n        provider.defaultSerializeField(if (isSnakeCase) snakeCase(fieldName) else fieldName, fieldValue, json)\n      }\n    }\n    json.writeEndObject()\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/ser/EitherSerializer.scala",
    "content": "package com.codahale.jerkson.ser\n\nimport com.fasterxml.jackson.core.JsonGenerator\nimport com.fasterxml.jackson.databind.{SerializerProvider, JsonSerializer}\n\nclass EitherSerializer extends JsonSerializer[Either[_, _]] {\n  def serialize(value: Either[_, _], json: JsonGenerator, provider: SerializerProvider) {\n    provider.defaultSerializeValue(value match {\n      case Left(o) => o.asInstanceOf[Object]\n      case Right(o) => o.asInstanceOf[Object]\n    }, json)\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/ser/IterableSerializer.scala",
    "content": "package com.codahale.jerkson.ser\n\nimport com.fasterxml.jackson.core.JsonGenerator\nimport com.fasterxml.jackson.databind.{SerializerProvider, JsonSerializer}\n\nclass IterableSerializer extends JsonSerializer[Iterable[_]] {\n  def serialize(value: Iterable[_], json: JsonGenerator, provider: SerializerProvider) {\n    json.writeStartArray()\n    for (element <- value) {\n      provider.defaultSerializeValue(element, json)\n    }\n    json.writeEndArray()\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/ser/IteratorSerializer.scala",
    "content": "package com.codahale.jerkson.ser\n\nimport com.fasterxml.jackson.core.JsonGenerator\nimport com.fasterxml.jackson.databind.{SerializerProvider, JsonSerializer}\n\nclass IteratorSerializer extends JsonSerializer[Iterator[_]] {\n  def serialize(value: Iterator[_], json: JsonGenerator,\n                provider: SerializerProvider) {\n    json.writeStartArray()\n    for (element <- value) {\n      provider.defaultSerializeValue(element, json)\n    }\n    json.writeEndArray()\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/ser/JValueSerializer.scala",
    "content": "package com.codahale.jerkson.ser\n\nimport com.fasterxml.jackson.core.JsonGenerator\nimport com.fasterxml.jackson.databind.{SerializerProvider, JsonSerializer}\nimport com.codahale.jerkson.AST._\nimport java.math.BigInteger\n\nclass JValueSerializer extends JsonSerializer[JValue] {\n  def serialize(value: JValue, json: JsonGenerator, provider: SerializerProvider) {\n    value match {\n      case JInt(v) => json.writeNumber(new BigInteger(v.toString()))\n      case JFloat(v) => json.writeNumber(v)\n      case JString(v) => json.writeString(v)\n      case JBoolean(v) => json.writeBoolean(v)\n      case JArray(elements) => json.writeObject(elements)\n      case JField(name, value) => {\n        json.writeFieldName(name)\n        json.writeObject(value)\n      }\n      case JObject(fields) => {\n        json.writeStartObject()\n        fields.foreach(json.writeObject)\n        json.writeEndObject()\n      }\n      case JNull => json.writeNull()\n    }\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/ser/MapSerializer.scala",
    "content": "package com.codahale.jerkson.ser\n\nimport com.fasterxml.jackson.core.JsonGenerator\nimport com.fasterxml.jackson.databind.{SerializerProvider, JsonSerializer}\n\nclass MapSerializer extends JsonSerializer[collection.Map[_ ,_]] {\n  def serialize(map: collection.Map[_,_], json: JsonGenerator, provider: SerializerProvider) {\n    json.writeStartObject()\n    for ((key, value) <- map) {\n      provider.defaultSerializeField(key.toString, value, json)\n    }\n    json.writeEndObject()\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/ser/OptionSerializer.scala",
    "content": "package com.codahale.jerkson.ser\n\nimport com.fasterxml.jackson.core.JsonGenerator\nimport com.fasterxml.jackson.databind.{SerializerProvider, JsonSerializer}\n\nclass OptionSerializer extends JsonSerializer[Option[_]] {\n  def serialize(value: Option[_], json: JsonGenerator,\n                provider: SerializerProvider) {\n    provider.defaultSerializeValue(value.orNull, json)\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/ser/RangeSerializer.scala",
    "content": "package com.codahale.jerkson.ser\n\nimport com.fasterxml.jackson.core.JsonGenerator\nimport com.fasterxml.jackson.databind.{SerializerProvider, JsonSerializer}\n\nclass RangeSerializer extends JsonSerializer[Range] {\n  def serialize(value: Range, json: JsonGenerator, provider: SerializerProvider) {\n    json.writeStartObject()\n    json.writeNumberField(\"start\", value.start)\n    json.writeNumberField(\"end\", value.end)\n\n    if (value.step != 1) {\n      json.writeNumberField(\"step\", value.step)\n    }\n\n    if (value.isInclusive) {\n      json.writeBooleanField(\"inclusive\", value.isInclusive)\n    }\n\n    json.writeEndObject()\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/ser/ScalaSerializers.scala",
    "content": "package com.codahale.jerkson.ser\n\nimport com.codahale.jerkson.AST.JValue\nimport com.fasterxml.jackson.databind._\nimport com.fasterxml.jackson.databind.ser.Serializers\n\nclass ScalaSerializers extends Serializers.Base {\n  override def findSerializer(config: SerializationConfig, javaType: JavaType, beanDesc: BeanDescription) = {\n    val ser: Object = if (classOf[Option[_]].isAssignableFrom(beanDesc.getBeanClass)) {\n        new OptionSerializer\n    } else if (classOf[StringBuilder].isAssignableFrom(beanDesc.getBeanClass)) {\n      new StringBuilderSerializer\n    } else if (classOf[collection.Map[_,_]].isAssignableFrom(beanDesc.getBeanClass)) {\n      new MapSerializer\n    } else if (classOf[Range].isAssignableFrom(beanDesc.getBeanClass)) {\n      new RangeSerializer\n    } else if (classOf[Iterable[_]].isAssignableFrom(beanDesc.getBeanClass)) {\n        new IterableSerializer\n    } else if (classOf[Iterator[_]].isAssignableFrom(beanDesc.getBeanClass)) {\n      new IteratorSerializer\n    } else if (classOf[JValue].isAssignableFrom(beanDesc.getBeanClass)) {\n      new JValueSerializer\n    } else if (classOf[Either[_,_]].isAssignableFrom(beanDesc.getBeanClass)) {\n      new EitherSerializer\n    } else if (classOf[Product].isAssignableFrom(beanDesc.getBeanClass)) {\n      new CaseClassSerializer(beanDesc.getBeanClass)\n    } else {\n      null\n    }\n    ser.asInstanceOf[JsonSerializer[Object]]\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/ser/StringBuilderSerializer.scala",
    "content": "package com.codahale.jerkson.ser\n\nimport com.fasterxml.jackson.core.JsonGenerator\nimport com.fasterxml.jackson.databind.{SerializerProvider, JsonSerializer}\n\nclass StringBuilderSerializer extends JsonSerializer[StringBuilder] {\n  def serialize(value: StringBuilder, json: JsonGenerator, provider: SerializerProvider) {\n    json.writeString(value.toString())\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/util/CaseClassSigParser.scala",
    "content": "package com.codahale.jerkson.util\n\nimport com.codahale.jerkson.util.scalax.rules.scalasig._\nimport com.fasterxml.jackson.databind.JavaType\nimport com.fasterxml.jackson.databind.`type`.TypeFactory\nimport scala.reflect.ScalaSignature\nimport scala.reflect.generic.ByteCodecs\n\nclass MissingPickledSig(clazz: Class[_]) extends Error(\"Failed to parse pickled Scala signature from: %s\".format(clazz))\n\nclass MissingExpectedType(clazz: Class[_]) extends Error(\n  \"Parsed pickled Scala signature, but no expected type found: %s\"\n  .format(clazz)\n)\n\nobject CaseClassSigParser {\n  val SCALA_SIG = \"ScalaSig\"\n  val SCALA_SIG_ANNOTATION = \"Lscala/reflect/ScalaSignature;\"\n  val BYTES_VALUE = \"bytes\"\n\n  private def parseClassFileFromByteCode(clazz: Class[_]): Option[ClassFile] = try {\n    // taken from ScalaSigParser parse method with the explicit purpose of walking away from NPE\n    val byteCode = ByteCode.forClass(clazz)\n    Option(ClassFileParser.parse(byteCode))\n  }\n  catch {\n    case e: NullPointerException => None // yes, this is the exception, but it is totally unhelpful to the end user\n  }\n\n  private def parseByteCodeFromAnnotation(clazz: Class[_]): Option[ByteCode] = {\n    if (clazz.isAnnotationPresent(classOf[ScalaSignature])) {\n      val sig = clazz.getAnnotation(classOf[ScalaSignature])\n      val bytes = sig.bytes.getBytes(\"UTF-8\")\n      val len = ByteCodecs.decode(bytes)\n      Option(ByteCode(bytes.take(len)))\n    } else {\n      None\n    }\n  }\n\n  private def parseScalaSig(_clazz: Class[_], classLoader: ClassLoader): Option[ScalaSig] = {\n    val clazz = findRootClass(_clazz, classLoader)\n    parseClassFileFromByteCode(clazz).map(ScalaSigParser.parse(_)).getOrElse(None) orElse\n      parseByteCodeFromAnnotation(clazz).map(ScalaSigAttributeParsers.parse(_)) orElse\n      None\n  }\n\n  protected def findRootClass(klass: Class[_], classLoader: ClassLoader) =\n    loadClass(klass.getName.split(\"\\\\$\").head, classLoader)\n\n  protected def simpleName(klass: Class[_]) =\n    klass.getName.split(\"\\\\$\").last\n\n  protected def findSym[A](clazz: Class[A], classLoader: ClassLoader) = {\n    val name = simpleName(clazz)\n    val pss = parseScalaSig(clazz, classLoader)\n    pss match {\n      case Some(x) => {\n        val topLevelClasses = x.topLevelClasses\n        topLevelClasses.headOption match {\n          case Some(tlc) => {\n            tlc\n          }\n          case None => {\n            val topLevelObjects = x.topLevelObjects\n            topLevelObjects.headOption match {\n              case Some(tlo) => {\n                x.symbols.find { s => !s.isModule && s.name == name } match {\n                  case Some(s) => s.asInstanceOf[ClassSymbol]\n                  case None => throw new MissingExpectedType(clazz)\n                }\n              }\n              case _ => throw new MissingExpectedType(clazz)\n            }\n          }\n        }\n      }\n      case None => throw new MissingPickledSig(clazz)\n    }\n  }\n\n  def parse[A](clazz: Class[A], factory: TypeFactory, classLoader: ClassLoader) = {\n    findSym(clazz, classLoader).children.filter(c => c.isCaseAccessor && !c.isPrivate)\n      .flatMap { ms =>\n        ms.asInstanceOf[MethodSymbol].infoType match {\n          case NullaryMethodType(t: TypeRefType) => ms.name -> typeRef2JavaType(t, factory, classLoader) :: Nil\n          case _ => Nil\n        }\n      }\n  }\n\n  protected def typeRef2JavaType(ref: TypeRefType, factory: TypeFactory, classLoader: ClassLoader): JavaType = {\n    try {\n      if (ref.symbol.path == \"scala.Array\") {\n        val elementType = typeRef2JavaType(ref.typeArgs.head.asInstanceOf[TypeRefType], factory, classLoader)\n        val realElementType = elementType.getRawClass.getName match {\n          case \"java.lang.Boolean\" => classOf[Boolean]\n          case \"java.lang.Byte\" => classOf[Byte]\n          case \"java.lang.Character\" => classOf[Char]\n          case \"java.lang.Double\" => classOf[Double]\n          case \"java.lang.Float\" => classOf[Float]\n          case \"java.lang.Integer\" => classOf[Int]\n          case \"java.lang.Long\" => classOf[Long]\n          case \"java.lang.Short\" => classOf[Short]\n          case _ => elementType.getRawClass\n        }\n\n        val array = java.lang.reflect.Array.newInstance(realElementType, 0)\n        factory.constructType(array.getClass)\n      } else {\n        val klass = loadClass(ref.symbol.path, classLoader)\n        factory.constructParametricType(\n          klass, ref.typeArgs.map {\n            t => typeRef2JavaType(t.asInstanceOf[TypeRefType], factory, classLoader)\n          }: _*\n        )\n      }\n    } catch {\n      case e: Throwable => {\n        e.printStackTrace()\n        null\n      }\n    }\n  }\n\n  protected def loadClass(path: String, classLoader: ClassLoader) = path match {\n    case \"scala.Predef.Map\" => classOf[Map[_, _]]\n    case \"scala.Predef.Set\" => classOf[Set[_]]\n    case \"scala.Predef.String\" => classOf[String]\n    case \"scala.package.List\" => classOf[List[_]]\n    case \"scala.package.Seq\" => classOf[Seq[_]]\n    case \"scala.package.Sequence\" => classOf[Seq[_]]\n    case \"scala.package.Collection\" => classOf[Seq[_]]\n    case \"scala.package.IndexedSeq\" => classOf[IndexedSeq[_]]\n    case \"scala.package.RandomAccessSeq\" => classOf[IndexedSeq[_]]\n    case \"scala.package.Iterable\" => classOf[Iterable[_]]\n    case \"scala.package.Iterator\" => classOf[Iterator[_]]\n    case \"scala.package.Vector\" => classOf[Vector[_]]\n    case \"scala.package.BigDecimal\" => classOf[BigDecimal]\n    case \"scala.package.BigInt\" => classOf[BigInt]\n    case \"scala.package.Integer\" => classOf[java.lang.Integer]\n    case \"scala.package.Character\" => classOf[java.lang.Character]\n    case \"scala.Long\" => classOf[java.lang.Long]\n    case \"scala.Int\" => classOf[java.lang.Integer]\n    case \"scala.Boolean\" => classOf[java.lang.Boolean]\n    case \"scala.Short\" => classOf[java.lang.Short]\n    case \"scala.Byte\" => classOf[java.lang.Byte]\n    case \"scala.Float\" => classOf[java.lang.Float]\n    case \"scala.Double\" => classOf[java.lang.Double]\n    case \"scala.Char\" => classOf[java.lang.Character]\n    case \"scala.Any\" => classOf[Any]\n    case \"scala.AnyRef\" => classOf[AnyRef]\n    case name => classLoader.loadClass(name)\n  }\n}\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/util/scalax/rules/Memoisable.scala",
    "content": "package com.codahale.jerkson.util\npackage scalax\npackage rules\n\nimport scala.collection.mutable.HashMap\n\ntrait MemoisableRules extends Rules {\n  def memo[In <: Memoisable, Out, A, X](key: AnyRef)\n                                       (toRule: => In => Result[Out, A, X]) = {\n    lazy val rule = toRule\n    from[In] {in => in.memo(key, rule(in))}\n  }\n\n  override def ruleWithName[In, Out, A, X](name: String,\n                                           f: In => rules.Result[Out, A, X]) = super.ruleWithName(\n    name, (in: In) =>\n      in match {\n        case s: Memoisable => s.memo(name, f(in))\n        case _ => f(in)\n      }\n  )\n}\n\ntrait Memoisable {\n  def memo[A](key: AnyRef, a: => A): A\n}\n\n\nobject DefaultMemoisable {\n  var debug = false\n}\n\ntrait DefaultMemoisable extends Memoisable {\n  protected val map = new HashMap[AnyRef, Any]\n\n  def memo[A](key: AnyRef, a: => A) = {\n    map.getOrElseUpdate(key, compute(key, a)).asInstanceOf[A]\n  }\n\n  protected def compute[A](key: AnyRef, a: => A): Any = a match {\n    case success: Success[_, _] => onSuccess(key, success); success\n    case other =>\n      if (DefaultMemoisable.debug) println(key + \" -> \" + other)\n      other\n  }\n\n  protected def onSuccess[S, T](key: AnyRef, result: Success[S, T]) {\n    val Success(out, t) = result\n    if (DefaultMemoisable.debug) println(key + \" -> \" + t + \" (\" + out + \")\")\n  }\n}\n\n\n\n\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/util/scalax/rules/Result.scala",
    "content": "package com.codahale.jerkson.util\npackage scalax\npackage rules\n\n/**Represents the combined value of two rules applied in sequence.\n *\n * @see the Scala parser combinator\n */\ncase class ~[+A, +B](_1: A, _2: B) {\n  override def toString = \"(\" + _1 + \" ~ \" + _2 + \")\"\n}\n\n\nsealed abstract class Result[+Out, +A, +X] {\n  def out: Out\n\n  def value: A\n\n  def error: X\n\n  implicit def toOption: Option[A]\n\n  def map[B](f: A => B): Result[Out, B, X]\n\n  def mapOut[Out2](f: Out => Out2): Result[Out2, A, X]\n\n  def map[Out2, B](f: (Out, A) => (Out2, B)): Result[Out2, B, X]\n\n  def flatMap[Out2, B](f: (Out, A) => Result[Out2, B, Nothing]): Result[Out2, B, X]\n\n  def orElse[Out2 >: Out, B >: A](other: => Result[Out2, B, Nothing]): Result[Out2, B, X]\n}\n\ncase class Success[+Out, +A](out: Out,\n                             value: A) extends Result[Out, A, Nothing] {\n  def error = throw new ScalaSigParserError(\"No error\")\n\n  def toOption = Some(value)\n\n  def map[B](f: A => B): Result[Out, B, Nothing] = Success(out, f(value))\n\n  def mapOut[Out2](f: Out => Out2): Result[Out2, A, Nothing] = Success(f(out), value)\n\n  def map[Out2, B](f: (Out, A) => (Out2, B)): Success[Out2, B] = f(out, value) match {case (out2, b) => Success(out2, b)}\n\n  def flatMap[Out2, B](f: (Out, A) => Result[Out2, B, Nothing]): Result[Out2, B, Nothing] = f(out, value)\n\n  def orElse[Out2 >: Out, B >: A](other: => Result[Out2, B, Nothing]): Result[Out2, B, Nothing] = this\n}\n\nsealed abstract class NoSuccess[+X] extends Result[Nothing, Nothing, X] {\n  def out = throw new ScalaSigParserError(\"No output\")\n\n  def value = throw new ScalaSigParserError(\"No value\")\n\n  def toOption = None\n\n  def map[B](f: Nothing => B) = this\n\n  def mapOut[Out2](f: Nothing => Out2) = this\n\n  def map[Out2, B](f: (Nothing, Nothing) => (Out2, B)) = this\n\n  def flatMap[Out2, B](f: (Nothing, Nothing) => Result[Out2, B, Nothing]) = this\n\n  def orElse[Out2, B](other: => Result[Out2, B, Nothing]) = other\n}\n\ncase object Failure extends NoSuccess[Nothing] {\n  def error = throw new ScalaSigParserError(\"No error\")\n}\n\ncase class ScalaSigParserError(msg: String) extends RuntimeException(msg)\n\ncase class Error[+X](error: X) extends NoSuccess[X] {\n}\n\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/util/scalax/rules/Rule.scala",
    "content": "package com.codahale.jerkson.util\npackage scalax\npackage rules\n\n/**A Rule is a function from some input to a Result.  The result may be:\n * <ul>\n * <li>Success, with a value of some type and an output that may serve as the input to subsequent rules.</li>\n * <li>Failure. A failure may result in some alternative rule being applied.</li>\n * <li>Error.  No further rules should be attempted.</li>\n * </ul>\n *\n * @author Andrew Foggin\n *\n * Inspired by the Scala parser combinator.\n */\ntrait Rule[-In, +Out, +A, +X] extends (In => Result[Out, A, X]) {\n  val factory: Rules\n\n  import factory._\n\n  def as(name: String) = ruleWithName(name, this)\n\n  def flatMap[Out2, B, X2 >: X](fa2ruleb: A => Out => Result[Out2, B, X2]) = mapResult {\n    case Success(out, a) => fa2ruleb(a)(out)\n    case Failure => Failure\n    case err@Error(_) => err\n  }\n\n  def map[B](fa2b: A => B) = flatMap {a => out => Success(out, fa2b(a))}\n\n  def filter(f: A => Boolean) = flatMap {a =>\n    out => if (f(a)) Success(out, a) else Failure\n  }\n\n  def mapResult[Out2, B, Y](f: Result[Out, A, X] => Result[Out2, B, Y]) = rule {\n    in: In => f(apply(in))\n  }\n\n  def orElse[In2 <: In, Out2 >: Out, A2 >: A, X2 >: X](other: => Rule[In2, Out2, A2, X2]): Rule[In2, Out2, A2, X2] = new Choice[In2, Out2, A2, X2] {\n    val factory = Rule.this.factory\n    lazy val choices = Rule.this :: other :: Nil\n  }\n\n  def orError[In2 <: In] = this orElse (error[In2])\n\n  def |[In2 <: In, Out2 >: Out, A2 >: A, X2 >: X](other: => Rule[In2, Out2, A2, X2]) = orElse(other)\n\n  def ^^[B](fa2b: A => B) = map(fa2b)\n\n  def ^^?[B](pf: PartialFunction[A, B]) = filter(pf.isDefinedAt(_)) ^^ pf\n\n  def ??(pf: PartialFunction[A, Any]) = filter(pf.isDefinedAt(_))\n\n  def -^[B](b: B) = map {any => b}\n\n  /**Maps an Error */\n  def !^[Y](fx2y: X => Y) = mapResult {\n    case s@Success(_, _) => s\n    case Failure => Failure\n    case Error(x) => Error(fx2y(x))\n  }\n\n  def >>[Out2, B, X2 >: X](fa2ruleb: A => Out => Result[Out2, B, X2]) = flatMap(fa2ruleb)\n\n  def >->[Out2, B, X2 >: X](fa2resultb: A => Result[Out2, B, X2]) = flatMap {\n    a => any => fa2resultb(a)\n  }\n\n  def >>?[Out2, B, X2 >: X](pf: PartialFunction[A, Rule[Out, Out2, B, X2]]) = filter(pf isDefinedAt _) flatMap pf\n\n  def >>&[B, X2 >: X](fa2ruleb: A => Out => Result[Any, B, X2]) = flatMap {a =>\n    out => fa2ruleb(a)(out) mapOut {any => out}\n  }\n\n  def ~[Out2, B, X2 >: X](next: => Rule[Out, Out2, B, X2]) = for (a <- this; b <- next) yield new ~(a, b)\n\n  def ~-[Out2, B, X2 >: X](next: => Rule[Out, Out2, B, X2]) = for (a <- this; b <- next) yield a\n\n  def -~[Out2, B, X2 >: X](next: => Rule[Out, Out2, B, X2]) = for (a <- this; b <- next) yield b\n\n  def ~++[Out2, B >: A, X2 >: X](next: => Rule[Out, Out2, Seq[B], X2]) = for (a <- this; b <- next) yield a :: b.toList\n\n  /**Apply the result of this rule to the function returned by the next rule */\n  def ~>[Out2, B, X2 >: X](next: => Rule[Out, Out2, A => B, X2]) = for (a <- this; fa2b <- next) yield fa2b(a)\n\n  /**Apply the result of this rule to the function returned by the previous rule */\n  def <~:[InPrev, B, X2 >: X](prev: => Rule[InPrev, In, A => B, X2]) = for (fa2b <- prev; a <- this) yield fa2b(a)\n\n  def ~![Out2, B, X2 >: X](next: => Rule[Out, Out2, B, X2]) = for (a <- this; b <- next orError) yield new ~(a, b)\n\n  def ~-![Out2, B, X2 >: X](next: => Rule[Out, Out2, B, X2]) = for (a <- this; b <- next orError) yield a\n\n  def -~![Out2, B, X2 >: X](next: => Rule[Out, Out2, B, X2]) = for (a <- this; b <- next orError) yield b\n\n  def -[In2 <: In](exclude: => Rule[In2, Any, Any, Any]) = !exclude -~ this\n\n  /**^~^(f) is equivalent to ^^ { case b1 ~ b2 => f(b1, b2) }\n   */\n  def ^~^[B1, B2, B >: A <% B1 ~ B2, C](f: (B1, B2) => C) = map {a =>\n    (a: B1 ~ B2) match {case b1 ~ b2 => f(b1, b2)}\n  }\n\n  /**^~~^(f) is equivalent to ^^ { case b1 ~ b2 ~ b3 => f(b1, b2, b3) }\n   */\n  def ^~~^[B1, B2, B3, B >: A <% B1 ~ B2 ~ B3, C](f: (B1, B2, B3) => C) = map {\n    a =>\n      (a: B1 ~ B2 ~ B3) match {case b1 ~ b2 ~ b3 => f(b1, b2, b3)}\n  }\n\n  /**^~~~^(f) is equivalent to ^^ { case b1 ~ b2 ~ b3 ~ b4 => f(b1, b2, b3, b4) }\n   */\n  def ^~~~^[B1, B2, B3, B4, B >: A <% B1 ~ B2 ~ B3 ~ B4, C](f: (B1, B2, B3, B4) => C) = map {\n    a =>\n      (a: B1 ~ B2 ~ B3 ~ B4) match {case b1 ~ b2 ~ b3 ~ b4 => f(b1, b2, b3, b4)}\n  }\n\n  /**^~~~~^(f) is equivalent to ^^ { case b1 ~ b2 ~ b3 ~ b4 ~ b5 => f(b1, b2, b3, b4, b5) }\n   */\n  def ^~~~~^[B1, B2, B3, B4, B5, B >: A <% B1 ~ B2 ~ B3 ~ B4 ~ B5, C](f: (B1, B2, B3, B4, B5) => C) = map {\n    a =>\n      (a: B1 ~ B2 ~ B3 ~ B4 ~ B5) match {case b1 ~ b2 ~ b3 ~ b4 ~ b5 => f(b1, b2, b3, b4, b5)}\n  }\n\n  /**^~~~~~^(f) is equivalent to ^^ { case b1 ~ b2 ~ b3 ~ b4 ~ b5 ~ b6 => f(b1, b2, b3, b4, b5, b6) }\n   */\n  def ^~~~~~^[B1, B2, B3, B4, B5, B6, B >: A <% B1 ~ B2 ~ B3 ~ B4 ~ B5 ~ B6, C](f: (B1, B2, B3, B4, B5, B6) => C) = map {\n    a =>\n      (a: B1 ~ B2 ~ B3 ~ B4 ~ B5 ~ B6) match {case b1 ~ b2 ~ b3 ~ b4 ~ b5 ~ b6 => f(b1, b2, b3, b4, b5, b6)}\n  }\n\n  /**^~~~~~~^(f) is equivalent to ^^ { case b1 ~ b2 ~ b3 ~ b4 ~ b5 ~ b6 => f(b1, b2, b3, b4, b5, b6) }\n   */\n  def ^~~~~~~^[B1, B2, B3, B4, B5, B6, B7, B >: A <% B1 ~ B2 ~ B3 ~ B4 ~ B5 ~ B6 ~ B7, C](f: (B1, B2, B3, B4, B5, B6, B7) => C) = map {\n    a =>\n      (a: B1 ~ B2 ~ B3 ~ B4 ~ B5 ~ B6 ~ B7) match {case b1 ~ b2 ~ b3 ~ b4 ~ b5 ~ b6 ~ b7 => f(b1, b2, b3, b4, b5, b6, b7)}\n  }\n\n  /**>~>(f) is equivalent to >> { case b1 ~ b2 => f(b1, b2) }\n   */\n  def >~>[Out2, B1, B2, B >: A <% B1 ~ B2, C, X2 >: X](f: (B1, B2) => Out => Result[Out2, C, X2]) = flatMap {\n    a =>\n      (a: B1 ~ B2) match {case b1 ~ b2 => f(b1, b2)}\n  }\n\n  /**^-^(f) is equivalent to ^^ { b2 => b1 => f(b1, b2) }\n   */\n  def ^-^[B1, B2 >: A, C](f: (B1, B2) => C) = map {b2: B2 =>\n    b1: B1 => f(b1, b2)\n  }\n\n  /**^~>~^(f) is equivalent to ^^ { case b2 ~ b3 => b1 => f(b1, b2, b3) }\n   */\n  def ^~>~^[B1, B2, B3, B >: A <% B2 ~ B3, C](f: (B1, B2, B3) => C) = map {a =>\n    (a: B2 ~ B3) match {case b2 ~ b3 => b1: B1 => f(b1, b2, b3)}\n  }\n}\n\n\ntrait Choice[-In, +Out, +A, +X] extends Rule[In, Out, A, X] {\n  def choices: List[Rule[In, Out, A, X]]\n\n  def apply(in: In) = {\n    def oneOf(list: List[Rule[In, Out, A, X]]): Result[Out, A, X] = list match {\n      case Nil => Failure\n      case first :: rest => first(in) match {\n        case Failure => oneOf(rest)\n        case result => result\n      }\n    }\n    oneOf(choices)\n  }\n\n  override def orElse[In2 <: In, Out2 >: Out, A2 >: A, X2 >: X](other: => Rule[In2, Out2, A2, X2]): Rule[In2, Out2, A2, X2] = new Choice[In2, Out2, A2, X2] {\n    val factory = Choice.this.factory\n    lazy val choices = Choice.this.choices ::: other :: Nil\n  }\n}\n\n\n\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/util/scalax/rules/Rules.scala",
    "content": "package com.codahale.jerkson.util\npackage scalax\npackage rules\n\ntrait Name {\n  def name: String\n\n  override def toString = name\n}\n\n/**A factory for rules.\n *\n * @author Andrew Foggin\n *\n * Inspired by the Scala parser combinator.\n */\ntrait Rules {\n  implicit def rule[In, Out, A, X](f: In => Result[Out, A, X]): Rule[In, Out, A, X] = new DefaultRule(f)\n\n  implicit def inRule[In, Out, A, X](rule: Rule[In, Out, A, X]): InRule[In, Out, A, X] = new InRule(rule)\n\n  implicit def seqRule[In, A, X](rule: Rule[In, In, A, X]): SeqRule[In, A, X] = new SeqRule(rule)\n\n  def from[In] = new {\n    def apply[Out, A, X](f: In => Result[Out, A, X]) = rule(f)\n  }\n\n  def state[s] = new StateRules {\n    type S = s\n    val factory = Rules.this\n  }\n\n  def success[Out, A](out: Out, a: A) = rule {in: Any => Success(out, a)}\n\n  def failure = rule {in: Any => Failure}\n\n  def error[In] = rule {in: In => Error(in)}\n\n  def error[X](err: X) = rule {in: Any => Error(err)}\n\n  def oneOf[In, Out, A, X](rules: Rule[In, Out, A, X]*): Rule[In, Out, A, X] = new Choice[In, Out, A, X] {\n    val factory = Rules.this\n    val choices = rules.toList\n  }\n\n  def ruleWithName[In, Out, A, X](_name: String,\n                                  f: In => Result[Out, A, X]): Rule[In, Out, A, X] with Name =\n    new DefaultRule(f) with Name {\n      val name = _name\n    }\n\n  class DefaultRule[In, Out, A, X](f: In => Result[Out, A, X]) extends Rule[In, Out, A, X] {\n    val factory = Rules.this\n\n    def apply(in: In) = f(in)\n  }\n\n  /**Converts a rule into a function that throws an Exception on failure. */\n  def expect[In, Out, A, Any](rule: Rule[In, Out, A, Any]): In => A = (in) =>\n    rule(in) match {\n      case Success(_, a) => a\n      case Failure => throw new ScalaSigParserError(\"Unexpected failure\")\n      case Error(x) => throw new ScalaSigParserError(\"Unexpected error: \" + x)\n    }\n}\n\n/**A factory for rules that apply to a particular context.\n *\n * @requires S the context to which rules apply.\n *\n * @author Andrew Foggin\n *\n * Inspired by the Scala parser combinator.\n */\ntrait StateRules {\n  type S\n  type Rule[+A, +X] = rules.Rule[S, S, A, X]\n\n  val factory: Rules\n\n  import factory._\n\n  def apply[A, X](f: S => Result[S, A, X]) = rule(f)\n\n  def unit[A](a: => A) = apply {s => Success(s, a)}\n\n  def read[A](f: S => A) = apply {s => Success(s, f(s))}\n\n  def get = apply {s => Success(s, s)}\n\n  def set(s: => S) = apply {oldS => Success(s, oldS)}\n\n  def update(f: S => S) = apply {s => Success(s, f(s))}\n\n  def nil = unit(Nil)\n\n  def none = unit(None)\n\n  /**Create a rule that identities if f(in) is true. */\n  def cond(f: S => Boolean) = get filter f\n\n  /**Create a rule that succeeds if all of the given rules succeed.\n      @param rules the rules to apply in sequence.\n   */\n  def allOf[A, X](rules: Seq[Rule[A, X]]) = {\n    def rep(in: S, rules: List[Rule[A, X]],\n            results: List[A]): Result[S, List[A], X] = {\n      rules match {\n        case Nil => Success(in, results.reverse)\n        case rule :: tl => rule(in) match {\n          case Failure => Failure\n          case Error(x) => Error(x)\n          case Success(out, v) => rep(out, tl, v :: results)\n        }\n      }\n    }\n    in: S => rep(in, rules.toList, Nil)\n  }\n\n\n  /**Create a rule that succeeds with a list of all the provided rules that succeed.\n      @param rules the rules to apply in sequence.\n   */\n  def anyOf[A, X](rules: Seq[Rule[A, X]]) = allOf(rules.map(_ ?)) ^^ {\n    opts => opts.flatMap(x => x)\n  }\n\n  /**Repeatedly apply a rule from initial value until finished condition is met. */\n  def repeatUntil[T, X](rule: Rule[T => T, X])(finished: T => Boolean)\n                       (initial: T) = apply {\n    // more compact using HoF but written this way so it's tail-recursive\n    def rep(in: S, t: T): Result[S, T, X] = {\n      if (finished(t)) Success(in, t)\n      else rule(in) match {\n        case Success(out, f) => rep(out, f(t))\n        case Failure => Failure\n        case Error(x) => Error(x)\n      }\n    }\n    in => rep(in, initial)\n  }\n\n\n}\n\ntrait RulesWithState extends Rules with StateRules {\n  val factory = this\n}\n\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/util/scalax/rules/SeqRule.scala",
    "content": "package com.codahale.jerkson.util\npackage scalax\npackage rules\n\n/**\n * A workaround for the difficulties of dealing with\n * a contravariant 'In' parameter type...\n */\nclass InRule[In, +Out, +A, +X](rule: Rule[In, Out, A, X]) {\n\n  def mapRule[Out2, B, Y](f: Result[Out, A, X] => In => Result[Out2, B, Y]): Rule[In, Out2, B, Y] = rule.factory.rule {\n    in: In => f(rule(in))(in)\n  }\n\n  /**Creates a rule that succeeds only if the original rule would fail on the given context. */\n  def unary_! : Rule[In, In, Unit, Nothing] = mapRule {\n    case Success(_, _) => in: In => Failure\n    case _ => in: In => Success(in, ())\n  }\n\n  /**Creates a rule that succeeds if the original rule succeeds, but returns the original input. */\n  def & : Rule[In, In, A, X] = mapRule {\n    case Success(_, a) => in: In => Success(in, a)\n    case Failure => in: In => Failure\n    case Error(x) => in: In => Error(x)\n  }\n}\n\nclass SeqRule[S, +A, +X](rule: Rule[S, S, A, X]) {\n\n  import rule.factory._\n\n  def ? = rule mapRule {\n    case Success(out, a) => in: S => Success(out, Some(a))\n    case Failure => in: S => Success(in, None)\n    case Error(x) => in: S => Error(x)\n  }\n\n  /**Creates a rule that always succeeds with a Boolean value.\n   *  Value is 'true' if this rule succeeds, 'false' otherwise */\n  def -? = ? map {_ isDefined}\n\n  def * = from[S] {\n    // tail-recursive function with reverse list accumulator\n    def rep(in: S, acc: List[A]): Result[S, List[A], X] = rule(in) match {\n      case Success(out, a) => rep(out, a :: acc)\n      case Failure => Success(in, acc.reverse)\n      case err: Error[_] => err\n    }\n    in => rep(in, Nil)\n  }\n\n  def + = rule ~++ *\n\n  def ~>?[B >: A, X2 >: X](f: => Rule[S, S, B => B, X2]) = for (a <- rule; fs <- f ?) yield fs.foldLeft[B](a) {(b,\n                                                                                                                f) => f(b)\n  }\n\n  def ~>*[B >: A, X2 >: X](f: => Rule[S, S, B => B, X2]) = for (a <- rule; fs <- f *) yield fs.foldLeft[B](a) {(b,\n                                                                                                                f) => f(b)\n  }\n\n  def ~*~[B >: A, X2 >: X](join: => Rule[S, S, (B, B) => B, X2]) = {\n    this ~>* (for (f <- join; a <- rule) yield f(_: B, a))\n  }\n\n  /**Repeats this rule one or more times with a separator (which is discarded) */\n  def +/[X2 >: X](sep: => Rule[S, S, Any, X2]) = rule ~++ (sep -~ rule *)\n\n  /**Repeats this rule zero or more times with a separator (which is discarded) */\n  def */[X2 >: X](sep: => Rule[S, S, Any, X2]) = +/(sep) | state[S].nil\n\n  def *~-[Out, X2 >: X](end: => Rule[S, Out, Any, X2]) = (rule - end *) ~- end\n\n  def +~-[Out, X2 >: X](end: => Rule[S, Out, Any, X2]) = (rule - end +) ~- end\n\n  /**Repeats this rule num times */\n  def times(num: Int): Rule[S, S, Seq[A], X] = from[S] {\n    val result = new collection.mutable.ArraySeq[A](num)\n    // more compact using HoF but written this way so it's tail-recursive\n    def rep(i: Int, in: S): Result[S, Seq[A], X] = {\n      if (i == num) Success(in, result)\n      else rule(in) match {\n        case Success(out, a) => {\n          result(i) = a\n          rep(i + 1, out)\n        }\n        case Failure => Failure\n        case err: Error[_] => err\n      }\n    }\n    in => rep(0, in)\n  }\n}\n\n\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/util/scalax/rules/scalasig/ClassFileParser.scala",
    "content": "package com.codahale.jerkson.util\npackage scalax\npackage rules\npackage scalasig\n\n\nimport java.io.IOException\n\nimport scala._\nimport scala.Predef._\n\nobject ByteCode {\n  def apply(bytes: Array[Byte]) = new ByteCode(bytes, 0, bytes.length)\n\n  def forClass(clazz: Class[_]) = {\n    val name = clazz.getName\n    val subPath = name.substring(name.lastIndexOf('.') + 1) + \".class\"\n    val in = clazz.getResourceAsStream(subPath)\n\n    try {\n      var rest = in.available()\n      val bytes = new Array[Byte](rest)\n      while (rest > 0) {\n        val res = in.read(bytes, bytes.length - rest, rest)\n        if (res == -1) throw new IOException(\"read error\")\n        rest -= res\n      }\n      ByteCode(bytes)\n\n    } finally {\n      in.close()\n    }\n  }\n}\n\n/**Represents a chunk of raw bytecode.  Used as input for the parsers\n */\nclass ByteCode(val bytes: Array[Byte], val pos: Int, val length: Int) {\n\n  assert(pos >= 0 && length >= 0 && pos + length <= bytes.length)\n\n  def nextByte = if (length == 0) Failure else Success(drop(1), bytes(pos))\n\n  def next(n: Int) = if (length >= n) Success(drop(n), take(n)) else Failure\n\n  def take(n: Int) = new ByteCode(bytes, pos, n)\n\n  def drop(n: Int) = new ByteCode(bytes, pos + n, length - n)\n\n  def fold[X](x: X)(f: (X, Byte) => X): X = {\n    var result = x\n    var i = pos\n    while (i < pos + length) {\n      result = f(result, bytes(i))\n      i += 1\n    }\n    result\n  }\n\n  override def toString = length + \" bytes\"\n\n  def toInt = fold(0) {(x, b) => (x << 8) + (b & 0xFF)}\n\n  def toLong = fold(0L) {(x, b) => (x << 8) + (b & 0xFF)}\n\n  private val utf8: Array[Byte] => Array[Char] = {\n    // scala 2.8.1\n    try {\n      val m1 = io.Codec.getClass.getDeclaredMethod(\"toUTF8\", classOf[Array[Byte]]);\n      {f => m1.invoke(io.Codec, f).asInstanceOf[Array[Char]]}\n    } catch {\n      case e: NoSuchMethodException => {\n        // scala 2.9.0.RC1\n        val m2 = io.Codec.getClass.getDeclaredMethod(\"fromUTF8\", classOf[Array[Byte]]);\n        {f => m2.invoke(io.Codec, f).asInstanceOf[Array[Char]]}\n      }\n    }\n  }\n\n  /**\n   * Transforms array subsequence of the current buffer into the UTF8 String and\n   * stores and array of bytes for the decompiler\n   */\n  def fromUTF8StringAndBytes: StringBytesPair = {\n    val chunk: Array[Byte] = bytes drop pos take length\n    StringBytesPair(utf8(chunk).mkString, chunk)\n  }\n\n  def byte(i: Int) = bytes(pos) & 0xFF\n}\n\n/**\n * The wrapper for decode UTF-8 string\n */\ncase class StringBytesPair(string: String, bytes: Array[Byte])\n\n/**Provides rules for parsing byte-code.\n */\ntrait ByteCodeReader extends RulesWithState {\n  type S = ByteCode\n  type Parser[A] = Rule[A, String]\n\n  val byte = apply(_ nextByte)\n\n  val u1 = byte ^^ (_ & 0xFF)\n  val u2 = bytes(2) ^^ (_ toInt)\n  val u4 = bytes(4) ^^ (_ toInt)\n  // should map to Long??\n\n  def bytes(n: Int) = apply(_ next n)\n}\n\nobject ClassFileParser extends ByteCodeReader {\n  def parse(byteCode: ByteCode) = expect(classFile)(byteCode)\n\n  def parseAnnotations(byteCode: ByteCode) = expect(annotations)(byteCode)\n\n  val magicNumber = (u4 filter (_ == 0xCAFEBABE)) | error(\"Not a valid class file\")\n  val version = u2 ~ u2 ^^ {case minor ~ major => (major, minor)}\n  val constantPool = (u2 ^^ ConstantPool) >> repeatUntil(constantPoolEntry)(_ isFull)\n\n  // NOTE currently most constants just evaluate to a string description\n  // TODO evaluate to useful values\n  val utf8String = (u2 >> bytes) ^^ add1 {raw =>\n    pool => raw.fromUTF8StringAndBytes\n  }\n  val intConstant = u4 ^^ add1 {x => pool => x}\n  val floatConstant = bytes(4) ^^ add1 {raw => pool => \"Float: TODO\"}\n  val longConstant = bytes(8) ^^ add2 {raw => pool => raw.toLong}\n  val doubleConstant = bytes(8) ^^ add2 {raw => pool => \"Double: TODO\"}\n  val classRef = u2 ^^ add1 {x => pool => \"Class: \" + pool(x)}\n  val stringRef = u2 ^^ add1 {x => pool => \"String: \" + pool(x)}\n  val fieldRef = memberRef(\"Field\")\n  val methodRef = memberRef(\"Method\")\n  val interfaceMethodRef = memberRef(\"InterfaceMethod\")\n  val nameAndType = u2 ~ u2 ^^ add1 {\n    case name ~ descriptor =>\n      pool => \"NameAndType: \" + pool(name) + \", \" + pool(descriptor)\n  }\n\n  val constantPoolEntry = u1 >> {\n    case 1 => utf8String\n    case 3 => intConstant\n    case 4 => floatConstant\n    case 5 => longConstant\n    case 6 => doubleConstant\n    case 7 => classRef\n    case 8 => stringRef\n    case 9 => fieldRef\n    case 10 => methodRef\n    case 11 => interfaceMethodRef\n    case 12 => nameAndType\n  }\n\n  val interfaces = u2 >> u2.times\n\n  // bytes are parametrizes by the length, declared in u4 section\n  val attribute = u2 ~ (u4 >> bytes) ^~^ Attribute\n  // parse attributes u2 times\n  val attributes = u2 >> attribute.times\n\n  // parse runtime-visible annotations\n  abstract class ElementValue\n\n  case class AnnotationElement(elementNameIndex: Int,\n                               elementValue: ElementValue)\n\n  case class ConstValueIndex(index: Int) extends ElementValue\n\n  case class EnumConstValue(typeNameIndex: Int,\n                            constNameIndex: Int) extends ElementValue\n\n  case class ClassInfoIndex(index: Int) extends ElementValue\n\n  case class Annotation(typeIndex: Int,\n                        elementValuePairs: Seq[AnnotationElement]) extends ElementValue\n\n  case class ArrayValue(values: Seq[ElementValue]) extends ElementValue\n\n  def element_value: Parser[ElementValue] = u1 >> {\n    case 'B' | 'C' | 'D' | 'F' | 'I' | 'J' | 'S' | 'Z' | 's' => u2 ^^ ConstValueIndex\n    case 'e' => u2 ~ u2 ^~^ EnumConstValue\n    case 'c' => u2 ^^ ClassInfoIndex\n    case '@' => annotation //nested annotation\n    case '[' => u2 >> element_value.times ^^ ArrayValue\n  }\n\n  val element_value_pair = u2 ~ element_value ^~^ AnnotationElement\n  val annotation: Parser[Annotation] = u2 ~ (u2 >> element_value_pair.times) ^~^ Annotation\n  val annotations = u2 >> annotation.times\n\n  val field = u2 ~ u2 ~ u2 ~ attributes ^~~~^ Field\n  val fields = u2 >> field.times\n\n  val method = u2 ~ u2 ~ u2 ~ attributes ^~~~^ Method\n  val methods = u2 >> method.times\n\n  val header = magicNumber -~ u2 ~ u2 ~ constantPool ~ u2 ~ u2 ~ u2 ~ interfaces ^~~~~~~^ ClassFileHeader\n  val classFile = header ~ fields ~ methods ~ attributes ~- !u1 ^~~~^ ClassFile\n\n  // TODO create a useful object, not just a string\n  def memberRef(description: String) = u2 ~ u2 ^^ add1 {\n    case classRef ~ nameAndTypeRef =>\n      pool => description + \": \" + pool(classRef) + \", \" + pool(nameAndTypeRef)\n  }\n\n  def add1[T](f: T => ConstantPool => Any)(raw: T)\n             (pool: ConstantPool) = pool add f(raw)\n\n  def add2[T](f: T => ConstantPool => Any)(raw: T)\n             (pool: ConstantPool) = pool add f(raw) add {pool => \"<empty>\"}\n}\n\ncase class ClassFile(\n                            header: ClassFileHeader,\n                            fields: Seq[Field],\n                            methods: Seq[Method],\n                            attributes: Seq[Attribute]) {\n\n  def majorVersion = header.major\n\n  def minorVersion = header.minor\n\n  def className = constant(header.classIndex)\n\n  def superClass = constant(header.superClassIndex)\n\n  def interfaces = header.interfaces.map(constant)\n\n  def constant(index: Int) = header.constants(index) match {\n    case StringBytesPair(str, _) => str\n    case z => z\n  }\n\n  def constantWrapped(index: Int) = header.constants(index)\n\n  def attribute(name: String) = attributes.find {\n    attrib => constant(attrib.nameIndex) == name\n  }\n\n  val RUNTIME_VISIBLE_ANNOTATIONS = \"RuntimeVisibleAnnotations\"\n\n  def annotations = (attributes.find(\n    attr => constant(attr.nameIndex) == RUNTIME_VISIBLE_ANNOTATIONS\n  )\n                     .map(\n    attr => ClassFileParser.parseAnnotations(attr.byteCode)\n  ))\n\n  def annotation(name: String) = annotations.flatMap(\n    seq => seq.find(\n      annot => constant(annot.typeIndex) == name\n    )\n  )\n}\n\ncase class Attribute(nameIndex: Int, byteCode: ByteCode)\n\ncase class Field(flags: Int, nameIndex: Int, descriptorIndex: Int,\n                 attributes: Seq[Attribute])\n\ncase class Method(flags: Int, nameIndex: Int, descriptorIndex: Int,\n                  attributes: Seq[Attribute])\n\ncase class ClassFileHeader(\n                                  minor: Int,\n                                  major: Int,\n                                  constants: ConstantPool,\n                                  flags: Int,\n                                  classIndex: Int,\n                                  superClassIndex: Int,\n                                  interfaces: Seq[Int]) {\n\n  def constant(index: Int) = constants(index)\n}\n\ncase class ConstantPool(len: Int) {\n  val size = len - 1\n\n  private val buffer = new scala.collection.mutable.ArrayBuffer[ConstantPool => Any]\n  private val values = Array.fill[Option[Any]](size)(None)\n\n  def isFull = buffer.length >= size\n\n  def apply(index: Int) = {\n    // Note constant pool indices are 1-based\n    val i = index - 1\n    values(i) getOrElse {\n      val value = buffer(i)(this)\n      buffer(i) = null\n      values(i) = Some(value)\n      value\n    }\n  }\n\n  def add(f: ConstantPool => Any) = {\n    buffer += f\n    this\n  }\n}\n\n\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/util/scalax/rules/scalasig/Flags.scala",
    "content": "package com.codahale.jerkson.util.scalax.rules.scalasig\n\ntrait Flags {\n  def hasFlag(flag: Long): Boolean\n\n  def isImplicit = hasFlag(0x00000001)\n\n  def isFinal = hasFlag(0x00000002)\n\n  def isPrivate = hasFlag(0x00000004)\n\n  def isProtected = hasFlag(0x00000008)\n\n  def isSealed = hasFlag(0x00000010)\n\n  def isOverride = hasFlag(0x00000020)\n\n  def isCase = hasFlag(0x00000040)\n\n  def isAbstract = hasFlag(0x00000080)\n\n  def isDeferred = hasFlag(0x00000100)\n\n  def isMethod = hasFlag(0x00000200)\n\n  def isModule = hasFlag(0x00000400)\n\n  def isInterface = hasFlag(0x00000800)\n\n  def isMutable = hasFlag(0x00001000)\n\n  def isParam = hasFlag(0x00002000)\n\n  def isPackage = hasFlag(0x00004000)\n\n  def isDeprecated = hasFlag(0x00008000)\n\n  def isCovariant = hasFlag(0x00010000)\n\n  def isCaptured = hasFlag(0x00010000)\n\n  def isByNameParam = hasFlag(0x00010000)\n\n  def isContravariant = hasFlag(0x00020000)\n\n  def isLabel = hasFlag(0x00020000)\n\n  // method symbol is a label. Set by TailCall\n  def isInConstructor = hasFlag(0x00020000)\n\n  // class symbol is defined in this/superclass constructor\n\n  def isAbstractOverride = hasFlag(0x00040000)\n\n  def isLocal = hasFlag(0x00080000)\n\n  def isJava = hasFlag(0x00100000)\n\n  def isSynthetic = hasFlag(0x00200000)\n\n  def isStable = hasFlag(0x00400000)\n\n  def isStatic = hasFlag(0x00800000)\n\n  def isCaseAccessor = hasFlag(0x01000000)\n\n  def isTrait = hasFlag(0x02000000)\n\n  def isBridge = hasFlag(0x04000000)\n\n  def isAccessor = hasFlag(0x08000000)\n\n  def isSuperAccessor = hasFlag(0x10000000)\n\n  def isParamAccessor = hasFlag(0x20000000)\n\n  def isModuleVar = hasFlag(0x40000000)\n\n  // for variables: is the variable caching a module value\n  def isMonomorphic = hasFlag(0x40000000)\n\n  // for type symbols: does not have type parameters\n  def isLazy = hasFlag(0x80000000L)\n\n  // symbol is a lazy val. can't have MUTABLE unless transformed by typer\n\n  def isError = hasFlag(0x100000000L)\n\n  def isOverloaded = hasFlag(0x200000000L)\n\n  def isLifted = hasFlag(0x400000000L)\n\n  def isMixedIn = hasFlag(0x800000000L)\n\n  def isExistential = hasFlag(0x800000000L)\n\n  def isExpandedName = hasFlag(0x1000000000L)\n\n  def isImplementationClass = hasFlag(0x2000000000L)\n\n  def isPreSuper = hasFlag(0x2000000000L)\n\n}\n\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/util/scalax/rules/scalasig/ScalaSig.scala",
    "content": "package com.codahale.jerkson.util\npackage scalax\npackage rules\npackage scalasig\n\nimport ClassFileParser.{ConstValueIndex, Annotation}\nimport scala.reflect.generic.ByteCodecs\n\nobject ScalaSigParser {\n\n  import CaseClassSigParser.{SCALA_SIG, SCALA_SIG_ANNOTATION, BYTES_VALUE}\n\n  def scalaSigFromAnnotation(classFile: ClassFile): Option[ScalaSig] = {\n    import classFile._\n\n    classFile.annotation(SCALA_SIG_ANNOTATION) map {\n      case Annotation(_, elements) =>\n        val bytesElem = elements.find(\n          elem => constant(elem.elementNameIndex) == BYTES_VALUE\n        ).get\n        val bytes = ((bytesElem.elementValue match {case ConstValueIndex(index) => constantWrapped(index)})\n                     .asInstanceOf[StringBytesPair].bytes)\n        val length = ByteCodecs.decode(bytes)\n\n        ScalaSigAttributeParsers.parse(ByteCode(bytes.take(length)))\n    }\n  }\n\n  def scalaSigFromAttribute(classFile: ClassFile): Option[ScalaSig] =\n    classFile.attribute(SCALA_SIG).map(_.byteCode).map(ScalaSigAttributeParsers.parse)\n\n  def parse(classFile: ClassFile): Option[ScalaSig] = {\n    val scalaSig = scalaSigFromAttribute(classFile)\n\n    scalaSig match {\n      // No entries in ScalaSig attribute implies that the signature is stored in the annotation\n      case Some(ScalaSig(_, _, entries)) if entries.length == 0 =>\n        scalaSigFromAnnotation(classFile)\n      case x => x\n    }\n  }\n\n  def parse(clazz: Class[_]): Option[ScalaSig] = {\n    val byteCode = ByteCode.forClass(clazz)\n    val classFile = ClassFileParser.parse(byteCode)\n\n    parse(classFile)\n  }\n}\n\nobject ScalaSigAttributeParsers extends ByteCodeReader {\n  def parse(byteCode: ByteCode) = expect(scalaSig)(byteCode)\n\n  val nat = apply {\n    def natN(in: ByteCode,\n             x: Int): Result[ByteCode, Int, Nothing] = in.nextByte match {\n      case Success(out, b) => {\n        val y = (x << 7) + (b & 0x7f)\n        if ((b & 0x80) == 0) Success(out, y) else natN(out, y)\n      }\n      case _ => Failure\n    }\n    in => natN(in, 0)\n  }\n\n  val rawBytes = nat >> bytes\n  val entry = nat ~ rawBytes\n  val symtab = nat >> entry.times\n  val scalaSig = nat ~ nat ~ symtab ^~~^ ScalaSig\n\n  val utf8 = read(x => x.fromUTF8StringAndBytes.string)\n  val longValue = read(_ toLong)\n}\n\ncase class ScalaSig(majorVersion: Int, minorVersion: Int,\n                    table: Seq[Int ~ ByteCode]) extends DefaultMemoisable {\n\n  case class Entry(index: Int, entryType: Int,\n                   byteCode: ByteCode) extends DefaultMemoisable {\n    def scalaSig = ScalaSig.this\n\n    def setByteCode(byteCode: ByteCode) = Entry(index, entryType, byteCode)\n  }\n\n  def hasEntry(index: Int) = table isDefinedAt index\n\n  def getEntry(index: Int) = {\n    val entryType ~ byteCode = table(index)\n    Entry(index, entryType, byteCode)\n  }\n\n  def parseEntry(index: Int) = applyRule(ScalaSigParsers.parseEntry(ScalaSigEntryParsers.entry)(index))\n\n  implicit def applyRule[A](parser: ScalaSigParsers.Parser[A]) = ScalaSigParsers.expect(parser)(this)\n\n  override def toString = \"ScalaSig version \" + majorVersion + \".\" + minorVersion + {\n                                                                                      for (i <- 0 until table.size) yield i + \":\\t\" + parseEntry(i) // + \"\\n\\t\" + getEntry(i)\n                                                                                    }.mkString(\"\\n\", \"\\n\", \"\")\n\n  lazy val symbols: Seq[Symbol] = ScalaSigParsers.symbols\n\n  lazy val topLevelClasses: List[ClassSymbol] = ScalaSigParsers.topLevelClasses\n  lazy val topLevelObjects: List[ObjectSymbol] = ScalaSigParsers.topLevelObjects\n}\n\nobject ScalaSigParsers extends RulesWithState with MemoisableRules {\n  type S = ScalaSig\n  type Parser[A] = Rule[A, String]\n\n  val symTab = read(_.table)\n  val size = symTab ^^ (_.size)\n\n  def entry(index: Int) = memo((\"entry\", index)) {\n    cond(_ hasEntry index) -~ read(_ getEntry index) >-> {\n      entry => Success(entry, entry.entryType)\n    }\n  }\n\n  def parseEntry[A](parser: ScalaSigEntryParsers.EntryParser[A])\n                   (index: Int): Parser[A] =\n    entry(index) -~ parser >> {a => entry => Success(entry.scalaSig, a)}\n\n  def allEntries[A](f: ScalaSigEntryParsers.EntryParser[A]) = size >> {\n    n => anyOf((0 until n) map parseEntry(f))\n  }\n\n  lazy val entries = allEntries(ScalaSigEntryParsers.entry) as \"entries\"\n  lazy val symbols = allEntries(ScalaSigEntryParsers.symbol) as \"symbols\"\n  lazy val methods = allEntries(ScalaSigEntryParsers.methodSymbol) as \"methods\"\n  lazy val attributes = allEntries(ScalaSigEntryParsers.attributeInfo) as \"attributes\"\n\n  lazy val topLevelClasses = allEntries(ScalaSigEntryParsers.topLevelClass)\n  lazy val topLevelObjects = allEntries(ScalaSigEntryParsers.topLevelObject)\n}\n\nobject ScalaSigEntryParsers extends RulesWithState with MemoisableRules {\n\n  import ScalaSigAttributeParsers.{nat, utf8, longValue}\n\n  type S = ScalaSig#Entry\n  type EntryParser[A] = Rule[A, String]\n\n  implicit def byteCodeEntryParser[A](rule: ScalaSigAttributeParsers.Parser[A]): EntryParser[A] = apply {\n    entry =>\n      rule(entry.byteCode) mapOut (entry setByteCode _)\n  }\n\n  def toEntry[A](index: Int) = apply {\n    sigEntry => ScalaSigParsers.entry(index)(sigEntry.scalaSig)\n  }\n\n  def parseEntry[A](parser: EntryParser[A])\n                   (index: Int) = (toEntry(index) -~ parser)\n\n  implicit def entryType(code: Int) = key filter (_ == code)\n\n  val index = read(_.index)\n  val key = read(_.entryType)\n\n  lazy val entry: EntryParser[Any] = symbol | typeEntry | literal | name | attributeInfo | annotInfo | children | get\n\n  val ref = byteCodeEntryParser(nat)\n\n  val termName = 1 -~ utf8\n  val typeName = 2 -~ utf8\n\n  val name = termName | typeName as \"name\"\n\n  def refTo[A](rule: EntryParser[A]): EntryParser[A] = ref >>& parseEntry(rule)\n\n  lazy val nameRef = refTo(name)\n  lazy val symbolRef = refTo(symbol)\n  lazy val typeRef = refTo(typeEntry)\n  lazy val constantRef = refTo(literal)\n\n  val symbolInfo = nameRef ~ symbolRef ~ nat ~ (symbolRef ?) ~ ref ~ get ^~~~~~^ SymbolInfo\n\n  def symHeader(key: Int) = (key -~ none | (key + 64) -~ nat)\n\n  def symbolEntry(key: Int) = symHeader(key) -~ symbolInfo\n\n  /***************************************************\n   * Symbol table attribute format:\n   *   Symtab         = nentries_Nat {Entry}\n   *   Entry          = 1 TERMNAME len_Nat NameInfo\n   *                  | 2 TYPENAME len_Nat NameInfo\n   *                  | 3 NONEsym len_Nat\n   *                  | 4 TYPEsym len_Nat SymbolInfo\n   *                  | 5 ALIASsym len_Nat SymbolInfo\n   *                  | 6 CLASSsym len_Nat SymbolInfo [thistype_Ref]\n   *                  | 7 MODULEsym len_Nat SymbolInfo\n   *                  | 8 VALsym len_Nat [defaultGetter_Ref /* no longer needed*/] SymbolInfo [alias_Ref]\n   *                  | 9 EXTref len_Nat name_Ref [owner_Ref]\n   *                  | 10 EXTMODCLASSref len_Nat name_Ref [owner_Ref]\n   *                  | 11 NOtpe len_Nat\n   *                  | 12 NOPREFIXtpe len_Nat\n   *                  | 13 THIStpe len_Nat sym_Ref\n   *                  | 14 SINGLEtpe len_Nat type_Ref sym_Ref\n   *                  | 15 CONSTANTtpe len_Nat constant_Ref\n   *                  | 16 TYPEREFtpe len_Nat type_Ref sym_Ref {targ_Ref}\n   *                  | 17 TYPEBOUNDStpe len_Nat tpe_Ref tpe_Ref\n   *                  | 18 REFINEDtpe len_Nat classsym_Ref {tpe_Ref}\n   *                  | 19 CLASSINFOtpe len_Nat classsym_Ref {tpe_Ref}\n   *                  | 20 METHODtpe len_Nat tpe_Ref {sym_Ref}\n   *                  | 21 POLYTtpe len_Nat tpe_Ref {sym_Ref}\n   *                  | 22 IMPLICITMETHODtpe len_Nat tpe_Ref {sym_Ref} /* no longer needed */\n   *                  | 52 SUPERtpe len_Nat tpe_Ref tpe_Ref\n   *                  | 24 LITERALunit len_Nat\n   *                  | 25 LITERALboolean len_Nat value_Long\n   *                  | 26 LITERALbyte len_Nat value_Long\n   *                  | 27 LITERALshort len_Nat value_Long\n   *                  | 28 LITERALchar len_Nat value_Long\n   *                  | 29 LITERALint len_Nat value_Long\n   *                  | 30 LITERALlong len_Nat value_Long\n   *                  | 31 LITERALfloat len_Nat value_Long\n   *                  | 32 LITERALdouble len_Nat value_Long\n   *                  | 33 LITERALstring len_Nat name_Ref\n   *                  | 34 LITERALnull len_Nat\n   *                  | 35 LITERALclass len_Nat tpe_Ref\n   *                  | 36 LITERALenum len_Nat sym_Ref\n   *                  | 40 SYMANNOT len_Nat sym_Ref AnnotInfoBody\n   *                  | 41 CHILDREN len_Nat sym_Ref {sym_Ref}\n   *                  | 42 ANNOTATEDtpe len_Nat [sym_Ref /* no longer needed */] tpe_Ref {annotinfo_Ref}\n   *                  | 43 ANNOTINFO len_Nat AnnotInfoBody\n   *                  | 44 ANNOTARGARRAY len_Nat {constAnnotArg_Ref}\n   *                  | 47 DEBRUIJNINDEXtpe len_Nat level_Nat index_Nat\n   *                  | 48 EXISTENTIALtpe len_Nat type_Ref {symbol_Ref}\n   */\n  val noSymbol = 3 -^ NoSymbol\n  val typeSymbol = symbolEntry(4) ^^ TypeSymbol as \"typeSymbol\"\n  val aliasSymbol = symbolEntry(5) ^^ AliasSymbol as \"alias\"\n  val classSymbol = symbolEntry(6) ~ (ref ?) ^~^ ClassSymbol as \"class\"\n  val objectSymbol = symbolEntry(7) ^^ ObjectSymbol as \"object\"\n  val methodSymbol = symHeader(8) -~ /*(ref?) -~*/ symbolInfo ~ (ref ?) ^~^ MethodSymbol as \"method\"\n  val extRef = 9 -~ nameRef ~ (symbolRef ?) ~ get ^~~^ ExternalSymbol as \"extRef\"\n  val extModClassRef = 10 -~ nameRef ~ (symbolRef ?) ~ get ^~~^ ExternalSymbol as \"extModClassRef\"\n\n  lazy val symbol: EntryParser[Symbol] = oneOf(\n    noSymbol,\n    typeSymbol,\n    aliasSymbol,\n    classSymbol,\n    objectSymbol,\n    methodSymbol,\n    extRef,\n    extModClassRef\n  ) as \"symbol\"\n\n  val classSymRef = refTo(classSymbol)\n  val attribTreeRef = ref\n  val typeLevel = nat\n  val typeIndex = nat\n\n  lazy val typeEntry: EntryParser[Type] = oneOf(\n    11 -^ NoType,\n    12 -^ NoPrefixType,\n    13 -~ symbolRef ^^ ThisType,\n    14 -~ typeRef ~ symbolRef ^~^ SingleType,\n    15 -~ constantRef ^^ ConstantType,\n    16 -~ typeRef ~ symbolRef ~ (typeRef *) ^~~^ TypeRefType,\n    17 -~ typeRef ~ typeRef ^~^ TypeBoundsType,\n    18 -~ classSymRef ~ (typeRef *) ^~^ RefinedType,\n    19 -~ symbolRef ~ (typeRef *) ^~^ ClassInfoType,\n    20 -~ typeRef ~ (symbolRef *) ^~^ MethodType,\n    21 -~ typeRef ~ (refTo(typeSymbol) +) ^~^ PolyType, // TODO: make future safe for past by doing the same transformation as in the full unpickler in case we're reading pre-2.9 classfiles\n    21 -~ typeRef ^^ NullaryMethodType,\n    22 -~ typeRef ~ (symbolRef *) ^~^ ImplicitMethodType,\n    42 -~ typeRef ~ (attribTreeRef *) ^~^ AnnotatedType,\n    51 -~ typeRef ~ symbolRef ~ (attribTreeRef *) ^~~^ AnnotatedWithSelfType,\n    47 -~ typeLevel ~ typeIndex ^~^ DeBruijnIndexType,\n    48 -~ typeRef ~ (symbolRef *) ^~^ ExistentialType\n  ) as \"type\"\n\n  lazy val literal = oneOf(\n    24 -^ (),\n    25 -~ longValue ^^ (_ != 0L),\n    26 -~ longValue ^^ (_.toByte),\n    27 -~ longValue ^^ (_.toShort),\n    28 -~ longValue ^^ (_.toChar),\n    29 -~ longValue ^^ (_.toInt),\n    30 -~ longValue ^^ (_.toLong),\n    31 -~ longValue ^^ (l => java.lang.Float.intBitsToFloat(l.toInt)),\n    32 -~ longValue ^^ (java.lang.Double.longBitsToDouble),\n    33 -~ nameRef,\n    34 -^ null,\n    35 -~ typeRef\n  )\n\n  lazy val attributeInfo = 40 -~ symbolRef ~ typeRef ~ (constantRef ?) ~ (nameRef ~ constantRef *) ^~~~^ AttributeInfo\n  // sym_Ref info_Ref {constant_Ref} {nameRef constantRef}\n  lazy val children = 41 -~ (nat *) ^^ Children\n  //sym_Ref {sym_Ref}\n  lazy val annotInfo = 43 -~ (nat *) ^^ AnnotInfo\n  // attarg_Ref {constant_Ref attarg_Ref}\n\n  lazy val topLevelClass = classSymbol filter isTopLevelClass\n  lazy val topLevelObject = objectSymbol filter isTopLevel\n\n  def isTopLevel(symbol: Symbol) = symbol.parent match {\n    case Some(ext: ExternalSymbol) => true\n    case _ => false\n  }\n\n  def isTopLevelClass(symbol: Symbol) = !symbol.isModule && isTopLevel(symbol)\n}\n\ncase class AttributeInfo(symbol: Symbol, typeRef: Type, value: Option[Any],\n                         values: Seq[String ~ Any])\n\n// sym_Ref info_Ref {constant_Ref} {nameRef constantRef}\ncase class Children(symbolRefs: Seq[Int])\n\n//sym_Ref {sym_Ref}\n\ncase class AnnotInfo(refs: Seq[Int])\n\n// attarg_Ref {constant_Ref attarg_Ref}\n\n/***************************************************\n *                  | 49 TREE len_Nat 1 EMPTYtree\n *                  | 49 TREE len_Nat 2 PACKAGEtree type_Ref sym_Ref mods_Ref name_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 3 CLASStree type_Ref sym_Ref mods_Ref name_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 4 MODULEtree type_Ref sym_Ref mods_Ref name_Ref tree_Ref\n *                  | 49 TREE len_Nat 5 VALDEFtree type_Ref sym_Ref mods_Ref name_Ref tree_Ref tree_Ref\n *                  | 49 TREE len_Nat 6 DEFDEFtree type_Ref sym_Ref mods_Ref name_Ref numtparams_Nat {tree_Ref} numparamss_Nat {numparams_Nat {tree_Ref}} tree_Ref tree_Ref\n *                  | 49 TREE len_Nat 7 TYPEDEFtree type_Ref sym_Ref mods_Ref name_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 8 LABELtree type_Ref sym_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 9 IMPORTtree type_Ref sym_Ref tree_Ref {name_Ref name_Ref}\n *                  | 49 TREE len_Nat 11 DOCDEFtree type_Ref sym_Ref string_Ref tree_Ref\n *                  | 49 TREE len_Nat 12 TEMPLATEtree type_Ref sym_Ref numparents_Nat {tree_Ref} tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 13 BLOCKtree type_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 14 CASEtree type_Ref tree_Ref tree_Ref tree_Ref\n *                  | 49 TREE len_Nat 15 SEQUENCEtree type_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 16 ALTERNATIVEtree type_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 17 STARtree type_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 18 BINDtree type_Ref sym_Ref name_Ref tree_Ref\n *                  | 49 TREE len_Nat 19 UNAPPLYtree type_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 20 ARRAYVALUEtree type_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 21 FUNCTIONtree type_Ref sym_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 22 ASSIGNtree type_Ref tree_Ref tree_Ref\n *                  | 49 TREE len_Nat 23 IFtree type_Ref tree_Ref tree_Ref tree_Ref\n *                  | 49 TREE len_Nat 24 MATCHtree type_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 25 RETURNtree type_Ref sym_Ref tree_Ref\n *                  | 49 TREE len_Nat 26 TREtree type_Ref tree_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 27 THROWtree type_Ref tree_Ref\n *                  | 49 TREE len_Nat 28 NEWtree type_Ref tree_Ref\n *                  | 49 TREE len_Nat 29 TYPEDtree type_Ref tree_Ref tree_Ref\n *                  | 49 TREE len_Nat 30 TYPEAPPLYtree type_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 31 APPLYtree type_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 32 APPLYDYNAMICtree type_Ref sym_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 33 SUPERtree type_Ref sym_Ref tree_Ref name_Ref\n *                  | 49 TREE len_Nat 34 THIStree type_Ref sym_Ref  name_Ref\n *                  | 49 TREE len_Nat 35 SELECTtree type_Ref sym_Ref tree_Ref name_Ref\n *                  | 49 TREE len_Nat 36 IDENTtree type_Ref sym_Ref name_Ref\n *                  | 49 TREE len_Nat 37 LITERALtree type_Ref constant_Ref\n *                  | 49 TREE len_Nat 38 TYPEtree type_Ref\n *                  | 49 TREE len_Nat 39 ANNOTATEDtree type_Ref tree_Ref tree_Ref\n *                  | 49 TREE len_Nat 40 SINGLETONTYPEtree type_Ref tree_Ref\n *                  | 49 TREE len_Nat 41 SELECTFROMTYPEtree type_Ref tree_Ref name_Ref\n *                  | 49 TREE len_Nat 42 COMPOUNDTYPEtree type_Ref tree_Ref\n *                  | 49 TREE len_Nat 43 APPLIEDTYPEtree type_Ref tree_Ref {tree_Ref}\n *                  | 49 TREE len_Nat 44 TYPEBOUNDStree type_Ref tree_Ref tree_Ref\n *                  | 49 TREE len_Nat 45 EXISTENTIALTYPEtree type_Ref tree_Ref {tree_Ref}\n *                  | 50 MODIFIERS len_Nat flags_Long privateWithin_Ref\n *   SymbolInfo     = name_Ref owner_Ref flags_LongNat [privateWithin_Ref] info_Ref\n *   NameInfo       = <character sequence of length len_Nat in Utf8 format>\n *   NumInfo        = <len_Nat-byte signed number in big endian format>\n *   Ref            = Nat\n *   AnnotInfoBody  = info_Ref {annotArg_Ref} {name_Ref constAnnotArg_Ref}\n *   AnnotArg       = Tree | Constant\n *   ConstAnnotArg  = Constant | AnnotInfo | AnnotArgArray\n *\n *   len is remaining length after `len'.\n */\n\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/util/scalax/rules/scalasig/Symbol.scala",
    "content": "package com.codahale.jerkson.util\npackage scalax\npackage rules\npackage scalasig\n\nimport ScalaSigEntryParsers._\n\ntrait Symbol extends Flags {\n  def name: String\n\n  def parent: Option[Symbol]\n\n  def children: Seq[Symbol]\n\n  def path: String = parent.map(_.path + \".\").getOrElse(\"\") + name\n}\n\ncase object NoSymbol extends Symbol {\n  def name = \"<no symbol>\"\n\n  def parent = None\n\n  def hasFlag(flag: Long) = false\n\n  def children = Nil\n}\n\nabstract class ScalaSigSymbol extends Symbol {\n  def applyRule[A](rule: EntryParser[A]): A = expect(rule)(entry)\n\n  def applyScalaSigRule[A](rule: ScalaSigParsers.Parser[A]) = ScalaSigParsers.expect(rule)(entry.scalaSig)\n\n  def entry: ScalaSig#Entry\n\n  def index = entry.index\n\n  lazy val children: Seq[Symbol] = applyScalaSigRule(ScalaSigParsers.symbols) filter (_.parent == Some(this))\n  lazy val attributes: Seq[AttributeInfo] = applyScalaSigRule(ScalaSigParsers.attributes) filter (_.symbol == this)\n}\n\ncase class ExternalSymbol(name: String, parent: Option[Symbol],\n                          entry: ScalaSig#Entry) extends ScalaSigSymbol {\n  override def toString = path\n\n  def hasFlag(flag: Long) = false\n}\n\ncase class SymbolInfo(name: String, owner: Symbol, flags: Int,\n                      privateWithin: Option[AnyRef], info: Int,\n                      entry: ScalaSig#Entry) {\n  def symbolString(any: AnyRef) = any match {\n    case sym: SymbolInfoSymbol => sym.index.toString\n    case other => other.toString\n  }\n\n  override def toString = name + \", owner=\" + symbolString(owner) + \", flags=\" + flags.toHexString + \", info=\" + info + (privateWithin match {\n    case Some(any) => \", privateWithin=\" + symbolString(any)\n    case None => \" \"\n  })\n}\n\nabstract class SymbolInfoSymbol extends ScalaSigSymbol {\n  def symbolInfo: SymbolInfo\n\n  def entry = symbolInfo.entry\n\n  def name = symbolInfo.name\n\n  def parent = Some(symbolInfo.owner)\n\n  def hasFlag(flag: Long) = (symbolInfo.flags & flag) != 0L\n\n  lazy val infoType = applyRule(parseEntry(typeEntry)(symbolInfo.info))\n}\n\ncase class TypeSymbol(symbolInfo: SymbolInfo) extends SymbolInfoSymbol {\n  override def path = name\n}\n\ncase class AliasSymbol(symbolInfo: SymbolInfo) extends SymbolInfoSymbol {\n  override def path = name\n}\n\ncase class ClassSymbol(symbolInfo: SymbolInfo,\n                       thisTypeRef: Option[Int]) extends SymbolInfoSymbol {\n  lazy val selfType = thisTypeRef.map {(x: Int) => applyRule(parseEntry(typeEntry)(x))}\n}\n\ncase class ObjectSymbol(symbolInfo: SymbolInfo) extends SymbolInfoSymbol\n\ncase class MethodSymbol(symbolInfo: SymbolInfo,\n                        aliasRef: Option[Int]) extends SymbolInfoSymbol\n\n"
  },
  {
    "path": "src/main/scala/com/codahale/jerkson/util/scalax/rules/scalasig/Type.scala",
    "content": "package com.codahale.jerkson.util\npackage scalax\npackage rules\npackage scalasig\n\nabstract class Type\n\ncase object NoType extends Type\n\ncase object NoPrefixType extends Type\n\ncase class ThisType(symbol: Symbol) extends Type\n\ncase class SingleType(typeRef: Type, symbol: Symbol) extends Type\n\ncase class ConstantType(constant: Any) extends Type\n\ncase class TypeRefType(prefix: Type, symbol: Symbol,\n                       typeArgs: Seq[Type]) extends Type\n\ncase class TypeBoundsType(lower: Type, upper: Type) extends Type\n\ncase class RefinedType(classSym: Symbol, typeRefs: List[Type]) extends Type\n\ncase class ClassInfoType(symbol: Symbol, typeRefs: Seq[Type]) extends Type\n\ncase class ClassInfoTypeWithCons(symbol: Symbol, typeRefs: Seq[Type],\n                                 cons: String) extends Type\n\ncase class MethodType(resultType: Type, paramSymbols: Seq[Symbol]) extends Type\n\ncase class NullaryMethodType(resultType: Type) extends Type\n\ncase class PolyType(typeRef: Type, symbols: Seq[TypeSymbol]) extends Type\n\ncase class PolyTypeWithCons(typeRef: Type, symbols: Seq[TypeSymbol],\n                            cons: String) extends Type\n\ncase class ImplicitMethodType(resultType: Type,\n                              paramSymbols: Seq[Symbol]) extends Type\n\ncase class AnnotatedType(typeRef: Type, attribTreeRefs: List[Int]) extends Type\n\ncase class AnnotatedWithSelfType(typeRef: Type, symbol: Symbol,\n                                 attribTreeRefs: List[Int]) extends Type\n\ncase class DeBruijnIndexType(typeLevel: Int, typeIndex: Int) extends Type\n\ncase class ExistentialType(typeRef: Type, symbols: Seq[Symbol]) extends Type\n"
  },
  {
    "path": "src/test/scala/com/codahale/jerkson/tests/ASTTypeSupportSpec.scala",
    "content": "package com.codahale.jerkson.tests\n\nimport com.codahale.jerkson.Json._\nimport com.codahale.jerkson.AST._\nimport com.codahale.simplespec.Spec\nimport org.junit.Test\n\nclass ASTTypeSupportSpec extends Spec {\n  class `An AST.JInt` {\n    @Test def `generates a JSON int` = {\n      generate(JInt(15)).must(be(\"15\"))\n    }\n\n    @Test def `is parsable from a JSON int` = {\n      parse[JInt](\"15\").must(be(JInt(15)))\n    }\n\n    @Test def `is parsable from a JSON int as a JValue` = {\n      parse[JValue](\"15\").must(be(JInt(15)))\n    }\n  }\n\n  class `An AST.JFloat` {\n    @Test def `generates a JSON int` = {\n      generate(JFloat(15.1)).must(be(\"15.1\"))\n    }\n\n    @Test def `is parsable from a JSON float` = {\n      parse[JFloat](\"15.1\").must(be(JFloat(15.1)))\n    }\n\n    @Test def `is parsable from a JSON float as a JValue` = {\n      parse[JValue](\"15.1\").must(be(JFloat(15.1)))\n    }\n  }\n\n\n  class `An AST.JString` {\n    @Test def `generates a JSON string` = {\n      generate(JString(\"woo\")).must(be(\"\\\"woo\\\"\"))\n    }\n\n    @Test def `is parsable from a JSON string` = {\n      parse[JString](\"\\\"woo\\\"\").must(be(JString(\"woo\")))\n    }\n\n    @Test def `is parsable from a JSON string as a JValue` = {\n      parse[JValue](\"\\\"woo\\\"\").must(be(JString(\"woo\")))\n    }\n  }\n\n  class `An AST.JNull` {\n    @Test def `generates a JSON null` = {\n      generate(JNull).must(be(\"null\"))\n    }\n\n    @Test def `is parsable from a JSON null` = {\n      parse[JNull.type](\"null\").must(be(JNull))\n    }\n\n    @Test def `is parsable from a JSON null as a JValue` = {\n      parse[JValue](\"null\").must(be(JNull))\n    }\n  }\n\n  class `An AST.JBoolean` {\n    @Test def `generates a JSON true` = {\n      generate(JBoolean(true)).must(be(\"true\"))\n    }\n\n    @Test def `generates a JSON false` = {\n      generate(JBoolean(false)).must(be(\"false\"))\n    }\n\n    @Test def `is parsable from a JSON true` = {\n      parse[JBoolean](\"true\").must(be(JBoolean(true)))\n    }\n\n    @Test def `is parsable from a JSON false` = {\n      parse[JBoolean](\"false\").must(be(JBoolean(false)))\n    }\n\n    @Test def `is parsable from a JSON true as a JValue` = {\n      parse[JValue](\"true\").must(be(JBoolean(true)))\n    }\n\n    @Test def `is parsable from a JSON false as a JValue` = {\n      parse[JValue](\"false\").must(be(JBoolean(false)))\n    }\n  }\n\n  class `An AST.JArray of JInts` {\n    @Test def `generates a JSON array of ints` = {\n      generate(JArray(List(JInt(1), JInt(2), JInt(3)))).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[JArray](\"[1,2,3]\").must(be(JArray(List(JInt(1), JInt(2), JInt(3)))))\n    }\n\n    @Test def `is parsable from a JSON array of ints as a JValue` = {\n      parse[JValue](\"[1,2,3]\").must(be(JArray(List(JInt(1), JInt(2), JInt(3)))))\n    }\n  }\n\n  class `An AST.JObject` {\n    val obj = JObject(List(JField(\"id\", JInt(1)), JField(\"name\", JString(\"Coda\"))))\n\n    @Test def `generates a JSON object with matching field values` = {\n      generate(obj).must(be(\"\"\"{\"id\":1,\"name\":\"Coda\"}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object` = {\n      parse[JObject](\"\"\"{\"id\":1,\"name\":\"Coda\"}\"\"\").must(be(obj))\n    }\n\n    @Test def `is parsable from a JSON object as a JValue` = {\n      parse[JValue](\"\"\"{\"id\":1,\"name\":\"Coda\"}\"\"\").must(be(obj))\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[JObject](\"\"\"{}\"\"\").must(be(JObject(Nil)))\n    }\n  }\n}\n"
  },
  {
    "path": "src/test/scala/com/codahale/jerkson/tests/BasicTypeSupportSpec.scala",
    "content": "package com.codahale.jerkson.tests\n\nimport com.codahale.simplespec.Spec\nimport com.codahale.jerkson.Json._\nimport com.fasterxml.jackson.databind.node.IntNode\nimport com.fasterxml.jackson.databind.JsonNode\nimport org.junit.Test\n\nclass BasicTypeSupportSpec extends Spec {\n  class `A Byte` {\n    @Test def `generates a JSON int` = {\n      generate(15.toByte).must(be(\"15\"))\n    }\n\n    @Test def `is parsable from a JSON int` = {\n      parse[Byte](\"15\").must(be(15))\n    }\n  }\n\n  class `A Short` {\n    @Test def `generates a JSON int` = {\n      generate(15.toShort).must(be(\"15\"))\n    }\n\n    @Test def `is parsable from a JSON int` = {\n      parse[Short](\"15\").must(be(15))\n    }\n  }\n\n  class `An Int` {\n    @Test def `generates a JSON int` = {\n      generate(15).must(be(\"15\"))\n    }\n\n    @Test def `is parsable from a JSON int` = {\n      parse[Int](\"15\").must(be(15))\n    }\n  }\n\n  class `A Long` {\n    @Test def `generates a JSON int` = {\n      generate(15L).must(be(\"15\"))\n    }\n\n    @Test def `is parsable from a JSON int` = {\n      parse[Long](\"15\").must(be(15L))\n    }\n  }\n\n  class `A BigInt` {\n    @Test def `generates a JSON int` = {\n      generate(BigInt(15)).must(be(\"15\"))\n    }\n\n    @Test def `is parsable from a JSON int` = {\n      parse[BigInt](\"15\").must(be(BigInt(15)))\n    }\n\n    @Test def `is parsable from a JSON string` = {\n      parse[BigInt](\"\\\"15\\\"\").must(be(BigInt(15)))\n    }\n  }\n\n  class `A Float` {\n    @Test def `generates a JSON float` = {\n      generate(15.1F).must(be(\"15.1\"))\n    }\n\n    @Test def `is parsable from a JSON float` = {\n      parse[Float](\"15.1\").must(be(15.1F))\n    }\n  }\n\n  class `A Double` {\n    @Test def `generates a JSON float` = {\n      generate(15.1).must(be(\"15.1\"))\n    }\n\n    @Test def `is parsable from a JSON float` = {\n      parse[Double](\"15.1\").must(be(15.1D))\n    }\n  }\n\n  class `A BigDecimal` {\n    @Test def `generates a JSON float` = {\n      generate(BigDecimal(15.5)).must(be(\"15.5\"))\n    }\n\n    @Test def `is parsable from a JSON float` = {\n      parse[BigDecimal](\"15.5\").must(be(BigDecimal(15.5)))\n    }\n\n    @Test def `is parsable from a JSON int` = {\n      parse[BigDecimal](\"15\").must(be(BigDecimal(15.0)))\n    }\n  }\n\n  class `A String` {\n    @Test def `generates a JSON string` = {\n      generate(\"woo\").must(be(\"\\\"woo\\\"\"))\n    }\n\n    @Test def `is parsable from a JSON string` = {\n      parse[String](\"\\\"woo\\\"\").must(be(\"woo\"))\n    }\n  }\n\n  class `A StringBuilder` {\n    @Test def `generates a JSON string` = {\n      generate(new StringBuilder(\"foo\")).must(be(\"\\\"foo\\\"\"))\n    }\n\n    @Test def `is parsable from a JSON string` = {\n      parse[StringBuilder](\"\\\"foo\\\"\").toString().must(be(\"foo\"))\n    }\n  }\n\n  class `A null Object` {\n    @Test def `generates a JSON null` = {\n      generate[Object](null).must(be(\"null\"))\n    }\n\n    @Test def `is parsable from a JSON null` = {\n      parse[Object](\"null\").must(be(not(notNull)))\n    }\n  }\n\n  class `A Boolean` {\n    @Test def `generates a JSON true` = {\n      generate(true).must(be(\"true\"))\n    }\n\n    @Test def `generates a JSON false` = {\n      generate(false).must(be(\"false\"))\n    }\n\n    @Test def `is parsable from a JSON true` = {\n      parse[Boolean](\"true\").must(be(true))\n    }\n\n    @Test def `is parsable from a JSON false` = {\n      parse[Boolean](\"false\").must(be(false))\n    }\n  }\n\n  class `A Some[Int]` {\n    @Test def `generates a JSON int` = {\n      generate(Some(12)).must(be(\"12\"))\n    }\n\n    @Test def `is parsable from a JSON int as an Option[Int]` = {\n      parse[Option[Int]](\"12\").must(be(Some(12)))\n    }\n  }\n\n  class `A None` {\n    @Test def `generates a JSON null` = {\n      generate(None).must(be(\"null\"))\n    }\n\n    @Test def `is parsable from a JSON null as an Option[Int]` = {\n      parse[Option[Int]](\"null\").must(be(None))\n    }\n  }\n\n  class `A Left[String]` {\n    @Test def `generates a JSON string` = {\n      generate(Left(\"woo\")).must(be(\"\\\"woo\\\"\"))\n    }\n\n    @Test def `is parsable from a JSON string as an Either[String, Int]` = {\n      parse[Either[String, Int]](\"\\\"woo\\\"\").must(be(Left(\"woo\")))\n    }\n  }\n\n  class `A Right[String]` {\n    @Test def `generates a JSON string` = {\n      generate(Right(\"woo\")).must(be(\"\\\"woo\\\"\"))\n    }\n\n    @Test def `is parsable from a JSON string as an Either[Int, String]` = {\n      parse[Either[Int, String]](\"\\\"woo\\\"\").must(be(Right(\"woo\")))\n    }\n  }\n\n  class `A JsonNode` {\n    @Test def `generates whatever the JsonNode is` = {\n      generate(new IntNode(2)).must(be(\"2\"))\n    }\n\n    @Test def `is parsable from a JSON AST node` = {\n      parse[JsonNode](\"2\").must(be(new IntNode(2)))\n    }\n\n    @Test def `is parsable from a JSON AST node as a specific type` = {\n      parse[IntNode](\"2\").must(be(new IntNode(2)))\n    }\n\n    @Test def `is itself parsable` = {\n      parse[Int](new IntNode(2)).must(be(2))\n    }\n  }\n\n  class `An Array[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Array(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Array[Int]](\"[1,2,3]\").toList.must(be(List(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Array[Int]](\"[]\").toList.must(be(List.empty))\n    }\n  }\n}\n"
  },
  {
    "path": "src/test/scala/com/codahale/jerkson/tests/CaseClassSupportSpec.scala",
    "content": "package com.codahale.jerkson.tests\n\nimport com.codahale.jerkson.Json._\nimport com.codahale.simplespec.Spec\nimport com.codahale.jerkson.ParsingException\nimport com.fasterxml.jackson.databind.node.IntNode\nimport org.junit.Test\n\nclass CaseClassSupportSpec extends Spec {\n  class `A basic case class` {\n    @Test def `generates a JSON object with matching field values` = {\n      generate(CaseClass(1, \"Coda\")).must(be(\"\"\"{\"id\":1,\"name\":\"Coda\"}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with corresponding fields` = {\n      parse[CaseClass](\"\"\"{\"id\":1,\"name\":\"Coda\"}\"\"\").must(be(CaseClass(1, \"Coda\")))\n    }\n\n    @Test def `is parsable from a JSON object with extra fields` = {\n      parse[CaseClass](\"\"\"{\"id\":1,\"name\":\"Coda\",\"derp\":100}\"\"\").must(be(CaseClass(1, \"Coda\")))\n    }\n\n    @Test def `is not parsable from an incomplete JSON object` = {\n      evaluating {\n        parse[CaseClass](\"\"\"{\"id\":1}\"\"\")\n      }.must(throwA[ParsingException](\"\"\"Invalid JSON. Needed [id, name], but found [id].\"\"\"))\n    }\n  }\n\n  class `A case class with lazy fields` {\n    @Test def `generates a JSON object with those fields evaluated` = {\n      generate(CaseClassWithLazyVal(1)).must(be(\"\"\"{\"id\":1,\"woo\":\"yeah\"}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object without those fields` = {\n      parse[CaseClassWithLazyVal](\"\"\"{\"id\":1}\"\"\").must(be(CaseClassWithLazyVal(1)))\n    }\n\n    @Test def `is not parsable from an incomplete JSON object` = {\n      evaluating {\n        parse[CaseClassWithLazyVal](\"\"\"{}\"\"\")\n      }.must(throwA[ParsingException](\"\"\"Invalid JSON. Needed [id], but found [].\"\"\"))\n    }\n  }\n\n  class `A case class with ignored members` {\n    @Test def `generates a JSON object without those fields` = {\n      generate(CaseClassWithIgnoredField(1)).must(be(\"\"\"{\"id\":1}\"\"\"))\n      generate(CaseClassWithIgnoredFields(1)).must(be(\"\"\"{\"id\":1}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object without those fields` = {\n      parse[CaseClassWithIgnoredField](\"\"\"{\"id\":1}\"\"\").must(be(CaseClassWithIgnoredField(1)))\n      parse[CaseClassWithIgnoredFields](\"\"\"{\"id\":1}\"\"\").must(be(CaseClassWithIgnoredFields(1)))\n    }\n\n    @Test def `is not parsable from an incomplete JSON object` = {\n      evaluating {\n        parse[CaseClassWithIgnoredField](\"\"\"{}\"\"\")\n      }.must(throwA[ParsingException](\"\"\"Invalid JSON. Needed [id], but found [].\"\"\"))\n\n      evaluating {\n        parse[CaseClassWithIgnoredFields](\"\"\"{}\"\"\")\n      }.must(throwA[ParsingException](\"\"\"Invalid JSON. Needed [id], but found [].\"\"\"))\n    }\n  }\n\n  class `A case class with transient members` {\n    @Test def `generates a JSON object without those fields` = {\n      generate(CaseClassWithTransientField(1)).must(be(\"\"\"{\"id\":1}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object without those fields` = {\n      parse[CaseClassWithTransientField](\"\"\"{\"id\":1}\"\"\").must(be(CaseClassWithTransientField(1)))\n    }\n\n    @Test def `is not parsable from an incomplete JSON object` = {\n      evaluating {\n        parse[CaseClassWithTransientField](\"\"\"{}\"\"\")\n      }.must(throwA[ParsingException](\"\"\"Invalid JSON. Needed [id], but found [].\"\"\"))\n    }\n  }\n\n  class `A case class with an overloaded field` {\n    @Test def `generates a JSON object with the nullary version of that field` = {\n      generate(CaseClassWithOverloadedField(1)).must(be(\"\"\"{\"id\":1}\"\"\"))\n    }\n  }\n\n  class `A case class with an Option[String] member` {\n    @Test def `generates a field if the member is Some` = {\n      generate(CaseClassWithOption(Some(\"what\"))).must(be(\"\"\"{\"value\":\"what\"}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with that field` = {\n      parse[CaseClassWithOption](\"\"\"{\"value\":\"what\"}\"\"\").must(be(CaseClassWithOption(Some(\"what\"))))\n    }\n\n    @Test def `doesn't generate a field if the member is None` = {\n      generate(CaseClassWithOption(None)).must(be(\"\"\"{}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object without that field` = {\n      parse[CaseClassWithOption](\"\"\"{}\"\"\").must(be(CaseClassWithOption(None)))\n    }\n\n    @Test def `is parsable from a JSON object with a null value for that field` = {\n      parse[CaseClassWithOption](\"\"\"{\"value\":null}\"\"\").must(be(CaseClassWithOption(None)))\n    }\n  }\n\n  class `A case class with a JsonNode member` {\n    @Test def `generates a field of the given type` = {\n      generate(CaseClassWithJsonNode(new IntNode(2))).must(be(\"\"\"{\"value\":2}\"\"\"))\n    }\n  }\n\n  class `A case class with members of all ScalaSig types` {\n    val json = \"\"\"\n               {\n                 \"map\": {\n                   \"one\": \"two\"\n                 },\n                 \"set\": [1, 2, 3],\n                 \"string\": \"woo\",\n                 \"list\": [4, 5, 6],\n                 \"seq\": [7, 8, 9],\n                 \"sequence\": [10, 11, 12],\n                 \"collection\": [13, 14, 15],\n                 \"indexedSeq\": [16, 17, 18],\n                 \"randomAccessSeq\": [19, 20, 21],\n                 \"vector\": [22, 23, 24],\n                 \"bigDecimal\": 12.0,\n                 \"bigInt\": 13,\n                 \"int\": 1,\n                 \"long\": 2,\n                 \"char\": \"x\",\n                 \"bool\": false,\n                 \"short\": 14,\n                 \"byte\": 15,\n                 \"float\": 34.5,\n                 \"double\": 44.9,\n                 \"any\": true,\n                 \"anyRef\": \"wah\",\n                 \"intMap\": {\n                   \"1\": \"1\"\n                 },\n                 \"longMap\": {\n                   \"2\": 2\n                 }\n               }\n               \"\"\"\n\n\n    @Test def `is parsable from a JSON object with those fields` = {\n      parse[CaseClassWithAllTypes](json).must(be(\n        CaseClassWithAllTypes(\n          map = Map(\"one\" -> \"two\"),\n          set = Set(1, 2, 3),\n          string = \"woo\",\n          list = List(4, 5, 6),\n          seq = Seq(7, 8, 9),\n          indexedSeq = IndexedSeq(16, 17, 18),\n          vector = Vector(22, 23, 24),\n          bigDecimal = BigDecimal(\"12.0\"),\n          bigInt = BigInt(\"13\"),\n          int = 1,\n          long = 2L,\n          char = 'x',\n          bool = false,\n          short = 14,\n          byte = 15,\n          float = 34.5f,\n          double = 44.9d,\n          any = true,\n          anyRef = \"wah\",\n          intMap = Map(1 -> 1),\n          longMap = Map(2L -> 2L)\n        )\n      ))\n    }\n  }\n\n  class `A case class nested inside of an object` {\n    @Test def `is parsable from a JSON object` = {\n      parse[OuterObject.NestedCaseClass](\"\"\"{\"id\": 1}\"\"\").must(be(OuterObject.NestedCaseClass(1)))\n    }\n  }\n\n  class `A case class nested inside of an object nested inside of an object` {\n    @Test def `is parsable from a JSON object` = {\n      parse[OuterObject.InnerObject.SuperNestedCaseClass](\"\"\"{\"id\": 1}\"\"\").must(be(OuterObject.InnerObject.SuperNestedCaseClass(1)))\n    }\n  }\n\n  class `A case class with two constructors` {\n    @Test def `is parsable from a JSON object with the same parameters as the case accessor` = {\n      parse[CaseClassWithTwoConstructors](\"\"\"{\"id\":1,\"name\":\"Bert\"}\"\"\").must(be(CaseClassWithTwoConstructors(1, \"Bert\")))\n    }\n\n    @Test def `is parsable from a JSON object which works with the second constructor` = {\n      evaluating {\n        parse[CaseClassWithTwoConstructors](\"\"\"{\"id\":1}\"\"\")\n      }.must(throwA[ParsingException])\n    }\n  }\n\n  class `A case class with snake-cased fields` {\n    @Test def `is parsable from a snake-cased JSON object` = {\n      parse[CaseClassWithSnakeCase](\"\"\"{\"one_thing\":\"yes\",\"two_thing\":\"good\"}\"\"\").must(be(CaseClassWithSnakeCase(\"yes\", \"good\")))\n    }\n\n    @Test def `generates a snake-cased JSON object` = {\n      generate(CaseClassWithSnakeCase(\"yes\", \"good\")).must(be(\"\"\"{\"one_thing\":\"yes\",\"two_thing\":\"good\"}\"\"\"))\n    }\n\n    @Test def `throws errors with the snake-cased field names present` = {\n      evaluating {\n        parse[CaseClassWithSnakeCase](\"\"\"{\"one_thing\":\"yes\"}\"\"\")\n      }.must(throwA[ParsingException](\"Invalid JSON. Needed [one_thing, two_thing], but found [one_thing].\"))\n    }\n  }\n\n  class `A case class with array members` {\n    @Test def `is parsable from a JSON object` = {\n      val c = parse[CaseClassWithArrays](\"\"\"{\"one\":\"1\",\"two\":[\"a\",\"b\",\"c\"],\"three\":[1,2,3]}\"\"\")\n\n      c.one.must(be(\"1\"))\n      c.two.must(be(Array(\"a\", \"b\", \"c\")))\n      c.three.must(be(Array(1, 2, 3)))\n    }\n\n    @Test def `generates a JSON object` = {\n      generate(CaseClassWithArrays(\"1\", Array(\"a\", \"b\", \"c\"), Array(1, 2, 3))).must(be(\n        \"\"\"{\"one\":\"1\",\"two\":[\"a\",\"b\",\"c\"],\"three\":[1,2,3]}\"\"\"\n      ))\n    }\n  }\n}\n"
  },
  {
    "path": "src/test/scala/com/codahale/jerkson/tests/CollectionSupportSpec.scala",
    "content": "package com.codahale.jerkson.tests\n\nimport scala.collection._\nimport com.codahale.jerkson.Json._\nimport com.codahale.simplespec.Spec\nimport org.junit.{Ignore, Test}\n\nclass CollectionSupportSpec extends Spec {\n  class `A collection.BitSet` {\n    @Test def `generates a JSON array of ints` = {\n      generate(BitSet(1)).must(be(\"[1]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[BitSet](\"[1,2,3]\").must(be(BitSet(1, 2, 3)))\n    }\n  }\n\n  class `A collection.Iterator[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Seq(1, 2, 3).iterator).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Iterator[Int]](\"[1,2,3]\").toList.must(be(List(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Iterator[Int]](\"[]\").toList.must(be(List.empty[Int]))\n    }\n  }\n\n  class `A collection.Traversable[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Seq(1, 2, 3).toTraversable).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Traversable[Int]](\"[1,2,3]\").toList.must(be(List(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Traversable[Int]](\"[]\").toList.must(be(List.empty[Int]))\n    }\n  }\n\n  class `A collection.BufferedIterator[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Seq(1, 2, 3).iterator.buffered).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[BufferedIterator[Int]](\"[1,2,3]\").toList.must(be(List(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[BufferedIterator[Int]](\"[]\").toList.must(be(List.empty[Int]))\n    }\n  }\n\n  class `A collection.Iterable[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Seq(1, 2, 3).toIterable).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Iterable[Int]](\"[1,2,3]\").toList.must(be(List(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Iterable[Int]](\"[]\").toList.must(be(List.empty[Int]))\n    }\n  }\n\n  class `A collection.Set[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Set(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Set[Int]](\"[1,2,3]\").must(be(Set(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Set[Int]](\"[]\").must(be(Set.empty[Int]))\n    }\n  }\n\n  class `A collection.Map[String, Int]` {\n    @Test def `generates a JSON object with int field values` = {\n      generate(Map(\"one\" -> 1, \"two\" -> 2)).must(be(\"\"\"{\"one\":1,\"two\":2}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with int field values` = {\n      parse[Map[String, Int]](\"\"\"{\"one\":1,\"two\":2}\"\"\").must(be(Map(\"one\" -> 1, \"two\" -> 2)))\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[Map[String, Int]](\"{}\").must(be(Map.empty[String, Int]))\n    }\n  }\n\n  class `A collection.IndexedSeq[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(IndexedSeq(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[IndexedSeq[Int]](\"[1,2,3]\").must(be(IndexedSeq(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[IndexedSeq[Int]](\"[]\").must(be(IndexedSeq.empty))\n    }\n  }\n\n  class `A collection.Seq[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Seq(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Seq[Int]](\"[1,2,3]\").must(be(Seq(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Seq[Int]](\"[]\").must(be(Seq.empty[Int]))\n    }\n  }\n\n  class `A collection.SortedMap[String, Int]` {\n    @Test def `generates a JSON object with int field values` = {\n      generate(SortedMap(\"one\" -> 1, \"two\" -> 2)).must(be(\"\"\"{\"one\":1,\"two\":2}\"\"\"))\n    }\n\n    // TODO: 6/1/11 <coda> -- figure out how to deserialize SortedMap instances\n\n    /**\n     * I think all this would take is a mapping from Class[_] to Ordering, which\n     * would need to have hard-coded the various primitive types, and then add\n     * support for Ordered and Comparable classes. Once we have the Ordering,\n     * we can pass it in manually to a builder.\n     */\n    \n    @Ignore @Test def `is parsable from a JSON object with int field values` = {\n      parse[SortedMap[String, Int]](\"\"\"{\"one\":1,\"two\":2}\"\"\").must(be(SortedMap(\"one\" -> 1, \"two\" -> 2)))\n    }\n\n    @Ignore @Test def `is parsable from an empty JSON object` = {\n      parse[SortedMap[String, Int]](\"{}\").must(be(SortedMap.empty[String, Int]))\n    }\n  }\n\n  class `A collection.SortedSet[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(SortedSet(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    // TODO: 6/1/11 <coda> -- figure out how to deserialize SortedMap instances\n\n    /**\n     * I think all this would take is a mapping from Class[_] to Ordering, which\n     * would need to have hard-coded the various primitive types, and then add\n     * support for Ordered and Comparable classes. Once we have the Ordering,\n     * we can pass it in manually to a builder.\n     */\n\n    @Ignore @Test def `is parsable from a JSON array of ints` = {\n      parse[SortedSet[Int]](\"[1,2,3]\").must(be(SortedSet(1, 2, 3)))\n\n    }\n\n    @Ignore @Test def `is parsable from an empty JSON array` = {\n      parse[SortedSet[Int]](\"[]\").must(be(SortedSet.empty[Int]))\n    }\n  }\n}\n"
  },
  {
    "path": "src/test/scala/com/codahale/jerkson/tests/DefaultCollectionSupportSpec.scala",
    "content": "package com.codahale.jerkson.tests\n\nimport com.codahale.jerkson.Json._\nimport com.codahale.simplespec.Spec\nimport com.codahale.jerkson.ParsingException\nimport org.junit.{Ignore, Test}\n\nclass DefaultCollectionSupportSpec extends Spec {\n  class `A Range` {\n    @Test def `generates a JSON object` = {\n      generate(Range.inclusive(1, 4, 3)).must(be(\"\"\"{\"start\":1,\"end\":4,\"step\":3,\"inclusive\":true}\"\"\"))\n    }\n\n    @Test def `generates a JSON object without the inclusive field if it's exclusive` = {\n      generate(Range(1, 4, 3)).must(be(\"\"\"{\"start\":1,\"end\":4,\"step\":3}\"\"\"))\n    }\n\n    @Test def `generates a JSON object without the step field if it's 1` = {\n      generate(Range(1, 4)).must(be(\"\"\"{\"start\":1,\"end\":4}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object` = {\n      parse[Range](\"\"\"{\"start\":1,\"end\":4,\"step\":3,\"inclusive\":true}\"\"\").must(be(Range.inclusive(1, 4, 3)))\n    }\n\n    @Test def `is parsable from a JSON object without the inclusive field` = {\n      parse[Range](\"\"\"{\"start\":1,\"end\":4,\"step\":3}\"\"\").must(be(Range(1, 4, 3)))\n    }\n\n    @Test def `is parsable from a JSON object without the step field` = {\n      parse[Range](\"\"\"{\"start\":1,\"end\":4}\"\"\").must(be(Range(1, 4)))\n    }\n\n    @Test def `is not parsable from a JSON object without the required fields` = {\n      evaluating {\n        parse[Range](\"\"\"{\"start\":1}\"\"\")\n      }.must(throwA[ParsingException](\"\"\"Invalid JSON. Needed [start, end, <step>, <inclusive>], but found [start].\"\"\"))\n    }\n\n  }\n\n  class `A Pair[Int]` {\n    @Ignore @Test def `generates a two-element JSON array of ints` = {\n      // TODO: 5/31/11 <coda> -- fix Pair serialization\n      generate(Pair(1, 2)).must(be(\"[1,2]\"))\n    }\n\n    @Ignore @Test def `is parsable from a two-element JSON array of ints` = {\n      // TODO: 5/31/11 <coda> -- fix Pair deserialization\n      parse[Pair[Int, Int]](\"[1,2]\").must(be(Pair(1, 2)))\n    }\n  }\n\n  class `A Triple[Int]` {\n    @Ignore @Test def `generates a three-element JSON array of ints` = {\n      // TODO: 5/31/11 <coda> -- fix Triple serialization\n      generate(Triple(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Ignore @Test def `is parsable from a three-element JSON array of ints` = {\n      // TODO: 5/31/11 <coda> -- fix Triple deserialization\n      parse[Triple[Int, Int, Int]](\"[1,2,3]\").must(be(Triple(1, 2, 3)))\n    }\n  }\n\n  class `A four-tuple` {\n    @Ignore @Test def `generates a four-element JSON array` = {\n      // TODO: 5/31/11 <coda> -- fix Tuple4 serialization\n      generate((1, \"2\", 3, \"4\")).must(be(\"[1,\\\"2\\\",3,\\\"4\\\"]\"))\n    }\n\n    @Ignore @Test def `is parsable from a three-element JSON array of ints` = {\n      // TODO: 5/31/11 <coda> -- fix Tuple4 deserialization\n      parse[(Int, String, Int, String)](\"[1,\\\"2\\\",3,\\\"4\\\"]\").must(be((1, \"2\", 3, \"4\")))\n    }\n  }\n\n  // TODO: 6/1/11 <coda> -- add support for all Tuple1->TupleBillionty types\n\n  class `A Seq[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Seq(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Seq[Int]](\"[1,2,3]\").must(be(Seq(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Seq[Int]](\"[]\").must(be(Seq.empty[Int]))\n    }\n  }\n\n  class `A List[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(List(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[List[Int]](\"[1,2,3]\").must(be(List(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[List[Int]](\"[]\").must(be(List.empty[Int]))\n    }\n  }\n\n  class `An IndexedSeq[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(IndexedSeq(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[IndexedSeq[Int]](\"[1,2,3]\").must(be(IndexedSeq(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[IndexedSeq[Int]](\"[]\").must(be(IndexedSeq.empty[Int]))\n    }\n  }\n\n  class `A Vector[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Vector(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Vector[Int]](\"[1,2,3]\").must(be(Vector(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Vector[Int]](\"[]\").must(be(Vector.empty[Int]))\n    }\n  }\n\n  class `A Set[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Set(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Set[Int]](\"[1,2,3]\").must(be(Set(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Set[Int]](\"[]\").must(be(Set.empty[Int]))\n    }\n  }\n\n  class `A Map[String, Int]` {\n    @Test def `generates a JSON object with int field values` = {\n      generate(Map(\"one\" -> 1, \"two\" -> 2)).must(be(\"\"\"{\"one\":1,\"two\":2}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with int field values` = {\n      parse[Map[String, Int]](\"\"\"{\"one\":1,\"two\":2}\"\"\").must(be(Map(\"one\" -> 1, \"two\" -> 2)))\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[Map[String, Int]](\"{}\").must(be(Map.empty[String, Int]))\n    }\n  }\n\n  class `A Map[String, Any]` {\n    @Test def `generates a JSON object with mixed field values` = {\n      generate(Map(\"one\" -> 1, \"two\" -> \"2\")).must(be(\"\"\"{\"one\":1,\"two\":\"2\"}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with mixed field values` = {\n      parse[Map[String, Any]](\"\"\"{\"one\":1,\"two\":\"2\"}\"\"\").must(be(Map[String, Any](\"one\" -> 1, \"two\" -> \"2\")))\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[Map[String, Any]](\"{}\").must(be(Map.empty[String, Any]))\n    }\n  }\n\n  class `A Stream[Int]` {\n    @Test def `generates a JSON array` = {\n      generate(Stream(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Stream[Int]](\"[1,2,3]\").must(be(Stream(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Stream[Int]](\"[]\").must(be(Stream.empty[Int]))\n    }\n  }\n\n  class `An Iterator[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Seq(1, 2, 3).iterator).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Iterator[Int]](\"[1,2,3]\").toList.must(be(List(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Iterator[Int]](\"[]\").toList.must(be(List.empty[Int]))\n    }\n  }\n\n  class `A Traversable[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Seq(1, 2, 3).toTraversable).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Traversable[Int]](\"[1,2,3]\").toList.must(be(List(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Traversable[Int]](\"[]\").toList.must(be(List.empty[Int]))\n    }\n  }\n\n  class `A BufferedIterator[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Seq(1, 2, 3).iterator.buffered).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[BufferedIterator[Int]](\"[1,2,3]\").toList.must(be(List(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[BufferedIterator[Int]](\"[]\").toList.must(be(List.empty[Int]))\n    }\n  }\n\n  class `An Iterable[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Seq(1, 2, 3).toIterable).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Iterable[Int]](\"[1,2,3]\").toList.must(be(List(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Iterable[Int]](\"[]\").toList.must(be(List.empty[Int]))\n    }\n  }\n}\n"
  },
  {
    "path": "src/test/scala/com/codahale/jerkson/tests/EdgeCaseSpec.scala",
    "content": "package com.codahale.jerkson.tests\n\nimport com.codahale.jerkson.Json._\nimport com.codahale.simplespec.Spec\nimport com.codahale.jerkson.ParsingException\nimport java.io.ByteArrayInputStream\nimport org.junit.Test\n\nclass EdgeCaseSpec extends Spec {\n  class `Deserializing lists` {\n    @Test def `doesn't cache Seq builders` = {\n      parse[List[Int]](\"[1,2,3,4]\").must(be(List(1, 2, 3, 4)))\n      parse[List[Int]](\"[1,2,3,4]\").must(be(List(1, 2, 3, 4)))\n    }\n  }\n\n  class `Parsing a JSON array of ints with nulls` {\n    @Test def `should be readable as a List[Option[Int]]` = {\n      parse[List[Option[Int]]](\"[1,2,null,4]\").must(be(List(Some(1), Some(2), None, Some(4))))\n    }\n  }\n\n  class `Deserializing maps` {\n    @Test def `doesn't cache Map builders` = {\n      parse[Map[String, Int]](\"\"\" {\"one\":1, \"two\": 2} \"\"\").must(be(Map(\"one\" -> 1, \"two\" -> 2)))\n      parse[Map[String, Int]](\"\"\" {\"one\":1, \"two\": 2} \"\"\").must(be(Map(\"one\" -> 1, \"two\" -> 2)))\n    }\n  }\n\n  class `Parsing malformed JSON` {\n    @Test def `should throw a ParsingException with an informative message` = {\n      evaluating {\n        parse[Boolean](\"jjf8;09\")\n      }.must(throwA[ParsingException](\n            \"Malformed JSON. Unexpected character ('j' (code 106)): expected a \" +\n                    \"valid value (number, String, array, object, 'true', 'false' \" +\n                    \"or 'null') at character offset 0.\"))\n\n      evaluating {\n        parse[CaseClass](\"{\\\"ye\\\":1\")\n      }.must(throwA[ParsingException](\n            \"Malformed JSON. Unexpected end-of-input: expected close marker for \" +\n                    \"OBJECT at character offset 20.\"))\n    }\n  }\n\n  class `Parsing invalid JSON` {\n    @Test def `should throw a ParsingException with an informative message` = {\n      evaluating {\n        parse[CaseClass](\"900\")\n      }.must(throwA[ParsingException](\n        (\"\"\"Can not deserialize instance of com.codahale.jerkson.tests.CaseClass out of VALUE_NUMBER_INT token\\n\"\"\" +\n          \"\"\" at \\[Source: java.io.StringReader@[0-9a-f]+; line: 1, column: 1\\]\"\"\").r))\n\n      evaluating {\n        parse[CaseClass](\"{\\\"woo\\\": 1}\")\n      }.must(throwA[ParsingException](\"Invalid JSON. Needed [id, name], but found [woo].\"))\n    }\n  }\n\n  class `Parsing an empty document` {\n    @Test def `should throw a ParsingException with an informative message` = {\n      val input = new ByteArrayInputStream(Array.empty)\n      evaluating {\n        parse[CaseClass](input)\n      }.must(throwA[ParsingException](\"\"\"No content to map due to end\\-of\\-input\"\"\".r))\n    }\n  }\n}\n"
  },
  {
    "path": "src/test/scala/com/codahale/jerkson/tests/ExampleCaseClasses.scala",
    "content": "package com.codahale.jerkson.tests\n\nimport com.fasterxml.jackson.databind.JsonNode\nimport com.fasterxml.jackson.annotation.{JsonIgnoreProperties, JsonIgnore}\nimport com.codahale.jerkson.JsonSnakeCase\n\ncase class CaseClass(id: Long, name: String)\n\ncase class CaseClassWithLazyVal(id: Long) {\n  lazy val woo = \"yeah\"\n}\n\ncase class CaseClassWithIgnoredField(id: Long) {\n  @JsonIgnore\n  val uncomfortable = \"Bad Touch\"\n}\n\n@JsonIgnoreProperties(Array(\"uncomfortable\", \"unpleasant\"))\ncase class CaseClassWithIgnoredFields(id: Long) {\n  val uncomfortable = \"Bad Touch\"\n  val unpleasant = \"The Creeps\"\n}\n\ncase class CaseClassWithTransientField(id: Long) {\n  @transient\n  val lol = \"I'm sure it's just a phase.\"\n}\n\ncase class CaseClassWithOverloadedField(id: Long) {\n  def id(prefix: String): String = prefix + id\n}\n\ncase class CaseClassWithOption(value: Option[String])\n\ncase class CaseClassWithJsonNode(value: JsonNode)\n\ncase class CaseClassWithAllTypes(map: Map[String, String],\n                                 set: Set[Int],\n                                 string: String,\n                                 list: List[Int],\n                                 seq: Seq[Int],\n                                 indexedSeq: IndexedSeq[Int],\n                                 vector: Vector[Int],\n                                 bigDecimal: BigDecimal,\n                                 bigInt: BigInt,\n                                 int: Int,\n                                 long: Long,\n                                 char: Char,\n                                 bool: Boolean,\n                                 short: Short,\n                                 byte: Byte,\n                                 float: Float,\n                                 double: Double,\n                                 any: Any,\n                                 anyRef: AnyRef,\n                                 intMap: Map[Int, Int],\n                                 longMap: Map[Long, Long])\n\nobject OuterObject {\n  case class NestedCaseClass(id: Long)\n\n  object InnerObject {\n    case class SuperNestedCaseClass(id: Long)\n  }\n}\n\ncase class CaseClassWithTwoConstructors(id: Long,  name: String) {\n  def this(id: Long) = this(id,  \"New User\")\n}\n\n@JsonSnakeCase\ncase class CaseClassWithSnakeCase(oneThing: String, twoThing: String)\n\ncase class CaseClassWithArrays(one: String, two: Array[String], three: Array[Int])\n"
  },
  {
    "path": "src/test/scala/com/codahale/jerkson/tests/FancyTypeSupportSpec.scala",
    "content": "package com.codahale.jerkson.tests\n\nimport java.net.URI\nimport com.codahale.simplespec.Spec\nimport org.junit.Test\nimport com.codahale.jerkson.Json._\nimport java.util.UUID\n\nclass FancyTypeSupportSpec extends Spec {\n  class `A URI` {\n    @Test def `generates a JSON string` = {\n      generate(new URI(\"http://example.com/resource?query=yes\")).must(be(\"\\\"http://example.com/resource?query=yes\\\"\"))\n    }\n\n    @Test def `is parsable from a JSON string` = {\n      parse[URI](\"\\\"http://example.com/resource?query=yes\\\"\").must(be(new URI(\"http://example.com/resource?query=yes\")))\n    }\n  }\n\n  class `A UUID` {\n    val uuid = UUID.fromString(\"a62047e4-bfb5-4d71-aad7-1a6b338eee63\")\n\n    @Test def `generates a JSON string` = {\n      generate(uuid).must(be(\"\\\"a62047e4-bfb5-4d71-aad7-1a6b338eee63\\\"\"))\n    }\n\n    @Test def `is parsable from a JSON string` = {\n      parse[UUID](\"\\\"a62047e4-bfb5-4d71-aad7-1a6b338eee63\\\"\").must(be(uuid))\n    }\n  }\n}\n"
  },
  {
    "path": "src/test/scala/com/codahale/jerkson/tests/ImmutableCollectionSupportSpec.scala",
    "content": "package com.codahale.jerkson.tests\n\nimport com.codahale.simplespec.Spec\nimport com.codahale.jerkson.Json._\nimport scala.collection.immutable._\nimport com.codahale.jerkson.ParsingException\nimport org.junit.{Ignore, Test}\n\nclass ImmutableCollectionSupportSpec extends Spec {\n  class `An immutable.Seq[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(Seq(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Seq[Int]](\"[1,2,3]\").must(be(Seq(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Seq[Int]](\"[]\").must(be(Seq.empty[Int]))\n    }\n  }\n\n  class `An immutable.List[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(List(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[List[Int]](\"[1,2,3]\").must(be(List(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[List[Int]](\"[]\").must(be(List.empty[Int]))\n    }\n  }\n\n  class `An immutable.IndexedSeq[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(IndexedSeq(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[IndexedSeq[Int]](\"[1,2,3]\").must(be(IndexedSeq(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[IndexedSeq[Int]](\"[]\").must(be(IndexedSeq.empty[Int]))\n    }\n  }\n\n  class `An immutable.TreeSet[Int]` {\n    @Test def `generates a JSON array` = {\n      generate(TreeSet(1)).must(be(\"[1]\"))\n    }\n\n    // TODO: 6/1/11 <coda> -- figure out how to deserialize TreeSet instances\n\n    /**\n     * I think all this would take is a mapping from Class[_] to Ordering, which\n     * would need to have hard-coded the various primitive types, and then add\n     * support for Ordered and Comparable classes. Once we have the Ordering,\n     * we can pass it in manually to a builder.\n     */\n    \n    @Ignore @Test def `is parsable from a JSON array of ints` = {\n      parse[TreeSet[Int]](\"[1,2,3]\").must(be(TreeSet(1, 2, 3)))\n    }\n\n    @Ignore @Test def `is parsable from an empty JSON array` = {\n      parse[TreeSet[Int]](\"[]\").must(be(TreeSet.empty[Int]))\n    }\n  }\n\n  class `An immutable.HashSet[Int]` {\n    @Test def `generates a JSON array` = {\n      generate(HashSet(1)).must(be(\"[1]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[HashSet[Int]](\"[1,2,3]\").must(be(HashSet(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[HashSet[Int]](\"[]\").must(be(HashSet.empty[Int]))\n    }\n  }\n\n  class `An immutable.BitSet` {\n    @Test def `generates a JSON array` = {\n      generate(BitSet(1)).must(be(\"[1]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[BitSet](\"[1,2,3]\").must(be(BitSet(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[BitSet](\"[]\").must(be(BitSet.empty))\n    }\n  }\n\n  class `An immutable.TreeMap[String, Int]` {\n    @Test def `generates a JSON object` = {\n      generate(TreeMap(\"one\" -> 1)).must(be(\"\"\"{\"one\":1}\"\"\"))\n    }\n\n    // TODO: 6/1/11 <coda> -- figure out how to deserialize TreeMap instances\n\n    /**\n     * I think all this would take is a mapping from Class[_] to Ordering, which\n     * would need to have hard-coded the various primitive types, and then add\n     * support for Ordered and Comparable classes. Once we have the Ordering,\n     * we can pass it in manually to a builder.\n     */\n    \n    @Ignore @Test def `is parsable from a JSON object with int field values` = {\n      parse[TreeMap[String, Int]](\"\"\"{\"one\":1}\"\"\").must(be(TreeMap(\"one\" -> 1)))\n    }\n\n    @Ignore @Test def `is parsable from an empty JSON object` = {\n      parse[TreeMap[String, Int]](\"{}\").must(be(TreeMap.empty[String, Int]))\n    }\n  }\n\n  class `An immutable.HashMap[String, Int]` {\n    @Test def `generates a JSON object` = {\n      generate(HashMap(\"one\" -> 1)).must(be(\"\"\"{\"one\":1}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with int field values` = {\n      parse[HashMap[String, Int]](\"\"\"{\"one\":1}\"\"\").must(be(HashMap(\"one\" -> 1)))\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[HashMap[String, Int]](\"{}\").must(be(HashMap.empty[String, Int]))\n    }\n  }\n\n  class `An immutable.HashMap[String, Any]` {\n    @Test def `generates a JSON object` = {\n      generate(HashMap[String, Any](\"one\" -> 1)).must(be(\"\"\"{\"one\":1}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with int field values` = {\n      parse[HashMap[String, Any]](\"\"\"{\"one\":1}\"\"\").must(be(HashMap(\"one\" -> 1)))\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[HashMap[String, Any]](\"{}\").must(be(HashMap.empty[String, Any]))\n    }\n\n    @Test def `is not parsable from an empty JSON object in a JSON array` = {\n      evaluating {\n        parse[HashMap[String, Any]](\"[{}]\")\n      }.must(throwA[ParsingException])\n    }\n  }\n\n  class `An immutable.Map[Int, String]` {\n    @Test def `generates a JSON object` = {\n      generate(Map(1 -> \"one\")).must(be(\"\"\"{\"1\":\"one\"}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with decimal field names and string field values` = {\n      parse[Map[Int, String]](\"\"\"{\"1\":\"one\"}\"\"\").must(be(Map(1 -> \"one\")))\n    }\n\n    @Test def `is not parsable from a JSON object with non-decimal field names` = {\n      evaluating {\n        parse[Map[Int, String]](\"\"\"{\"one\":\"one\"}\"\"\")\n      }.must(throwA[ParsingException])\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[Map[Int, String]](\"{}\").must(be(Map.empty[Int, String]))\n    }\n  }\n\n  class `An immutable.Map[Int, Any]` {\n    @Test def `is not parsable from an empty JSON object in a JSON array` = {\n      evaluating {\n        parse[Map[Int, Any]](\"[{}]\")\n      }.must(throwA[ParsingException])\n    }\n  }\n\n  class `An immutable.IntMap[Any]` {\n    @Test def `is not parsable from an empty JSON object in a JSON array` = {\n      evaluating {\n        parse[IntMap[Any]](\"[{}]\")\n      }.must(throwA[ParsingException])\n    }\n  }\n\n  class `An immutable.LongMap[Any]` {\n    @Test def `is not parsable from an empty JSON object in a JSON array` = {\n      evaluating {\n        parse[LongMap[Any]](\"[{}]\")\n      }.must(throwA[ParsingException])\n    }\n  }\n\n  class `An immutable.Map[Long, Any]` {\n    @Test def `is not parsable from an empty JSON object in a JSON array` = {\n      evaluating {\n        parse[Map[Long, Any]](\"[{}]\")\n      }.must(throwA[ParsingException])\n    }\n  }\n\n  class `An immutable.Map[Long, String]` {\n    @Test def `generates a JSON object` = {\n      generate(Map(1L -> \"one\")).must(be(\"\"\"{\"1\":\"one\"}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with decimal field names and string field values` = {\n      parse[Map[Long, String]](\"\"\"{\"1\":\"one\"}\"\"\").must(be(Map(1L -> \"one\")))\n    }\n\n    @Test def `is not parsable from a JSON object with non-decimal field names` = {\n      evaluating {\n        parse[Map[Long, String]](\"\"\"{\"one\":\"one\"}\"\"\")\n      }.must(throwA[ParsingException])\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[Map[Long, String]](\"{}\").must(be(Map.empty[Long, String]))\n    }\n  }\n\n  class `An immutable.IntMap[String]` {\n    @Test def `generates a JSON object` = {\n      generate(IntMap(1 -> \"one\")).must(be(\"\"\"{\"1\":\"one\"}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with decimal field names and string field values` = {\n      parse[IntMap[String]](\"\"\"{\"1\":\"one\"}\"\"\").must(be(IntMap(1 -> \"one\")))\n    }\n\n    @Test def `is not parsable from a JSON object with non-decimal field names` = {\n      evaluating {\n        parse[IntMap[String]](\"\"\"{\"one\":\"one\"}\"\"\")\n      }.must(throwA[ParsingException])\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[IntMap[String]](\"{}\").must(be(IntMap.empty[String]))\n    }\n  }\n\n  class `An immutable.LongMap[String]` {\n    @Test def `generates a JSON object` = {\n      generate(LongMap(1L -> \"one\")).must(be(\"\"\"{\"1\":\"one\"}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with int field names and string field values` = {\n      parse[LongMap[String]](\"\"\"{\"1\":\"one\"}\"\"\").must(be(LongMap(1L -> \"one\")))\n    }\n\n    @Test def `is not parsable from a JSON object with non-decimal field names` = {\n      evaluating {\n        parse[LongMap[String]](\"\"\"{\"one\":\"one\"}\"\"\")\n      }.must(throwA[ParsingException])\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[LongMap[String]](\"{}\").must(be(LongMap.empty))\n    }\n  }\n\n  class `An immutable.Queue[Int]` {\n    @Test def `generates a JSON array` = {\n      generate(Queue(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Queue[Int]](\"[1,2,3]\").must(be(Queue(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Queue[Int]](\"[]\").must(be(Queue.empty))\n    }\n  }\n}\n"
  },
  {
    "path": "src/test/scala/com/codahale/jerkson/tests/JValueSpec.scala",
    "content": "package com.codahale.jerkson.tests\n\nimport com.codahale.jerkson.Json._\nimport com.codahale.jerkson.AST._\nimport com.codahale.simplespec.Spec\nimport org.junit.Test\n\nclass JValueSpec extends Spec {\n  class `Selecting single nodes` {\n    @Test def `returns None with primitives` = {\n      (parse[JValue](\"8\") \\ \"blah\").must(be(JNull))\n    }\n    \n    @Test def `returns None on nonexistent fields` = {\n      (parse[JValue](\"{\\\"one\\\": \\\"1\\\"}\") \\ \"two\").must(be(JNull))\n    }\n    \n    @Test def `returns a JValue with an existing field` = {\n      (parse[JValue](\"{\\\"one\\\": \\\"1\\\"}\") \\ \"one\").must(be(JString(\"1\")))\n    }\n  }\n  \n  class `Selecting array members` {\n    @Test def `returns None with primitives` = {\n      (parse[JValue](\"\\\"derp\\\"\").apply(0)).must(be(JNull))\n    }\n    \n    @Test def `returns None on out of bounds` = {\n      (parse[JValue](\"[0, 1, 2, 3]\").apply(4)).must(be(JNull))\n    }\n    \n    @Test def `returns a JValue` = {\n      (parse[JValue](\"[0, 1, 2, 3]\").apply(2)).must(be(JInt(2)))\n    }\n  }\n  \n  class `Deep selecting` {\n    @Test def `returns Nil with primitives` = {\n      (parse[JValue](\"0.234\") \\\\ \"herp\").must(be(empty))\n    }\n\n    @Test def `returns Nil on nothing found` = {\n      (parse[JValue](\"{\\\"one\\\": {\\\"two\\\" : \\\"three\\\"}}\") \\\\ \"four\").must(be(empty))\n    }\n    \n    @Test def `returns single leaf nodes` = {\n      (parse[JValue](\"{\\\"one\\\": {\\\"two\\\" : \\\"three\\\"}}\") \\\\ \"two\").must(be(Seq(JString(\"three\"))))\n    }\n    \n    @Test def `should return multiple leaf nodes` = {\n      (parse[JValue](\"{\\\"one\\\": {\\\"two\\\" : \\\"three\\\"}, \\\"four\\\": {\\\"two\\\" : \\\"five\\\"}}\") \\\\ \"two\").must(be(Seq(JString(\"three\"),JString(\"five\"))))\n    }\n  }\n}\n"
  },
  {
    "path": "src/test/scala/com/codahale/jerkson/tests/MutableCollectionSupportSpec.scala",
    "content": "package com.codahale.jerkson.tests\n\nimport com.codahale.simplespec.Spec\nimport com.codahale.jerkson.Json._\nimport scala.collection.mutable._\nimport com.codahale.jerkson.ParsingException\nimport org.junit.Test\n\nclass MutableCollectionSupportSpec extends Spec {\n  class `A mutable.ResizableArray[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(ResizableArray(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[ResizableArray[Int]](\"[1,2,3]\").must(be(ResizableArray(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[ResizableArray[Int]](\"[]\").must(be(ResizableArray.empty[Int]))\n    }\n  }\n\n  class `A mutable.ArraySeq[Int]` {\n    @Test def `generates a JSON array of ints` = {\n      generate(ArraySeq(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[ArraySeq[Int]](\"[1,2,3]\").must(be(ArraySeq(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[ArraySeq[Int]](\"[]\").must(be(ArraySeq.empty[Int]))\n    }\n  }\n\n  class `A mutable.MutableList[Int]` {\n    private val xs = new MutableList[Int]\n    xs ++= List(1, 2, 3)\n\n    @Test def `generates a JSON array` = {\n      generate(xs).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[MutableList[Int]](\"[1,2,3]\").must(be(xs))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[MutableList[Int]](\"[]\").must(be(new MutableList[Int]()))\n    }\n  }\n\n  class `A mutable.Queue[Int]` {\n    @Test def `generates a JSON array` = {\n      generate(Queue(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[Queue[Int]](\"[1,2,3]\").must(be(Queue(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[Queue[Int]](\"[]\").must(be(new Queue[Int]()))\n    }\n  }\n\n  class `A mutable.ListBuffer[Int]` {\n    @Test def `generates a JSON array` = {\n      generate(ListBuffer(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[ListBuffer[Int]](\"[1,2,3]\").must(be(ListBuffer(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[ListBuffer[Int]](\"[]\").must(be(ListBuffer.empty[Int]))\n    }\n  }\n\n  class `A mutable.ArrayBuffer[Int]` {\n    @Test def `generates a JSON array` = {\n      generate(ArrayBuffer(1, 2, 3)).must(be(\"[1,2,3]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[ArrayBuffer[Int]](\"[1,2,3]\").must(be(ArrayBuffer(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[ArrayBuffer[Int]](\"[]\").must(be(ArrayBuffer.empty[Int]))\n    }\n  }\n\n  class `A mutable.BitSet` {\n    @Test def `generates a JSON array` = {\n      generate(BitSet(1)).must(be(\"[1]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[BitSet](\"[1,2,3]\").must(be(BitSet(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[BitSet](\"[]\").must(be(BitSet.empty))\n    }\n  }\n\n  class `A mutable.HashSet[Int]` {\n    @Test def `generates a JSON array` = {\n      generate(HashSet(1)).must(be(\"[1]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[HashSet[Int]](\"[1,2,3]\").must(be(HashSet(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[HashSet[Int]](\"[]\").must(be(HashSet.empty[Int]))\n    }\n  }\n\n  class `A mutable.LinkedHashSet[Int]` {\n    @Test def `generates a JSON array` = {\n      generate(LinkedHashSet(1)).must(be(\"[1]\"))\n    }\n\n    @Test def `is parsable from a JSON array of ints` = {\n      parse[LinkedHashSet[Int]](\"[1,2,3]\").must(be(LinkedHashSet(1, 2, 3)))\n    }\n\n    @Test def `is parsable from an empty JSON array` = {\n      parse[LinkedHashSet[Int]](\"[]\").must(be(LinkedHashSet.empty[Int]))\n    }\n  }\n\n  class `A mutable.Map[String, Int]` {\n    @Test def `generates a JSON object` = {\n      generate(Map(\"one\" -> 1)).must(be(\"\"\"{\"one\":1}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with int field values` = {\n      parse[Map[String, Int]](\"\"\"{\"one\":1}\"\"\").must(be(Map(\"one\" -> 1)))\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[Map[String, Int]](\"{}\").must(be(Map.empty[String, Int]))\n    }\n  }\n\n  class `A mutable.Map[String, Any]` {\n    @Test def `is not parsable from an empty JSON object in a JSON array` = {\n      evaluating {\n        parse[Map[String, Any]](\"[{}]\")\n      }.must(throwA[ParsingException])\n    }\n  }\n\n  class `A mutable.HashMap[String, Int]` {\n    @Test def `generates a JSON object` = {\n      generate(HashMap(\"one\" -> 1)).must(be(\"\"\"{\"one\":1}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with int field values` = {\n      parse[HashMap[String, Int]](\"\"\"{\"one\":1}\"\"\").must(be(HashMap(\"one\" -> 1)))\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[HashMap[String, Int]](\"{}\").must(be(HashMap.empty[String, Int]))\n    }\n  }\n\n  class `A mutable.LinkedHashMap[String, Int]` {\n    @Test def `generates a JSON object` = {\n      generate(LinkedHashMap(\"one\" -> 1)).must(be(\"\"\"{\"one\":1}\"\"\"))\n    }\n\n    @Test def `is parsable from a JSON object with int field values` = {\n      parse[LinkedHashMap[String, Int]](\"\"\"{\"one\":1}\"\"\").must(be(LinkedHashMap(\"one\" -> 1)))\n    }\n\n    @Test def `is parsable from an empty JSON object` = {\n      parse[LinkedHashMap[String, Int]](\"{}\").must(be(LinkedHashMap.empty[String, Int]))\n    }\n  }\n}\n"
  },
  {
    "path": "src/test/scala/com/codahale/jerkson/tests/StreamingSpec.scala",
    "content": "package com.codahale.jerkson.tests\n\nimport com.codahale.jerkson.Json._\nimport java.io.ByteArrayInputStream\nimport com.codahale.simplespec.Spec\nimport org.junit.Test\n\nclass StreamingSpec extends Spec {\n  class `Parsing a stream of objects` {\n    val json = \"\"\"[\n      {\"id\":1, \"name\": \"Coda\"},\n      {\"id\":2, \"name\": \"Niki\"},\n      {\"id\":3, \"name\": \"Biscuit\"},\n      {\"id\":4, \"name\": \"Louie\"}\n    ]\"\"\"\n\n    @Test def `returns an iterator of stream elements` = {\n      stream[CaseClass](new ByteArrayInputStream(json.getBytes)).toList\n        .must(be(CaseClass(1, \"Coda\") :: CaseClass(2, \"Niki\") ::\n                  CaseClass(3, \"Biscuit\") :: CaseClass(4, \"Louie\") :: Nil))\n    }\n  }\n}\n"
  }
]