func (pkg Package) DeclarationFor(importPath string, targetFile string) (PackageDeclaration, bool) {
	declrs := pkg.Declarations(importPath)
	for _, declr := range declrs {
		if declr.File == targetFile {
			return declr, true
		}
	}
	return PackageDeclaration{}, false
}
DeclarationFor returns the associated declaration for the giving file path.
package ast
import (
	"bytes"
	"encoding/json"
	"errors"
	"fmt"
	"go/ast"
	"go/token"
	"io"
	"math/rand"
	"os"
	"path/filepath"
	"regexp"
	"strconv"
	"strings"
	"time"
	"github.com/icrowley/fake"
	"github.com/influx6/faux/metrics"
	"github.com/influx6/gobuild/build"
	"github.com/influx6/moz/gen"
)
const (
	annotationFileFormat    = "%s_annotation_%s.%s"
	altAnnotationFileFormat = "%s_annotation_%s"
)
var (
	goPath    = os.Getenv("GOPATH")
	goSrcPath = filepath.Join(goPath, "src")
	spaces     = regexp.MustCompile(`/s+`)
	itag       = regexp.MustCompile(`((\w+):"(\w+|[\w,?\s+\w]+)")`)
	annotation = regexp.MustCompile("@(\\w+(:\\w+)?)(\\([.\\s\\S]+\\))?")
	ASTTemplatFuncs = map[string]interface{}{
		"getTag":            GetTag,
		"fieldFor":          FieldFor,
		"getFields":         GetFields,
		"fieldNameFor":      FieldNameFor,
		"mapoutFields":      MapOutFields,
		"mapoutValues":      MapOutValues,
		"fieldByName":       FieldByFieldName,
		"randomValue":       RandomFieldAssign,
		"fieldsJSON":        MapOutFieldsToJSON,
		"randomValuesJSON":  MapOutFieldsWithRandomValuesToJSON,
		"stringValueFor":    ToValueString,
		"defaultValue":      AssignDefaultValue,
		"randomFieldValue":  RandomFieldValue,
		"defaultType":       DefaultTypeValueString,
		"defaultFieldValue": DefaultFieldValue,
	}
	naturalIdents = map[string]bool{
		"string":      true,
		"bool":        true,
		"rune":        true,
		"byte":        true,
		"int":         true,
		"int8":        true,
		"int16":       true,
		"int32":       true,
		"int64":       true,
		"uint":        true,
		"uint8":       true,
		"uint32":      true,
		"uint64":      true,
		"uintptr":     true,
		"float32":     true,
		"float64":     true,
		"complex128":  true,
		"complex64":   true,
		"error":       true,
		"struct":      true,
		"interface":   true,
		"interface{}": true,
		"struct{}":    true,
	}
)
type Packages []Package
func (pkgs Packages) TestPackageForFile(path string, targetFile string) (PackageDeclaration, Package, bool) {
	pl, ok := pkgs.TestPackageFor(path)
	if !ok {
		return PackageDeclaration{}, Package{}, ok
	}
	plDeclr, ok := pl.DeclarationFor(path, targetFile)
	return plDeclr, pl, ok
}
func (pkgs Packages) PackageForFile(path string, targetFile string) (PackageDeclaration, Package, bool) {
	pl, ok := pkgs.PackageFor(path)
	if !ok {
		return PackageDeclaration{}, Package{}, ok
	}
	plDeclr, ok := pl.DeclarationFor(path, targetFile)
	return plDeclr, pl, ok
}
func (pkgs Packages) TestPackageFor(path string) (Package, bool) {
	for _, pkg := range pkgs {
		if pkg.Path == path && strings.HasSuffix(pkg.Tag, "_test") {
			return pkg, true
		}
	}
	return Package{}, false
}
func (pkgs Packages) PackageFor(path string) (Package, bool) {
	for _, pkg := range pkgs {
		if pkg.Path == path && !strings.HasSuffix(pkg.Tag, "_test") {
			return pkg, true
		}
	}
	return Package{}, false
}
type ImportDeclaration struct {
	Name        string
	Path        string
	Source      string
	Comments    string
	InternalPkg bool
}
type Package struct {
	Name         string
	Tag          string
	Path         string
	FilePath     string
	Files        []string
	BuildPkg     *build.Package
	Packages     []PackageDeclaration
	TestPackages []PackageDeclaration
}
func (pkg *Package) loadImported(m metrics.Metrics) error {
	for index, item := range pkg.Packages {
		if err := item.loadImported(m); err != nil {
			return err
		}
		pkg.Packages[index] = item
	}
	return nil
}
func (pkg Package) HasFunctionFor(str StructDeclaration, funcName string) bool {
	for _, elem := range pkg.Packages {
		if elem.HasFunctionFor(str, funcName) {
			return true
		}
	}
	return false
}
func (pkg Package) PackagesWithAnnotation(name string) []PackageDeclaration {
	var pkgs []PackageDeclaration
	for _, elem := range pkg.Packages {
		if !elem.HasAnnotation(name) {
			continue
		}
		pkgs = append(pkgs, elem)
	}
	return pkgs
}
func (pkg Package) AnnotationFirstFor(typeName string) (AnnotationDeclaration, PackageDeclaration, bool) {
	for _, elem := range pkg.Packages {
		if annon, ok := elem.GetAnnotation(typeName); ok {
			return annon, elem, true
		}
	}
	return AnnotationDeclaration{}, PackageDeclaration{}, false
}
func (pkg Package) HasAnnotation(name string) bool {
	for _, elem := range pkg.Packages {
		if elem.HasAnnotation(name) {
			return true
		}
	}
	return false
}
func (pkg Package) AnnotationsFor(typeName string) []AnnotationDeclaration {
	var found []AnnotationDeclaration
	for _, elem := range pkg.Packages {
		found = append(found, elem.AnnotationsFor(typeName)...)
	}
	return found
}
func (pkg Package) FunctionsForName(objName string) []FuncDeclaration {
	var funcs []FuncDeclaration
	for _, elem := range pkg.Packages {
		funcs = append(funcs, elem.FunctionsForName(objName)...)
	}
	return funcs
}
func (pkg Package) ImportFor(imp string) (ImportDeclaration, error) {
	for _, elem := range pkg.Packages {
		if impDeclr, err := elem.ImportFor(imp); err == nil {
			return impDeclr, nil
		}
	}
	return ImportDeclaration{}, errors.New("Not found")
}
func (pkg Package) FunctionsFor(obj *ast.Object) []FuncDeclaration {
	var funcs []FuncDeclaration
	for _, elem := range pkg.Packages {
		funcs = append(funcs, elem.FunctionsFor(obj)...)
	}
	return funcs
}
func (pkg Package) TestDeclarations(importPath string) []PackageDeclaration {
	var declrs []PackageDeclaration
	for _, declr := range pkg.TestPackages {
		if declr.Path == importPath {
			declrs = append(declrs, declr)
		}
	}
	return declrs
}
func (pkg Package) Declarations(importPath string) []PackageDeclaration {
	var declrs []PackageDeclaration
	for _, declr := range pkg.Packages {
		if declr.Path == importPath {
			declrs = append(declrs, declr)
		}
	}
	return declrs
}
func (pkg Package) TestDeclarationFor(importPath string, targetFile string) (PackageDeclaration, bool) {
	declrs := pkg.TestDeclarations(importPath)
	for _, declr := range declrs {
		if declr.File == targetFile {
			return declr, true
		}
	}
	return PackageDeclaration{}, false
}