protected void outputNSString(
      String name,
      String value,
      DeclarationsHolder out,
      Signatures signatures,
      Element... elementsToTakeCommentsFrom) {

    if (!signatures.addVariable(name)) return;

    TypeRef tr = typeRef(String.class);
    VariablesDeclaration vd = new VariablesDeclaration(tr, new DirectDeclarator(name, expr(value)));
    if (!result.config.noComments)
      for (Element e : elementsToTakeCommentsFrom) {
        vd.addToCommentBefore(e.getCommentBefore());
        vd.addToCommentBefore(e.getCommentAfter());
      }
    vd.addModifiers(ModifierType.Public);
    out.addDeclaration(vd);
  }
  public Struct convertCallback(
      FunctionSignature functionSignature, Signatures signatures, Identifier callerLibraryName) {
    Identifier name =
        result.typeConverter.inferCallBackName(functionSignature, true, false, callerLibraryName);
    if (name == null) return null;

    name = result.typeConverter.getValidJavaArgumentName(name);

    Function function = functionSignature.getFunction();

    int i = 1;
    Identifier chosenName = name;
    while (!(signatures.addClass(chosenName))) {
      chosenName = ident(name.toString() + (++i));
    }

    Element parent = functionSignature.getParentElement();
    Element comel = parent != null && parent instanceof TypeDef ? parent : functionSignature;

    Struct callbackStruct = new Struct();
    configureCallbackStruct(callbackStruct);
    // callbackStruct.setParents(Arrays.asList(getCallbackType(functionSignature, chosenName)));
    callbackStruct.setTag(ident(chosenName));
    if (!result.config.noComments)
      callbackStruct.addToCommentBefore(
          comel.getCommentBefore(), comel.getCommentAfter(), getFileCommentContent(comel));
    convertFunction(function, new Signatures(), true, callbackStruct, callerLibraryName, -1);
    for (Declaration d : callbackStruct.getDeclarations()) {
      if (d instanceof Function) {
        callbackStruct.addAnnotations(callbackStruct.getAnnotations());
        callbackStruct.setAnnotations(null);
        break;
      }
    }
    return callbackStruct;
  }
  @SuppressWarnings("static-access")
  protected Declaration outputConstant(
      String name,
      Pair<Expression, TypeRef> x,
      Signatures signatures,
      Element element,
      String elementTypeDescription,
      Identifier libraryClassName,
      boolean addFileComment,
      boolean signalErrors,
      boolean forceInteger,
      boolean alreadyConverted)
      throws UnsupportedConversionException {
    try {
      if (result.typeConverter.isJavaKeyword(name))
        throw new UnsupportedConversionException(
            element, "The name '" + name + "' is invalid for a Java field.");

      Pair<Expression, TypeRef> converted =
          alreadyConverted
              ? x
              : result.typeConverter.convertExpressionToJava(x.getFirst(), libraryClassName, true);
      // TypeRef tr = result.typeConverter.inferJavaType(converted);
      JavaPrim prim = result.typeConverter.getPrimitive(converted.getValue(), libraryClassName);

      if (forceInteger && prim == JavaPrim.Boolean) {
        prim = JavaPrim.Int;
        // tr = typeRef("int");
        converted =
            pair(
                expr("true".equals(String.valueOf(converted.toString())) ? 1 : 0),
                typeRef(Integer.TYPE));
      }

      if ((prim == null || converted.getValue() == null) && signalErrors) {
        if (result.config.limitComments) return null;

        return new EmptyDeclaration("Failed to infer type of " + converted);
      } else if (prim != JavaPrim.Void && converted.getValue() != null) {
        //				if (prim == JavaPrim.Int)
        //					tr = typeRef("long");

        if (signatures.addVariable(name)) {
          String t = converted.toString();
          if (t.contains("sizeof")) {
            converted =
                alreadyConverted
                    ? x
                    : result.typeConverter.convertExpressionToJava(
                        x.getFirst(), libraryClassName, false);
          }
          // TypeRef tr = new TypeRef.SimpleTypeRef(result.typeConverter.typeToJNA(type, vs,
          // TypeConversion.TypeConversionMode.FieldType, callerLibraryClass));
          TypeRef tr = converted.getValue();
          Expression value = converted.getFirst();
          if (result.config.castConstants) {
            if (!(value instanceof Constant) && !(value instanceof VariableRef))
              value.setParenthesis(true);
            value = new Cast(tr, value);
          }

          Declaration declaration = new VariablesDeclaration(tr, new DirectDeclarator(name, value));
          declaration.addModifiers(ModifierType.Public, ModifierType.Static, ModifierType.Final);
          if (!result.config.noComments)
            declaration.importComments(
                element, addFileComment ? getFileCommentContent(element) : null);
          return declaration;
        }
      }
      return skipDeclaration(element, elementTypeDescription);
    } catch (UnsupportedConversionException e) {
      return skipDeclaration(element, elementTypeDescription, e.toString());
    }
  }
 public void addMissingMethods(
     Class<?> originalLib, Signatures existingSignatures, Struct outputLib) {
   for (Pair<Function, String> f : getMethodsAndTheirSignatures(originalLib).getFirst())
     if (existingSignatures.addMethod(f.getSecond()))
       outputLib.addDeclaration(f.getFirst().clone());
 }