docs: @SuppressWarnings("unchecked")
      public static <T> T valueOf(Instance obj, String pathSpec) {
          PathStep[] steps = HeapPath.parsePath(pathSpec, true);
          if (steps.length > 0 && steps[steps.length - 1] instanceof FieldStep) {
              PathStep[] shortPath = Arrays.copyOf(steps, steps.length - 1);
              FieldStep lastStep = (FieldStep) steps[steps.length - 1];
              String fieldName = lastStep.getFieldName();
              for(Instance i: HeapPath.collect(obj, shortPath)) {
                  for(FieldValue fv: i.getFieldValues()) {
                      if ((fieldName == null && (!fv.getField().isStatic()))
                              || (fv.getField().getName().equals(fieldName))) {
                          if (fv instanceof ObjectFieldValue) {
                              return valueOf(((ObjectFieldValue) fv).getInstance());
                          }
                          else {
                              // have to use this as private package API is used behind scene
                              return (T) i.getValueOfField(fv.getField().getName());
                          }
                      }
                  }
              }
              return null;
          }
          else if (steps.length > 0 && steps[steps.length - 1] instanceof ArrayIndexStep) {
              PathStep[] shortPath = Arrays.copyOf(steps, steps.length - 1);
              ArrayIndexStep lastStep = (ArrayIndexStep) steps[steps.length - 1];
              for(Instance i: HeapPath.collect(obj, shortPath)) {
                  if (i instanceof PrimitiveArrayInstance) {
                      Object array = valueOf(i);
                      if (array != null) {
                          int len = Array.getLength(array);
                          int n = lastStep.getIndex();
                          if (n < 0) {
                              n = 0;
                          }
                          if (n < len) {
                              return (T) Array.get(array, n);
                          }
                          else {
                              return null;
                          }
                      }
                  }
                  else {
                      for(Instance x: HeapPath.collect(i, new PathStep[]{lastStep})) {
                          return valueOf(x);                        
                      }
                  }
              }            
              return null;
              
          } else {
              for(Instance i: HeapPath.collect(obj, steps)) {
                  return valueOf(i);
              }
              return null;
          }
      }