diff --git a/lint/analyzer.go b/lint/analyzer.go
index 495cc732..265a9f73 100644
--- a/lint/analyzer.go
+++ b/lint/analyzer.go
@@ -31,6 +31,7 @@ const (
 	UpdateCategory          = "update recommended"
 	UnnecessaryCastCategory = "unnecessary-cast-hint"
 	DeprecatedCategory      = "deprecated"
+	CadenceV1Category       = "cadence-v1"
 )
 
 var Analyzers = map[string]*analysis.Analyzer{}
diff --git a/lint/analyzers_test.go b/lint/analyzers_test.go
index f4d81f19..2830454e 100644
--- a/lint/analyzers_test.go
+++ b/lint/analyzers_test.go
@@ -24,6 +24,7 @@ import (
 	"github.com/stretchr/testify/require"
 
 	"github.com/onflow/cadence/runtime/common"
+	"github.com/onflow/cadence/runtime/sema"
 	"github.com/onflow/cadence/tools/analysis"
 
 	"github.com/onflow/cadence-tools/lint"
@@ -32,6 +33,27 @@ import (
 var testLocation = common.StringLocation("test")
 
 func testAnalyzers(t *testing.T, code string, analyzers ...*analysis.Analyzer) []analysis.Diagnostic {
+	return testAnalyzersAdvanced(t, code, nil, analyzers...)
+}
+
+func testAnalyzersWithCheckerError(t *testing.T, code string, analyzers ...*analysis.Analyzer) ([]analysis.Diagnostic, *sema.CheckerError) {
+	var checkerErr *sema.CheckerError
+	diagnostics := testAnalyzersAdvanced(t, code, func(config *analysis.Config) {
+		config.HandleCheckerError = func(err analysis.ParsingCheckingError, checker *sema.Checker) error {
+			require.NotNil(t, checker)
+			require.Equal(t, err.ImportLocation(), testLocation)
+
+			require.ErrorAs(t, err, &checkerErr)
+			require.Len(t, checkerErr.Errors, 1)
+			return nil
+		}
+	}, analyzers...)
+
+	require.NotNil(t, checkerErr)
+	return diagnostics, checkerErr
+}
+
+func testAnalyzersAdvanced(t *testing.T, code string, setCustomConfigOptions func(config *analysis.Config), analyzers ...*analysis.Analyzer) []analysis.Diagnostic {
 
 	config := analysis.NewSimpleConfig(
 		lint.LoadMode,
@@ -42,6 +64,10 @@ func testAnalyzers(t *testing.T, code string, analyzers ...*analysis.Analyzer) [
 		nil,
 	)
 
+	if setCustomConfigOptions != nil {
+		setCustomConfigOptions(config)
+	}
+
 	programs, err := analysis.Load(config, testLocation)
 	require.NoError(t, err)
 
diff --git a/lint/cadence_v1_analyzer.go b/lint/cadence_v1_analyzer.go
new file mode 100644
index 00000000..bfb9ae70
--- /dev/null
+++ b/lint/cadence_v1_analyzer.go
@@ -0,0 +1,349 @@
+/*
+ * Cadence-lint - The Cadence linter
+ *
+ * Copyright 2019-2022 Dapper Labs, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package lint
+
+import (
+	"fmt"
+
+	"github.com/onflow/cadence/runtime/ast"
+	"github.com/onflow/cadence/runtime/common"
+	"github.com/onflow/cadence/runtime/sema"
+	"github.com/onflow/cadence/tools/analysis"
+)
+
+type cadenceV1Analyzer struct {
+	program     *analysis.Program
+	elaboration *sema.Elaboration
+	report      func(analysis.Diagnostic)
+	inspector   *ast.Inspector
+}
+
+var CadenceV1Analyzer = (func() *analysis.Analyzer {
+	return &analysis.Analyzer{
+		Description: "Detects uses of removed features in Cadence 1.0",
+		Requires: []*analysis.Analyzer{
+			analysis.InspectorAnalyzer,
+		},
+		Run: func(pass *analysis.Pass) interface{} {
+			analyzer := newCadenceV1Analyzer(pass)
+			analyzer.AnalyzeAll()
+			return nil
+		},
+	}
+})()
+
+func init() {
+	RegisterAnalyzer(
+		"cadence-v1",
+		CadenceV1Analyzer,
+	)
+}
+
+func newCadenceV1Analyzer(pass *analysis.Pass) *cadenceV1Analyzer {
+	return &cadenceV1Analyzer{
+		program:     pass.Program,
+		elaboration: pass.Program.Checker.Elaboration,
+		report:      pass.Report,
+		inspector:   pass.ResultOf[analysis.InspectorAnalyzer].(*ast.Inspector),
+	}
+}
+
+func (v *cadenceV1Analyzer) AnalyzeAll() {
+	// Analyze account members removed in Cadence 1.0
+	v.analyzeRemovedAccountMembers()
+	// Analyze any type identifiers removed in Cadence 1.0
+	v.analyzeRemovedTypeIdentifiers()
+	// Analyze use of removed `destroy` function for resources
+	v.analyzeResourceDestructors()
+}
+
+func (v *cadenceV1Analyzer) analyzeRemovedAccountMembers() {
+	v.inspector.Preorder(
+		[]ast.Element{
+			(*ast.MemberExpression)(nil),
+		},
+		func(element ast.Element) {
+			memberExpression, ok := element.(*ast.MemberExpression)
+			if !ok {
+				return
+			}
+
+			memberInfo, _ := v.elaboration.MemberExpressionMemberAccessInfo(memberExpression)
+			unwrappedType := unwrapReferenceType(memberInfo.AccessedType)
+			if unwrappedType != sema.AccountType {
+				return
+			}
+
+			identifier := memberExpression.Identifier
+			switch identifier.String() {
+			// acct.save()
+			case "save":
+				v.newDiagnostic(
+					identifier,
+					"`save` has been replaced by the new Storage API.",
+					"C1.0-StorageAPI-Save",
+					"https://forum.flow.com/t/update-on-cadence-1-0/5197#account-access-got-improved-55",
+				).WithSimpleReplacement("storage.save").Report()
+
+			// acct.linkAccount()
+			case "linkAccount":
+				v.newDiagnostic(
+					identifier,
+					"`linkAccount` has been replaced by the Capability Controller API.",
+					"C1.0-StorageAPI-LinkAccount",
+					"https://forum.flow.com/t/update-on-cadence-1-0/5197#capability-controller-api-replaced-existing-linking-based-capability-api-82",
+				).Report()
+
+			// acct.link()
+			case "link":
+				v.newDiagnostic(
+					identifier,
+					"`link` has been replaced by the Capability Controller API.",
+					"C1.0-StorageAPI-Link",
+					"https://forum.flow.com/t/update-on-cadence-1-0/5197#capability-controller-api-replaced-existing-linking-based-capability-api-82",
+				).Report()
+
+			// acct.unlink()
+			case "unlink":
+				v.newDiagnostic(
+					identifier,
+					"`unlink` has been replaced by the Capability Controller API.",
+					"C1.0-StorageAPI-Unlink",
+					"https://forum.flow.com/t/update-on-cadence-1-0/5197#capability-controller-api-replaced-existing-linking-based-capability-api-82",
+				).Report()
+
+			// acct.getCapability<&A>()
+			case "getCapability":
+				v.newDiagnostic(
+					identifier,
+					"`getCapability` has been replaced by the Capability Controller API.",
+					"C1.0-CapabilityAPI-GetCapability",
+					"https://forum.flow.com/t/update-on-cadence-1-0/5197#capability-controller-api-replaced-existing-linking-based-capability-api-82",
+				).WithSimpleReplacement("capabilities.get").Report()
+
+			// acct.getLinkTarget()
+			case "getLinkTarget":
+				v.newDiagnostic(
+					identifier,
+					"`getLinkTarget` has been replaced by the Capability Controller API.",
+					"C1.0-CapabilityAPI-GetLinkTarget",
+					"https://forum.flow.com/t/update-on-cadence-1-0/5197#capability-controller-api-replaced-existing-linking-based-capability-api-82",
+				).Report()
+
+			// acct.addPublicKey()
+			case "addPublicKey":
+				v.newDiagnostic(
+					identifier,
+					"`addPublicKey` has been removed in favour of the new Key Management API. Please use `keys.add` instead.",
+					"C1.0-KeyAPI-AddPublicKey",
+					"https://forum.flow.com/t/update-on-cadence-1-0/5197#capability-controller-api-replaced-existing-linking-based-capability-api-82",
+				).Report()
+
+			// acct.removePublicKey()
+			case "removePublicKey":
+				v.newDiagnostic(
+					identifier,
+					"`removePublicKey` has been removed in favour of the new Key Management API.\nPlease use `keys.revoke` instead.",
+					"C1.0-KeyAPI-RemovePublicKey",
+					"https://forum.flow.com/t/update-on-cadence-1-0/5197#deprecated-key-management-api-got-removed-60",
+				).WithSimpleReplacement("keys.revoke").Report()
+			}
+		},
+	)
+}
+
+func (v *cadenceV1Analyzer) analyzeRemovedTypeIdentifiers() {
+	v.inspectTypeAnnotations(func(typeAnnotation *ast.TypeAnnotation) {
+		switch typeAnnotation.Type.String() {
+		case "AuthAccount":
+			v.
+				newDiagnostic(
+					typeAnnotation.Type,
+					"`AuthAccount` has been removed in Cadence 1.0.  Please use an authorized `&Account` reference with necessary entitlements instead.",
+					"C1.0-AuthAccount",
+					"https://forum.flow.com/t/update-on-cadence-1-0/5197#account-access-got-improved-55",
+				).
+				WithSimpleReplacement("&Account").
+				Report()
+		case "PublicAccount":
+			v.
+				newDiagnostic(
+					typeAnnotation.Type,
+					"`PublicAccount` has been removed in Cadence 1.0.  Please use an `&Account` reference instead.",
+					"C1.0-PublicAccount",
+					"https://forum.flow.com/t/update-on-cadence-1-0/5197#account-access-got-improved-55",
+				).
+				WithSimpleReplacement("&Account").
+				Report()
+		}
+	})
+}
+
+func (v *cadenceV1Analyzer) analyzeResourceDestructors() {
+	v.inspector.WithStack(
+		[]ast.Element{
+			(*ast.SpecialFunctionDeclaration)(nil),
+		},
+		func(element ast.Element, push bool, stack []ast.Element) bool {
+			declaration := element.(*ast.SpecialFunctionDeclaration)
+			if declaration.DeclarationIdentifier().Identifier != "destroy" {
+				return true
+			}
+
+			if len(stack) < 2 {
+				return true
+			}
+
+			parent, ok := stack[len(stack)-2].(*ast.CompositeDeclaration)
+			if !ok {
+				return true
+			}
+
+			if parent.Kind() != common.CompositeKindResource {
+				return true
+			}
+
+			v.reportRemovedResourceDestructor(declaration)
+			return false
+		},
+	)
+}
+
+func (v *cadenceV1Analyzer) reportRemovedResourceDestructor(
+	declaration *ast.SpecialFunctionDeclaration,
+) {
+	shouldSuggestRemoval := func() bool {
+		functionDeclaration := declaration.FunctionDeclaration
+		if !functionDeclaration.FunctionBlock.HasStatements() {
+			return true
+		}
+
+		for _, statement := range functionDeclaration.FunctionBlock.Block.Statements {
+			expressionStatement, ok := statement.(*ast.ExpressionStatement)
+			if !ok {
+				return false
+			}
+
+			if _, ok := expressionStatement.Expression.(*ast.DestroyExpression); !ok {
+				return false
+			}
+		}
+
+		return true
+	}
+
+	diagnostic := v.newDiagnostic(
+		declaration,
+		"`destroy` keyword has been removed.  Nested resources will now be implicitly destroyed with their parent.  A `ResourceDestroyed` event can be configured to be emitted to notify clients of the destruction.",
+		"C1.0-ResourceDestruction",
+		"https://forum.flow.com/t/update-on-cadence-1-0/5197#force-destruction-of-resources-101",
+	)
+
+	if shouldSuggestRemoval() {
+		diagnostic.WithSimpleReplacement("")
+	}
+	diagnostic.Report()
+}
+
+// Type annotations are not part of traversal, so we need to inspect them separately
+func (v *cadenceV1Analyzer) inspectTypeAnnotations(f func(typeAnnotation *ast.TypeAnnotation)) {
+	// Filter out nil type annotations
+	var processAnnotation func(annotation *ast.TypeAnnotation)
+	processAnnotation = func(annotation *ast.TypeAnnotation) {
+		if annotation == nil {
+			return
+		}
+
+		switch t := annotation.Type.(type) {
+		case *ast.InstantiationType:
+			// We need to process the type arguments of an instantiation type
+			for _, typeArgument := range t.TypeArguments {
+				processAnnotation(typeArgument)
+			}
+		}
+
+		f(annotation)
+	}
+
+	// Helper function to process a parameter list
+	processParameterList := func(parameterList *ast.ParameterList) {
+		for _, parameter := range parameterList.Parameters {
+			processAnnotation(parameter.TypeAnnotation)
+		}
+	}
+
+	v.inspector.Preorder(
+		[]ast.Element{
+			(*ast.FieldDeclaration)(nil),
+			(*ast.FunctionExpression)(nil),
+			(*ast.CastingExpression)(nil),
+			(*ast.FunctionDeclaration)(nil),
+			(*ast.TransactionDeclaration)(nil),
+			(*ast.VariableDeclaration)(nil),
+			(*ast.SpecialFunctionDeclaration)(nil),
+			(*ast.InvocationExpression)(nil),
+		},
+		func(element ast.Element) {
+			switch declaration := element.(type) {
+			case *ast.FieldDeclaration:
+				processAnnotation(declaration.TypeAnnotation)
+			case *ast.FunctionExpression:
+				processAnnotation(declaration.ReturnTypeAnnotation)
+				processParameterList(declaration.ParameterList)
+			case *ast.CastingExpression:
+				processAnnotation(declaration.TypeAnnotation)
+			case *ast.FunctionDeclaration:
+				processAnnotation(declaration.ReturnTypeAnnotation)
+				processParameterList(declaration.ParameterList)
+			case *ast.TransactionDeclaration:
+				processParameterList(declaration.ParameterList)
+			case *ast.VariableDeclaration:
+				processAnnotation(declaration.TypeAnnotation)
+			case *ast.SpecialFunctionDeclaration:
+				processParameterList(declaration.FunctionDeclaration.ParameterList)
+			case *ast.InvocationExpression:
+				for _, argument := range declaration.TypeArguments {
+					processAnnotation(argument)
+				}
+			}
+		},
+	)
+}
+
+func (v *cadenceV1Analyzer) newDiagnostic(
+	position ast.HasPosition,
+	message string,
+	code string,
+	docURL string,
+) *diagnostic {
+	return newDiagnostic(
+		v.program.Location,
+		v.report,
+		fmt.Sprintf("[Cadence 1.0] %s", message),
+		ast.NewRangeFromPositioned(nil, position),
+	).WithCode(code).WithURL(docURL).WithCategory(CadenceV1Category)
+}
+
+// Helpers
+func unwrapReferenceType(t sema.Type) sema.Type {
+	if refType, ok := t.(*sema.ReferenceType); ok {
+		return refType.Type
+	}
+	return t
+}
diff --git a/lint/cadence_v1_analyzer_test.go b/lint/cadence_v1_analyzer_test.go
new file mode 100644
index 00000000..d488e12c
--- /dev/null
+++ b/lint/cadence_v1_analyzer_test.go
@@ -0,0 +1,689 @@
+/*
+ * Cadence-lint - The Cadence linter
+ *
+ * Copyright 2019-2022 Dapper Labs, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package lint_test
+
+import (
+	"testing"
+
+	"github.com/stretchr/testify/require"
+
+	"github.com/onflow/cadence/runtime/ast"
+	"github.com/onflow/cadence/runtime/errors"
+	"github.com/onflow/cadence/runtime/parser"
+	"github.com/onflow/cadence/runtime/sema"
+	"github.com/onflow/cadence/tools/analysis"
+
+	"github.com/onflow/cadence-tools/lint"
+)
+
+func TestCadenceV1Analyzer(t *testing.T) {
+
+	t.Parallel()
+
+	t.Run("account.save()", func(t *testing.T) {
+
+		t.Parallel()
+
+		diagnostics, err := testAnalyzersWithCheckerError(t,
+			`
+			access(all) contract Test {
+				init() {
+					self.account.save()
+				}
+			}
+			`,
+			lint.CadenceV1Analyzer,
+		)
+
+		var notDeclaredMemberError *sema.NotDeclaredMemberError
+		require.ErrorAs(t, err, &notDeclaredMemberError)
+
+		require.Equal(
+			t,
+			[]analysis.Diagnostic{
+				{
+					Location: testLocation,
+					Category: lint.CadenceV1Category,
+					Message:  "[Cadence 1.0] `save` has been replaced by the new Storage API.",
+					Code:     "C1.0-StorageAPI-Save",
+					URL:      "https://forum.flow.com/t/update-on-cadence-1-0/5197#account-access-got-improved-55",
+					SuggestedFixes: []analysis.SuggestedFix{
+						{
+							Message: "Replace with `storage.save`",
+							TextEdits: []ast.TextEdit{
+								{
+									Replacement: "storage.save",
+									Insertion:   "",
+									Range: ast.Range{
+										StartPos: ast.Position{
+											Offset: 63,
+											Line:   4,
+											Column: 18,
+										},
+										EndPos: ast.Position{
+											Offset: 66,
+											Line:   4,
+											Column: 21,
+										},
+									},
+								},
+							},
+						},
+					},
+					Range: ast.Range{
+						StartPos: ast.Position{
+							Offset: 63,
+							Line:   4,
+							Column: 18,
+						},
+						EndPos: ast.Position{
+							Offset: 66,
+							Line:   4,
+							Column: 21,
+						},
+					},
+				}},
+			diagnostics,
+		)
+	})
+
+	t.Run("account.linkAccount()", func(t *testing.T) {
+
+		t.Parallel()
+
+		diagnostics, err := testAnalyzersWithCheckerError(t,
+			`
+			access(all) contract Test {
+				init() {
+					self.account.linkAccount()
+				}
+			}
+			`,
+			lint.CadenceV1Analyzer,
+		)
+
+		var notDeclaredMemberError *sema.NotDeclaredMemberError
+		require.ErrorAs(t, err, &notDeclaredMemberError)
+
+		require.Equal(
+			t,
+			[]analysis.Diagnostic{
+				{
+					Location:       testLocation,
+					Category:       lint.CadenceV1Category,
+					Message:        "[Cadence 1.0] `linkAccount` has been replaced by the Capability Controller API.",
+					Code:           "C1.0-StorageAPI-LinkAccount",
+					URL:            "https://forum.flow.com/t/update-on-cadence-1-0/5197#capability-controller-api-replaced-existing-linking-based-capability-api-82",
+					SuggestedFixes: []analysis.SuggestedFix{},
+					Range: ast.Range{
+						StartPos: ast.Position{
+							Offset: 63,
+							Line:   4,
+							Column: 18,
+						},
+						EndPos: ast.Position{
+							Offset: 73,
+							Line:   4,
+							Column: 28,
+						},
+					},
+				}},
+			diagnostics,
+		)
+	})
+
+	t.Run("account.link()", func(t *testing.T) {
+
+		t.Parallel()
+
+		diagnostics, err := testAnalyzersWithCheckerError(t,
+			`
+			access(all) contract Test {
+				init() {
+					self.account.link()
+				}
+			}
+			`,
+			lint.CadenceV1Analyzer,
+		)
+
+		var notDeclaredMemberError *sema.NotDeclaredMemberError
+		require.ErrorAs(t, err, &notDeclaredMemberError)
+
+		require.Equal(
+			t,
+			[]analysis.Diagnostic{
+				{
+					Location:       testLocation,
+					Category:       lint.CadenceV1Category,
+					Message:        "[Cadence 1.0] `link` has been replaced by the Capability Controller API.",
+					Code:           "C1.0-StorageAPI-Link",
+					URL:            "https://forum.flow.com/t/update-on-cadence-1-0/5197#capability-controller-api-replaced-existing-linking-based-capability-api-82",
+					SuggestedFixes: []analysis.SuggestedFix{},
+					Range: ast.Range{
+						StartPos: ast.Position{
+							Offset: 63,
+							Line:   4,
+							Column: 18,
+						},
+						EndPos: ast.Position{
+							Offset: 66,
+							Line:   4,
+							Column: 21,
+						},
+					},
+				},
+			},
+			diagnostics,
+		)
+	})
+
+	t.Run("account.unlink()", func(t *testing.T) {
+		t.Parallel()
+
+		diagnostics, err := testAnalyzersWithCheckerError(t,
+			`
+			access(all) contract Test {
+				init() {
+					self.account.unlink()
+				}
+			}
+			`,
+			lint.CadenceV1Analyzer,
+		)
+
+		var notDeclaredMemberError *sema.NotDeclaredMemberError
+		require.ErrorAs(t, err, &notDeclaredMemberError)
+
+		require.Equal(
+			t,
+			[]analysis.Diagnostic{
+				{
+					Location:       testLocation,
+					Category:       lint.CadenceV1Category,
+					Message:        "[Cadence 1.0] `unlink` has been replaced by the Capability Controller API.",
+					Code:           "C1.0-StorageAPI-Unlink",
+					URL:            "https://forum.flow.com/t/update-on-cadence-1-0/5197#capability-controller-api-replaced-existing-linking-based-capability-api-82",
+					SuggestedFixes: []analysis.SuggestedFix{},
+					Range: ast.Range{
+						StartPos: ast.Position{
+							Offset: 63,
+							Line:   4,
+							Column: 18,
+						},
+						EndPos: ast.Position{
+							Offset: 68,
+							Line:   4,
+							Column: 23,
+						},
+					},
+				},
+			},
+			diagnostics,
+		)
+	})
+
+	t.Run("account.getCapability()", func(t *testing.T) {
+		t.Parallel()
+
+		diagnostics, err := testAnalyzersWithCheckerError(t,
+			`
+			access(all) contract Test {
+				init() {
+					self.account.getCapability()
+				}
+			}
+			`,
+			lint.CadenceV1Analyzer,
+		)
+
+		var notDeclaredMemberError *sema.NotDeclaredMemberError
+		require.ErrorAs(t, err, &notDeclaredMemberError)
+
+		require.Equal(
+			t,
+			[]analysis.Diagnostic{
+				{
+					Location: testLocation,
+					Category: lint.CadenceV1Category,
+					Message:  "[Cadence 1.0] `getCapability` has been replaced by the Capability Controller API.",
+					Code:     "C1.0-CapabilityAPI-GetCapability",
+					URL:      "https://forum.flow.com/t/update-on-cadence-1-0/5197#capability-controller-api-replaced-existing-linking-based-capability-api-82",
+					SuggestedFixes: []analysis.SuggestedFix{
+						{
+							Message: "Replace with `capabilities.get`",
+							TextEdits: []ast.TextEdit{
+								{
+									Replacement: "capabilities.get",
+									Insertion:   "",
+									Range: ast.Range{
+										StartPos: ast.Position{
+											Offset: 63,
+											Line:   4,
+											Column: 18,
+										},
+										EndPos: ast.Position{
+											Offset: 75,
+											Line:   4,
+											Column: 30,
+										},
+									},
+								},
+							},
+						},
+					},
+					Range: ast.Range{
+						StartPos: ast.Position{
+							Offset: 63,
+							Line:   4,
+							Column: 18,
+						},
+						EndPos: ast.Position{
+							Offset: 75,
+							Line:   4,
+							Column: 30,
+						},
+					},
+				},
+			},
+			diagnostics,
+		)
+	})
+
+	t.Run("account.getLinkTarget()", func(t *testing.T) {
+		t.Parallel()
+
+		diagnostics, err := testAnalyzersWithCheckerError(t,
+			`
+			access(all) contract Test {
+				init() {
+					self.account.getLinkTarget()
+				}
+			}
+			`,
+			lint.CadenceV1Analyzer,
+		)
+
+		var notDeclaredMemberError *sema.NotDeclaredMemberError
+		require.ErrorAs(t, err, &notDeclaredMemberError)
+
+		require.Equal(
+			t,
+			[]analysis.Diagnostic{
+				{
+					Location:       testLocation,
+					Category:       lint.CadenceV1Category,
+					Message:        "[Cadence 1.0] `getLinkTarget` has been replaced by the Capability Controller API.",
+					Code:           "C1.0-CapabilityAPI-GetLinkTarget",
+					URL:            "https://forum.flow.com/t/update-on-cadence-1-0/5197#capability-controller-api-replaced-existing-linking-based-capability-api-82",
+					SuggestedFixes: []analysis.SuggestedFix{},
+					Range: ast.Range{
+						StartPos: ast.Position{
+							Offset: 63,
+							Line:   4,
+							Column: 18,
+						},
+						EndPos: ast.Position{
+							Offset: 75,
+							Line:   4,
+							Column: 30,
+						},
+					},
+				},
+			},
+			diagnostics,
+		)
+	})
+
+	t.Run("account.addPublicKey()", func(t *testing.T) {
+		t.Parallel()
+
+		diagnostics, err := testAnalyzersWithCheckerError(t,
+			`
+			access(all) contract Test {
+				init() {
+					self.account.addPublicKey()
+				}
+			}
+			`,
+			lint.CadenceV1Analyzer,
+		)
+
+		var notDeclaredMemberError *sema.NotDeclaredMemberError
+		require.ErrorAs(t, err, &notDeclaredMemberError)
+
+		require.Equal(
+			t,
+			[]analysis.Diagnostic{
+				{
+					Location:       testLocation,
+					Category:       lint.CadenceV1Category,
+					Message:        "[Cadence 1.0] `addPublicKey` has been removed in favour of the new Key Management API. Please use `keys.add` instead.",
+					Code:           "C1.0-KeyAPI-AddPublicKey",
+					URL:            "https://forum.flow.com/t/update-on-cadence-1-0/5197#capability-controller-api-replaced-existing-linking-based-capability-api-82",
+					SuggestedFixes: []analysis.SuggestedFix{},
+					Range: ast.Range{
+						StartPos: ast.Position{
+							Offset: 63,
+							Line:   4,
+							Column: 18,
+						},
+						EndPos: ast.Position{
+							Offset: 74,
+							Line:   4,
+							Column: 29,
+						},
+					},
+				},
+			}, diagnostics,
+		)
+	})
+
+	t.Run("account.removePublicKey()", func(t *testing.T) {
+		t.Parallel()
+
+		diagnostics, err := testAnalyzersWithCheckerError(t,
+			`
+			access(all) contract Test {
+				init() {
+					self.account.removePublicKey()
+				}
+			}
+			`,
+			lint.CadenceV1Analyzer,
+		)
+
+		var notDeclaredMemberError *sema.NotDeclaredMemberError
+		require.ErrorAs(t, err, &notDeclaredMemberError)
+
+		require.Equal(
+			t,
+			[]analysis.Diagnostic{
+				{
+					Location: testLocation,
+					Category: lint.CadenceV1Category,
+					Message:  "[Cadence 1.0] `removePublicKey` has been removed in favour of the new Key Management API.\nPlease use `keys.revoke` instead.",
+					Code:     "C1.0-KeyAPI-RemovePublicKey",
+					URL:      "https://forum.flow.com/t/update-on-cadence-1-0/5197#deprecated-key-management-api-got-removed-60",
+					SuggestedFixes: []analysis.SuggestedFix{
+						{
+							Message: "Replace with `keys.revoke`",
+							TextEdits: []ast.TextEdit{
+								{
+									Replacement: "keys.revoke",
+									Insertion:   "",
+									Range: ast.Range{
+										StartPos: ast.Position{
+											Offset: 63,
+											Line:   4,
+											Column: 18,
+										},
+										EndPos: ast.Position{
+											Offset: 77,
+											Line:   4,
+											Column: 32,
+										},
+									},
+								},
+							},
+						},
+					},
+					Range: ast.Range{
+						StartPos: ast.Position{
+							Offset: 63,
+							Line:   4,
+							Column: 18,
+						},
+						EndPos: ast.Position{
+							Offset: 77,
+							Line:   4,
+							Column: 32,
+						},
+					},
+				}},
+			diagnostics,
+		)
+	})
+
+	t.Run("resource destruction", func(t *testing.T) {
+		t.Parallel()
+
+		var checkerErr *sema.CheckerError
+		var parserError errors.ParentError
+		diagnostics := testAnalyzersAdvanced(t,
+			`
+			access(all) contract Test {
+				access(all) resource R {
+					init() {}
+					destroy() {
+						// i'm bad :)
+					}
+				}
+				init() {}
+			}
+			`,
+			func(config *analysis.Config) {
+				config.HandleCheckerError = func(err analysis.ParsingCheckingError, checker *sema.Checker) error {
+					require.Equal(t, err.ImportLocation(), testLocation)
+					require.NotNil(t, checker)
+					require.ErrorAs(t, err, &checkerErr)
+					return nil
+				}
+				config.HandleParserError = func(err analysis.ParsingCheckingError, program *ast.Program) error {
+					require.Equal(t, err.ImportLocation(), testLocation)
+					require.ErrorAs(t, err, &parserError)
+					return nil
+				}
+			},
+			lint.CadenceV1Analyzer,
+		)
+
+		// Ensure that the checker error and parser error exist
+		require.NotNil(t, checkerErr)
+		require.NotNil(t, parserError)
+
+		// Ensure that the checker error is of the correct type
+		var unknownSpecialFunctionError *sema.UnknownSpecialFunctionError
+		require.Len(t, checkerErr.ChildErrors(), 1)
+		require.ErrorAs(t, checkerErr, &unknownSpecialFunctionError)
+
+		// Ensure that the parser error is of the correct type
+		var invalidDestructorError *parser.CustomDestructorError
+		require.Len(t, parserError.ChildErrors(), 1)
+		require.ErrorAs(t, parserError, &invalidDestructorError)
+
+		require.Equal(
+			t,
+			[]analysis.Diagnostic{
+				{
+					Location: testLocation,
+					Category: lint.CadenceV1Category,
+					Message:  "[Cadence 1.0] `destroy` keyword has been removed.  Nested resources will now be implicitly destroyed with their parent.  A `ResourceDestroyed` event can be configured to be emitted to notify clients of the destruction.",
+					Code:     "C1.0-ResourceDestruction",
+					URL:      "https://forum.flow.com/t/update-on-cadence-1-0/5197#force-destruction-of-resources-101",
+					SuggestedFixes: []analysis.SuggestedFix{
+						{
+							Message: "Remove code",
+							TextEdits: []ast.TextEdit{
+								{
+									Replacement: "",
+									Insertion:   "",
+									Range: ast.Range{
+										StartPos: ast.Position{
+											Offset: 81,
+											Line:   5,
+											Column: 5,
+										},
+										EndPos: ast.Position{
+											Offset: 118,
+											Line:   7,
+											Column: 5,
+										},
+									},
+								},
+							},
+						},
+					},
+					Range: ast.Range{
+						StartPos: ast.Position{
+							Offset: 81,
+							Line:   5,
+							Column: 5,
+						},
+						EndPos: ast.Position{
+							Offset: 118,
+							Line:   7,
+							Column: 5,
+						},
+					},
+				},
+			},
+			diagnostics,
+		)
+	})
+
+	t.Run("AuthAccount type", func(t *testing.T) {
+		t.Parallel()
+
+		var notDeclaredError *sema.NotDeclaredError
+		diagnostics, checkerErr := testAnalyzersWithCheckerError(t,
+			`
+			transaction () {
+				prepare(signer: AuthAccount) {}
+			}
+			`,
+			lint.CadenceV1Analyzer,
+		)
+		require.ErrorAs(t, checkerErr, &notDeclaredError)
+
+		require.Equal(
+			t,
+			[]analysis.Diagnostic{
+				{
+					Location: testLocation,
+					Category: lint.CadenceV1Category,
+					Message:  "[Cadence 1.0] `AuthAccount` has been removed in Cadence 1.0.  Please use an authorized `&Account` reference with necessary entitlements instead.",
+					Code:     "C1.0-AuthAccount",
+					URL:      "https://forum.flow.com/t/update-on-cadence-1-0/5197#account-access-got-improved-55",
+					SuggestedFixes: []analysis.SuggestedFix{
+						{
+							Message: "Replace with `&Account`",
+							TextEdits: []ast.TextEdit{
+								{
+									Replacement: "&Account",
+									Insertion:   "",
+									Range: ast.Range{
+										StartPos: ast.Position{
+											Offset: 41,
+											Line:   3,
+											Column: 20,
+										},
+										EndPos: ast.Position{
+											Offset: 51,
+											Line:   3,
+											Column: 30,
+										},
+									},
+								},
+							},
+						},
+					},
+					Range: ast.Range{
+						StartPos: ast.Position{
+							Offset: 41,
+							Line:   3,
+							Column: 20,
+						},
+						EndPos: ast.Position{
+							Offset: 51,
+							Line:   3,
+							Column: 30,
+						},
+					},
+				},
+			},
+			diagnostics,
+		)
+	})
+
+	t.Run("PublicAccount type", func(t *testing.T) {
+		t.Parallel()
+
+		diagnostics, err := testAnalyzersWithCheckerError(t,
+			`
+			access(all) fun main(addr: Address) {
+				let account: PublicAccount = getAccount(addr)
+			}
+			`,
+			lint.CadenceV1Analyzer,
+		)
+
+		var notDeclaredError *sema.NotDeclaredError
+		require.ErrorAs(t, err, &notDeclaredError)
+
+		require.Equal(
+			t,
+			[]analysis.Diagnostic{
+				{
+					Location: testLocation,
+					Category: lint.CadenceV1Category,
+					Message:  "[Cadence 1.0] `PublicAccount` has been removed in Cadence 1.0.  Please use an `&Account` reference instead.",
+					Code:     "C1.0-PublicAccount",
+					URL:      "https://forum.flow.com/t/update-on-cadence-1-0/5197#account-access-got-improved-55",
+					SuggestedFixes: []analysis.SuggestedFix{
+						{
+							Message: "Replace with `&Account`",
+							TextEdits: []ast.TextEdit{
+								{
+									Replacement: "&Account",
+									Insertion:   "",
+									Range: ast.Range{
+										StartPos: ast.Position{
+											Offset: 59,
+											Line:   3,
+											Column: 17,
+										},
+										EndPos: ast.Position{
+											Offset: 71,
+											Line:   3,
+											Column: 29,
+										},
+									},
+								},
+							},
+						},
+					},
+					Range: ast.Range{
+						StartPos: ast.Position{
+							Offset: 59,
+							Line:   3,
+							Column: 17,
+						},
+						EndPos: ast.Position{
+							Offset: 71,
+							Line:   3,
+							Column: 29,
+						},
+					},
+				},
+			},
+			diagnostics,
+		)
+	})
+}
diff --git a/lint/diagnostic.go b/lint/diagnostic.go
new file mode 100644
index 00000000..ce815247
--- /dev/null
+++ b/lint/diagnostic.go
@@ -0,0 +1,86 @@
+/*
+ * Cadence-lint - The Cadence linter
+ *
+ * Copyright 2019-2022 Dapper Labs, Inc.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package lint
+
+import (
+	"github.com/onflow/cadence/runtime/ast"
+	"github.com/onflow/cadence/runtime/common"
+	"github.com/onflow/cadence/tools/analysis"
+)
+
+type diagnostic struct {
+	diagnostic analysis.Diagnostic
+	report     func(analysis.Diagnostic)
+}
+
+func newDiagnostic(
+	location common.Location,
+	report func(analysis.Diagnostic),
+	message string,
+	position ast.Range,
+) *diagnostic {
+	return &diagnostic{
+		diagnostic: analysis.Diagnostic{
+			Location:       location,
+			SuggestedFixes: []analysis.SuggestedFix{},
+			Range:          position,
+			Message:        message,
+		},
+		report: report,
+	}
+}
+
+func (d *diagnostic) WithCode(code string) *diagnostic {
+	d.diagnostic.Code = code
+	return d
+}
+
+func (d *diagnostic) WithURL(url string) *diagnostic {
+	d.diagnostic.URL = url
+	return d
+}
+
+func (d *diagnostic) WithCategory(category string) *diagnostic {
+	d.diagnostic.Category = category
+	return d
+}
+
+func (d *diagnostic) WithSimpleReplacement(replacement string) *diagnostic {
+	message := "Replace with `" + replacement + "`"
+	if replacement == "" {
+		message = "Remove code"
+	}
+
+	suggestedFix := analysis.SuggestedFix{
+		Message: message,
+		TextEdits: []ast.TextEdit{
+			{
+				Range:       ast.NewRangeFromPositioned(nil, d.diagnostic.Range),
+				Replacement: replacement,
+			},
+		},
+	}
+
+	d.diagnostic.SuggestedFixes = append(d.diagnostic.SuggestedFixes, suggestedFix)
+	return d
+}
+
+func (d *diagnostic) Report() {
+	d.report(d.diagnostic)
+}