class FieldResolutionFailedException extends ResolutionFailedException {
    /**
     *
     */
    private static final long serialVersionUID = -4657113720516199499L;

    public FieldResolutionFailedException() {
      super("Class " + declaringClass + " doesn't have field " + name + " : " + type
          + "; failed to resolve in superclasses and interfaces");
    }

    @Override
    public String toString() {
      StringBuffer ret = new StringBuffer();
      ret.append(super.toString());
      resolve(ret);
      return ret.toString();
    }
  }

  @Override
  public SootField resolve() {
    return resolve(null);
  }

  private SootField checkStatic(SootField ret) {
    if ((Options.v().wrong_staticness() == Options.wrong_staticness_fail
        || Options.v().wrong_staticness() == Options.wrong_staticness_fixstrict) && ret.isStatic() != isStatic()
        && !ret.isPhantom()) {
      throw new ResolutionFailedException("Resolved " + this + " to " + ret + " which has wrong static-ness");
    }
    return ret;
  }

  private SootField resolve(StringBuffer trace) {<FILL_FUNCTION_BODY>

    SootClass cl = declaringClass;
    while (true) {
      if (trace != null) {
        trace.append("Looking in " + cl + " which has fields " + cl.getFields() + "\n");
      }

      // Check whether we have the field in the current class
      SootField clField = cl.getFieldUnsafe(name, type);
      if (clField != null) {
        return checkStatic(clField);
      }
      // If we have a phantom class, we directly construct a phantom field
      // in it and don't care about superclasses.
      else if (Scene.v().allowsPhantomRefs() && cl.isPhantom()) {
        synchronized (cl) {
          // Check that no other thread has created the field in the
          // meantime
          clField = cl.getFieldUnsafe(name, type);
          if (clField != null) {
            return checkStatic(clField);
          }

          // Make sure that we don't have a conflicting field
          SootField existingField = cl.getFieldByNameUnsafe(name);
          if (existingField != null) {
            return handleFieldTypeMismatch(clField);
          }

          // Create the phantom field
          SootField f = Scene.v().makeSootField(name, type, isStatic() ? Modifier.STATIC : 0);
          f.setPhantom(true);
          cl.addField(f);
          return f;
        }
      } else {
        // Since this class is not phantom, we look at its interfaces
        ArrayDeque<SootClass> queue = new ArrayDeque<SootClass>();
        queue.addAll(cl.getInterfaces());
        while (true) {
          SootClass iface = queue.poll();
          if (iface == null) {
            break;
          }

          if (trace != null) {
            trace.append("Looking in " + iface + " which has fields " + iface.getFields() + "\n");
          }
          SootField ifaceField = iface.getFieldUnsafe(name, type);
          if (ifaceField != null) {
            return checkStatic(ifaceField);
          }
          queue.addAll(iface.getInterfaces());
        }

        // If we have not found a suitable field in the current class,
        // try the superclass
        if (cl.hasSuperclass()) {
          cl = cl.getSuperclass();
        } else {
          break;
        }
      }
    }

    // If we allow phantom refs, we construct phantom fields
    if (Options.v().allow_phantom_refs()) {
      SootField sf = Scene.v().makeSootField(name, type, isStatic ? Modifier.STATIC : 0);
      sf.setPhantom(true);
      synchronized (declaringClass) {
        // Be careful: Another thread may have already created this
        // field in the meantime, so better check twice.
        SootField clField = declaringClass.getFieldByNameUnsafe(name);
        if (clField != null) {
          if (clField.getType().equals(type)) {
            return checkStatic(clField);
          } else {
            return handleFieldTypeMismatch(clField);
          }
        } else {
          // Add the new phantom field
          declaringClass.addField(sf);
          return sf;
        }
      }
    }

    if (trace == null) {
      FieldResolutionFailedException e = new FieldResolutionFailedException();
      if (Options.v().ignore_resolution_errors()) {
        logger.debug("" + e.getMessage());
      } else {
        throw e;
      }
    }
    return null;
  
<no_super_class>