Repository: joelittlejohn/jsonschema2pojo
Pull request #964 (2019-03-26 08:20:31)

Check schema required array before is required flag
Hi,

The generated code is incorrect when a required field is an object, and it has required internal fields. It because of wrong algorithm checks is required flag of the field previously than tests a top defined required fields list. I've changed the checking order.

I mean the case where is the top schema follows:

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": ["object", "null"],
  "required": [
    "payment_type",
    "change_alignment",
    "billing_alignment"
  ],
  "properties": {
    "payment_type": {
      "type": "object",
      "$ref": "payment_type.json"
    },
    "change_alignment": {
      "type": "object",
      "$ref": "change_alignment.json"
    },
    "billing_alignment": {
      "type": "object",
      "$ref": "billing_alignment.json"
    }
  }
}
```

and `billing_alignment.json` is:

```json
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "required": [
    "date_type"
  ],
  "properties": {
    "date_type": {
      "type": "string",
      "enum": [
        "activation",
        "anniversary"
      ]
    },
    "day": {
      "type": "integer",
      "minimum": 1,
      "maximum": 28
    }
  }
}
```

For this example, the wrong plugin with `useOptionalForGetters=true` generates `Optional<BillingAlignment>` type of `getBillingAlignment` method instead of just `BillingAlignment`.
I've fixed it and now the type is `BillingAlignment`.


Patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 3d0c04fc..5fac78ae 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,13 +1,8 @@
 # Changelog
 
-## 1.0.0
-* Don't register output directory as a set of files, since this breaks Gradle 5.0+ ([#940](https://github.com/joelittlejohn/jsonschema2pojo/pull/940))
-* **Builder method should be named consistently with getter/setter ([#905](https://github.com/joelittlejohn/jsonschema2pojo/issues/905))**
-* Objects inside array with name ending with "List" are generated as "SomeNameList" ([#780](https://github.com/joelittlejohn/jsonschema2pojo/issues/780))
-
 ## 1.0.0-beta1
 * Add 'formatTypeMapping' config option to allow overriding types used for formats ([#923](https://github.com/joelittlejohn/jsonschema2pojo/pull/923))
-* **Modify Rule#apply signature to include parent node (allows context-aware rules) ([#917](https://github.com/joelittlejohn/jsonschema2pojo/pull/917))**
+* **Enable development of context-aware rules. ([#917](https://github.com/joelittlejohn/jsonschema2pojo/pull/917))**
 * Add 'javaOptional' extension rule to allow individual fields to use Java Optional on getter ([#913](https://github.com/joelittlejohn/jsonschema2pojo/pull/913))
 * Allow schema title to be used as class name (new useTitleAsClassname config option) ([#908](https://github.com/joelittlejohn/jsonschema2pojo/issues/908))
 * Incorrect @Nullable JSR305 annotations generated when using 'required' array ([#906](https://github.com/joelittlejohn/jsonschema2pojo/issues/906))
diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md
index 943d4323..65a04125 100644
--- a/CONTRIBUTORS.md
+++ b/CONTRIBUTORS.md
@@ -94,4 +94,3 @@
 * Klevis Ramo
 * Martin Bramwell
 * Jan Oopkaup
-* Michał Szymborski
diff --git a/README.md b/README.md
index 1626d2c5..091e93ba 100644
--- a/README.md
+++ b/README.md
@@ -1,8 +1,9 @@
 # jsonschema2pojo [![Build Status](https://travis-ci.org/joelittlejohn/jsonschema2pojo.svg?branch=master)](https://travis-ci.org/joelittlejohn/jsonschema2pojo) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/org.jsonschema2pojo/jsonschema2pojo/badge.svg)](http://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.jsonschema2pojo%22)
 
-_jsonschema2pojo_ generates Java types from JSON Schema (or example JSON) and can annotate those types for data-binding with Jackson 1.x, Jackson 2.x or Gson.
+Current stable: **0.5.1**<br>
+Current unstable: **1.0.0-beta1**<br>
 
-**_*Note:*_ there are breaking changes between 0.5.1 and 1.0.0. Check the [change log](https://github.com/joelittlejohn/jsonschema2pojo/blob/master/CHANGELOG.md). Anything marked in bold in the 1.0.0 alpha, beta and final release is a breaking change.**
+_jsonschema2pojo_ generates Java types from JSON Schema (or example JSON) and can annotate those types for data-binding with Jackson 1.x, Jackson 2.x or Gson.
 
 ### [Try jsonschema2pojo online](http://jsonschema2pojo.org/)<br>or `brew install jsonschema2pojo`
 
@@ -13,7 +14,7 @@ A very simple Maven example:
 <plugin>
     <groupId>org.jsonschema2pojo</groupId>
     <artifactId>jsonschema2pojo-maven-plugin</artifactId>
-    <version>1.0.0</version>
+    <version>0.5.1</version>
     <configuration>
         <sourceDirectory>${basedir}/src/main/resources/schema</sourceDirectory>
         <targetPackage>com.example.types</targetPackage>
@@ -32,9 +33,9 @@ Useful pages:
   * **[Getting started](https://github.com/joelittlejohn/jsonschema2pojo/wiki/Getting-Started)**
   * **[How to contribute](https://github.com/joelittlejohn/jsonschema2pojo/blob/master/CONTRIBUTING.md)**
   * [Reference](https://github.com/joelittlejohn/jsonschema2pojo/wiki/Reference)
-  * [Latest Javadocs](https://joelittlejohn.github.io/jsonschema2pojo/javadocs/1.0.0/)
-  * [Documentation for the Maven plugin](https://joelittlejohn.github.io/jsonschema2pojo/site/1.0.0/generate-mojo.html)
-  * [Documentation for the Ant task](https://joelittlejohn.github.io/jsonschema2pojo/site/1.0.0/Jsonschema2PojoTask.html)
+  * [Latest Javadocs](https://joelittlejohn.github.io/jsonschema2pojo/javadocs/0.5.1/)
+  * [Documentation for the Maven plugin](https://joelittlejohn.github.io/jsonschema2pojo/site/0.5.1/generate-mojo.html)
+  * [Documentation for the Ant task](https://joelittlejohn.github.io/jsonschema2pojo/site/0.5.1/Jsonschema2PojoTask.html)
 
 Project resources:
   * [Downloads](https://github.com/joelittlejohn/jsonschema2pojo/releases)
diff --git a/jsonschema2pojo-ant/pom.xml b/jsonschema2pojo-ant/pom.xml
index 18c4f6f8..d49c0511 100644
--- a/jsonschema2pojo-ant/pom.xml
+++ b/jsonschema2pojo-ant/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>jsonschema2pojo</artifactId>
         <groupId>org.jsonschema2pojo</groupId>
-        <version>1.0.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
 
     <artifactId>jsonschema2pojo-ant</artifactId>
diff --git a/jsonschema2pojo-ant/src/main/java/org/jsonschema2pojo/ant/Jsonschema2PojoTask.java b/jsonschema2pojo-ant/src/main/java/org/jsonschema2pojo/ant/Jsonschema2PojoTask.java
index 4bcbe11f..5e0a7f62 100644
--- a/jsonschema2pojo-ant/src/main/java/org/jsonschema2pojo/ant/Jsonschema2PojoTask.java
+++ b/jsonschema2pojo-ant/src/main/java/org/jsonschema2pojo/ant/Jsonschema2PojoTask.java
@@ -69,8 +69,6 @@ public class Jsonschema2PojoTask extends Task implements GenerationConfig {
 
     private boolean generateBuilders;
 
-    private boolean useInnerClassBuilders = false;
-
     private boolean includeConstructors = false;
 
     private boolean usePrimitives;
@@ -1203,18 +1201,5 @@ public class Jsonschema2PojoTask extends Task implements GenerationConfig {
     public Map<String, String> getFormatTypeMapping() {
         return formatTypeMapping;
     }
-
-    @Override
-    public boolean isUseInnerClassBuilders() {
-        return useInnerClassBuilders;
-    }
-
-    /**
-     * Sets the 'useInnerClassBuilders' property of this class
-     *
-     * @param useInnerClassBuilders determines whether builders will be chainable setters or embedded classes when {@link #isGenerateBuilders()} used
-     */
-    public void setUseInnerClassBuilders(boolean useInnerClassBuilders) {
-        this.useInnerClassBuilders = useInnerClassBuilders;
-    }
+    
 }
diff --git a/jsonschema2pojo-ant/src/site/Jsonschema2PojoTask.html b/jsonschema2pojo-ant/src/site/Jsonschema2PojoTask.html
index cf725b08..5b823df1 100644
--- a/jsonschema2pojo-ant/src/site/Jsonschema2PojoTask.html
+++ b/jsonschema2pojo-ant/src/site/Jsonschema2PojoTask.html
@@ -156,11 +156,6 @@
         </td>
         <td align="center" valign="top">No (default <code>false</code>)</td>
     </tr>
-    <tr>
-        <td valign="top">useInnerClassBuilders</td>
-        <td valign="top">Determines whether builders will be chainable setters or embedded classes when generateBuilders is used</td>
-        <td align="center" valign="top">No (default <code>false</code>)</td>
-    </tr>
     <tr>
         <td valign="top">includeGetters</td>
         <td valign="top">Whether to include getters or to omit these accessor methods and create public fields instead.</td>
diff --git a/jsonschema2pojo-cli/pom.xml b/jsonschema2pojo-cli/pom.xml
index 07449403..afe767c6 100644
--- a/jsonschema2pojo-cli/pom.xml
+++ b/jsonschema2pojo-cli/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>jsonschema2pojo</artifactId>
         <groupId>org.jsonschema2pojo</groupId>
-        <version>1.0.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
 
     <artifactId>jsonschema2pojo-cli</artifactId>
diff --git a/jsonschema2pojo-cli/src/main/java/org/jsonschema2pojo/cli/Arguments.java b/jsonschema2pojo-cli/src/main/java/org/jsonschema2pojo/cli/Arguments.java
index 9f6704e5..f7b5f33d 100644
--- a/jsonschema2pojo-cli/src/main/java/org/jsonschema2pojo/cli/Arguments.java
+++ b/jsonschema2pojo-cli/src/main/java/org/jsonschema2pojo/cli/Arguments.java
@@ -63,9 +63,6 @@ public class Arguments implements GenerationConfig {
     @Parameter(names = { "-b", "--generate-builders" }, description = "Generate builder-style methods as well as setters")
     private boolean generateBuilderMethods = false;
 
-    @Parameter(names = { "--use-inner-class-builders" }, description = "Generate an inner class with builder-style methods")
-    private boolean useInnerClassBuilders = false;
-
     @Parameter(names = { "-c", "--generate-constructors" }, description = "Generate constructors")
     private boolean generateConstructors = false;
 
@@ -281,11 +278,6 @@ public class Arguments implements GenerationConfig {
         return generateBuilderMethods;
     }
 
-    @Override
-    public boolean isUseInnerClassBuilders() {
-        return useInnerClassBuilders;
-    }
-
     @Override
     public boolean isUsePrimitives() {
         return usePrimitives;
diff --git a/jsonschema2pojo-core/pom.xml b/jsonschema2pojo-core/pom.xml
index be05cc4c..fa929b80 100644
--- a/jsonschema2pojo-core/pom.xml
+++ b/jsonschema2pojo-core/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>jsonschema2pojo</artifactId>
         <groupId>org.jsonschema2pojo</groupId>
-        <version>1.0.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
 
     <artifactId>jsonschema2pojo-core</artifactId>
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/DefaultGenerationConfig.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/DefaultGenerationConfig.java
index 068a853d..d295b269 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/DefaultGenerationConfig.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/DefaultGenerationConfig.java
@@ -444,7 +444,5 @@ public class DefaultGenerationConfig implements GenerationConfig {
     public Map<String, String> getFormatTypeMapping() {
         return Collections.emptyMap();
     }
-
-    @Override
-    public boolean isUseInnerClassBuilders() { return false; }
+    
 }
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/GenerationConfig.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/GenerationConfig.java
index ec27b894..efcf91f5 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/GenerationConfig.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/GenerationConfig.java
@@ -571,13 +571,4 @@ public interface GenerationConfig {
      *         fully qualified type name (e.g. 'java.net.URI').
      */
     Map<String, String> getFormatTypeMapping();
-
-    /**
-     * If set to true, then the gang of four builder pattern will be used to generate builders on generated classes. Note: This property works
-     * in collaboration with the {@link #isGenerateBuilders()} method. If the {@link #isGenerateBuilders()} is false,
-     * then this property will not do anything.
-     * @return whether to include the gang of four builder patter on the generated classes. The default value for this is false.
-     */
-    default boolean isUseInnerClassBuilders(){ return false;}
-
 }
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/ScalaSingleStreamCodeWriter.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/ScalaSingleStreamCodeWriter.java
index 17f7691a..1f843c84 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/ScalaSingleStreamCodeWriter.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/ScalaSingleStreamCodeWriter.java
@@ -16,15 +16,16 @@
 
 package org.jsonschema2pojo;
 
-import com.mysema.scalagen.ConversionSettings;
-import com.mysema.scalagen.Converter;
-import com.sun.codemodel.JPackage;
-import com.sun.codemodel.writer.SingleStreamCodeWriter;
 import java.io.ByteArrayOutputStream;
 import java.io.FilterOutputStream;
 import java.io.IOException;
 import java.io.OutputStream;
 
+import com.mysema.scalagen.ConversionSettings;
+import com.mysema.scalagen.Converter;
+import com.sun.codemodel.JPackage;
+import com.sun.codemodel.writer.SingleStreamCodeWriter;
+
 public class ScalaSingleStreamCodeWriter extends SingleStreamCodeWriter {
 
     public ScalaSingleStreamCodeWriter(OutputStream os) {
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/AdditionalPropertiesRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/AdditionalPropertiesRule.java
index aaddb1a7..3225252d 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/AdditionalPropertiesRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/AdditionalPropertiesRule.java
@@ -19,11 +19,6 @@ package org.jsonschema2pojo.rules;
 import java.util.HashMap;
 import java.util.Map;
 
-import java.util.Optional;
-import java.util.Spliterator;
-import java.util.Spliterators;
-import java.util.stream.StreamSupport;
-import org.apache.commons.collections15.CollectionUtils;
 import org.jsonschema2pojo.Schema;
 
 import com.fasterxml.jackson.databind.JsonNode;
@@ -165,19 +160,7 @@ public class AdditionalPropertiesRule implements Rule<JDefinedClass, JDefinedCla
         return getter;
     }
 
-    private JMethod addBuilder(JDefinedClass jclass, JType propertyType, JFieldVar field) {
-
-        JMethod result = null;
-        if(ruleFactory.getGenerationConfig().isUseInnerClassBuilders()) {
-            result = addInnerBuilder(jclass, propertyType, field);
-        } else {
-            result = addLegacyBuilder(jclass, propertyType, field);
-        }
-
-        return result;
-    }
-
-    private JMethod addLegacyBuilder(JDefinedClass jclass, JType propertyType, JFieldVar field) {
+    private void addBuilder(JDefinedClass jclass, JType propertyType, JFieldVar field) {
         JMethod builder = jclass.method(JMod.PUBLIC, jclass, "withAdditionalProperty");
 
         JVar nameParam = builder.param(String.class, "name");
@@ -188,32 +171,6 @@ public class AdditionalPropertiesRule implements Rule<JDefinedClass, JDefinedCla
         mapInvocation.arg(nameParam);
         mapInvocation.arg(valueParam);
         body._return(JExpr._this());
-
-        return builder;
-    }
-
-    private JMethod addInnerBuilder(JDefinedClass jclass, JType propertyType, JFieldVar field) {
-        Optional<JDefinedClass> builderClass = StreamSupport
-            .stream(Spliterators.spliteratorUnknownSize(jclass.classes(), Spliterator.ORDERED), false)
-            .filter(definedClass -> definedClass.name().equals(getBuilderClassName(jclass)))
-            .findFirst();
-
-        JMethod builder = builderClass.get().method(JMod.PUBLIC, builderClass.get(), "withAdditionalProperty");
-
-        JVar nameParam = builder.param(String.class, "name");
-        JVar valueParam = builder.param(propertyType, "value");
-
-        JBlock body = builder.body();
-        JInvocation mapInvocation = body.invoke(JExpr.ref(JExpr.cast(jclass, JExpr._this().ref("instance")), field), "put");
-        mapInvocation.arg(nameParam);
-        mapInvocation.arg(valueParam);
-        body._return(JExpr._this());
-
-        return builder;
-    }
-
-    private String getBuilderClassName(JDefinedClass c) {
-        return ruleFactory.getNameHelper().getBuilderClassName(c);
     }
 
 }
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/BuilderRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/BuilderRule.java
deleted file mode 100644
index 7f509513..00000000
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/BuilderRule.java
+++ /dev/null
@@ -1,121 +0,0 @@
-/**
- * Copyright Â© 2010-2017 Nokia
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jsonschema2pojo.rules;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.sun.codemodel.JAnnotationUse;
-import com.sun.codemodel.JBlock;
-import com.sun.codemodel.JClass;
-import com.sun.codemodel.JClassAlreadyExistsException;
-import com.sun.codemodel.JConditional;
-import com.sun.codemodel.JDefinedClass;
-import com.sun.codemodel.JExpr;
-import com.sun.codemodel.JFieldVar;
-import com.sun.codemodel.JInvocation;
-import com.sun.codemodel.JMethod;
-import com.sun.codemodel.JMod;
-import com.sun.codemodel.JTypeVar;
-import com.sun.codemodel.JVar;
-import java.util.Objects;
-import org.jsonschema2pojo.Schema;
-import org.jsonschema2pojo.util.ReflectionHelper;
-
-public class BuilderRule implements Rule<JDefinedClass, JDefinedClass> {
-
-  private RuleFactory ruleFactory;
-  private ReflectionHelper reflectionHelper;
-
-  BuilderRule(RuleFactory ruleFactory, ReflectionHelper reflectionHelper) {
-    this.ruleFactory = ruleFactory;
-    this.reflectionHelper = reflectionHelper;
-  }
-
-  @Override
-  public JDefinedClass apply(String nodeName, JsonNode node, JsonNode parent, JDefinedClass instanceClass, Schema currentSchema) {
-
-    // Create the inner class for the builder
-    JDefinedClass builderClass;
-
-    try {
-      String builderName = ruleFactory.getNameHelper().getBuilderClassName(instanceClass);
-      builderClass = instanceClass._class(JMod.PUBLIC + JMod.STATIC, builderName);
-    } catch (JClassAlreadyExistsException e) {
-      return e.getExistingClass();
-    }
-
-    // Determine which builder (if any) this builder should inherit from
-    JClass parentBuilderClass = null;
-    JClass parentClass = instanceClass._extends();
-    if (!(parentClass.isPrimitive() || reflectionHelper.isFinal(parentClass) || Objects.equals(parentClass.fullName(), "java.lang.Object"))) {
-      parentBuilderClass = reflectionHelper.getBuilderClass(parentClass);
-    }
-
-    // Determine the generic type 'T' that the builder will create instances of
-    JTypeVar instanceType = builderClass.generify("T", instanceClass);
-
-    // For new builders we need to create an instance variable and 'build' method
-    // for inheriting builders we'll receive these from the superType
-    if (parentBuilderClass == null) {
-
-      // Create the instance variable
-      JFieldVar instanceField = builderClass.field(JMod.PROTECTED, instanceType, "instance");
-
-      // Create the actual "build" method
-      JMethod buildMethod = builderClass.method(JMod.PUBLIC, instanceType, "build");
-
-      JBlock body = buildMethod.body();
-      JVar result = body.decl(instanceType, "result");
-      body.assign(result, JExpr._this().ref(instanceField));
-      body.assign(JExpr._this().ref(instanceField), JExpr._null());
-      body._return(result);
-
-      // Create the noargs builder constructor
-      generateNoArgsBuilderConstructor(instanceClass, builderClass);
-    } else {
-      // Declare the inheritance
-      builderClass._extends(parentBuilderClass);
-
-      // Create the noargs builder constructor
-      generateNoArgsBuilderConstructor(instanceClass, builderClass);
-    }
-
-    return builderClass;
-  }
-
-  private void generateNoArgsBuilderConstructor(JDefinedClass instanceClass, JDefinedClass builderClass) {
-    JMethod noargsConstructor = builderClass.constructor(JMod.PUBLIC);
-    JAnnotationUse warningSuppression = noargsConstructor.annotate(SuppressWarnings.class);
-    warningSuppression.param("value", "unchecked");
-
-    JBlock constructorBlock = noargsConstructor.body();
-
-    JFieldVar instanceField = reflectionHelper.searchClassAndSuperClassesForField("instance", builderClass);
-
-    // Determine if we need to invoke the super() method for our parent builder
-    JClass parentClass = builderClass._extends();
-    if (!(parentClass.isPrimitive() || reflectionHelper.isFinal(parentClass) || Objects.equals(parentClass.fullName(), "java.lang.Object"))) {
-      constructorBlock.invoke("super");
-    }
-
-    // Only initialize the instance if the object being constructed is actually this class
-    // if it's a subtype then ignore the instance initialization since the subclass will initialize it
-    constructorBlock.directStatement("// Skip initialization when called from subclass");
-    JInvocation comparison = JExpr._this().invoke("getClass").invoke("equals").arg(JExpr.dotclass(builderClass));
-    JConditional ifNotSubclass = constructorBlock._if(comparison);
-    ifNotSubclass._then().assign(JExpr._this().ref(instanceField), JExpr.cast(instanceField.type(), JExpr._new(instanceClass)));
-  }
-
-}
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/ConstructorRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/ConstructorRule.java
deleted file mode 100644
index a1fa614f..00000000
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/ConstructorRule.java
+++ /dev/null
@@ -1,240 +0,0 @@
-/**
- * Copyright Â© 2010-2017 Nokia
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jsonschema2pojo.rules;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.sun.codemodel.JBlock;
-import com.sun.codemodel.JClass;
-import com.sun.codemodel.JConditional;
-import com.sun.codemodel.JDefinedClass;
-import com.sun.codemodel.JExpr;
-import com.sun.codemodel.JFieldVar;
-import com.sun.codemodel.JInvocation;
-import com.sun.codemodel.JMethod;
-import com.sun.codemodel.JMod;
-import com.sun.codemodel.JVar;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.LinkedHashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.Objects;
-import java.util.Set;
-import org.jsonschema2pojo.GenerationConfig;
-import org.jsonschema2pojo.Schema;
-import org.jsonschema2pojo.util.NameHelper;
-import org.jsonschema2pojo.util.ReflectionHelper;
-
-public class ConstructorRule  implements Rule<JDefinedClass, JDefinedClass> {
-
-  private final RuleFactory ruleFactory;
-  private final ReflectionHelper reflectionHelper;
-
-  ConstructorRule(RuleFactory ruleFactory, ReflectionHelper reflectionHelper) {
-    this.ruleFactory = ruleFactory;
-    this.reflectionHelper = reflectionHelper;
-  }
-
-  @Override
-  public JDefinedClass apply(String nodeName, JsonNode node, JsonNode parent, JDefinedClass instanceClass, Schema currentSchema) {
-
-    GenerationConfig generationConfig = ruleFactory.getGenerationConfig();
-
-    // Determine which properties belong to that class (or its superType/parent)
-    LinkedHashSet<String> classProperties = getConstructorProperties(node, generationConfig.isConstructorsRequiredPropertiesOnly());
-    LinkedHashSet<String> combinedSuperProperties = getSuperTypeConstructorPropertiesRecursive(node, currentSchema, generationConfig.isConstructorsRequiredPropertiesOnly());
-
-    // no properties to put in the constructor => default constructor is good enough.
-    if (classProperties.isEmpty() && combinedSuperProperties.isEmpty()) {
-      return instanceClass;
-    }
-
-    // Generate the no arguments constructor
-    generateNoArgsConstructor(instanceClass);
-
-    // Generate the constructor with the properties which were located
-    JMethod instanceConstructor = generateFieldsConstructor(instanceClass, classProperties, combinedSuperProperties);
-
-    // If we're using InnerClassBuilder implementations then we also need to generate those
-    if (generationConfig.isGenerateBuilders() && generationConfig.isUseInnerClassBuilders()) {
-      JDefinedClass builderClass = ruleFactory.getReflectionHelper().getBuilderClass(instanceClass);
-      generateFieldsBuilderConstructor(builderClass, instanceClass, instanceConstructor);
-    }
-
-    return instanceClass;
-  }
-
-  /**
-   * Retrieve the list of properties to go in the constructor from node. This is all properties listed in node["properties"] if ! onlyRequired, and
-   * only required properties if onlyRequired.
-   */
-  private LinkedHashSet<String> getConstructorProperties(JsonNode node, boolean onlyRequired) {
-
-    if (!node.has("properties")) {
-      return new LinkedHashSet<>();
-    }
-
-    LinkedHashSet<String> rtn = new LinkedHashSet<>();
-    Set<String> draft4RequiredProperties = new HashSet<>();
-
-    // setup the set of required properties for draft4 style "required"
-    if (onlyRequired && node.has("required")) {
-      JsonNode requiredArray = node.get("required");
-      if (requiredArray.isArray()) {
-        for (JsonNode requiredEntry : requiredArray) {
-          if (requiredEntry.isTextual()) {
-            draft4RequiredProperties.add(requiredEntry.asText());
-          }
-        }
-      }
-    }
-
-    NameHelper nameHelper = ruleFactory.getNameHelper();
-    for (Iterator<Entry<String, JsonNode>> properties = node.get("properties").fields(); properties.hasNext(); ) {
-      Map.Entry<String, JsonNode> property = properties.next();
-
-      JsonNode propertyObj = property.getValue();
-      if (onlyRequired) {
-        // draft3 style
-        if (propertyObj.has("required") && propertyObj.get("required").asBoolean()) {
-          rtn.add(nameHelper.getPropertyName(property.getKey(), property.getValue()));
-        }
-
-        // draft4 style
-        if (draft4RequiredProperties.contains(property.getKey())) {
-          rtn.add(nameHelper.getPropertyName(property.getKey(), property.getValue()));
-        }
-      } else {
-        rtn.add(nameHelper.getPropertyName(property.getKey(), property.getValue()));
-      }
-    }
-    return rtn;
-  }
-
-  /**
-   * Recursive, walks the schema tree and assembles a list of all properties of this schema's super schemas
-   */
-  private LinkedHashSet<String> getSuperTypeConstructorPropertiesRecursive(JsonNode node, Schema schema, boolean onlyRequired) {
-    Schema superTypeSchema = reflectionHelper.getSuperSchema(node, schema, true);
-
-    if (superTypeSchema == null) {
-      return new LinkedHashSet<>();
-    }
-
-    JsonNode superSchemaNode = superTypeSchema.getContent();
-
-    LinkedHashSet<String> rtn = getConstructorProperties(superSchemaNode, onlyRequired);
-    rtn.addAll(getSuperTypeConstructorPropertiesRecursive(superSchemaNode, superTypeSchema, onlyRequired));
-
-    return rtn;
-  }
-
-  private void generateFieldsBuilderConstructor(JDefinedClass builderClass, JDefinedClass instanceClass, JMethod instanceConstructor) {
-    // Locate the instance field since we'll need it to assign a value
-    JFieldVar instanceField = reflectionHelper.searchClassAndSuperClassesForField("instance", builderClass);
-
-    // Create a new method to be the builder constructor we're defining
-    JMethod builderConstructor = builderClass.constructor(JMod.PUBLIC);
-    builderConstructor.annotate(SuppressWarnings.class).param("value", "unchecked");
-    JBlock constructorBlock = builderConstructor.body();
-
-    // The builder constructor should have the exact same parameters as the instanceConstructor
-    for(JVar param : instanceConstructor.params()) {
-      builderConstructor.param(param.type(), param.name());
-    }
-
-    // Determine if we need to invoke the super() method for our parent builder
-    JClass parentClass = builderClass._extends();
-    if (!(parentClass.isPrimitive() || reflectionHelper.isFinal(parentClass) || Objects.equals(parentClass.fullName(), "java.lang.Object"))) {
-      constructorBlock.invoke("super");
-    }
-
-    // The constructor invocation will also need all the parameters passed through
-    JInvocation instanceConstructorInvocation = JExpr._new(instanceClass);
-    for(JVar param : instanceConstructor.params()) {
-      instanceConstructorInvocation.arg(param);
-    }
-
-    // Only initialize the instance if the object being constructed is actually this class
-    // if it's a subtype then ignore the instance initialization since the subclass will initialize it
-    constructorBlock.directStatement("// Skip initialization when called from subclass");
-
-    JInvocation comparison = JExpr._this().invoke("getClass").invoke("equals").arg(JExpr.dotclass(builderClass));
-    JConditional ifNotSubclass = constructorBlock._if(comparison);
-    ifNotSubclass._then().assign(JExpr._this().ref(instanceField), JExpr.cast(instanceField.type(), instanceConstructorInvocation));
-  }
-
-  private JMethod generateFieldsConstructor(JDefinedClass jclass, LinkedHashSet<String> classProperties, LinkedHashSet<String> combinedSuperProperties) {
-    // add the public constructor with property parameters
-    JMethod fieldsConstructor = jclass.constructor(JMod.PUBLIC);
-    JBlock constructorBody = fieldsConstructor.body();
-    JInvocation superInvocation = constructorBody.invoke("super");
-
-    Map<String, JFieldVar> fields = jclass.fields();
-    Map<String, JVar> classFieldParams = new HashMap<>();
-
-    for (String property : classProperties) {
-      JFieldVar field = fields.get(property);
-
-      if (field == null) {
-        throw new IllegalStateException("Property " + property + " hasn't been added to JDefinedClass before calling addConstructors");
-      }
-
-      fieldsConstructor.javadoc().addParam(property);
-      JVar param = fieldsConstructor.param(field.type(), field.name());
-      constructorBody.assign(JExpr._this().ref(field), param);
-      classFieldParams.put(property, param);
-    }
-
-    List<JVar> superConstructorParams = new ArrayList<>();
-
-    for (String property : combinedSuperProperties) {
-      JFieldVar field = reflectionHelper.searchSuperClassesForField(property, jclass);
-
-      if (field == null) {
-        throw new IllegalStateException("Property " + property + " hasn't been added to JDefinedClass before calling addConstructors");
-      }
-
-      JVar param = classFieldParams.get(property);
-
-      if (param == null) {
-        param = fieldsConstructor.param(field.type(), field.name());
-      }
-
-      fieldsConstructor.javadoc().addParam(property);
-      superConstructorParams.add(param);
-    }
-
-    for (JVar param : superConstructorParams) {
-      superInvocation.arg(param);
-    }
-
-    return fieldsConstructor;
-  }
-
-  private void generateNoArgsConstructor(JDefinedClass jclass) {
-    // add a no-args constructor for serialization purposes
-    JMethod noargsConstructor = jclass.constructor(JMod.PUBLIC);
-    noargsConstructor.javadoc().add("No args constructor for use in serialization");
-  }
-
-
-
-
-}
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/ObjectRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/ObjectRule.java
index b193abba..8ec98277 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/ObjectRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/ObjectRule.java
@@ -13,13 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package org.jsonschema2pojo.rules;
 
-import static org.apache.commons.lang3.StringUtils.substringAfter;
-import static org.apache.commons.lang3.StringUtils.substringBefore;
-import static org.jsonschema2pojo.rules.PrimitiveTypes.isPrimitive;
-import static org.jsonschema2pojo.rules.PrimitiveTypes.primitiveType;
-import static org.jsonschema2pojo.util.TypeUtil.resolveType;
+package org.jsonschema2pojo.rules;
 
 import com.fasterxml.jackson.annotation.JsonTypeInfo;
 import com.fasterxml.jackson.databind.JsonNode;
@@ -34,26 +29,41 @@ import com.sun.codemodel.JExpr;
 import com.sun.codemodel.JExpression;
 import com.sun.codemodel.JFieldRef;
 import com.sun.codemodel.JFieldVar;
+import com.sun.codemodel.JInvocation;
 import com.sun.codemodel.JMethod;
 import com.sun.codemodel.JMod;
 import com.sun.codemodel.JOp;
 import com.sun.codemodel.JPackage;
 import com.sun.codemodel.JType;
 import com.sun.codemodel.JVar;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Set;
+
 import org.jsonschema2pojo.AnnotationStyle;
 import org.jsonschema2pojo.Schema;
 import org.jsonschema2pojo.exception.ClassAlreadyExistsException;
 import org.jsonschema2pojo.exception.GenerationException;
+import org.jsonschema2pojo.util.MakeUniqueClassName;
+import org.jsonschema2pojo.util.NameHelper;
 import org.jsonschema2pojo.util.ParcelableHelper;
-import org.jsonschema2pojo.util.ReflectionHelper;
 import org.jsonschema2pojo.util.SerializableHelper;
 
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import static org.apache.commons.lang3.StringUtils.capitalize;
+import static org.apache.commons.lang3.StringUtils.substringAfter;
+import static org.apache.commons.lang3.StringUtils.substringBefore;
+import static org.jsonschema2pojo.rules.PrimitiveTypes.isPrimitive;
+import static org.jsonschema2pojo.rules.PrimitiveTypes.primitiveType;
+import static org.jsonschema2pojo.util.TypeUtil.resolveType;
+
 /**
  * Applies the generation steps required for schemas of type "object".
  *
@@ -64,13 +74,11 @@ import org.jsonschema2pojo.util.SerializableHelper;
 public class ObjectRule implements Rule<JPackage, JType> {
 
     private final RuleFactory ruleFactory;
-    private final ReflectionHelper reflectionHelper;
     private final ParcelableHelper parcelableHelper;
 
-    protected ObjectRule(RuleFactory ruleFactory, ParcelableHelper parcelableHelper, ReflectionHelper reflectionHelper) {
+    protected ObjectRule(RuleFactory ruleFactory, ParcelableHelper parcelableHelper) {
         this.ruleFactory = ruleFactory;
         this.parcelableHelper = parcelableHelper;
-        this.reflectionHelper = reflectionHelper;
     }
 
     /**
@@ -83,8 +91,9 @@ public class ObjectRule implements Rule<JPackage, JType> {
     @Override
     public JType apply(String nodeName, JsonNode node, JsonNode parent, JPackage _package, Schema schema) {
 
-        JType superType = reflectionHelper.getSuperType(nodeName, node, _package, schema);
-        if (superType.isPrimitive() || reflectionHelper.isFinal(superType)) {
+        JType superType = getSuperType(nodeName, node, _package, schema);
+
+        if (superType.isPrimitive() || isFinal(superType)) {
             return superType;
         }
 
@@ -111,11 +120,6 @@ public class ObjectRule implements Rule<JPackage, JType> {
             ruleFactory.getDescriptionRule().apply(nodeName, node.get("description"), node, jclass, schema);
         }
 
-        // Creates the class definition for the builder
-        if(ruleFactory.getGenerationConfig().isGenerateBuilders() && ruleFactory.getGenerationConfig().isUseInnerClassBuilders()){
-            ruleFactory.getBuilderRule().apply(nodeName, node, parent, jclass, schema);
-        }
-
         ruleFactory.getPropertiesRule().apply(nodeName, node.get("properties"), node, jclass, schema);
 
         if (node.has("javaInterfaces")) {
@@ -144,8 +148,7 @@ public class ObjectRule implements Rule<JPackage, JType> {
         }
 
         if (ruleFactory.getGenerationConfig().isIncludeConstructors()) {
-            ruleFactory.getConstructorRule().apply(nodeName, node, parent, jclass, schema);
-
+            addConstructors(jclass, node, schema, ruleFactory.getGenerationConfig().isConstructorsRequiredPropertiesOnly());
         }
 
         if (ruleFactory.getGenerationConfig().isSerializable()) {
@@ -170,7 +173,74 @@ public class ObjectRule implements Rule<JPackage, JType> {
         }
     }
 
+    /**
+     * Retrieve the list of properties to go in the constructor from node. This
+     * is all properties listed in node["properties"] if ! onlyRequired, and
+     * only required properties if onlyRequired.
+     *
+     * @param node
+     * @return
+     */
+    private LinkedHashSet<String> getConstructorProperties(JsonNode node, boolean onlyRequired) {
+
+        if (!node.has("properties")) {
+            return new LinkedHashSet<>();
+        }
+
+        LinkedHashSet<String> rtn = new LinkedHashSet<>();
+        Set<String> draft4RequiredProperties = new HashSet<>();
+
+        // setup the set of required properties for draft4 style "required"
+        if (onlyRequired && node.has("required")) {
+            JsonNode requiredArray =  node.get("required");
+            if (requiredArray.isArray()) {
+                for (JsonNode requiredEntry: requiredArray) {
+                    if (requiredEntry.isTextual()) {
+                        draft4RequiredProperties.add(requiredEntry.asText());
+                    }
+                }
+            }
+        }
+
+        NameHelper nameHelper = ruleFactory.getNameHelper();
+        for (Iterator<Map.Entry<String, JsonNode>> properties = node.get("properties").fields(); properties.hasNext();) {
+            Map.Entry<String, JsonNode> property = properties.next();
+
+            JsonNode propertyObj = property.getValue();
+            if (onlyRequired) {
+                // draft3 style
+                if (propertyObj.has("required") && propertyObj.get("required").asBoolean()) {
+                    rtn.add(nameHelper.getPropertyName(property.getKey(), property.getValue()));
+                }
+
+                // draft4 style
+                if (draft4RequiredProperties.contains(property.getKey())) {
+                    rtn.add(nameHelper.getPropertyName(property.getKey(), property.getValue()));
+                }
+            } else {
+                rtn.add(nameHelper.getPropertyName(property.getKey(), property.getValue()));
+            }
+        }
+        return rtn;
+    }
+
+    /**
+     * Recursive, walks the schema tree and assembles a list of all properties of this schema's super schemas
+     */
+    private LinkedHashSet<String> getSuperTypeConstructorPropertiesRecursive(JsonNode node, Schema schema, boolean onlyRequired) {
+        Schema superTypeSchema = getSuperSchema(node, schema, true);
+
+        if (superTypeSchema == null) {
+            return new LinkedHashSet<>();
+        }
+
+        JsonNode superSchemaNode = superTypeSchema.getContent();
 
+        LinkedHashSet<String> rtn = getConstructorProperties(superSchemaNode, onlyRequired);
+        rtn.addAll(getSuperTypeConstructorPropertiesRecursive(superSchemaNode, superTypeSchema, onlyRequired));
+
+        return rtn;
+    }
 
     /**
      * Creates a new Java class that will be generated.
@@ -231,9 +301,9 @@ public class ObjectRule implements Rule<JPackage, JType> {
                 }
             } else {
                 if (usePolymorphicDeserialization) {
-                    newType = _package._class(JMod.PUBLIC, ruleFactory.getNameHelper().getUniqueClassName(nodeName, node, _package), ClassType.CLASS);
+                    newType = _package._class(JMod.PUBLIC, getClassName(nodeName, node, _package), ClassType.CLASS);
                 } else {
-                    newType = _package._class(ruleFactory.getNameHelper().getUniqueClassName(nodeName, node, _package));
+                    newType = _package._class(getClassName(nodeName, node, _package));
                 }
             }
         } catch (JClassAlreadyExistsException e) {
@@ -246,6 +316,60 @@ public class ObjectRule implements Rule<JPackage, JType> {
 
     }
 
+    private boolean isFinal(JType superType) {
+        try {
+            Class<?> javaClass = Class.forName(superType.fullName());
+            return Modifier.isFinal(javaClass.getModifiers());
+        } catch (ClassNotFoundException e) {
+            return false;
+        }
+    }
+
+    private JType getSuperType(String nodeName, JsonNode node, JPackage jPackage, Schema schema) {
+        if (node.has("extends") && node.has("extendsJavaClass")) {
+            throw new IllegalStateException("'extends' and 'extendsJavaClass' defined simultaneously");
+        }
+
+        JType superType = jPackage.owner().ref(Object.class);
+        Schema superTypeSchema = getSuperSchema(node, schema, false);
+        if (superTypeSchema != null) {
+            superType = ruleFactory.getSchemaRule().apply(nodeName + "Parent", node.get("extends"), node, jPackage, superTypeSchema);
+        } else if (node.has("extendsJavaClass")) {
+            superType = resolveType(jPackage, node.get("extendsJavaClass").asText());
+        }
+
+        return superType;
+    }
+
+    private Schema getSuperSchema(JsonNode node, Schema schema, boolean followRefs) {
+        if (node.has("extends")) {
+            String path;
+            if (schema.getId().getFragment() == null) {
+                path = "#extends";
+            } else {
+                path = "#" + schema.getId().getFragment() + "/extends";
+            }
+
+            Schema superSchema = ruleFactory.getSchemaStore().create(schema, path, ruleFactory.getGenerationConfig().getRefFragmentPathDelimiters());
+
+            if (followRefs) {
+                superSchema = resolveSchemaRefsRecursive(superSchema);
+            }
+
+            return superSchema;
+        }
+        return null;
+    }
+
+    private Schema resolveSchemaRefsRecursive(Schema schema) {
+        JsonNode schemaNode = schema.getContent();
+        if (schemaNode.has("$ref")) {
+            schema = ruleFactory.getSchemaStore().create(schema, schemaNode.get("$ref").asText(), ruleFactory.getGenerationConfig().getRefFragmentPathDelimiters());
+            return resolveSchemaRefsRecursive(schema);
+        }
+        return schema;
+    }
+
     private void addJsonTypeInfoAnnotation(JDefinedClass jclass, JsonNode node) {
         if (ruleFactory.getGenerationConfig().getAnnotationStyle() == AnnotationStyle.JACKSON2) {
             String annotationName = node.get("deserializationClassProperty").asText();
@@ -451,6 +575,98 @@ public class ObjectRule implements Rule<JPackage, JType> {
         return filteredFields;
     }
 
+    private void addConstructors(JDefinedClass jclass, JsonNode node, Schema schema, boolean onlyRequired) {
+
+        LinkedHashSet<String> classProperties = getConstructorProperties(node, onlyRequired);
+        LinkedHashSet<String> combinedSuperProperties = getSuperTypeConstructorPropertiesRecursive(node, schema, onlyRequired);
+
+        // no properties to put in the constructor => default constructor is good enough.
+        if (classProperties.isEmpty() && combinedSuperProperties.isEmpty()) {
+            return;
+        }
+
+        // add a no-args constructor for serialization purposes
+        JMethod noargsConstructor = jclass.constructor(JMod.PUBLIC);
+        noargsConstructor.javadoc().add("No args constructor for use in serialization");
+
+        // add the public constructor with property parameters
+        JMethod fieldsConstructor = jclass.constructor(JMod.PUBLIC);
+        JBlock constructorBody = fieldsConstructor.body();
+        JInvocation superInvocation = constructorBody.invoke("super");
+
+        Map<String, JFieldVar> fields = jclass.fields();
+        Map<String, JVar> classFieldParams = new HashMap<>();
+
+        for (String property : classProperties) {
+            JFieldVar field = fields.get(property);
+
+            if (field == null) {
+                throw new IllegalStateException("Property " + property + " hasn't been added to JDefinedClass before calling addConstructors");
+            }
+
+            fieldsConstructor.javadoc().addParam(property);
+            JVar param = fieldsConstructor.param(field.type(), field.name());
+            constructorBody.assign(JExpr._this().ref(field), param);
+            classFieldParams.put(property, param);
+        }
+
+        List<JVar> superConstructorParams = new ArrayList<>();
+
+
+        for (String property : combinedSuperProperties) {
+            JFieldVar field = searchSuperClassesForField(property, jclass);
+
+            if (field == null) {
+                throw new IllegalStateException("Property " + property + " hasn't been added to JDefinedClass before calling addConstructors");
+            }
+
+            JVar param = classFieldParams.get(property);
+
+            if (param == null) {
+                param = fieldsConstructor.param(field.type(), field.name());
+            }
+
+            fieldsConstructor.javadoc().addParam(property);
+            superConstructorParams.add(param);
+        }
+
+        for (JVar param : superConstructorParams) {
+            superInvocation.arg(param);
+        }
+    }
+
+    private static JDefinedClass definedClassOrNullFromType(JType type)
+    {
+        if (type == null || type.isPrimitive())
+        {
+            return null;
+        }
+        JClass fieldClass = type.boxify();
+        JPackage jPackage = fieldClass._package();
+        return jPackage._getClass(fieldClass.name());
+    }
+
+    /**
+     * This is recursive with searchClassAndSuperClassesForField
+     */
+    private JFieldVar searchSuperClassesForField(String property, JDefinedClass jclass) {
+        JClass superClass = jclass._extends();
+        JDefinedClass definedSuperClass = definedClassOrNullFromType(superClass);
+        if (definedSuperClass == null) {
+            return null;
+        }
+        return searchClassAndSuperClassesForField(property, definedSuperClass);
+    }
+
+    private JFieldVar searchClassAndSuperClassesForField(String property, JDefinedClass jclass) {
+        Map<String, JFieldVar> fields = jclass.fields();
+        JFieldVar field = fields.get(property);
+        if (field == null) {
+            return searchSuperClassesForField(property, jclass);
+        }
+        return field;
+    }
+
     private void addEquals(JDefinedClass jclass, JsonNode node) {
         Map<String, JFieldVar> fields = removeFieldsExcludedFromEqualsAndHashCode(jclass.fields(), node);
 
@@ -520,6 +736,41 @@ public class ObjectRule implements Rule<JPackage, JType> {
         }
     }
 
+    private String getClassName(String nodeName, JsonNode node, JPackage _package) {
+        String prefix = ruleFactory.getGenerationConfig().getClassNamePrefix();
+        String suffix = ruleFactory.getGenerationConfig().getClassNameSuffix();
+        String fieldName = ruleFactory.getNameHelper().getClassName(nodeName, node);
+        String capitalizedFieldName = capitalize(fieldName);
+        String fullFieldName = createFullFieldName(capitalizedFieldName, prefix, suffix);
+
+        String className = ruleFactory.getNameHelper().replaceIllegalCharacters(fullFieldName);
+        String normalizedName = ruleFactory.getNameHelper().normalizeName(className);
+        return makeUnique(normalizedName, _package);
+    }
+
+    private String createFullFieldName(String nodeName, String prefix, String suffix) {
+        String returnString = nodeName;
+        if (prefix != null) {
+            returnString = prefix + returnString;
+        }
+
+        if (suffix != null) {
+            returnString = returnString + suffix;
+        }
+
+        return returnString;
+    }
+
+    private String makeUnique(String className, JPackage _package) {
+        try {
+            JDefinedClass _class = _package._class(className);
+            _package.remove(_class);
+            return className;
+        } catch (JClassAlreadyExistsException e) {
+            return makeUnique(MakeUniqueClassName.makeUnique(className), _package);
+        }
+    }
+
     private boolean usesPolymorphicDeserialization(JsonNode node) {
         if (ruleFactory.getGenerationConfig().getAnnotationStyle() == AnnotationStyle.JACKSON2) {
             return node.has("deserializationClassProperty");
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertiesRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertiesRule.java
index f58d2009..38f817ef 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertiesRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertiesRule.java
@@ -93,7 +93,6 @@ public class PropertiesRule implements Rule<JDefinedClass, JDefinedClass> {
 
     private void addOverrideBuilder(JDefinedClass thisJDefinedClass, JMethod parentBuilder, JVar parentParam) {
 
-        // Confirm that this class doesn't already have a builder method matching the same name as the parentBuilder
         if (thisJDefinedClass.getMethod(parentBuilder.name(), new JType[] {parentParam.type()}) == null) {
 
             JMethod builder = thisJDefinedClass.method(parentBuilder.mods().getValue(), thisJDefinedClass, parentBuilder.name());
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertyRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertyRule.java
index 40f41580..dc6170df 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertyRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/PropertyRule.java
@@ -17,15 +17,7 @@
 package org.jsonschema2pojo.rules;
 
 import com.fasterxml.jackson.databind.JsonNode;
-import com.sun.codemodel.JBlock;
-import com.sun.codemodel.JDefinedClass;
-import com.sun.codemodel.JDocCommentable;
-import com.sun.codemodel.JExpr;
-import com.sun.codemodel.JFieldVar;
-import com.sun.codemodel.JMethod;
-import com.sun.codemodel.JMod;
-import com.sun.codemodel.JType;
-import com.sun.codemodel.JVar;
+import com.sun.codemodel.*;
 import org.jsonschema2pojo.GenerationConfig;
 import org.jsonschema2pojo.Schema;
 
@@ -96,7 +88,7 @@ public class PropertyRule implements Rule<JDefinedClass, JDefinedClass> {
         }
 
         if (ruleFactory.getGenerationConfig().isGenerateBuilders()) {
-            addBuilderMethod(jclass, field, nodeName, node);
+            addBuilder(jclass, field, nodeName, node);
         }
 
         if (node.has("pattern")) {
@@ -118,16 +110,10 @@ public class PropertyRule implements Rule<JDefinedClass, JDefinedClass> {
         return jclass;
     }
 
-    private boolean isRequired(String nodeName, JsonNode node, Schema schema) {
-        if (node.has("required")) {
-            final JsonNode requiredNode = node.get("required");
-            return requiredNode.asBoolean();
-        }
-
-        JsonNode requiredArray = schema.getContent().get("required");
-
-        if (requiredArray != null) {
-            for (JsonNode requiredNode : requiredArray) {
+    private boolean hasEnumerated(Schema schema, String arrayFieldName, String nodeName) {
+        JsonNode array = schema.getContent().get(arrayFieldName);
+        if (array != null) {
+            for (JsonNode requiredNode : array) {
                 if (nodeName.equals(requiredNode.asText()))
                     return true;
             }
@@ -136,22 +122,25 @@ public class PropertyRule implements Rule<JDefinedClass, JDefinedClass> {
         return false;
     }
 
-    private boolean useOptional(String nodeName, JsonNode node, Schema schema) {
-        if (node.has("javaOptional")) {
-            final JsonNode requiredNode = node.get("javaOptional");
+    private boolean hasFlag(JsonNode node, String fieldName) {
+        if (node.has(fieldName)) {
+            final JsonNode requiredNode = node.get(fieldName);
             return requiredNode.asBoolean();
         }
 
-        JsonNode javaOptionalArray = schema.getContent().get("javaOptional");
+        return false;
+    }
 
-        if (javaOptionalArray != null) {
-            for (JsonNode requiredNode : javaOptionalArray) {
-                if (nodeName.equals(requiredNode.asText()))
-                    return true;
-            }
-        }
+    private boolean isDeclaredAs(String type, String nodeName, JsonNode node, Schema schema) {
+        return hasEnumerated(schema, type, nodeName) || hasFlag(node, type);
+    }
 
-        return false;
+    private boolean isRequired(String nodeName, JsonNode node, Schema schema) {
+        return isDeclaredAs("required", nodeName, node, schema);
+    }
+
+    private boolean useOptional(String nodeName, JsonNode node, Schema schema) {
+        return isDeclaredAs("javaOptional", nodeName, node, schema);
     }
 
     private void propertyAnnotations(String nodeName, JsonNode node, Schema schema, JDocCommentable generatedJavaConstruct) {
@@ -241,54 +230,27 @@ public class PropertyRule implements Rule<JDefinedClass, JDefinedClass> {
         return setter;
     }
 
-  private JMethod addBuilderMethod(JDefinedClass c, JFieldVar field, String jsonPropertyName, JsonNode node) {
-    JMethod result = null;
-    if(ruleFactory.getGenerationConfig().isUseInnerClassBuilders()) {
-      result = addInnerBuilderMethod(c, field, jsonPropertyName, node);
-    } else {
-      result = addLegacyBuilder(c, field, jsonPropertyName, node);
-    }
-    return result;
-  }
-
-  private JMethod addLegacyBuilder(JDefinedClass c, JFieldVar field, String jsonPropertyName, JsonNode node) {
-    JMethod builder = c.method(JMod.PUBLIC, c, getBuilderName(jsonPropertyName, node));
-
-    JVar param = builder.param(field.type(), field.name());
-    JBlock body = builder.body();
-    body.assign(JExpr._this().ref(field), param);
-    body._return(JExpr._this());
-
-    return builder;
-  }
-
-  private JMethod addInnerBuilderMethod(JDefinedClass c, JFieldVar field, String jsonPropertyName, JsonNode node)    {
-    JDefinedClass builderClass = ruleFactory.getReflectionHelper().getBuilderClass(c);
+    private JMethod addBuilder(JDefinedClass c, JFieldVar field, String jsonPropertyName, JsonNode node) {
+        JMethod builder = c.method(JMod.PUBLIC, c, getBuilderName(jsonPropertyName, node));
 
-    JMethod builderMethod = builderClass.method(JMod.PUBLIC, builderClass, getBuilderName(jsonPropertyName, node));
-
-    JVar param = builderMethod.param(field.type(), field.name());
-    JBlock body = builderMethod.body();
-    body.assign(JExpr.ref(JExpr.cast(c, JExpr._this().ref("instance")), field), param);
-    body._return(JExpr._this());
-
-    return builderMethod;
-  }
+        JVar param = builder.param(field.type(), field.name());
+        JBlock body = builder.body();
+        body.assign(JExpr._this().ref(field), param);
+        body._return(JExpr._this());
 
-  private String getBuilderClassName(JDefinedClass c) {
-    return ruleFactory.getNameHelper().getBuilderClassName(c);
-  }
+        return builder;
+    }
 
-  private String getBuilderName(String propertyName, JsonNode node) {
-      return ruleFactory.getNameHelper().getBuilderName(propertyName, node);
-  }
+    private String getBuilderName(String propertyName, JsonNode node) {
+        return ruleFactory.getNameHelper().getBuilderName(propertyName, node);
+    }
 
-  private String getSetterName(String propertyName, JsonNode node) {
-      return ruleFactory.getNameHelper().getSetterName(propertyName, node);
-  }
+    private String getSetterName(String propertyName, JsonNode node) {
+        return ruleFactory.getNameHelper().getSetterName(propertyName, node);
+    }
 
-  private String getGetterName(String propertyName, JType type, JsonNode node) {
-      return ruleFactory.getNameHelper().getGetterName(propertyName, type, node);
-  }
+    private String getGetterName(String propertyName, JType type, JsonNode node) {
+        return ruleFactory.getNameHelper().getGetterName(propertyName, type, node);
+    }
 
 }
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/RuleFactory.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/RuleFactory.java
index 64ce830f..ca1342e2 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/RuleFactory.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/RuleFactory.java
@@ -32,8 +32,6 @@ import com.sun.codemodel.JDocCommentable;
 import com.sun.codemodel.JFieldVar;
 import com.sun.codemodel.JPackage;
 import com.sun.codemodel.JType;
-import org.jsonschema2pojo.util.ReflectionHelper;
-import sun.reflect.Reflection;
 
 /**
  * Provides factory/creation methods for the code generation rules.
@@ -41,7 +39,6 @@ import sun.reflect.Reflection;
 public class RuleFactory {
 
     private NameHelper nameHelper;
-    private ReflectionHelper reflectionHelper;
     private GenerationConfig generationConfig;
     private Annotator annotator;
     private SchemaStore schemaStore;
@@ -64,7 +61,6 @@ public class RuleFactory {
         this.annotator = annotator;
         this.schemaStore = schemaStore;
         this.nameHelper = new NameHelper(generationConfig);
-        this.reflectionHelper = new ReflectionHelper(this);
     }
 
     /**
@@ -123,17 +119,7 @@ public class RuleFactory {
      * @return a schema rule that can handle the "object" declaration.
      */
     public Rule<JPackage, JType> getObjectRule() {
-        return new ObjectRule(this, new ParcelableHelper(), reflectionHelper);
-    }
-
-    /**
-     * Provides a rule instance that should be applied to add constructors to a generated type
-     *
-     * @return a schema rule that can handle the "object" declaration.
-     */
-    public Rule<JDefinedClass, JDefinedClass> getConstructorRule()
-    {
-        return new ConstructorRule(this, reflectionHelper);
+        return new ObjectRule(this, new ParcelableHelper());
     }
 
     /**
@@ -370,11 +356,6 @@ public class RuleFactory {
         return nameHelper;
     }
 
-    public ReflectionHelper getReflectionHelper()    {
-        return reflectionHelper;
-    }
-
-
     /**
      * Provides a rule instance that should be applied when a "media"
      * declaration is found in the schema.
@@ -393,10 +374,6 @@ public class RuleFactory {
         return new DynamicPropertiesRule(this);
     }
 
-    public Rule<JDefinedClass, JDefinedClass> getBuilderRule(){
-        return new BuilderRule(this, reflectionHelper);
-    }
-
     public Rule<JDocCommentable, JDocComment> getJavaNameRule() {
         return new JavaNameRule();
     }
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/TypeRule.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/TypeRule.java
index 92f958cb..6a7c9c5a 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/TypeRule.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/rules/TypeRule.java
@@ -1,14 +1,17 @@
 /**
  * Copyright © 2010-2017 Nokia
  *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- * http://www.apache.org/licenses/LICENSE-2.0
+ *      http://www.apache.org/licenses/LICENSE-2.0
  *
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations
- * under the License.
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 
 package org.jsonschema2pojo.rules;
@@ -30,145 +33,155 @@ import com.sun.codemodel.JType;
 /**
  * Applies the "type" schema rule.
  *
- * @see <a href= "http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1">http:/ /tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1</a>
+ * @see <a href=
+ *      "http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1">http:/
+ *      /tools.ietf.org/html/draft-zyp-json-schema-03#section-5.1</a>
  */
 public class TypeRule implements Rule<JClassContainer, JType> {
 
-  private static final String DEFAULT_TYPE_NAME = "any";
-
-  private final RuleFactory ruleFactory;
-
-  protected TypeRule(RuleFactory ruleFactory) {
-    this.ruleFactory = ruleFactory;
-  }
-
-  /**
-   * Applies this schema rule to take the required code generation steps.
-   * <p>
-   * When applied, this rule reads the details of the given node to determine the appropriate Java type to return. This may be a newly generated type,
-   * it may be a primitive type or other type such as {@link java.lang.String} or {@link java.lang.Object}.
-   * <p>
-   * JSON schema types and their Java type equivalent:
-   * <ul>
-   * <li>"type":"any" =&gt; {@link java.lang.Object}
-   * <li>"type":"array" =&gt; Either {@link java.util.Set} or
-   * {@link java.util.List}, see {@link ArrayRule}
-   * <li>"type":"boolean" =&gt; <code>boolean</code>
-   * <li>"type":"integer" =&gt; <code>int</code>
-   * <li>"type":"null" =&gt; {@link java.lang.Object}
-   * <li>"type":"number" =&gt; <code>double</code>
-   * <li>"type":"object" =&gt; Generated type (see {@link ObjectRule})
-   * <li>"type":"string" =&gt; {@link java.lang.String} (or alternative based
-   * on presence of "format", see {@link FormatRule})
-   * </ul>
-   *
-   * @param nodeName the name of the node for which this "type" rule applies
-   * @param node the node for which this "type" rule applies
-   * @param parent the parent node
-   * @param jClassContainer the package into which any newly generated type may be placed
-   * @return the Java type which, after reading the details of the given schema node, most appropriately matches the "type" specified
-   */
-  @Override
-  public JType apply(String nodeName, JsonNode node, JsonNode parent, JClassContainer jClassContainer, Schema schema) {
-
-    String propertyTypeName = getTypeName(node);
-
-    JType type;
-
-    if (propertyTypeName.equals("object") || node.has("properties") && node.path("properties").size() > 0) {
-
-      type = ruleFactory.getObjectRule().apply(nodeName, node, parent, jClassContainer.getPackage(), schema);
-    } else if (node.has("existingJavaType")) {
-      String typeName = node.path("existingJavaType").asText();
-
-      if (isPrimitive(typeName, jClassContainer.owner())) {
-        type = primitiveType(typeName, jClassContainer.owner());
-      } else {
-        type = resolveType(jClassContainer, typeName);
-      }
-    } else if (propertyTypeName.equals("string")) {
-
-      type = jClassContainer.owner().ref(String.class);
-    } else if (propertyTypeName.equals("number")) {
-
-      type = getNumberType(jClassContainer.owner(), ruleFactory.getGenerationConfig());
-    } else if (propertyTypeName.equals("integer")) {
-
-      type = getIntegerType(jClassContainer.owner(), node, ruleFactory.getGenerationConfig());
-    } else if (propertyTypeName.equals("boolean")) {
-
-      type = unboxIfNecessary(jClassContainer.owner().ref(Boolean.class), ruleFactory.getGenerationConfig());
-    } else if (propertyTypeName.equals("array")) {
-
-      type = ruleFactory.getArrayRule().apply(nodeName, node, parent, jClassContainer.getPackage(), schema);
-    } else {
-
-      type = jClassContainer.owner().ref(Object.class);
-    }
+    private static final String DEFAULT_TYPE_NAME = "any";
+
+    private final RuleFactory ruleFactory;
 
-    if (!node.has("javaType") && !node.has("existingJavaType") && node.has("format")) {
-      type = ruleFactory.getFormatRule().apply(nodeName, node.get("format"), node, type, schema);
-    } else if (!node.has("javaType") && !node.has("existingJavaType") && propertyTypeName.equals("string") && node.has("media")) {
-      type = ruleFactory.getMediaRule().apply(nodeName, node.get("media"), node, type, schema);
+    protected TypeRule(RuleFactory ruleFactory) {
+        this.ruleFactory = ruleFactory;
     }
 
-    return type;
-  }
+    /**
+     * Applies this schema rule to take the required code generation steps.
+     * <p>
+     * When applied, this rule reads the details of the given node to determine
+     * the appropriate Java type to return. This may be a newly generated type,
+     * it may be a primitive type or other type such as {@link java.lang.String}
+     * or {@link java.lang.Object}.
+     * <p>
+     * JSON schema types and their Java type equivalent:
+     * <ul>
+     * <li>"type":"any" =&gt; {@link java.lang.Object}
+     * <li>"type":"array" =&gt; Either {@link java.util.Set} or
+     * {@link java.util.List}, see {@link ArrayRule}
+     * <li>"type":"boolean" =&gt; <code>boolean</code>
+     * <li>"type":"integer" =&gt; <code>int</code>
+     * <li>"type":"null" =&gt; {@link java.lang.Object}
+     * <li>"type":"number" =&gt; <code>double</code>
+     * <li>"type":"object" =&gt; Generated type (see {@link ObjectRule})
+     * <li>"type":"string" =&gt; {@link java.lang.String} (or alternative based
+     * on presence of "format", see {@link FormatRule})
+     * </ul>
+     *
+     * @param nodeName
+     *            the name of the node for which this "type" rule applies
+     * @param node
+     *            the node for which this "type" rule applies
+     * @param parent
+     *            the parent node
+     * @param jClassContainer
+     *            the package into which any newly generated type may be placed
+     * @return the Java type which, after reading the details of the given
+     *         schema node, most appropriately matches the "type" specified
+     */
+    @Override
+    public JType apply(String nodeName, JsonNode node, JsonNode parent, JClassContainer jClassContainer, Schema schema) {
+
+        String propertyTypeName = getTypeName(node);
+
+        JType type;
+
+        if (propertyTypeName.equals("object") || node.has("properties") && node.path("properties").size() > 0) {
+
+            type = ruleFactory.getObjectRule().apply(nodeName, node, parent, jClassContainer.getPackage(), schema);
+        } else if (node.has("existingJavaType")) {
+            String typeName = node.path("existingJavaType").asText();
+
+            if (isPrimitive(typeName, jClassContainer.owner())) {
+                type = primitiveType(typeName, jClassContainer.owner());
+            } else {
+                type = resolveType(jClassContainer, typeName);
+            }
+        } else if (propertyTypeName.equals("string")) {
+
+            type = jClassContainer.owner().ref(String.class);
+        } else if (propertyTypeName.equals("number")) {
+
+            type = getNumberType(jClassContainer.owner(), ruleFactory.getGenerationConfig());
+        } else if (propertyTypeName.equals("integer")) {
+
+            type = getIntegerType(jClassContainer.owner(), node, ruleFactory.getGenerationConfig());
+        } else if (propertyTypeName.equals("boolean")) {
+
+            type = unboxIfNecessary(jClassContainer.owner().ref(Boolean.class), ruleFactory.getGenerationConfig());
+        } else if (propertyTypeName.equals("array")) {
+
+            type = ruleFactory.getArrayRule().apply(nodeName, node, parent, jClassContainer.getPackage(), schema);
+        } else {
+
+            type = jClassContainer.owner().ref(Object.class);
+        }
 
-  private String getTypeName(JsonNode node) {
-    if (node.has("type") && node.get("type").isArray() && node.get("type").size() > 0) {
-      for (JsonNode jsonNode : node.get("type")) {
-        String typeName = jsonNode.asText();
-        if (!typeName.equals("null")) {
-          return typeName;
+        if (!node.has("javaType") && !node.has("existingJavaType") && node.has("format")) {
+            type = ruleFactory.getFormatRule().apply(nodeName, node.get("format"), node, type, schema);
+        } else if (!node.has("javaType") && !node.has("existingJavaType") && propertyTypeName.equals("string") && node.has("media")) {
+            type = ruleFactory.getMediaRule().apply(nodeName, node.get("media"), node, type, schema);
         }
-      }
-    }
 
-    if (node.has("type") && node.get("type").isTextual()) {
-      return node.get("type").asText();
+        return type;
     }
 
-    return DEFAULT_TYPE_NAME;
-  }
+    private String getTypeName(JsonNode node) {
+        if (node.has("type") && node.get("type").isArray() && node.get("type").size() > 0) {
+            for (JsonNode jsonNode : node.get("type")) {
+                String typeName = jsonNode.asText();
+                if (!typeName.equals("null")) {
+                    return typeName;
+                }
+            }
+        }
 
-  private JType unboxIfNecessary(JType type, GenerationConfig config) {
-    if (config.isUsePrimitives()) {
-      return type.unboxify();
-    } else {
-      return type;
-    }
-  }
-
-  /**
-   * Returns the JType for an integer field. Handles type lookup and unboxing.
-   */
-  private JType getIntegerType(JCodeModel owner, JsonNode node, GenerationConfig config) {
-
-    if (config.isUseBigIntegers()) {
-      return unboxIfNecessary(owner.ref(BigInteger.class), config);
-    } else if (config.isUseLongIntegers() || node.has("minimum") && node.get("minimum").isLong() || node.has("maximum") && node.get("maximum")
-        .isLong()) {
-      return unboxIfNecessary(owner.ref(Long.class), config);
-    } else {
-      return unboxIfNecessary(owner.ref(Integer.class), config);
+        if (node.has("type") && node.get("type").isTextual()) {
+            return node.get("type").asText();
+        }
+
+        return DEFAULT_TYPE_NAME;
     }
 
-  }
+    private JType unboxIfNecessary(JType type, GenerationConfig config) {
+        if (config.isUsePrimitives()) {
+            return type.unboxify();
+        } else {
+            return type;
+        }
+    }
 
-  /**
-   * Returns the JType for a number field. Handles type lookup and unboxing.
-   */
-  private JType getNumberType(JCodeModel owner, GenerationConfig config) {
+    /**
+     * Returns the JType for an integer field. Handles type lookup and unboxing.
+     */
+    private JType getIntegerType(JCodeModel owner, JsonNode node, GenerationConfig config) {
+
+        if (config.isUseBigIntegers()) {
+            return unboxIfNecessary(owner.ref(BigInteger.class), config);
+        } else if (config.isUseLongIntegers() ||
+                node.has("minimum") && node.get("minimum").isLong() ||
+                node.has("maximum") && node.get("maximum").isLong()) {
+            return unboxIfNecessary(owner.ref(Long.class), config);
+        } else {
+            return unboxIfNecessary(owner.ref(Integer.class), config);
+        }
 
-    if (config.isUseBigDecimals()) {
-      return unboxIfNecessary(owner.ref(BigDecimal.class), config);
-    } else if (config.isUseDoubleNumbers()) {
-      return unboxIfNecessary(owner.ref(Double.class), config);
-    } else {
-      return unboxIfNecessary(owner.ref(Float.class), config);
     }
 
-  }
+    /**
+     * Returns the JType for a number field. Handles type lookup and unboxing.
+     */
+    private JType getNumberType(JCodeModel owner, GenerationConfig config) {
+
+        if (config.isUseBigDecimals()) {
+            return unboxIfNecessary(owner.ref(BigDecimal.class), config);
+        } else if (config.isUseDoubleNumbers()) {
+            return unboxIfNecessary(owner.ref(Double.class), config);
+        } else {
+            return unboxIfNecessary(owner.ref(Float.class), config);
+        }
+
+    }
 
 }
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/util/NameHelper.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/util/NameHelper.java
index 0a519ab3..d3a4cb4d 100644
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/util/NameHelper.java
+++ b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/util/NameHelper.java
@@ -16,22 +16,16 @@
 
 package org.jsonschema2pojo.util;
 
-import static java.lang.Character.isDigit;
-import static java.lang.Character.toLowerCase;
-import static javax.lang.model.SourceVersion.isKeyword;
-import static org.apache.commons.lang3.StringUtils.capitalize;
-import static org.apache.commons.lang3.StringUtils.containsAny;
-import static org.apache.commons.lang3.StringUtils.remove;
+import static java.lang.Character.*;
+import static javax.lang.model.SourceVersion.*;
+import static org.apache.commons.lang3.StringUtils.*;
 
-import com.fasterxml.jackson.databind.JsonNode;
-import com.sun.codemodel.JClass;
-import com.sun.codemodel.JClassAlreadyExistsException;
-import com.sun.codemodel.JDefinedClass;
-import com.sun.codemodel.JPackage;
-import com.sun.codemodel.JType;
 import org.apache.commons.lang3.text.WordUtils;
 import org.jsonschema2pojo.GenerationConfig;
 
+import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.codemodel.JType;
+
 public class NameHelper {
 
     public static final String ILLEGAL_CHARACTER_REGEX = "[^0-9a-zA-Z_$]";
@@ -219,46 +213,4 @@ public class NameHelper {
         jsonPropertyName = capitalizeTrailingWords(jsonPropertyName);
         return jsonPropertyName;
     }
-
-    public String getBuilderClassName(JClass outterClass) {
-        return outterClass.name() + "Builder";
-    }
-
-    public String getUniqueClassName(String nodeName, JsonNode node, JPackage _package) {
-        return makeUnique(getClassName(nodeName, node, _package), _package);
-    }
-
-    public String getClassName(String nodeName, JsonNode node, JPackage _package) {
-        String prefix = generationConfig.getClassNamePrefix();
-        String suffix = generationConfig.getClassNameSuffix();
-        String fieldName = getClassName(nodeName, node);
-        String capitalizedFieldName = capitalize(fieldName);
-        String fullFieldName = createFullFieldName(capitalizedFieldName, prefix, suffix);
-
-        String className = replaceIllegalCharacters(fullFieldName);
-        return normalizeName(className);
-    }
-
-    private String createFullFieldName(String nodeName, String prefix, String suffix) {
-        String returnString = nodeName;
-        if (prefix != null) {
-            returnString = prefix + returnString;
-        }
-
-        if (suffix != null) {
-            returnString = returnString + suffix;
-        }
-
-        return returnString;
-    }
-
-    private String makeUnique(String className, JPackage _package) {
-        try {
-            JDefinedClass _class = _package._class(className);
-            _package.remove(_class);
-            return className;
-        } catch (JClassAlreadyExistsException e) {
-            return makeUnique(MakeUniqueClassName.makeUnique(className), _package);
-        }
-    }
 }
diff --git a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/util/ReflectionHelper.java b/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/util/ReflectionHelper.java
deleted file mode 100644
index 4fff8313..00000000
--- a/jsonschema2pojo-core/src/main/java/org/jsonschema2pojo/util/ReflectionHelper.java
+++ /dev/null
@@ -1,162 +0,0 @@
-/**
- * Copyright Â© 2010-2017 Nokia
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.jsonschema2pojo.util;
-
-import static org.jsonschema2pojo.util.TypeUtil.resolveType;
-
-import com.fasterxml.jackson.databind.JsonNode;
-import com.sun.codemodel.JClass;
-import com.sun.codemodel.JDefinedClass;
-import com.sun.codemodel.JFieldVar;
-import com.sun.codemodel.JPackage;
-import com.sun.codemodel.JType;
-import java.lang.reflect.Modifier;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.Map;
-import java.util.Spliterator;
-import java.util.Spliterators;
-import java.util.stream.StreamSupport;
-import org.jsonschema2pojo.Schema;
-import org.jsonschema2pojo.rules.RuleFactory;
-
-public class ReflectionHelper {
-
-  private RuleFactory ruleFactory;
-
-  public ReflectionHelper(RuleFactory ruleFactory) {
-    this.ruleFactory = ruleFactory;
-  }
-
-  public JType getSuperType(String nodeName, JsonNode node, JPackage jPackage, Schema schema) {
-    if (node.has("extends") && node.has("extendsJavaClass")) {
-      throw new IllegalStateException("'extends' and 'extendsJavaClass' defined simultaneously");
-    }
-
-    JType superType = jPackage.owner().ref(Object.class);
-    Schema superTypeSchema = getSuperSchema(node, schema, false);
-    if (superTypeSchema != null) {
-      superType = ruleFactory.getSchemaRule().apply(nodeName + "Parent", node.get("extends"), node, jPackage, superTypeSchema);
-    } else if (node.has("extendsJavaClass")) {
-      superType = resolveType(jPackage, node.get("extendsJavaClass").asText());
-    }
-
-    return superType;
-  }
-
-  public Schema getSuperSchema(JsonNode node, Schema schema, boolean followRefs) {
-    if (node.has("extends")) {
-      String path;
-      if (schema.getId().getFragment() == null) {
-        path = "#extends";
-      } else {
-        path = "#" + schema.getId().getFragment() + "/extends";
-      }
-
-      Schema superSchema = ruleFactory.getSchemaStore().create(schema, path, ruleFactory.getGenerationConfig().getRefFragmentPathDelimiters());
-
-      if (followRefs) {
-        superSchema = resolveSchemaRefsRecursive(superSchema);
-      }
-
-      return superSchema;
-    }
-    return null;
-  }
-
-  /**
-   * This is recursive with searchClassAndSuperClassesForField
-   */
-  public JFieldVar searchSuperClassesForField(String property, JDefinedClass jclass) {
-    JClass superClass = jclass._extends();
-    JDefinedClass definedSuperClass = definedClassOrNullFromType(superClass);
-    if (definedSuperClass == null) {
-      return null;
-    }
-    return searchClassAndSuperClassesForField(property, definedSuperClass);
-  }
-
-  public JDefinedClass getBuilderClass(JDefinedClass target) {
-    String builderClassname = ruleFactory.getNameHelper().getBuilderClassName(target);
-
-    return StreamSupport.stream(Spliterators.spliteratorUnknownSize(target.classes(), Spliterator.ORDERED), false)
-        .filter(definedClass -> definedClass.name().equals(builderClassname)).findFirst().orElse(null);
-  }
-
-  public JDefinedClass getBuilderClass(JClass target) {
-    String builderClassname = ruleFactory.getNameHelper().getBuilderClassName(target);
-    return getAllPackageClasses(target._package()).stream().filter(definedClass -> definedClass.name().equals(builderClassname)).findFirst()
-        .orElse(null);
-  }
-
-  public boolean isFinal(JType superType) {
-    try {
-      Class<?> javaClass = Class.forName(superType.fullName());
-      return Modifier.isFinal(javaClass.getModifiers());
-    } catch (ClassNotFoundException e) {
-      return false;
-    }
-  }
-
-  public JFieldVar searchClassAndSuperClassesForField(String property, JDefinedClass jclass) {
-    Map<String, JFieldVar> fields = jclass.fields();
-    JFieldVar field = fields.get(property);
-    if (field == null) {
-      return searchSuperClassesForField(property, jclass);
-    }
-    return field;
-  }
-
-  private JDefinedClass definedClassOrNullFromType(JType type) {
-    if (type == null || type.isPrimitive()) {
-      return null;
-    }
-    JClass fieldClass = type.boxify();
-    JPackage jPackage = fieldClass._package();
-    return this._getClass(fieldClass.name(), jPackage);
-  }
-
-  private JDefinedClass _getClass(String name, JPackage _package) {
-    return getAllPackageClasses(_package).stream().filter(definedClass -> definedClass.name().equals(name)).findFirst()
-        .orElseThrow(() -> new NoClassDefFoundError(name));
-  }
-
-  private Collection<JDefinedClass> getAllPackageClasses(JPackage _package) {
-    LinkedList<JDefinedClass> result = new LinkedList<>();
-    StreamSupport.stream(Spliterators.spliteratorUnknownSize(_package.classes(), Spliterator.ORDERED), false)
-        .forEach(_class -> result.addAll(getAllClassClasses(_class)));
-    return result;
-  }
-
-  private Collection<JDefinedClass> getAllClassClasses(JDefinedClass _class) {
-    LinkedList<JDefinedClass> result = new LinkedList<>();
-    result.add(_class);
-
-    _class.classes().forEachRemaining(result::add);
-    return result;
-  }
-
-  private Schema resolveSchemaRefsRecursive(Schema schema) {
-    JsonNode schemaNode = schema.getContent();
-    if (schemaNode.has("$ref")) {
-      schema = ruleFactory.getSchemaStore()
-          .create(schema, schemaNode.get("$ref").asText(), ruleFactory.getGenerationConfig().getRefFragmentPathDelimiters());
-      return resolveSchemaRefsRecursive(schema);
-    }
-    return schema;
-  }
-
-}
diff --git a/jsonschema2pojo-gradle-plugin/pom.xml b/jsonschema2pojo-gradle-plugin/pom.xml
index 5f0df0b2..7a0f1e9b 100644
--- a/jsonschema2pojo-gradle-plugin/pom.xml
+++ b/jsonschema2pojo-gradle-plugin/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>jsonschema2pojo</artifactId>
         <groupId>org.jsonschema2pojo</groupId>
-        <version>1.0.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
 
     <artifactId>jsonschema2pojo-gradle-plugin</artifactId>
diff --git a/jsonschema2pojo-gradle-plugin/src/main/groovy/org/jsonschema2pojo/gradle/JsonSchemaExtension.groovy b/jsonschema2pojo-gradle-plugin/src/main/groovy/org/jsonschema2pojo/gradle/JsonSchemaExtension.groovy
index 4b570103..55c68b79 100644
--- a/jsonschema2pojo-gradle-plugin/src/main/groovy/org/jsonschema2pojo/gradle/JsonSchemaExtension.groovy
+++ b/jsonschema2pojo-gradle-plugin/src/main/groovy/org/jsonschema2pojo/gradle/JsonSchemaExtension.groovy
@@ -45,7 +45,6 @@ public class JsonSchemaExtension implements GenerationConfig {
   Class<? extends Annotator> customAnnotator
   Class<? extends RuleFactory> customRuleFactory
   boolean generateBuilders
-  boolean useInnerClassBuilders
   boolean includeGetters
   boolean includeSetters
   boolean includeAdditionalProperties
@@ -96,7 +95,6 @@ public class JsonSchemaExtension implements GenerationConfig {
   public JsonSchemaExtension() {
     // See DefaultGenerationConfig
     generateBuilders = false
-    useInnerClassBuilders = false
     usePrimitives = false
     sourceFiles = []
     targetPackage = ''
@@ -256,7 +254,6 @@ public class JsonSchemaExtension implements GenerationConfig {
        |sourceSortOrder = ${sourceSortOrder}
        |targetLanguage = ${targetLanguage}
        |formatTypeMapping = ${formatTypeMapping}
-       |useInnerClassBuilders = ${useInnerClassBuilders}
      """.stripMargin()
   }
   
diff --git a/jsonschema2pojo-maven-plugin/pom.xml b/jsonschema2pojo-maven-plugin/pom.xml
index 825af4da..0b354019 100644
--- a/jsonschema2pojo-maven-plugin/pom.xml
+++ b/jsonschema2pojo-maven-plugin/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>jsonschema2pojo</artifactId>
         <groupId>org.jsonschema2pojo</groupId>
-        <version>1.0.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
 
     <artifactId>jsonschema2pojo-maven-plugin</artifactId>
diff --git a/jsonschema2pojo-maven-plugin/src/main/java/org/jsonschema2pojo/maven/Jsonschema2PojoMojo.java b/jsonschema2pojo-maven-plugin/src/main/java/org/jsonschema2pojo/maven/Jsonschema2PojoMojo.java
index 4a065a3b..b049cd4a 100644
--- a/jsonschema2pojo-maven-plugin/src/main/java/org/jsonschema2pojo/maven/Jsonschema2PojoMojo.java
+++ b/jsonschema2pojo-maven-plugin/src/main/java/org/jsonschema2pojo/maven/Jsonschema2PojoMojo.java
@@ -745,14 +745,6 @@ public class Jsonschema2PojoMojo extends AbstractMojo implements GenerationConfi
      */
     private Map<String, String> formatTypeMapping = new HashMap<>();
 
-    /**
-     * @parameter property="jsonschema2pojo.useInnerClassBuilders"
-     *            default-value="false"
-     * @since 1.0.0
-     */
-    private boolean useInnerClassBuilders = false;
-
-
     /**
      * Executes the plugin, to read the given source and behavioural properties
      * and generate POJOs. The current implementation acts as a wrapper around
@@ -1167,9 +1159,4 @@ public class Jsonschema2PojoMojo extends AbstractMojo implements GenerationConfi
     public Map<String, String> getFormatTypeMapping() {
         return formatTypeMapping;
     }
-
-    @Override
-    public boolean isUseInnerClassBuilders() {
-        return useInnerClassBuilders;
-    }
 }
diff --git a/jsonschema2pojo-scalagen/pom.xml b/jsonschema2pojo-scalagen/pom.xml
index 4a289dee..e5525547 100644
--- a/jsonschema2pojo-scalagen/pom.xml
+++ b/jsonschema2pojo-scalagen/pom.xml
@@ -6,12 +6,12 @@
     <parent>
         <artifactId>jsonschema2pojo</artifactId>
         <groupId>org.jsonschema2pojo</groupId>
-        <version>1.0.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
 
     <groupId>org.jsonschema2pojo</groupId>
     <artifactId>jsonschema2pojo-scalagen</artifactId>
-    <version>1.0.1-SNAPSHOT</version>
+    <version>1.0.0</version>
 
     <properties>
         <commons.collections.version>4.01</commons.collections.version>
diff --git a/pom.xml b/pom.xml
index 0bace5a4..a5e8235c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,7 +10,7 @@
 
     <groupId>org.jsonschema2pojo</groupId>
     <artifactId>jsonschema2pojo</artifactId>
-    <version>1.0.1-SNAPSHOT</version>
+    <version>1.0.0</version>
 
     <packaging>pom</packaging>
     <name>jsonschema2pojo</name>


Test patch:
diff --git a/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/PropertyRuleTest.java b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/PropertyRuleTest.java
new file mode 100755
index 00000000..6187cbc1
--- /dev/null
+++ b/jsonschema2pojo-core/src/test/java/org/jsonschema2pojo/rules/PropertyRuleTest.java
@@ -0,0 +1,131 @@
+/**
+ * Copyright © 2010-2017 Nokia
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.jsonschema2pojo.rules;
+
+import static org.hamcrest.MatcherAssert.*;
+import static org.hamcrest.Matchers.*;
+import static org.mockito.Mockito.*;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.node.BooleanNode;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+import com.sun.codemodel.JClassAlreadyExistsException;
+import com.sun.codemodel.JCodeModel;
+import com.sun.codemodel.JDefinedClass;
+import com.sun.codemodel.JType;
+import org.jsonschema2pojo.GenerationConfig;
+import org.jsonschema2pojo.NoopAnnotator;
+import org.jsonschema2pojo.Schema;
+import org.jsonschema2pojo.SchemaStore;
+import org.junit.Before;
+import org.junit.Test;
+
+public class PropertyRuleTest {
+    private static final String TARGET_CLASS_NAME = PropertyRuleTest.class.getName() + ".DummyClass";
+
+    private static final String internalFieldName = "internalRequired";
+    private static final String targetFieldName = "requiredFoo";
+
+    private final GenerationConfig config = mock(GenerationConfig.class);
+    private final PropertyRule rule = new PropertyRule(new RuleFactory(config, new NoopAnnotator(), new SchemaStore()));
+
+    private ObjectMapper mapper;
+
+    @Before
+    public void setup() {
+        mapper = new ObjectMapper();
+
+        when(config.isIncludeGetters()).thenReturn(true);
+        when(config.isUseOptionalForGetters()).thenReturn(true);
+    }
+
+    private String getGeneratedMethodTypeName(JDefinedClass jclass) {
+        return jclass.getMethod("getRequiredFoo", new JType[] {}).type().name();
+    }
+
+    private Schema getMockedSchema(ObjectNode parentNode) {
+        Schema schema = mock(Schema.class);
+        when(schema.getContent()).thenReturn(parentNode);
+        when(schema.deriveChildSchema(any())).thenReturn(schema);
+        return schema;
+    }
+
+    private JDefinedClass applyRule(ObjectNode propertyNode, ObjectNode parentNode) throws JClassAlreadyExistsException {
+        JDefinedClass jclass = new JCodeModel()._class(TARGET_CLASS_NAME);
+        return rule.apply(targetFieldName, propertyNode, parentNode, jclass, getMockedSchema(parentNode));
+    }
+
+    @Test
+    public void applyRequiredByTopArray() throws JClassAlreadyExistsException {
+        ObjectNode propertyNode = mapper.createObjectNode();
+        propertyNode.set("required", mapper.createArrayNode().add(internalFieldName));
+        propertyNode.set("properties", mapper.createObjectNode().set(internalFieldName, mapper.createObjectNode()));
+
+        ObjectNode parentNode = mapper.createObjectNode();
+        parentNode.set("required", mapper.createArrayNode().add(targetFieldName));
+        parentNode.set("properties", mapper.createObjectNode().set(targetFieldName, propertyNode));
+
+        JDefinedClass jclass = applyRule(propertyNode, parentNode);
+
+        assertThat(jclass, notNullValue());
+        assertThat(getGeneratedMethodTypeName(jclass), is("RequiredFoo"));
+    }
+
+    @Test
+    public void applyNotRequiredByTopArray() throws JClassAlreadyExistsException {
+        ObjectNode propertyNode = mapper.createObjectNode();
+        propertyNode.set("required", mapper.createArrayNode().add(internalFieldName));
+        propertyNode.set("properties", mapper.createObjectNode().set(internalFieldName, mapper.createObjectNode()));
+
+        ObjectNode parentNode = mapper.createObjectNode();
+        parentNode.set("properties", mapper.createObjectNode().set(targetFieldName, propertyNode));
+
+        JDefinedClass jclass = applyRule(propertyNode, parentNode);
+
+        assertThat(jclass, notNullValue());
+        assertThat(getGeneratedMethodTypeName(jclass), is("Optional<RequiredFoo>"));
+    }
+
+    @Test
+    public void applyRequiredByFlag() throws JClassAlreadyExistsException {
+        ObjectNode propertyNode = mapper.createObjectNode();
+        propertyNode.set("required", BooleanNode.TRUE);
+        propertyNode.set("properties", mapper.createObjectNode().set(internalFieldName, mapper.createObjectNode()));
+
+        ObjectNode parentNode = mapper.createObjectNode();
+        parentNode.set("properties", mapper.createObjectNode().set(targetFieldName, propertyNode));
+
+        JDefinedClass jclass = applyRule(propertyNode, parentNode);
+
+        assertThat(jclass, notNullValue());
+        assertThat(getGeneratedMethodTypeName(jclass), is("RequiredFoo"));
+    }
+
+    @Test
+    public void applyNotRequiredByFlag() throws JClassAlreadyExistsException {
+        ObjectNode propertyNode = mapper.createObjectNode();
+        propertyNode.set("properties", mapper.createObjectNode().set(internalFieldName, mapper.createObjectNode()));
+
+        ObjectNode parentNode = mapper.createObjectNode();
+        parentNode.set("properties", mapper.createObjectNode().set(targetFieldName, propertyNode));
+
+        JDefinedClass jclass = applyRule(propertyNode, parentNode);
+
+        assertThat(jclass, notNullValue());
+        assertThat(getGeneratedMethodTypeName(jclass), is("Optional<RequiredFoo>"));
+    }
+}
diff --git a/jsonschema2pojo-core/src/test/resources/schema/child.json b/jsonschema2pojo-core/src/test/resources/schema/child.json
deleted file mode 100644
index 7c8c259b..00000000
--- a/jsonschema2pojo-core/src/test/resources/schema/child.json
+++ /dev/null
@@ -1,15 +0,0 @@
-{
-  "$id": "https://example.com/child.schema.json",
-  "$schema": "http://json-schema.org/draft-07/schema#",
-  "description" : "A schema definition for an object which can be inherited",
-  "javaType" : "com.example.package.GeneratedChildType",
-  "type" : "object",
-  "extends" : {
-    "$ref" : "parent.json"
-  },
-  "properties" : {
-    "childProperty" : { "type" : "string" }
-  },
-  "dependencies" : {
-  }
-}
\ No newline at end of file
diff --git a/jsonschema2pojo-core/src/test/resources/schema/parent.json b/jsonschema2pojo-core/src/test/resources/schema/parent.json
deleted file mode 100644
index f2a9b7d7..00000000
--- a/jsonschema2pojo-core/src/test/resources/schema/parent.json
+++ /dev/null
@@ -1,12 +0,0 @@
-{
-  "$id": "https://example.com/address.schema.json",
-  "$schema": "http://json-schema.org/draft-07/schema#",
-  "description" : "A schema definition for an object which can be inherited",
-  "javaType" : "com.example.package.GeneratedParentType",
-  "type" : "object",
-  "properties" : {
-    "parentProperty" : { "type" : "string" }
-  },
-  "dependencies" : {
-  }
-}
\ No newline at end of file
diff --git a/jsonschema2pojo-integration-tests/pom.xml b/jsonschema2pojo-integration-tests/pom.xml
index 0c92facb..0bb5a9de 100644
--- a/jsonschema2pojo-integration-tests/pom.xml
+++ b/jsonschema2pojo-integration-tests/pom.xml
@@ -5,7 +5,7 @@
     <parent>
         <artifactId>jsonschema2pojo</artifactId>
         <groupId>org.jsonschema2pojo</groupId>
-        <version>1.0.1-SNAPSHOT</version>
+        <version>1.0.0</version>
     </parent>
 
     <artifactId>jsonschema2pojo-integration-tests</artifactId>
diff --git a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/UseInnerClassBuildersIT.java b/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/UseInnerClassBuildersIT.java
deleted file mode 100644
index 680fd2fb..00000000
--- a/jsonschema2pojo-integration-tests/src/test/java/org/jsonschema2pojo/integration/config/UseInnerClassBuildersIT.java
+++ /dev/null
@@ -1,227 +0,0 @@
-/**
- * Copyright © 2010-2017 Nokia
- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a
- * copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
- * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations
- * under the License.
- */
-
-package org.jsonschema2pojo.integration.config;
-
-import static org.hamcrest.Matchers.not;
-import static org.jsonschema2pojo.integration.util.CodeGenerationHelper.config;
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertNotNull;
-import static org.junit.Assert.assertThat;
-import static org.junit.Assert.assertTrue;
-
-import java.io.File;
-import java.lang.reflect.Constructor;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.util.stream.Stream;
-import org.apache.commons.lang.StringUtils;
-import org.hamcrest.Matcher;
-import org.jsonschema2pojo.integration.util.FileSearchMatcher;
-import org.jsonschema2pojo.integration.util.Jsonschema2PojoRule;
-import org.junit.Rule;
-import org.junit.Test;
-
-@SuppressWarnings("rawtypes")
-public class UseInnerClassBuildersIT {
-
-  @Rule
-  public Jsonschema2PojoRule schemaRule = new Jsonschema2PojoRule();
-
-  private static Matcher<File> containsText(String searchText) {
-    return new FileSearchMatcher(searchText);
-  }
-
-  /**
-   * This test asserts that no methods containing 'with' appear in the generated code using the default configuration
-   */
-  @Test
-  public void noBuilderMethodsByDefault() {
-    File outputDirectory = schemaRule.generate("/schema.useInnerClassBuilders/child.json", "com.example", config());
-
-    assertThat(outputDirectory, not(containsText("with")));
-  }
-
-  /**
-   * This method confirms that if you choose to generate builders, but don't indicate that useInnerBuilders is true, they will be generated using the
-   * chaining setters instead of the inner classes
-   */
-  @Test(expected = ClassNotFoundException.class)
-  public void defaultBuilderIsChainedSetters() throws ClassNotFoundException {
-    ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema.useInnerClassBuilders/child.json", "com.example",
-        config("generateBuilders", true));
-
-    Class<?> childClass = resultsClassLoader.loadClass("com.example.Child");
-    boolean containsWithMethod = Stream.of(childClass.getMethods())
-        .map(Method::getName)
-        .anyMatch(methodName -> StringUtils.contains(methodName, "with"));
-
-    assertTrue("Generated class missing any builders at all", containsWithMethod);
-
-    resultsClassLoader.loadClass("com.example.Child.ChildBuilder");
-  }
-
-  /**
-   * This method confirms that if you choose to use inner class builders then the chaining setters will be removed from the generated class
-   */
-  @Test
-  public void innerBuildersRemoveChainedSetters() throws ClassNotFoundException {
-    ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema.useInnerClassBuilders/child.json", "com.example",
-        config("generateBuilders", true, "useInnerClassBuilders", true));
-
-    Class<?> childClass = resultsClassLoader.loadClass("com.example.Child");
-    boolean containsWithMethod = Stream.of(childClass.getMethods())
-        .map(Method::getName)
-        .anyMatch(methodName -> StringUtils.contains(methodName, "with"));
-
-    assertFalse("Generated contains unexpected builders", containsWithMethod);
-
-    assertNotNull(resultsClassLoader.loadClass("com.example.Child$ChildBuilder"));
-  }
-
-  /**
-   * This methods confirms that the builders can be constructed using the empty constructor and possess a 'build' method that will return a non-null
-   * object
-   */
-  @Test
-  public void innerBuildersInvokeBuild()
-      throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
-    ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema.useInnerClassBuilders/child.json", "com.example",
-        config("generateBuilders", true, "useInnerClassBuilders", true));
-
-    Class<?> builderClass = resultsClassLoader.loadClass("com.example.Child$ChildBuilder");
-    Method buildMethod = builderClass.getMethod("build");
-
-    Object builder = builderClass.newInstance();
-    assertNotNull(builder);
-
-    assertNotNull(buildMethod.invoke(builder));
-  }
-
-  /**
-   * This method walks through invoking the various incremental 'with' methods to build out an entire object, then invokes build on the constructed
-   * object and confirms all values on the object match those provided to the with methods
-   */
-  @Test
-  public void innerBuildersBuildObjectIncrementally()
-      throws ClassNotFoundException, IllegalAccessException, InstantiationException, InvocationTargetException, NoSuchMethodException {
-    ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema.useInnerClassBuilders/child.json", "com.example",
-        config("generateBuilders", true, "useInnerClassBuilders", true));
-
-    Class<?> builderClass = resultsClassLoader.loadClass("com.example.Child$ChildBuilder");
-    Method buildMethod = builderClass.getMethod("build");
-    Method withChildProperty = builderClass.getMethod("withChildProperty", Integer.class);
-    Method withParentProperty = builderClass.getMethod("withParentProperty", String.class);
-    Method withSharedProperty = builderClass.getMethod("withSharedProperty", String.class);
-
-    int childProperty = 1;
-    String parentProperty = "parentProperty";
-    String sharedProperty = "sharedProperty";
-
-    Object builder = builderClass.newInstance();
-    withChildProperty.invoke(builder, childProperty);
-    withParentProperty.invoke(builder, parentProperty);
-    withSharedProperty.invoke(builder, sharedProperty);
-    Object childObject = buildMethod.invoke(builder);
-
-    Class<?> childClass = resultsClassLoader.loadClass("com.example.Child");
-    Method getChildProperty = childClass.getMethod("getChildProperty");
-    Method getParentProperty = childClass.getMethod("getParentProperty");
-    Method getSharedProperty = childClass.getMethod("getSharedProperty");
-
-    assertEquals(childProperty, getChildProperty.invoke(childObject));
-    assertEquals(parentProperty, getParentProperty.invoke(childObject));
-    assertEquals(sharedProperty, getSharedProperty.invoke(childObject));
-  }
-
-  /**
-   * This method confirms that by default the only constructor available to a builder is the empty argument constructor
-   */
-  @Test
-  public void innerBuilderExtraConstructorsRequireConfig() throws ClassNotFoundException {
-    ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema.useInnerClassBuilders/child.json", "com.example",
-        config("generateBuilders", true, "useInnerClassBuilders", true));
-
-    Class<?> builderClass = resultsClassLoader.loadClass("com.example.Child$ChildBuilder");
-    assertEquals(1, builderClass.getConstructors().length);
-
-    Constructor<?> constructor = builderClass.getConstructors()[0];
-    assertEquals(0, constructor.getParameterCount());
-  }
-
-  /**
-   * This method confirms that if constructors are enabled then a builder constructor which takes all properties will be created
-   */
-  @Test
-  public void innerBuilderWithAllPropertyConstructor()
-      throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
-    ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema.useInnerClassBuilders/child.json", "com.example",
-        config("generateBuilders", true, "useInnerClassBuilders", true, "includeConstructors", true));
-
-    Class<?> builderClass = resultsClassLoader.loadClass("com.example.Child$ChildBuilder");
-    Constructor<?> constructor = builderClass.getConstructor(Integer.class, String.class, String.class);
-    Method buildMethod = builderClass.getMethod("build");
-
-    int childProperty = 1;
-    String parentProperty = "parentProperty";
-    String sharedProperty = "sharedProperty";
-
-    Object builder = constructor.newInstance(childProperty, sharedProperty, parentProperty);
-    Object childObject = buildMethod.invoke(builder);
-
-    Class<?> childClass = resultsClassLoader.loadClass("com.example.Child");
-    Method getChildProperty = childClass.getMethod("getChildProperty");
-    Method getParentProperty = childClass.getMethod("getParentProperty");
-    Method getSharedProperty = childClass.getMethod("getSharedProperty");
-
-    assertEquals(childProperty, getChildProperty.invoke(childObject));
-    assertEquals(parentProperty, getParentProperty.invoke(childObject));
-    assertEquals(sharedProperty, getSharedProperty.invoke(childObject));
-  }
-
-  /**
-   * This method confirms that if constructors are enabled and constructorsRequiredPropertiesOnly is set to true then a only a builder constructor
-   * with the required properties will be created
-   */
-  @Test
-  public void innerBuilderWithRequiredPropertyConstructor()
-      throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
-    ClassLoader resultsClassLoader = schemaRule.generateAndCompile("/schema.useInnerClassBuilders/child.json", "com.example",
-        config("generateBuilders", true, "useInnerClassBuilders", true, "includeConstructors", true, "constructorsRequiredPropertiesOnly", true));
-
-    Class<?> builderClass = resultsClassLoader.loadClass("com.example.Child$ChildBuilder");
-    Constructor<?> constructor = builderClass.getConstructor(String.class);
-    Method buildMethod = builderClass.getMethod("build");
-    Method withChildProperty = builderClass.getMethod("withChildProperty", Integer.class);
-    Method withSharedProperty = builderClass.getMethod("withSharedProperty", String.class);
-
-    int childProperty = 1;
-    String parentProperty = "parentProperty";
-    String sharedProperty = "sharedProperty";
-
-    Object builder = constructor.newInstance(parentProperty);
-    withChildProperty.invoke(builder, childProperty);
-    withSharedProperty.invoke(builder, sharedProperty);
-    Object childObject = buildMethod.invoke(builder);
-
-    Class<?> childClass = resultsClassLoader.loadClass("com.example.Child");
-    Method getChildProperty = childClass.getMethod("getChildProperty");
-    Method getParentProperty = childClass.getMethod("getParentProperty");
-    Method getSharedProperty = childClass.getMethod("getSharedProperty");
-
-    assertEquals(childProperty, getChildProperty.invoke(childObject));
-    assertEquals(parentProperty, getParentProperty.invoke(childObject));
-    assertEquals(sharedProperty, getSharedProperty.invoke(childObject));
-  }
-}
diff --git a/jsonschema2pojo-integration-tests/src/test/resources/schema.useInnerClassBuilders/child.json b/jsonschema2pojo-integration-tests/src/test/resources/schema.useInnerClassBuilders/child.json
deleted file mode 100644
index 1a71d461..00000000
--- a/jsonschema2pojo-integration-tests/src/test/resources/schema.useInnerClassBuilders/child.json
+++ /dev/null
@@ -1,10 +0,0 @@
-{
-  "type" : "object",
-  "extends" : {
-    "$ref" : "parent.json"
-  },
-  "properties" : {
-    "childProperty" : { "type" : "integer"},
-    "sharedProperty" : { "type" : "string" }
-  }
-}
\ No newline at end of file
diff --git a/jsonschema2pojo-integration-tests/src/test/resources/schema.useInnerClassBuilders/parent.json b/jsonschema2pojo-integration-tests/src/test/resources/schema.useInnerClassBuilders/parent.json
deleted file mode 100644
index 99779bab..00000000
--- a/jsonschema2pojo-integration-tests/src/test/resources/schema.useInnerClassBuilders/parent.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-  "type" : "object",
-  "properties" : {
-    "parentProperty" : { "type" : "string" },
-    "sharedProperty" : { "type" : "string" }
-  },
-  "required" : ["parentProperty"]
-}
\ No newline at end of file