code: function parse( lang, sample ) {
      // TODO: this should be refactored
      let ianaLang;
      const language = {
          desc: lang.trim(),
          tag: lang.trim(),
          src: lang
      };
      const parts = lang.match( /^([^(]+)\((.*)\)\s*$/ );
  
      if ( parts && parts.length > 2 ) {
          language.desc = parts[ 1 ].trim();
          language.tag = parts[ 2 ].trim();
          ianaLang = _getLangWithTag( language.tag );
      } else {
          // First check whether lang is a known IANA subtag like 'en' or 'en-GB'
          ianaLang = _getLangWithTag( lang.split( '-' )[ 0 ] );
          if ( ianaLang ) {
              language.desc = ianaLang.descriptions()[ 0 ];
          } else {
              // Check whether IANA language can be found with description
              ianaLang = _getLangWithDesc( language.desc );
              if ( ianaLang ) {
                  language.tag = ianaLang.data.subtag;
              }
          }
      }
  
      language.dir = _getDirectionality( sample );
  
      return language;
  }
docs: Parses a language string into a language object. Guesses missing properties.
  
  @see    http://www.iana.org/assignments/language-subtag-registry/language-subtag-registry
  @param  {string} lang language strings as included in the XForm
  @return {{desc: string, tag: string, dir: string, src: string}}      language object