/**
   * Returns the qualified signature corresponding to <code>signature</code>.
   *
   * @param signature the signature to qualify
   * @param context the type inside which an unqualified type will be resolved to find the
   *     qualifier, or <code>null</code> if no context is available
   * @return the qualified signature
   */
  public static String qualifySignature(final String signature, final IType context) {
    if (context == null) return signature;

    String qualifier = Signature.getSignatureQualifier(signature);
    if (qualifier.length() > 0) return signature;

    String elementType = Signature.getElementType(signature);
    String erasure = Signature.getTypeErasure(elementType);
    String simpleName = Signature.getSignatureSimpleName(erasure);
    String genericSimpleName = Signature.getSignatureSimpleName(elementType);

    int dim = Signature.getArrayCount(signature);

    try {
      String[][] strings = context.resolveType(simpleName);
      if (strings != null && strings.length > 0) qualifier = strings[0][0];
    } catch (JavaModelException e) {
      // ignore - not found
    }

    if (qualifier.length() == 0) return signature;

    String qualifiedType = Signature.toQualifiedName(new String[] {qualifier, genericSimpleName});
    String qualifiedSignature = Signature.createTypeSignature(qualifiedType, true);
    String newSignature = Signature.createArraySignature(qualifiedSignature, dim);

    return newSignature;
  }
 private static String typeSignatureToFqn(String signature) {
   try {
     switch (Signature.getTypeSignatureKind(signature)) {
       case Signature.ARRAY_TYPE_SIGNATURE:
         return typeSignatureToFqn(Signature.getElementType(signature))
             + brackets.substring(0, 2 * Signature.getArrayCount(signature));
       case Signature.CLASS_TYPE_SIGNATURE:
         String args[] = Signature.getTypeArguments(signature);
         if (args.length == 0) {
           int firstDollar = signature.indexOf('$');
           if (firstDollar == -1) {
             return Signature.getSignatureQualifier(signature)
                 + "."
                 + Signature.getSignatureSimpleName(signature);
           } else {
             String shortSig = signature.substring(0, firstDollar) + ";";
             return Signature.getSignatureQualifier(shortSig)
                 + "."
                 + Signature.getSignatureSimpleName(shortSig)
                 + signature.substring(firstDollar, signature.length() - 1);
           }
         } else {
           StringBuilder fqnBuilder =
               new StringBuilder(typeSignatureToFqn(Signature.getTypeErasure(signature)));
           fqnBuilder.append('<');
           boolean first = true;
           for (String arg : args) {
             if (first) {
               first = false;
             } else {
               fqnBuilder.append(',');
             }
             fqnBuilder.append(typeSignatureToFqn(arg));
           }
           fqnBuilder.append('>');
           return fqnBuilder.toString();
         }
       case Signature.BASE_TYPE_SIGNATURE:
         return Signature.getSignatureSimpleName(signature);
       case Signature.TYPE_VARIABLE_SIGNATURE:
         return "<" + Signature.getSignatureSimpleName(signature) + ">";
       case Signature.WILDCARD_TYPE_SIGNATURE:
         if (signature.startsWith("+")) {
           return "<?+" + typeSignatureToFqn(signature.substring(1)) + ">";
         } else if (signature.startsWith("-")) {
           return "<?-" + typeSignatureToFqn(signature.substring(1)) + ">";
         } else {
           return "<?>";
         }
       case Signature.CAPTURE_TYPE_SIGNATURE:
         System.out.println("eek");
         return "";
       default:
         throw new IllegalArgumentException("Not a valid type signature");
     }
   } catch (Exception e) {
     e.printStackTrace();
     System.out.println("bad");
     return null;
   }
 }