You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: factory.go
    path of file: ./repos/werf/pkg/path_matcher
    
    the code of the file until where you have to start completion: package path_matcher

type PathMatcherOptions struct {
	BasePath             string
	IncludeGlobs         []string
	ExcludeGlobs         []string
	DockerignorePatterns []string
	Matchers             []PathMatcher
}

func NewPathMatcher(options PathMatcherOptions) PathMatcher {
	var matchers []PathMatcher

	if len(options.IncludeGlobs) != 0 {
		matchers = append(matchers, newIncludePathMatcher(options.IncludeGlobs))
	}

	if len(options.ExcludeGlobs) != 0 {
		matchers = append(matchers, newExcludePathMatcher(options.ExcludeGlobs))
	}

	if options.DockerignorePatterns != nil {
		matchers = append(matchers, newDockerfileIgnor
    
func NewPathMatcher(options PathMatcherOptions) PathMatcher {
	var matchers []PathMatcher

	if len(options.IncludeGlobs) != 0 {
		matchers = append(matchers, newIncludePathMatcher(options.IncludeGlobs))
	}

	if len(options.ExcludeGlobs) != 0 {
		matchers = append(matchers, newExcludePathMatcher(options.ExcludeGlobs))
	}

	if options.DockerignorePatterns != nil {
		matchers = append(matchers, newDockerfileIgnorePathMatcher(options.DockerignorePatterns))
	}

	if len(options.Matchers) != 0 {
		matchers = append(matchers, options.Matchers...)
	}

	if len(matchers) == 0 {
		matchers = append(matchers, NewTruePathMatcher())
	}

	var matcher PathMatcher
	matcher = NewMultiPathMatcher(matchers...)
	if options.BasePath != "" {
		matcher = newBasePathMatcher(options.BasePath, matcher)
	}

	return matcher
}