/*
   * Extract and store type signatures and arguments using unique key for parameterized types
   * and type parameters for non-generic ones
   */
  void storeTypeSignaturesAndArguments(IType type) {
    if (type.isResolved()) {
      BindingKey bindingKey = new BindingKey(type.getKey());
      if (bindingKey.isParameterizedType() || bindingKey.isRawType()) {
        String signature = bindingKey.toSignature();
        this.typeSignatures = Util.splitTypeLevelsSignature(signature);
        setTypeArguments(Util.getAllTypeArguments(this.typeSignatures));
      }
      return;
    }

    // Scan hierarchy to store type arguments at each level
    char[][][] typeParameters = new char[10][][];
    int ptr = -1;
    boolean hasParameters = false;
    try {
      IJavaElement parent = type;
      ITypeParameter[] parameters = null;
      while (parent != null && parent.getElementType() == IJavaElement.TYPE) {
        if (++ptr > typeParameters.length) {
          System.arraycopy(
              typeParameters, 0, typeParameters = new char[typeParameters.length + 10][][], 0, ptr);
        }
        IType parentType = (IType) parent;
        parameters = parentType.getTypeParameters();
        if (parameters != null) {
          int length = parameters.length;
          if (length > 0) {
            hasParameters = true;
            typeParameters[ptr] = new char[length][];
            for (int i = 0; i < length; i++)
              typeParameters[ptr][i] =
                  Signature.createTypeSignature(parameters[i].getElementName(), false)
                      .toCharArray();
          }
        }
        parent = parent.getParent();
      }
    } catch (JavaModelException jme) {
      return;
    }

    // Store type arguments if any
    if (hasParameters) {
      if (++ptr < typeParameters.length)
        System.arraycopy(typeParameters, 0, typeParameters = new char[ptr][][], 0, ptr);
      setTypeArguments(typeParameters);
    }
  }