private ImportedAlbumTrack ParseTrack(DataRow dataRow, int nextTrackNum) {

			var track = new ImportedAlbumTrack();

			track.Title = dataRow.GetString(AlbumFileField.Title);
			var trackNumMatch = numRegex.Match(dataRow.GetString(AlbumFileField.Track, string.Empty));
			if (trackNumMatch.Success)
				track.TrackNum = int.Parse(trackNumMatch.Groups[1].Value);
			else
				track.TrackNum = nextTrackNum;

			var artists = new List<string>();

			var composer = dataRow.GetString(AlbumFileField.Composer, string.Empty);

			if (composer != string.Empty)
				artists.Add(composer);

			var artist = dataRow.GetString(AlbumFileField.Artist, string.Empty);

			if (artist != string.Empty) {

				var featPos = artist.IndexOf("feat.", StringComparison.InvariantCultureIgnoreCase);

				if (featPos != -1) {

					var vocaloidName = artist.Substring(featPos + 5, artist.Length - featPos - 5).Trim();
					track.VocalistNames = GetArtistNames(vocaloidName);
					artist = artist.Substring(0, featPos).Trim();

				} else {

					track.VocalistNames = new string[] {};

				}

				artists.AddRange(GetArtistNames(artist));

			}

			track.ArtistNames = artists.Distinct().ToArray();
			return track;

		}
		public MikuDbAlbumContract Parse(Stream input) {

			var tracks = new List<ImportedAlbumTrack>();
			var parser = new DataRowParser();
			var data = new ImportedAlbumDataContract();
			data.Title = "Unknown";

			using (var reader = new StreamReader(input)) {

				string row;
				while ((row = reader.ReadLine()) != null) {

					if (!parser.IsConfigured) {
						parser.Configure(row);
					} else {

						var dataRow = new DataRow(parser, row);

						var albumName = dataRow.GetString(AlbumFileField.Album, string.Empty);
						if (albumName != string.Empty)
							data.Title = albumName;

						var year = dataRow.GetIntOrDefault(AlbumFileField.Year, 0);
						if (year != 0)
							data.ReleaseYear = year;

						var track = ParseTrack(dataRow, tracks.Count + 1);
						tracks.Add(track);

					}

				}

			}

			data.ArtistNames = tracks.SelectMany(t => t.ArtistNames).Distinct().ToArray();
			data.VocalistNames = tracks.SelectMany(t => t.VocalistNames).Distinct().ToArray();
			data.Tracks = tracks.OrderBy(t => t.TrackNum).ToArray();

			return new MikuDbAlbumContract(data);

		}