// ReplaceWithMatcher replaces each element in the set of matched elements with
// the nodes matched by the given Matcher.
// It returns the removed elements.
//
// This follows the same rules as Selection.Append.
198905
func (s *Selection) ReplaceWithMatcher(m Matcher) *Selection {
	return s.ReplaceWithNodes(m.MatchAll(s.document.rootNode)...)
}
726565
func ReplaceAll(rgx *regexp.Regexp, src *[]byte, rpl []byte) {
	// Find all matches
	var start, end, delta, offset, i int
	var l = len(rpl)
	for _, indexes := range rgx.FindAllIndex(*src, -1) {
		// Update indexes
		start = indexes[0] + offset
		end = indexes[1] + offset
		delta = (end - start) - l
		offset -= delta

		// Update src length
		if delta < 0 {
			// Insert
			(*src) = append((*src)[:start], append(make([]byte, -delta), (*src)[start:]...)...)
		} else if delta > 0 {
			// Delete
			(*src) = append((*src)[:start], (*src)[start+delta:]...)
		}

		// Update src content
		for i = 0; i < l; i++ {
			(*src)[i+start] = rpl[i]
		}
	}
}
1282296
func AddMatcher(fileType types.Type, matcher matchers.Matcher) matchers.TypeMatcher {
	return matchers.NewMatcher(fileType, matcher)
}
669380
func MultiMatcher(m ...Matcher) Matcher {
	fn := func(r *Request) bool {
		for _, matcher := range m {
			if !matcher.Match(r) {
				return false
			}
		}

		return true
	}

	return &MatcherFunc{fn}
}
1179385
func (c Context) Replace(input, find, replacement string) string {
	return strings.Replace(input, find, replacement, -1)
}
890245
func (s *Selection) IsMatcher(m Matcher) bool {
	if len(s.Nodes) > 0 {
		if len(s.Nodes) == 1 {
			return m.Match(s.Nodes[0])
		}
		return len(m.Filter(s.Nodes)) > 0
	}

	return false
}
294468
func NewMatcher(sectionSize uint64, filters [][][]byte) *Matcher {
	// Create the matcher instance
	m := &Matcher{
		sectionSize: sectionSize,
		schedulers:  make(map[uint]*scheduler),
		retrievers:  make(chan chan uint),
		counters:    make(chan chan uint),
		retrievals:  make(chan chan *Retrieval),
		deliveries:  make(chan *Retrieval),
	}
	// Calculate the bloom bit indexes for the groups we're interested in
	m.filters = nil

	for _, filter := range filters {
		// Gather the bit indexes of the filter rule, special casing the nil filter
		if len(filter) == 0 {
			continue
		}
		bloomBits := make([]bloomIndexes, len(filter))
		for i, clause := range filter {
			if clause == nil {
				bloomBits = nil
				break
			}
			bloomBits[i] = calcBloomIndexes(clause)
		}
		// Accumulate the filter rules if no nil rule was within
		if bloomBits != nil {
			m.filters = append(m.filters, bloomBits)
		}
	}
	// For every bit, create a scheduler to load/download the bit vectors
	for _, bloomIndexLists := range m.filters {
		for _, bloomIndexList := range bloomIndexLists {
			for _, bloomIndex := range bloomIndexList {
				m.addScheduler(bloomIndex)
			}
		}
	}
	return m
}
1250313
func (s *Selection) IndexMatcher(m Matcher) int {
	if len(s.Nodes) > 0 {
		sel := s.document.FindMatcher(m)
		return indexInSlice(sel.Nodes, s.Nodes[0])
	}
	return -1
}
419859
func (s *Selection) ParentsUntilMatcher(m Matcher) *Selection {
	return pushStack(s, getParentsNodes(s.Nodes, m, nil))
}
98363
func (s *Selection) NextUntilMatcher(m Matcher) *Selection {
	return pushStack(s, getSiblingNodes(s.Nodes, siblingNextUntil,
		m, nil))
}
822270
func replaceTagWithContents(tagSelection *goquery.Selection, collapsibleAtomTypes []atom.Atom) {
	if tagSelection.Length() == 0 {
		return
	}
	node := tagSelection.Get(0)
	node.Data = tagSelection.Text()
	node.Type = html.TextNode
	if node.FirstChild == nil {
		node.Attr = []html.Attribute{}
		node.DataAtom = 0
		node.FirstChild = nil
		node.LastChild = nil
	} else {
		// If all children are text only, the parent already contains the text, so drop them
		collapseTextNodes(node, collapsibleAtomTypes)
	}
}
624648
func NewMatcher(kind types.Type, fn Matcher) TypeMatcher {
	matcher := func(buf []byte) types.Type {
		if fn(buf) {
			return kind
		}
		return types.Unknown
	}

	Matchers[kind] = matcher
	// prepend here so any user defined matchers get added first
	MatcherKeys = append([]types.Type{kind}, MatcherKeys...)
	return matcher
}
751
func (s *Selection) NextMatcher(m Matcher) *Selection {
	return filterAndPush(s, getSiblingNodes(s.Nodes, siblingNext, nil, nil), m)
}
1361431
func (s *Selection) ParentsMatcherUntilSelection(filter Matcher, sel *Selection) *Selection {
	if sel == nil {
		return s.ParentsMatcher(filter)
	}
	return s.ParentsMatcherUntilNodes(filter, sel.Nodes...)
}
595508
func (s *Selection) FilterMatcher(m Matcher) *Selection {
	return pushStack(s, winnow(s, m, true))
}
1185218
func (v *TreeVertex) replace(id string, r *TreeVertex) {
	if v.Id == id {
		v.Descendants = r.Descendants
		return
	}
	for _, u := range v.Descendants {
		u.replace(id, r)
	}
}
241884
func (s *Selection) WrapMatcher(m Matcher) *Selection {
	return s.wrapNodes(m.MatchAll(s.document.rootNode)...)
}