whole_func_string: function (path, body, contentType, options) {
      const fullPath = googleDrivePath(path);
  
      function putDone(response) {
        if (response.status >= 200 && response.status < 300) {
          const meta = JSON.parse(response.responseText);
          const etagWithoutQuotes = removeQuotes(meta.etag);
          return Promise.resolve({statusCode: 200, contentType: meta.mimeType, revision: etagWithoutQuotes});
        } else if (response.status === 412) {
          return Promise.resolve({statusCode: 412, revision: 'conflict'});
        } else {
          return Promise.reject("PUT failed with status " + response.status + " (" + response.responseText + ")");
        }
      }
  
      return this._getFileId(fullPath).then((id) => {
        if (id) {
          if (options && (options.ifNoneMatch === '*')) {
            return putDone({ status: 412 });
          }
          return this._updateFile(id, fullPath, body, contentType, options).then(putDone);
        } else {
          return this._createFile(fullPath, body, contentType, options).then(putDone);
        }
      });
    }
func_code_string: function (path, body, contentType, options) {
      const fullPath = googleDrivePath(path);
  
      function putDone(response) {
        if (response.status >= 200 && response.status < 300) {
          const meta = JSON.parse(response.responseText);
          const etagWithoutQuotes = removeQuotes(meta.etag);
          return Promise.resolve({statusCode: 200, contentType: meta.mimeType, revision: etagWithoutQuotes});
        } else if (response.status === 412) {
          return Promise.resolve({statusCode: 412, revision: 'conflict'});
        } else {
          return Promise.reject("PUT failed with status " + response.status + " (" + response.responseText + ")");
        }
      }
  
      return this._getFileId(fullPath).then((id) => {
        if (id) {
          if (options && (options.ifNoneMatch === '*')) {
            return putDone({ status: 412 });
          }
          return this._updateFile(id, fullPath, body, contentType, options).then(putDone);
        } else {
          return this._createFile(fullPath, body, contentType, options).then(putDone);
        }
      });
    }
func_documentation_string: Create or update a file.
  
  @param {string} path - File path
  @param body - File content
  @param {string} contentType - File content-type
  @param {Object} options
  @param {string} options.ifNoneMatch - Only create of update the file if the
  current ETag doesn't match this string
  @returns {Promise} Resolves with an object containing the status code,
  content-type and revision
  
  @protected