public void generateAction(String serviceName, HashMap<String, String> actionFields,
      String responseField, String handlerClass, String simpleName, String packageName,
      boolean cacheable, String postfix) {

    String actionName = serviceName + simpleName + "Action" + postfix;
    String responseName = serviceName + simpleName + "Response" + postfix;

    PrintWriter writer = getPrintWriter(packageName + "." + actionName);
    writer.println("package " + packageName + ";");

    if (cacheable) {
      writer.println("import com.guit.client.command.action.Cacheable;");
    }

    writer.println("import com.guit.client.command.HashCodeBuilder;");
    writer.println("import com.guit.client.command.action.Action;");
    writer.println("import com.guit.client.command.action.ActionHandler;");

    writer.println("import " + packageName + "." + responseName + ";");
    Generated.printGeneratedImport(writer);

    Generated.printGenerated(writer, simpleName);
    writer.println("@ActionHandler(\"" + handlerClass + "\")");
    writer.print("public class " + actionName + " implements Action<" + responseName + ">");

    // Cache
    if (cacheable) {
      writer.print(", Cacheable ");
    }

    writer.println(" {");

    StringBuilder actionString = new StringBuilder();

    for (Entry<String, String> f : actionFields.entrySet()) {
      String type = f.getValue();
      String name = f.getKey();

      printGetterAndSetter(writer, type, name, actionName);

      if (actionString.length() > 0) {
        actionString.append(", ");
      }
      actionString.append(name + "=" + "\" + " + name + " + \"");
    }

    writer.println("  public " + actionName + "() {");
    writer.println("  }");

    writer.println("  public boolean equals(Object o) {");
    writer.println("    if (this == null) {");
    writer.println("        return false;");
    writer.println("    }");
    writer.println("    if (this == o) {");
    writer.println("        return true;");
    writer.println("    }");
    writer.println("    if (o instanceof " + actionName
        + ") { return o.hashCode() == hashCode(); } else { return super.equals(o);}");
    writer.println("  }");

    writer.println("  public int hashCode() {");
    writer.print("    return new HashCodeBuilder()");
    for (Entry<String, String> f : actionFields.entrySet()) {
      String name = f.getKey();
      writer.print(".append(" + name + ")");
    }
    writer.println(".toHashCode();");
    writer.println("  }");

    writer.println("  public String toString() {");
    writer.println("      if (!com.google.gwt.core.client.GWT.isScript()) {");
    writer.println("          return \"" + actionName + "[" + actionString.toString() + "]\";");
    writer.println("      }");
    writer.println("      return super.toString();");
    writer.println("  }");

    writer.println("}");
    writer.close();

    writer = getPrintWriter(packageName + "." + responseName);
    writer.println("package " + packageName + ";");

    writer.println("import com.guit.client.command.action.Response;");
    Generated.printGeneratedImport(writer);

    Generated.printGenerated(writer, simpleName);
    writer.println("public class " + responseName + " implements Response {");

    StringBuilder responseString = new StringBuilder();
    if (responseField != null) {
      printGetterAndSetter(writer, responseField, "result", responseName);

      if (responseString.length() > 0) {
        responseString.append(", ");
      }
      responseString.append("result = \" + result + \"");
    }

    writer.println("  public String toString() {");
    writer.println("      if (!com.google.gwt.core.client.GWT.isScript()) {");
    writer.println("          return \"" + responseName + "[" + responseString.toString() + "]\";");
    writer.println("      }");
    writer.println("      return super.toString();");
    writer.println("  }");

    writer.println("  public " + responseName + "() {");
    writer.println("  }");

    if (responseField != null) {
      writer.println("  public " + responseName + "(" + responseField + " result) {");
      writer.println("    this.result = result;");
      writer.println("  }");
    }

    writer.println("}");
    writer.close();
  }