docs: @Override
      public void emitEquals(final Sink sink, final String indent, Constructor constructor, List<String> typeArguments) {
      	logger.finest("Generating equals() for " + constructor.name);
          sink.write(indent + "@Override\n");
          sink.write(indent + "public boolean equals(Object obj) {\n");
          sink.write(indent + "   if (this == obj) return true;\n");
          sink.write(indent + "   if (obj == null) return false;\n");
          sink.write(indent + "   if (getClass() != obj.getClass()) return false;\n");
          if (!constructor.args.isEmpty()) {
          	if (!typeArguments.isEmpty()) {
          		sink.write(indent + "   @SuppressWarnings(\"rawtypes\")");
          	}
              sink.write(indent + "   " + constructor.name + " other = (" + constructor.name + ")obj;\n");
              
              for (final Arg arg : constructor.args) {
                  arg.type._switch(new Type.SwitchBlock(){
                      @Override
                      public void _case(Ref x) {
                          x.type._switch(new RefType.SwitchBlock() {
                              @Override
                              public void _case(ClassType x) {
                                  sink.write(indent + "   if (" + arg.name + " == null) {\n");
                                  sink.write(indent + "      if (other." + arg.name + " != null) return false;\n");
                                  sink.write(indent + "   } else if (!" + arg.name + ".equals(other." + arg.name + ")) return false;\n");
                              }
  
                              @Override
                              public void _case(ArrayType x) {
                                  sink.write(indent + "   if (!java.util.Arrays.equals(" + arg.name + ", other." + arg.name + ")) return false;\n");
                              }});
                      }
  
                      @Override
                      public void _case(Primitive x) {
                          sink.write(indent + "   if (" + arg.name + " != other." + arg.name + ") return false;\n");
                      }});
              }
          }
          sink.write(indent + "   return true;\n");
          sink.write(indent + "}");
      }