public OJField getCopy() {
    /*if (isAlterable())  return substance.getCopy();*/
    /** **************** */
    // return (FieldDeclaration) substance.clone () ;
    try {

      if (substance instanceof OJFieldByteCode) {
        java.lang.reflect.Field field = ((OJFieldByteCode) substance).getByteCode();
        OJField result = (OJField) this.clone();
        // On remplace du ByteCode par du SourceCode
        FieldDeclaration fd =
            new FieldDeclaration(
                new ModifierList(field.getModifiers()),
                TypeName.forOJClass(OJClass.forClass(field.getDeclaringClass())),
                field.getName(),
                null);
        Environment env = substance.getDeclaringClass().getEnvironment();
        result.substance = new OJFieldSourceCode(env, substance.getDeclaringClass(), fd);
        return result;
      } else if (substance instanceof OJFieldSourceCode) {
        OJField result = (OJField) this.clone();
        result.substance =
            new OJFieldSourceCode(
                ((OJFieldSourceCode) this.substance).getEnvironment(),
                this.substance.getDeclaringClass(),
                (FieldDeclaration) this.substance.getSourceCode().makeRecursiveCopy());
        return result;
      }
    } catch (Exception e) {
      System.err.println("Failed to copy " + this + ": " + e);
      e.printStackTrace();
    }
    return null;
  }
 /**
  * Compares this field against the given object. The algorithm is borrowed by
  * java.lang.reflect.Field.equals().
  *
  * @see java.lang.reflect.Field#equals
  */
 public boolean equals(Object obj) {
   if (obj != null && obj instanceof OJField) {
     OJField other = (OJField) obj;
     return (getDeclaringClass() == other.getDeclaringClass())
         && (getName().equals(other.getName()))
         && (getType() == other.getType());
   } else {
     return false;
   }
 }