///|
pub fn SourceBundle::blank_lines(self : SourceBundle) -> Int {
  let mut count = 0
  for summary in self.summaries() {
    count += summary.blank_lines
  }
  count
}

///|
pub fn SourceBundle::comment_lines(self : SourceBundle) -> Int {
  let mut count = 0
  for summary in self.summaries() {
    count += summary.comment_lines
  }
  count
}

///|
pub fn SourceBundle::max_line_length(self : SourceBundle) -> Int {
  let mut result = 0
  for summary in self.summaries() {
    if summary.max_line_length > result {
      result = summary.max_line_length
    }
  }
  result
}

///|
pub fn SourceBundle::has_duplicate_names(self : SourceBundle) -> Bool {
  let names = self.names()
  let seen : Array[String] = []
  for name in names {
    if seen.contains(name) {
      return true
    }
    seen.push(name)
  }
  false
}

///|
pub fn SourceBundle::normalized(self : SourceBundle) -> SourceBundle {
  let result = SourceBundle::new()
  for file in self.files {
    result.add(file.normalized())
  }
  result
}

///|
pub fn SourceBundle::with_prefix(
  self : SourceBundle,
  prefix : String,
) -> SourceBundle {
  let result = SourceBundle::new()
  for file in self.files {
    if file.name().has_prefix(prefix) {
      result.add(file)
    }
  }
  result
}

///|
pub fn SourceBundle::contains_text(self : SourceBundle, text : String) -> Bool {
  for file in self.files {
    if file.text().contains(text) {
      return true
    }
  }
  false
}

///|
pub fn SourceBundle::file_names_with_text(
  self : SourceBundle,
  text : String,
) -> Array[String] {
  let result : Array[String] = []
  for file in self.files {
    if file.text().contains(text) {
      result.push(file.name())
    }
  }
  result
}

///|
pub fn SourceBundle::summary_line(self : SourceBundle) -> String {
  self.summary() +
  ", blank=" +
  self.blank_lines().to_string() +
  ", comments=" +
  self.comment_lines().to_string() +
  ", max_line=" +
  self.max_line_length().to_string()
}