code: public FeatureList getFeatureList() throws IOException, ServerException {
  
          if (this.session.featureList != null) {
              return this.session.featureList;
          }
  
          // TODO: this can also be optimized. Instead of parsing the
          // reply after it is reveiced, we can parse it as it is
          // received.
          Reply featReply = null;
          try {
              featReply = controlChannel.execute(Command.FEAT);
  
              if (featReply.getCode() != 211) {
                  throw ServerException.embedUnexpectedReplyCodeException(
                                    new UnexpectedReplyCodeException(featReply),
                                    "Server refused returning features");
              }
          } catch (FTPReplyParseException rpe) {
              throw ServerException.embedFTPReplyParseException(rpe);
          } catch (UnexpectedReplyCodeException urce) {
              throw ServerException.embedUnexpectedReplyCodeException(
                                  urce,
                                  "Server refused returning features");
          }
  
          this.session.featureList = new FeatureList(featReply.getMessage());
  
          return session.featureList;
      }
docs: Returns list of features supported by remote server.
  @return list of features supported by remote server.