diff --git a/frontend/src/metabase/App.jsx b/frontend/src/metabase/App.jsx
index a35f4d951010de50ab4f0468dea7b685b58e6d78..d80a693f399ca7341dfa214aa703600d1cdaa253 100644
--- a/frontend/src/metabase/App.jsx
+++ b/frontend/src/metabase/App.jsx
@@ -13,3 +13,4 @@ export default class App extends Component {
         )
     }
 }
+
diff --git a/frontend/src/metabase/admin/datamodel/containers/MetricApp.jsx b/frontend/src/metabase/admin/datamodel/containers/MetricApp.jsx
index a1ac509f7a9e53448137928c268958065f390fe2..1987225464b21ef4c06e5f9e7417ee1ba43c0e01 100644
--- a/frontend/src/metabase/admin/datamodel/containers/MetricApp.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/MetricApp.jsx
@@ -8,9 +8,11 @@ import MetricForm from "./MetricForm.jsx";
 
 import { metricEditSelectors } from "../selectors";
 import * as actions from "../metadata";
+import { clearRequestState } from "metabase/redux/requests";
 
 const mapDispatchToProps = {
     ...actions,
+    clearRequestState,
     onChangeLocation: push
 };
 
@@ -37,9 +39,11 @@ export default class MetricApp extends Component {
         let { tableMetadata } = this.props;
         if (metric.id != null) {
             await this.props.updateMetric(metric);
+            this.props.clearRequestState({statePath: ['metadata', 'metrics']});
             MetabaseAnalytics.trackEvent("Data Model", "Metric Updated");
         } else {
             await this.props.createMetric(metric);
+            this.props.clearRequestState({statePath: ['metadata', 'metrics']});
             MetabaseAnalytics.trackEvent("Data Model", "Metric Created");
         }
 
diff --git a/frontend/src/metabase/admin/datamodel/containers/SegmentApp.jsx b/frontend/src/metabase/admin/datamodel/containers/SegmentApp.jsx
index 7903451caf57d270b8331647494ffd0fdd857fb0..c751b87bc981e66d14ef3546eb068f85c3e8c349 100644
--- a/frontend/src/metabase/admin/datamodel/containers/SegmentApp.jsx
+++ b/frontend/src/metabase/admin/datamodel/containers/SegmentApp.jsx
@@ -8,9 +8,11 @@ import SegmentForm from "./SegmentForm.jsx";
 
 import { segmentEditSelectors } from "../selectors";
 import * as actions from "../metadata";
+import { clearRequestState } from "metabase/redux/requests";
 
 const mapDispatchToProps = {
     ...actions,
+    clearRequestState,
     onChangeLocation: push
 };
 
@@ -37,9 +39,11 @@ export default class SegmentApp extends Component {
         let { tableMetadata } = this.props;
         if (segment.id != null) {
             await this.props.updateSegment(segment);
+            this.props.clearRequestState({statePath: ['metadata', 'segments']});
             MetabaseAnalytics.trackEvent("Data Model", "Segment Updated");
         } else {
             await this.props.createSegment(segment);
+            this.props.clearRequestState({statePath: ['metadata', 'segments']});
             MetabaseAnalytics.trackEvent("Data Model", "Segment Created");
         }
 
diff --git a/frontend/src/metabase/components/AccordianList.jsx b/frontend/src/metabase/components/AccordianList.jsx
index 3d1c30aae02a55b7bb2b7f34fcf27480d238cf8e..d43753c45399b6e4661df71a972ebc22d9fe6ec5 100644
--- a/frontend/src/metabase/components/AccordianList.jsx
+++ b/frontend/src/metabase/components/AccordianList.jsx
@@ -41,6 +41,7 @@ export default class AccordianList extends Component {
         onChange: PropTypes.func,
         onChangeSection: PropTypes.func,
         itemIsSelected: PropTypes.func,
+        itemIsClickable: PropTypes.func,
         renderItem: PropTypes.func,
         renderSectionIcon: PropTypes.func,
         getItemClasses: PropTypes.func,
@@ -101,6 +102,14 @@ export default class AccordianList extends Component {
         return selectedSection === sectionIndex;
     }
 
+    itemIsClickable(item) {
+        if (this.props.itemIsClickable) {
+            return this.props.itemIsClickable(item);
+        } else {
+            return true;
+        }
+    }
+
     itemIsSelected(item) {
         if (this.props.itemIsSelected) {
             return this.props.itemIsSelected(item);
@@ -144,7 +153,7 @@ export default class AccordianList extends Component {
     }
 
     render() {
-        const { searchable, sections, showItemArrows, alwaysTogglable, alwaysExpanded, hideSingleSectionTitle, style } = this.props;
+        const { searchable, searchPlaceholder, sections, showItemArrows, alwaysTogglable, alwaysExpanded, hideSingleSectionTitle, style } = this.props;
         const { searchText } = this.state;
 
         const openSection = this.getOpenSection();
@@ -188,6 +197,7 @@ export default class AccordianList extends Component {
                                     <ListSearchField
                                         onChange={(val) => this.setState({searchText: val})}
                                         searchText={this.state.searchText}
+                                        placeholder={searchPlaceholder}
                                     />
                                 </div>
                             </div>
@@ -199,11 +209,11 @@ export default class AccordianList extends Component {
                                 className={cx("p1", { "border-bottom scroll-y scroll-show": !alwaysExpanded })}
                             >
                                 { section.items.filter((i) => searchText ? (i.name.toLowerCase().includes(searchText.toLowerCase())) : true ).map((item, itemIndex) =>
-                                    <li key={itemIndex} className={cx("List-item flex", { 'List-item--selected': this.itemIsSelected(item, itemIndex) }, this.getItemClasses(item, itemIndex))}>
+                                    <li key={itemIndex} className={cx("List-item flex", { 'List-item--selected': this.itemIsSelected(item, itemIndex), 'List-item--disabled': !this.itemIsClickable(item) }, this.getItemClasses(item, itemIndex))}>
                                         <a
-                                            className="flex-full flex align-center px1 cursor-pointer"
+                                            className={cx("flex-full flex align-center px1", this.itemIsClickable(item) ? "cursor-pointer" : "cursor-default")}
                                             style={{ paddingTop: "0.25rem", paddingBottom: "0.25rem" }}
-                                            onClick={this.onChange.bind(this, item)}
+                                            onClick={this.itemIsClickable(item) && this.onChange.bind(this, item)}
                                         >
                                             { this.renderItemIcon(item, itemIndex) }
                                             <h4 className="List-item-title ml2">{item.name}</h4>
diff --git a/frontend/src/metabase/components/ColumnarSelector.css b/frontend/src/metabase/components/ColumnarSelector.css
index 431b64226461aaa365e375332c9e0db8fa6f5031..450c587f3a48150229d9e790d0500c7dfba2ce69 100644
--- a/frontend/src/metabase/components/ColumnarSelector.css
+++ b/frontend/src/metabase/components/ColumnarSelector.css
@@ -44,12 +44,12 @@
     align-items: center;
 }
 
-.ColumnarSelector-row:hover {
+.ColumnarSelector-row:not(.ColumnarSelector-row--disabled):hover {
     background-color: var(--brand-color) !important;
     color: white !important;
 }
 
-.ColumnarSelector-row:hover .ColumnarSelector-description {
+.ColumnarSelector-row:not(.ColumnarSelector-row--disabled):hover .ColumnarSelector-description {
     color: rgba(255,255,255,0.50);
 }
 
@@ -60,6 +60,10 @@
     border-bottom: var(--border-size) var(--border-style) var(--border-color);
 }
 
+.ColumnarSelector-row--disabled {
+    color: var(--grey-3);
+}
+
 .ColumnarSelector-row .Icon-check {
     margin-right: var(--margin-2);
     visibility: hidden;
diff --git a/frontend/src/metabase/components/ColumnarSelector.jsx b/frontend/src/metabase/components/ColumnarSelector.jsx
index 77bd8914753d3613c703ed6956b13738951a0cd8..c6ccb0e23ed498e898683c744ea57080f1441902 100644
--- a/frontend/src/metabase/components/ColumnarSelector.jsx
+++ b/frontend/src/metabase/components/ColumnarSelector.jsx
@@ -12,6 +12,10 @@ export default class ColumnarSelector extends Component {
     };
 
     render() {
+        const isItemSelected = (item, column) => column.selectedItems ?
+            column.selectedItems.includes(item) :
+            column.selectedItem === item; 
+
         var columns = this.props.columns.map((column, columnIndex) => {
             var sectionElements;
             if (column) {
@@ -22,9 +26,11 @@ export default class ColumnarSelector extends Component {
                     var items = section.items.map((item, rowIndex) => {
                         var itemClasses = cx({
                             'ColumnarSelector-row': true,
-                            'ColumnarSelector-row--selected': item === column.selectedItem,
+                            'ColumnarSelector-row--selected': isItemSelected(item, column),
+                            'ColumnarSelector-row--disabled': column.disabledOptionIds.includes(item.id),
                             'flex': true,
-                            'no-decoration': true
+                            'no-decoration': true,
+                            'cursor-default': column.disabledOptionIds.includes(item.id)
                         });
                         var checkIcon = lastColumn ? <Icon name="check" size={14}/> : null;
                         var descriptionElement;
@@ -34,7 +40,7 @@ export default class ColumnarSelector extends Component {
                         }
                         return (
                             <li key={rowIndex}>
-                                <a className={itemClasses} onClick={column.itemSelectFn.bind(null, item)}>
+                                <a className={itemClasses} onClick={!column.disabledOptionIds.includes(item.id) && column.itemSelectFn.bind(null, item)}>
                                     {checkIcon}
                                     <div className="flex flex-column">
                                         {column.itemTitleFn(item)}
diff --git a/frontend/src/metabase/components/List.css b/frontend/src/metabase/components/List.css
index f4fe3be6cc727e2ad2d35422b6d490cc9777be03..b90fb3425882a78356b384da05a5ff2816e8aa5c 100644
--- a/frontend/src/metabase/components/List.css
+++ b/frontend/src/metabase/components/List.css
@@ -36,7 +36,7 @@
 }
 
 :local(.headerLink) {
-    composes: text-brand ml2 from "style";
+    composes: text-brand ml2 flex-no-shrink from "style";
     font-size: 14px;
 }
 
diff --git a/frontend/src/metabase/components/Select.jsx b/frontend/src/metabase/components/Select.jsx
index 4038bd1fe20685ab42caff6b1d1c015d6f37454c..720ac18b2309033e780dc36db3d6ca450c889773 100644
--- a/frontend/src/metabase/components/Select.jsx
+++ b/frontend/src/metabase/components/Select.jsx
@@ -145,19 +145,25 @@ export class Option extends Component {
 class LegacySelect extends Component {
     static propTypes = {
         value: PropTypes.any,
+        values: PropTypes.array,
         options: PropTypes.array.isRequired,
+        disabledOptionIds: PropTypes.array, 
         placeholder: PropTypes.string,
+        emptyPlaceholder: PropTypes.string,
         onChange: PropTypes.func,
         optionNameFn: PropTypes.func,
         optionValueFn: PropTypes.func,
         className: PropTypes.string,
         isInitiallyOpen: PropTypes.bool,
+        disabled: PropTypes.bool,
         //TODO: clean up hardcoded "AdminSelect" class on trigger to avoid this workaround
         triggerClasses: PropTypes.string
     };
 
     static defaultProps = {
         placeholder: "",
+        emptyPlaceholder: "Nothing to select",
+        disabledOptionIds: [],
         optionNameFn: (option) => option.name,
         optionValueFn: (option) => option,
         isInitiallyOpen: false,
@@ -168,13 +174,23 @@ class LegacySelect extends Component {
     }
 
     render() {
-        const { className, value, onChange, options, optionNameFn, optionValueFn, placeholder, isInitiallyOpen } = this.props;
+        const { className, value, values, onChange, options, disabledOptionIds, optionNameFn, optionValueFn, placeholder, emptyPlaceholder, isInitiallyOpen, disabled } = this.props;
 
-        var selectedName = value ? optionNameFn(value) : placeholder;
+        var selectedName = value ? 
+            optionNameFn(value) : 
+            options && options.length > 0 ? 
+                placeholder : 
+                emptyPlaceholder;
 
         var triggerElement = (
-            <div className={"flex align-center " + (!value ? " text-grey-3" : "")}>
-                <span className="mr1">{selectedName}</span>
+            <div className={cx("flex align-center", !value && (!values || values.length === 0) ? " text-grey-2" : "")}>
+                { values && values.length !== 0 ?
+                    values
+                        .map(value => optionNameFn(value))
+                        .sort()
+                        .map((name, index) => <span key={index} className="mr1">{`${name}${index !== (values.length - 1) ? ',   ' : ''}`}</span>) :
+                    <span className="mr1">{selectedName}</span>
+                }
                 <Icon className="flex-align-right" name="chevrondown" size={12}/>
             </div>
         );
@@ -190,16 +206,22 @@ class LegacySelect extends Component {
         var columns = [
             {
                 selectedItem: value,
+                selectedItems: values,
                 sections: sections,
+                disabledOptionIds: disabledOptionIds,
                 itemTitleFn: optionNameFn,
                 itemDescriptionFn: (item) => item.description,
                 itemSelectFn: (item) => {
-                    onChange(optionValueFn(item))
-                    this.toggle();
+                    onChange(optionValueFn(item));
+                    if (!values) {
+                        this.toggle();
+                    }
                 }
             }
         ];
 
+        const disablePopover = disabled || !options || options.length === 0;
+
         return (
             <PopoverWithTrigger
                 ref="popover"
@@ -207,6 +229,7 @@ class LegacySelect extends Component {
                 triggerElement={triggerElement}
                 triggerClasses={this.props.triggerClasses || cx("AdminSelect", this.props.className)}
                 isInitiallyOpen={isInitiallyOpen}
+                disabled={disablePopover}
             >
                 <div onClick={(e) => e.stopPropagation()}>
                     <ColumnarSelector
diff --git a/frontend/src/metabase/components/Triggerable.jsx b/frontend/src/metabase/components/Triggerable.jsx
index 87d21025299e539495e7ab1cc95e2c53e5f817cf..084e52a3ab5e627aafbe0d006d68da40a7f32e35 100644
--- a/frontend/src/metabase/components/Triggerable.jsx
+++ b/frontend/src/metabase/components/Triggerable.jsx
@@ -106,7 +106,7 @@ export default ComposedComponent => class extends Component {
         }
 
         return (
-            <a ref="trigger" onClick={() => this.toggle()} className={cx("no-decoration", triggerClasses, isOpen ? triggerClassesOpen : null)}>
+            <a ref="trigger" onClick={!this.props.disabled && (() => this.toggle())} className={cx("no-decoration", triggerClasses, isOpen ? triggerClassesOpen : null, this.props.disabled ? 'cursor-default' : null)}>
                 {triggerElement}
                 <ComposedComponent
                     {...this.props}
diff --git a/frontend/src/metabase/css/components/buttons.css b/frontend/src/metabase/css/components/buttons.css
index 8b32aa7f1f8349f5721c7f062235f4131ed63418..bc391150739ed2b4baa3238b327d985c0183668d 100644
--- a/frontend/src/metabase/css/components/buttons.css
+++ b/frontend/src/metabase/css/components/buttons.css
@@ -54,6 +54,11 @@
     font-size: 0.8rem;
 }
 
+.Button--large {
+    padding: 0.8rem 1.25rem;
+    font-size: 1rem;
+}
+
 .Button-normal {
     font-weight: normal;
 }
@@ -95,7 +100,12 @@
 .Button--purple {
     color: white;
     background-color: #A989C5;
-    border: 1px solid #885AB1;
+    border: 1px solid #A989C5;
+}
+
+.Button--purple:hover {
+    background-color: #885AB1;
+    border-color: #885AB1;
 }
 
 .Button--borderless {
diff --git a/frontend/src/metabase/css/core/bordered.css b/frontend/src/metabase/css/core/bordered.css
index eceb8bd95e3463f86e101166d01fbd7a53d1b4c3..fded00ab191bfb6c545dd966e88be46f42605189 100644
--- a/frontend/src/metabase/css/core/bordered.css
+++ b/frontend/src/metabase/css/core/bordered.css
@@ -83,7 +83,7 @@
     border-color: var(--success-color) !important;
 }
 
-.border-brand {
+.border-brand, :local(.border-brand) {
     border-color: var(--brand-color) !important;
 }
 
diff --git a/frontend/src/metabase/css/core/colors.css b/frontend/src/metabase/css/core/colors.css
index 709307322c22f430f5a2925d62758cff392d9efd..da9c96bcf719d348f57a68180c942d530821b3af 100644
--- a/frontend/src/metabase/css/core/colors.css
+++ b/frontend/src/metabase/css/core/colors.css
@@ -151,7 +151,9 @@
 .bg-grey-3 { background-color: var(--grey-3) }
 .bg-grey-4 { background-color: var(--grey-4) }
 
-.text-dark, :local(.text-dark) { color: var(--dark-color); }
+.text-dark, :local(.text-dark) {
+    color: var(--dark-color);
+}
 
 /* white  - move to bottom for specificity since its often used on hovers, etc */
 .text-white, :local(.text-white),
diff --git a/frontend/src/metabase/css/core/cursor.css b/frontend/src/metabase/css/core/cursor.css
index a38c4d2c2df90627321c0945fe6f750d106c124d..2de366c0f853a38828613c1e03978ef96e503597 100644
--- a/frontend/src/metabase/css/core/cursor.css
+++ b/frontend/src/metabase/css/core/cursor.css
@@ -1,3 +1,7 @@
-:local .cursor-pointer {
+.cursor-pointer, :local(.cursor-pointer) {
     cursor: pointer;
 }
+
+.cursor-default, :local(.cursor-default) {
+    cursor: default;
+}
diff --git a/frontend/src/metabase/css/core/text.css b/frontend/src/metabase/css/core/text.css
index 88cec0eb838d0c136e0b15e99527f5297c851252..3e2aa7ce4044735cfa268425efb05c8471db5955 100644
--- a/frontend/src/metabase/css/core/text.css
+++ b/frontend/src/metabase/css/core/text.css
@@ -23,7 +23,7 @@
 
 /* left */
 
-.text-left { text-align: left; }
+.text-left, :local(.text-left) { text-align: left; }
 
 @media screen and (--breakpoint-min-sm) {
     .sm-text-left { text-align: left; }
@@ -43,7 +43,7 @@
 
 /* right */
 
-.text-right { text-align: right; }
+.text-right, :local(.text-right) { text-align: right; }
 
 @media screen and (--breakpoint-min-sm) {
     .sm-text-right { text-align: right; }
@@ -91,11 +91,11 @@
 }
 
 .text-underline {
-    text-decoration: underline;;
+    text-decoration: underline;
 }
 
 .text-underline-hover:hover {
-    text-decoration: underline;;
+    text-decoration: underline;
 }
 
 .text-ellipsis {
@@ -111,3 +111,7 @@
     line-height: 1.4em;
     white-space: pre;
 }
+
+.text-measure {
+    max-width: 620px;
+}
diff --git a/frontend/src/metabase/css/home.css b/frontend/src/metabase/css/home.css
index 75ed5e8ae0a9b06c27d1bead0291638aec773932..4e301f009750f23d0f3afde5ba30955f0bb5028a 100644
--- a/frontend/src/metabase/css/home.css
+++ b/frontend/src/metabase/css/home.css
@@ -168,10 +168,6 @@
     word-wrap: break-word;
 }
 
-.cursor-pointer {
-    cursor: pointer;
-}
-
 .tooltip {
     position: absolute;
     background-color: #fff;
diff --git a/frontend/src/metabase/css/query_builder.css b/frontend/src/metabase/css/query_builder.css
index 00d5025a1402bb179976f3d85dab4f5733acdd0f..cd06f972dccf04602340ff217ac2910845902ba4 100644
--- a/frontend/src/metabase/css/query_builder.css
+++ b/frontend/src/metabase/css/query_builder.css
@@ -663,6 +663,10 @@
     margin-bottom: 2px;
 }
 
+.List-item--disabled .List-item-title {
+    color: var(--grey-3);
+}
+
 .List-item--segment .Icon,
 .List-item--segment .List-item-title {
   color: var(--purple-color);
@@ -673,7 +677,7 @@
   color: var(--brand-color);
 }
 
-.List-item:hover,
+.List-item:not(.List-item--disabled):hover,
 .List-item--selected {
     background-color: currentColor;
     border-color: rgba(0,0,0,0.2);
@@ -684,12 +688,12 @@
     color: var(--default-font-color);
 }
 
-.List-item:hover .List-item-title,
+.List-item:not(.List-item--disabled):hover .List-item-title,
 .List-item--selected .List-item-title {
     color: white;
 }
 
-.List-item:hover .Icon,
+.List-item:not(.List-item--disabled):hover .Icon,
 .List-item--selected .Icon {
     color: white;
 }
@@ -699,7 +703,7 @@
     visibility: hidden;
 }
 
-.List-item:hover .FieldList-grouping-trigger,
+.List-item:not(.List-item--disabled):hover .FieldList-grouping-trigger,
 .List-item--selected .FieldList-grouping-trigger {
     visibility: visible;
     border-left: 2px solid rgba(0,0,0,0.1);
diff --git a/frontend/src/metabase/dashboard/dashboard.js b/frontend/src/metabase/dashboard/dashboard.js
index 61c804bd86ed631f48b298f249ae32edffe833f3..351435beac696f439574d426b09a5afc7d1a1f68 100644
--- a/frontend/src/metabase/dashboard/dashboard.js
+++ b/frontend/src/metabase/dashboard/dashboard.js
@@ -34,6 +34,7 @@ export const FETCH_DASHBOARD = "metabase/dashboard/FETCH_DASHBOARD";
 export const FETCH_DASHBOARDS = "metabase/dashboard/FETCH_DASHBOARDS";
 export const CREATE_DASHBOARD = "metabase/dashboard/CREATE_DASHBOARD";
 export const SAVE_DASHBOARD = "metabase/dashboard/SAVE_DASHBOARD";
+export const UPDATE_DASHBOARD = "metabase/dashboard/UPDATE_DASHBOARD";
 export const DELETE_DASHBOARD = "metabase/dashboard/DELETE_DASHBOARD";
 export const SET_DASHBOARD_ATTRIBUTES = "metabase/dashboard/SET_DASHBOARD_ATTRIBUTES";
 
@@ -269,6 +270,38 @@ export const saveDashboard = createThunkAction(SAVE_DASHBOARD, function(dashId)
     };
 });
 
+export const updateDashboard = createThunkAction(UPDATE_DASHBOARD, (dashboard) =>
+    async (dispatch, getState) => {
+        const { 
+            id, 
+            name, 
+            description, 
+            public_perms, 
+            parameters, 
+            caveats, 
+            points_of_interest, 
+            show_in_getting_started 
+        } = dashboard;
+
+        const cleanDashboard = { 
+            id, 
+            name, 
+            description, 
+            public_perms, 
+            parameters, 
+            caveats, 
+            points_of_interest, 
+            show_in_getting_started 
+        };
+
+        const updatedDashboard = await DashboardApi.update(cleanDashboard);
+        
+        MetabaseAnalytics.trackEvent("Dashboard", "Update");
+        
+        return updatedDashboard;
+    }
+);
+
 export const fetchDashboards = createAction(FETCH_DASHBOARDS, () =>
     DashboardApi.list({ f: "all" })
 );
@@ -420,6 +453,7 @@ const dashboardListing = handleActions({
     [CREATE_DASHBOARD]: (state, { payload }) => state.concat(payload),
     [DELETE_DASHBOARD]: (state, { payload }) => state.filter(d => d.id !== payload),
     [SAVE_DASHBOARD]:   (state, { payload }) => state.map(d => d.id === payload.id ? payload : d),
+    [UPDATE_DASHBOARD]: (state, { payload }) => state.map(d => d.id === payload.id ? payload : d),
 }, []);
 
 export default combineReducers({
diff --git a/frontend/src/metabase/icon_paths.js b/frontend/src/metabase/icon_paths.js
index 0f0d5dafd046f196d0c371d1d9348b9cd0a36610..4fb6f764b36fd4e1deaed579790fa0ad3336d349 100644
--- a/frontend/src/metabase/icon_paths.js
+++ b/frontend/src/metabase/icon_paths.js
@@ -53,6 +53,7 @@ export var ICON_PATHS = {
     cursor_move: 'M14.8235294,14.8235294 L14.8235294,6.58823529 L17.1764706,6.58823529 L17.1764706,14.8235294 L25.4117647,14.8235294 L25.4117647,17.1764706 L17.1764706,17.1764706 L17.1764706,25.4117647 L14.8235294,25.4117647 L14.8235294,17.1764706 L6.58823529,17.1764706 L6.58823529,14.8235294 L14.8235294,14.8235294 L14.8235294,14.8235294 Z M16,0 L20.1176471,6.58823529 L11.8823529,6.58823529 L16,0 Z M11.8823529,25.4117647 L20.1176471,25.4117647 L16,32 L11.8823529,25.4117647 Z M32,16 L25.4117647,20.1176471 L25.4117647,11.8823529 L32,16 Z M6.58823529,11.8823529 L6.58823529,20.1176471 L0,16 L6.58823529,11.8823529 Z',
     cursor_resize: 'M17.4017952,6.81355995 L15.0488541,6.81355995 L15.0488541,25.6370894 L17.4017952,25.6370894 L17.4017952,6.81355995 Z M16.2253247,0.225324657 L20.3429717,6.81355995 L12.1076776,6.81355995 L16.2253247,0.225324657 Z M12.1076776,25.6370894 L20.3429717,25.6370894 L16.2253247,32.2253247 L12.1076776,25.6370894 Z',
     database: 'M1.18285296e-08,10.5127919 C-1.47856568e-08,7.95412848 1.18285298e-08,4.57337284 1.18285298e-08,4.57337284 C1.18285298e-08,4.57337284 1.58371041,5.75351864e-10 15.6571342,0 C29.730558,-5.7535027e-10 31.8900148,4.13849684 31.8900148,4.57337284 L31.8900148,10.4843058 C31.8900148,10.4843058 30.4448001,15.1365942 16.4659751,15.1365944 C2.48715012,15.1365947 2.14244494e-08,11.4353349 1.18285296e-08,10.5127919 Z M0.305419478,21.1290071 C0.305419478,21.1290071 0.0405133833,21.2033291 0.0405133833,21.8492606 L0.0405133833,27.3032816 C0.0405133833,27.3032816 1.46515486,31.941655 15.9641228,31.941655 C30.4630908,31.941655 32,27.3446712 32,27.3446712 C32,27.3446712 32,21.7986104 32,21.7986105 C32,21.2073557 31.6620557,21.0987647 31.6620557,21.0987647 C31.6620557,21.0987647 29.7146434,25.22314 16.0318829,25.22314 C2.34912233,25.22314 0.305419478,21.1290071 0.305419478,21.1290071 Z M0.305419478,12.656577 C0.305419478,12.656577 0.0405133833,12.730899 0.0405133833,13.3768305 L0.0405133833,18.8308514 C0.0405133833,18.8308514 1.46515486,23.4692249 15.9641228,23.4692249 C30.4630908,23.4692249 32,18.8722411 32,18.8722411 C32,18.8722411 32,13.3261803 32,13.3261803 C32,12.7349256 31.6620557,12.6263346 31.6620557,12.6263346 C31.6620557,12.6263346 29.7146434,16.7507099 16.0318829,16.7507099 C2.34912233,16.7507099 0.305419478,12.656577 0.305419478,12.656577 Z',
+    dashboard: 'M32,29 L32,4 L32,0 L0,0 L0,8 L28,8 L28,28 L4,28 L4,8 L0,8 L0,29.5 L0,32 L32,32 L32,29 Z M7.27272727,18.9090909 L17.4545455,18.9090909 L17.4545455,23.2727273 L7.27272727,23.2727273 L7.27272727,18.9090909 Z M7.27272727,12.0909091 L24.7272727,12.0909091 L24.7272727,16.4545455 L7.27272727,16.4545455 L7.27272727,12.0909091 Z M20.3636364,18.9090909 L24.7272727,18.9090909 L24.7272727,23.2727273 L20.3636364,23.2727273 L20.3636364,18.9090909 Z',
     dashboards: 'M17,5.49100518 L17,10.5089948 C17,10.7801695 17.2276528,11 17.5096495,11 L26.4903505,11 C26.7718221,11 27,10.7721195 27,10.5089948 L27,5.49100518 C27,5.21983051 26.7723472,5 26.4903505,5 L17.5096495,5 C17.2281779,5 17,5.22788048 17,5.49100518 Z M18.5017326,14 C18.225722,14 18,13.77328 18,13.4982674 L18,26.5017326 C18,26.225722 18.22672,26 18.5017326,26 L5.49826741,26 C5.77427798,26 6,26.22672 6,26.5017326 L6,13.4982674 C6,13.774278 5.77327997,14 5.49826741,14 L18.5017326,14 Z M14.4903505,6 C14.2278953,6 14,5.78028538 14,5.49100518 L14,10.5089948 C14,10.2167107 14.2224208,10 14.4903505,10 L5.50964952,10 C5.77210473,10 6,10.2197146 6,10.5089948 L6,5.49100518 C6,5.78328929 5.77757924,6 5.50964952,6 L14.4903505,6 Z M26.5089948,22 C26.2251201,22 26,21.7774008 26,21.4910052 L26,26.5089948 C26,26.2251201 26.2225992,26 26.5089948,26 L21.4910052,26 C21.7748799,26 22,26.2225992 22,26.5089948 L22,21.4910052 C22,21.7748799 21.7774008,22 21.4910052,22 L26.5089948,22 Z M26.5089948,14 C26.2251201,14 26,13.7774008 26,13.4910052 L26,18.5089948 C26,18.2251201 26.2225992,18 26.5089948,18 L21.4910052,18 C21.7748799,18 22,18.2225992 22,18.5089948 L22,13.4910052 C22,13.7748799 21.7774008,14 21.4910052,14 L26.5089948,14 Z M26.4903505,6 C26.2278953,6 26,5.78028538 26,5.49100518 L26,10.5089948 C26,10.2167107 26.2224208,10 26.4903505,10 L17.5096495,10 C17.7721047,10 18,10.2197146 18,10.5089948 L18,5.49100518 C18,5.78328929 17.7775792,6 17.5096495,6 L26.4903505,6 Z M5,13.4982674 L5,26.5017326 C5,26.7769181 5.21990657,27 5.49826741,27 L18.5017326,27 C18.7769181,27 19,26.7800934 19,26.5017326 L19,13.4982674 C19,13.2230819 18.7800934,13 18.5017326,13 L5.49826741,13 C5.22308192,13 5,13.2199066 5,13.4982674 Z M5,5.49100518 L5,10.5089948 C5,10.7801695 5.22765279,11 5.50964952,11 L14.4903505,11 C14.7718221,11 15,10.7721195 15,10.5089948 L15,5.49100518 C15,5.21983051 14.7723472,5 14.4903505,5 L5.50964952,5 C5.22817786,5 5,5.22788048 5,5.49100518 Z M21,21.4910052 L21,26.5089948 C21,26.7801695 21.2278805,27 21.4910052,27 L26.5089948,27 C26.7801695,27 27,26.7721195 27,26.5089948 L27,21.4910052 C27,21.2198305 26.7721195,21 26.5089948,21 L21.4910052,21 C21.2198305,21 21,21.2278805 21,21.4910052 Z M21,13.4910052 L21,18.5089948 C21,18.7801695 21.2278805,19 21.4910052,19 L26.5089948,19 C26.7801695,19 27,18.7721195 27,18.5089948 L27,13.4910052 C27,13.2198305 26.7721195,13 26.5089948,13 L21.4910052,13 C21.2198305,13 21,13.2278805 21,13.4910052 Z',
     document: 'M29,10.1052632 L29,28.8325291 C29,30.581875 27.5842615,32 25.8337327,32 L7.16626728,32 C5.41758615,32 4,30.5837102 4,28.8441405 L4,3.15585953 C4,1.41292644 5.42339685,9.39605581e-15 7.15970573,8.42009882e-15 L20.713352,8.01767853e-16 L20.713352,8.42105263 L22.3846872,8.42105263 L22.3846872,0.310375032 L28.7849894,8.42105263 L20.713352,8.42105263 L20.713352,10.1052632 L29,10.1052632 Z M7.3426704,12.8000006 L25.7273576,12.8000006 L25.7273576,14.4842112 L7.3426704,14.4842112 L7.3426704,12.8000006 Z M7.3426704,17.3473687 L25.7273576,17.3473687 L25.7273576,19.0315793 L7.3426704,19.0315793 L7.3426704,17.3473687 Z M7.3426704,21.8947352 L25.7273576,21.8947352 L25.7273576,23.5789458 L7.3426704,23.5789458 L7.3426704,21.8947352 Z M7.43137255,26.2736849 L16.535014,26.2736849 L16.535014,27.9578954 L7.43137255,27.9578954 L7.43137255,26.2736849 Z',
     download: {
diff --git a/frontend/src/metabase/lib/redux.js b/frontend/src/metabase/lib/redux.js
index 1492e39cd9c70c7228a14942e7dc9bf5d73d48d3..3684c78eed27a6722ced8c5e6440b2b60492c917 100644
--- a/frontend/src/metabase/lib/redux.js
+++ b/frontend/src/metabase/lib/redux.js
@@ -1,5 +1,6 @@
 import moment from "moment";
 import _ from "underscore";
+import i from "icepick";
 
 import { createStore as originalCreateStore, applyMiddleware, compose } from "redux";
 import promise from 'redux-promise';
@@ -11,6 +12,8 @@ import { createAngularHistory } from "./createAngularHistory";
 
 import { reduxReactRouter } from 'redux-router';
 
+import { setRequestState, clearRequestState } from "metabase/redux/requests";
+
 // convienence
 export { combineReducers } from "redux";
 export { handleActions, createAction } from "redux-actions";
@@ -91,12 +94,72 @@ export function momentifyObjectsTimestamps(objects, keys) {
     return _.mapObject(objects, o => momentifyTimestamps(o, keys));
 }
 
+//filters out angular cruft in resource list
+export const cleanResources = (resources) => resources
+    .filter(resource => resource.id !== undefined);
+
 //filters out angular cruft and turns into id indexed map
-export const resourceListToMap = (resources) => resources
-    .filter(resource => resource.id !== undefined)
+export const resourceListToMap = (resources) => cleanResources(resources)
     .reduce((map, resource) => Object.assign({}, map, {[resource.id]: resource}), {});
 
 //filters out angular cruft in resource
 export const cleanResource = (resource) => Object.keys(resource)
     .filter(key => key.charAt(0) !== "$")
     .reduce((map, key) => Object.assign({}, map, {[key]: resource[key]}), {});
+
+export const fetchData = async ({
+    dispatch, 
+    getState, 
+    requestStatePath, 
+    existingStatePath, 
+    getData, 
+    reload
+}) => {
+    const existingData = i.getIn(getState(), existingStatePath);
+    const statePath = requestStatePath.concat(['fetch']);
+    try {
+        const requestState = i.getIn(getState(), ["requests", ...statePath]);
+        if (!requestState || requestState.error || reload) {
+            dispatch(setRequestState({ statePath, state: "LOADING" }));
+            const data = await getData();
+            dispatch(setRequestState({ statePath, state: "LOADED" }));
+
+            return data;
+        }
+
+        return existingData;
+    }
+    catch(error) {
+        dispatch(setRequestState({ statePath, error }));
+        console.error(error);
+        return existingData;
+    }
+}
+
+export const updateData = async ({
+    dispatch, 
+    getState, 
+    requestStatePath, 
+    existingStatePath,
+    // specify any request paths that need to be invalidated after this update 
+    dependentRequestStatePaths,
+    putData
+}) => {
+    const existingData = i.getIn(getState(), existingStatePath);
+    const statePath = requestStatePath.concat(['update']);
+    try {
+        dispatch(setRequestState({ statePath, state: "LOADING" }));
+        const data = await putData();
+        dispatch(setRequestState({ statePath, state: "LOADED" }));
+
+        (dependentRequestStatePaths || [])
+            .forEach(statePath => dispatch(clearRequestState({ statePath })));
+
+        return data;
+    }
+    catch(error) {
+        dispatch(setRequestState({ statePath, error }));
+        console.error(error);
+        return existingData;
+    }
+}
\ No newline at end of file
diff --git a/frontend/src/metabase/query_builder/DataSelector.jsx b/frontend/src/metabase/query_builder/DataSelector.jsx
index 2b51ed2b185be2258395bff895e90fad6727e966..2261e80ef407a0383f17f6b4a9c0c403089ae651 100644
--- a/frontend/src/metabase/query_builder/DataSelector.jsx
+++ b/frontend/src/metabase/query_builder/DataSelector.jsx
@@ -17,17 +17,23 @@ export default class DataSelector extends Component {
         this.state = {
             databases: null,
             selectedSchema: null,
-            showTablePicker: true
+            showTablePicker: true,
+            showSegmentPicker: props.segments && props.segments.length > 0
         }
 
-        _.bindAll(this, "onChangeDatabase", "onChangeSchema", "onChangeTable", "onBack");
+        _.bindAll(this, "onChangeDatabase", "onChangeSchema", "onChangeTable", "onChangeSegment", "onBack");
     }
 
     static propTypes = {
         query: PropTypes.object.isRequired,
         databases: PropTypes.array.isRequired,
+        tables: PropTypes.array,
+        segments: PropTypes.array,
+        disabledTableIds: PropTypes.array,
+        disabledSegmentIds: PropTypes.array,
         setDatabaseFn: PropTypes.func.isRequired,
         setSourceTableFn: PropTypes.func,
+        setSourceSegmentFn: PropTypes.func,
         isInitiallyOpen: PropTypes.bool
     };
 
@@ -38,7 +44,7 @@ export default class DataSelector extends Component {
 
     componentWillMount() {
         this.componentWillReceiveProps(this.props);
-        if (this.props.databases.length === 1) {
+        if (this.props.databases.length === 1 && !this.props.segments) {
             setTimeout(() => this.onChangeDatabase(0));
         }
     }
@@ -86,6 +92,14 @@ export default class DataSelector extends Component {
         this.refs.popover.toggle();
     }
 
+    onChangeSegment(item) {
+        if (item.segment != null) {
+            this.props.setSourceSegmentFn(item.segment.id);
+        }
+
+        this.refs.popover.toggle();
+    }
+
     onChangeSchema(schema) {
         this.setState({
             selectedSchema: schema,
@@ -93,9 +107,16 @@ export default class DataSelector extends Component {
         });
     }
 
+    onChangeSegmentSection() {
+        this.setState({
+            showSegmentPicker: true
+        });
+    }
+
     onBack() {
         this.setState({
-            showTablePicker: false
+            showTablePicker: false,
+            showSegmentPicker: false
         });
     }
 
@@ -115,6 +136,10 @@ export default class DataSelector extends Component {
         });
     }
 
+    getSegmentId() {
+        return this.props.query.segment;
+    }
+
     getDatabaseId() {
         return this.props.query.database;
     }
@@ -176,13 +201,52 @@ export default class DataSelector extends Component {
         );
     }
 
+    renderSegmentAndDatabasePicker() {
+        const { selectedSchema } = this.state;
+        
+        const segmentItem = [{ name: 'Segments', items: [], icon: 'segment'}];
+        
+        const sections = segmentItem.concat(this.state.databases.map(database => {
+            return {
+                name: database.name,
+                items: database.schemas.length > 1 ? database.schemas : []
+            };
+        }));
+
+        // FIXME: this seems a bit brittle and hard to follow
+        let openSection = selectedSchema && (_.findIndex(this.state.databases, (db) => _.find(db.schemas, selectedSchema)) + segmentItem.length);
+        if (openSection >= 0 && this.state.databases[openSection - segmentItem.length] && this.state.databases[openSection - segmentItem.length].schemas.length === 1) {
+            openSection = -1;
+        }
+
+        return (
+            <AccordianList
+                key="schemaPicker"
+                className="text-brand"
+                sections={sections}
+                onChange={this.onChangeSchema}
+                onChangeSection={(index) => index === 0 ?
+                    this.onChangeSegmentSection() :
+                    this.onChangeDatabase(index - segmentItem.length)
+                }
+                itemIsSelected={(schema) => this.state.selectedSchema === schema}
+                renderSectionIcon={(section, sectionIndex) => <Icon className="Icon text-default" name={section.icon || "database"} size={18} />}
+                renderItemIcon={() => <Icon name="folder" size={16} />}
+                initiallyOpenSection={openSection}
+                showItemArrows={true}
+                alwaysTogglable={true}
+            />
+        );
+    }
+
     renderTablePicker() {
         const schema = this.state.selectedSchema;
         const hasMultipleDatabases = this.props.databases.length > 1;
+        const hasSegments = !!this.props.segments;
         let header = (
             <span className="flex align-center">
-                <span className={cx("flex align-center text-slate", { "cursor-pointer": hasMultipleDatabases })} onClick={hasMultipleDatabases && this.onBack}>
-                    { hasMultipleDatabases && <Icon name="chevronleft" size={18} /> }
+                <span className={cx("flex align-center text-slate", { "cursor-pointer": hasMultipleDatabases || hasSegments })} onClick={(hasMultipleDatabases || hasSegments) && this.onBack}>
+                    { (hasMultipleDatabases || hasSegments) && <Icon name="chevronleft" size={18} /> }
                     <span className="ml1">{schema.database.name}</span>
                 </span>
                 { schema.name &&
@@ -207,11 +271,13 @@ export default class DataSelector extends Component {
         } else {
             let sections = [{
                 name: header,
-                items: schema.tables.map(table => ({
-                    name: table.display_name,
-                    table: table,
-                    database: schema.database
-                }))
+                items: schema.tables
+                    .map(table => ({
+                        name: table.display_name,
+                        disabled: this.props.disabledTableIds && this.props.disabledTableIds.includes(table.id),
+                        table: table,
+                        database: schema.database
+                    }))
             }];
             return (
                 <AccordianList
@@ -221,7 +287,7 @@ export default class DataSelector extends Component {
                     searchable={true}
                     onChange={this.onChangeTable}
                     itemIsSelected={(item) => item.table ? item.table.id === this.getTableId() : false}
-                    itemIsClickable={(item) => item.table}
+                    itemIsClickable={(item) => item.table && !item.disabled}
                     renderItemIcon={(item) => item.table ? <Icon name="table2" size={18} /> : null}
                     hideSingleSectionTitle={true}
                 />
@@ -229,6 +295,57 @@ export default class DataSelector extends Component {
         }
     }
 
+    //TODO: refactor this. lots of shared code with renderTablePicker()
+    renderSegmentPicker() {
+        const { segments } = this.props;
+        const header = (
+            <span className="flex align-center">
+                <span className="flex align-center text-slate cursor-pointer" onClick={this.onBack}>
+                    <Icon name="chevronleft" size={18} />
+                    <span className="ml1">Segments</span>
+                </span>
+            </span>
+        );
+
+        if (!segments || segments.length === 0) {
+            return (
+                <section className="List-section List-section--open" style={{width: '300px'}}>
+                    <div className="p1 border-bottom">
+                        <div className="px1 py1 flex align-center">
+                            <h3 className="text-default">{header}</h3>
+                        </div>
+                    </div>
+                    <div className="p4 text-centered">No segments were found.</div>
+                </section>
+            );
+        }
+
+        const sections = [{
+            name: header,
+            items: segments
+                .map(segment => ({
+                    name: segment.name,
+                    segment: segment,
+                    disabled: this.props.disabledSegmentIds && this.props.disabledSegmentIds.includes(segment.id)
+                }))
+        }];
+
+        return (
+            <AccordianList
+                key="segmentPicker"
+                className="text-brand"
+                sections={sections}
+                searchable={true}
+                searchPlaceholder="Find a segment"
+                onChange={this.onChangeSegment}
+                itemIsSelected={(item) => item.segment ? item.segment.id === this.getSegmentId() : false}
+                itemIsClickable={(item) => item.segment && !item.disabled}
+                renderItemIcon={(item) => item.segment ? <Icon name="segment" size={18} /> : null}
+                hideSingleSectionTitle={true}
+            />
+        );
+    }
+
     render() {
         const { databases } = this.props;
 
@@ -238,7 +355,17 @@ export default class DataSelector extends Component {
         var table = _.find(database.tables, (table) => table.id === tableId);
 
         var content;
-        if (this.props.includeTables) {
+        if (this.props.includeTables && this.props.segments) {
+            const segmentId = this.getSegmentId();
+            const segment = _.find(this.props.segments, (segment) => segment.id === segmentId);
+            if (table) {
+                content = <span className="text-grey no-decoration">{table.display_name || table.name}</span>;
+            } else if (segment) {
+                content = <span className="text-grey no-decoration">{segment.name}</span>;
+            } else {
+                content = <span className="text-grey-4 no-decoration">Pick a segment or table</span>;
+            }
+        } else if (this.props.includeTables) {
             if (table) {
                 content = <span className="text-grey no-decoration">{table.display_name || table.name}</span>;
             } else {
@@ -253,9 +380,9 @@ export default class DataSelector extends Component {
         }
 
         var triggerElement = (
-            <span className="px2 py2 text-bold cursor-pointer text-default">
+            <span className={this.props.className || "px2 py2 text-bold cursor-pointer text-default"} style={this.props.style}>
                 {content}
-                <Icon className="ml1" name="chevrondown" size={8}/>
+                <Icon className="ml1" name="chevrondown" size={this.props.triggerIconSize || 8}/>
             </span>
         )
 
@@ -265,14 +392,17 @@ export default class DataSelector extends Component {
                 isInitiallyOpen={this.props.isInitiallyOpen}
                 triggerElement={triggerElement}
                 triggerClasses="flex align-center"
-                horizontalAttachments={["left"]}
+                horizontalAttachments={this.props.segments ? ["center", "left", "right"] : ["left"]}
             >
                 { !this.props.includeTables ?
-                    this.renderDatabasePicker()
-                : this.state.selectedSchema && this.state.showTablePicker ?
-                    this.renderTablePicker()
-                :
-                    this.renderDatabaseSchemaPicker()
+                    this.renderDatabasePicker() : 
+                    this.state.selectedSchema && this.state.showTablePicker ?
+                        this.renderTablePicker() :
+                        this.props.segments ?
+                            this.state.showSegmentPicker ?  
+                                this.renderSegmentPicker() :
+                                this.renderSegmentAndDatabasePicker() :
+                            this.renderDatabaseSchemaPicker()
                 }
             </PopoverWithTrigger>
         );
diff --git a/frontend/src/metabase/redux/metadata.js b/frontend/src/metabase/redux/metadata.js
index b710190bcbd4ea148c0f8c9c39805ef5a1c10fbf..5543b536e7e0a84d873ced1369b895916121669d 100644
--- a/frontend/src/metabase/redux/metadata.js
+++ b/frontend/src/metabase/redux/metadata.js
@@ -4,7 +4,9 @@ import {
     AngularResourceProxy,
     createThunkAction,
     resourceListToMap,
-    cleanResource
+    cleanResource,
+    fetchData,
+    updateData,
 } from "metabase/lib/redux";
 
 import { normalize, Schema, arrayOf } from 'normalizr';
@@ -12,16 +14,19 @@ import i from "icepick";
 import _ from "underscore";
 
 import { augmentDatabase, augmentTable } from "metabase/lib/table";
-import { setRequestState, clearRequestState } from "./requests";
 
 const MetabaseApi = new AngularResourceProxy("Metabase", ["db_list", "db_update", "db_metadata", "table_list", "table_update", "table_query_metadata", "field_update"]);
-const MetricApi = new AngularResourceProxy("Metric", ["list", "update"]);
+const MetricApi = new AngularResourceProxy("Metric", ["list", "update", "update_important_fields"]);
 const SegmentApi = new AngularResourceProxy("Segment", ["list", "update"]);
 const RevisionApi = new AngularResourceProxy("Revisions", ["get"]);
 
+const database_list = new Schema('database_list');
 const database = new Schema('databases');
 const table = new Schema('tables');
 const field = new Schema('fields');
+database_list.define({
+    databases: arrayOf(database)
+});
 database.define({
     tables: arrayOf(table)
 });
@@ -29,45 +34,6 @@ table.define({
     fields: arrayOf(field)
 });
 
-export const fetchData = async ({dispatch, getState, requestStatePath, existingStatePath, getData, reload}) => {
-    const existingData = i.getIn(getState(), existingStatePath);
-    const statePath = requestStatePath.concat(['fetch']);
-    try {
-        const requestState = i.getIn(getState(), ["requests", ...statePath]);
-        if (!requestState || requestState.error || reload) {
-            dispatch(setRequestState({ statePath, state: "LOADING" }));
-            const data = await getData();
-            dispatch(setRequestState({ statePath, state: "LOADED" }));
-
-            return data;
-        }
-
-        return existingData;
-    }
-    catch(error) {
-        dispatch(setRequestState({ statePath, error }));
-        console.error(error);
-        return existingData;
-    }
-}
-
-export const updateData = async ({dispatch, getState, requestStatePath, existingStatePath, putData}) => {
-    const existingData = i.getIn(getState(), existingStatePath);
-    const statePath = requestStatePath.concat(['update']);
-    try {
-        dispatch(setRequestState({ statePath, state: "LOADING" }));
-        const data = await putData();
-        dispatch(setRequestState({ statePath, state: "LOADED" }));
-
-        return data;
-    }
-    catch(error) {
-        dispatch(setRequestState({ statePath, error }));
-        console.error(error);
-        return existingData;
-    }
-}
-
 const FETCH_METRICS = "metabase/metadata/FETCH_METRICS";
 export const fetchMetrics = createThunkAction(FETCH_METRICS, (reload = false) => {
     return async (dispatch, getState) => {
@@ -79,7 +45,14 @@ export const fetchMetrics = createThunkAction(FETCH_METRICS, (reload = false) =>
             return metricMap;
         };
 
-        return await fetchData({dispatch, getState, requestStatePath, existingStatePath, getData, reload});
+        return await fetchData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            getData, 
+            reload
+        });
     };
 });
 
@@ -88,8 +61,8 @@ export const updateMetric = createThunkAction(UPDATE_METRIC, function(metric) {
     return async (dispatch, getState) => {
         const requestStatePath = ["metadata", "metrics", metric.id];
         const existingStatePath = ["metadata", "metrics"];
+        const dependentRequestStatePaths = [['metadata', 'revisions', 'metric', metric.id]];
         const putData = async () => {
-            //FIXME: need to clear requestState for revisions for it to reload
             const updatedMetric = await MetricApi.update(metric);
             const cleanMetric = cleanResource(updatedMetric);
             const existingMetrics = i.getIn(getState(), existingStatePath);
@@ -97,11 +70,38 @@ export const updateMetric = createThunkAction(UPDATE_METRIC, function(metric) {
 
             const mergedMetric = {...existingMetric, ...cleanMetric};
 
-            dispatch(clearRequestState({statePath: ['metadata', 'revisions', 'metric', metric.id]}));
             return i.assoc(existingMetrics, mergedMetric.id, mergedMetric);
         };
 
-        return await updateData({dispatch, getState, requestStatePath, existingStatePath, putData});
+        return await updateData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            dependentRequestStatePaths,
+            putData
+        });
+    };
+});
+
+const UPDATE_METRIC_IMPORTANT_FIELDS = "metabase/guide/UPDATE_METRIC_IMPORTANT_FIELDS";
+export const updateMetricImportantFields = createThunkAction(UPDATE_METRIC_IMPORTANT_FIELDS, function(metricId, importantFieldIds) {
+    return async (dispatch, getState) => {
+        const requestStatePath = ["reference", "guide", "metric_important_fields", metricId];
+        const existingStatePath = requestStatePath;
+        const dependentRequestStatePaths = [['reference', 'guide']];
+        const putData = async () => {
+            await MetricApi.update_important_fields({ metricId, important_field_ids: importantFieldIds });
+        };
+
+        return await updateData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            dependentRequestStatePaths,
+            putData
+        });
     };
 });
 
@@ -121,7 +121,14 @@ export const fetchSegments = createThunkAction(FETCH_SEGMENTS, (reload = false)
             return segmentMap;
         };
 
-        return await fetchData({dispatch, getState, requestStatePath, existingStatePath, getData, reload});
+        return await fetchData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            getData, 
+            reload
+        });
     };
 });
 
@@ -130,6 +137,7 @@ export const updateSegment = createThunkAction(UPDATE_SEGMENT, function(segment)
     return async (dispatch, getState) => {
         const requestStatePath = ["metadata", "segments", segment.id];
         const existingStatePath = ["metadata", "segments"];
+        const dependentRequestStatePaths = [['metadata', 'revisions', 'segment', segment.id]];
         const putData = async () => {
             const updatedSegment = await SegmentApi.update(segment);
             const cleanSegment = cleanResource(updatedSegment);
@@ -138,11 +146,17 @@ export const updateSegment = createThunkAction(UPDATE_SEGMENT, function(segment)
 
             const mergedSegment = {...existingSegment, ...cleanSegment};
 
-            dispatch(clearRequestState({statePath: ['metadata', 'revisions', 'segment', segment.id]}));
             return i.assoc(existingSegments, mergedSegment.id, mergedSegment);
         };
 
-        return await updateData({dispatch, getState, requestStatePath, existingStatePath, putData});
+        return await updateData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            dependentRequestStatePaths,
+            putData
+        });
     };
 });
 
@@ -166,7 +180,14 @@ export const fetchDatabases = createThunkAction(FETCH_DATABASES, (reload = false
             return {...databaseMap, ...existingDatabases};
         };
 
-        return await fetchData({dispatch, getState, requestStatePath, existingStatePath, getData, reload});
+        return await fetchData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            getData, 
+            reload
+        });
     };
 });
 
@@ -182,7 +203,14 @@ export const fetchDatabaseMetadata = createThunkAction(FETCH_DATABASE_METADATA,
             return normalize(databaseMetadata, database).entities;
         };
 
-        return await fetchData({dispatch, getState, requestStatePath, existingStatePath, getData, reload});
+        return await fetchData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            getData, 
+            reload
+        });
     };
 });
 
@@ -206,7 +234,13 @@ export const updateDatabase = createThunkAction(UPDATE_DATABASE, function(databa
             return i.assoc(existingDatabases, mergedDatabase.id, mergedDatabase);
         };
 
-        return await updateData({dispatch, getState, requestStatePath, existingStatePath, putData});
+        return await updateData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            putData
+        });
     };
 });
 
@@ -236,7 +270,13 @@ export const updateTable = createThunkAction(UPDATE_TABLE, function(table) {
             return i.assoc(existingTables, mergedTable.id, mergedTable);
         };
 
-        return await updateData({dispatch, getState, requestStatePath, existingStatePath, putData});
+        return await updateData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            putData
+        });
     };
 });
 
@@ -254,7 +294,14 @@ export const fetchTables = createThunkAction(FETCH_TABLES, (reload = false) => {
             return {...tableMap, ...existingTables};
         };
 
-        return await fetchData({dispatch, getState, requestStatePath, existingStatePath, getData, reload});
+        return await fetchData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            getData, 
+            reload
+        });
     };
 });
 
@@ -270,7 +317,14 @@ export const fetchTableMetadata = createThunkAction(FETCH_TABLE_METADATA, functi
             return normalize(tableMetadata, table).entities;
         };
 
-        return await fetchData({dispatch, getState, requestStatePath, existingStatePath, getData, reload});
+        return await fetchData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            getData, 
+            reload
+        });
     };
 });
 
@@ -301,7 +355,13 @@ export const updateField = createThunkAction(UPDATE_FIELD, function(field) {
             return i.assoc(existingFields, mergedField.id, mergedField);
         };
 
-        return await updateData({dispatch, getState, requestStatePath, existingStatePath, putData});
+        return await updateData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            putData
+        });
     };
 });
 
@@ -324,7 +384,14 @@ export const fetchRevisions = createThunkAction(FETCH_REVISIONS, (type, id, relo
             return i.assocIn(existingRevisions, [type, id], revisionMap);
         };
 
-        return await fetchData({dispatch, getState, requestStatePath, existingStatePath, getData, reload});
+        return await fetchData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            getData, 
+            reload
+        });
     };
 });
 
@@ -392,6 +459,18 @@ export const fetchSegmentRevisions = createThunkAction(FETCH_SEGMENT_REVISIONS,
     };
 });
 
+const FETCH_DATABASES_WITH_METADATA = "metabase/metadata/FETCH_DATABASES_WITH_METADATA";
+export const fetchDatabasesWithMetadata = createThunkAction(FETCH_DATABASES_WITH_METADATA, (reload = false) => {
+    return async (dispatch, getState) => {
+        await dispatch(fetchDatabases());
+        const databases = i.getIn(getState(), ['metadata', 'databases']);
+        await Promise.all(
+            Object.keys(databases)
+                .map(databaseId => dispatch(fetchDatabaseMetadata(databaseId)))
+        );
+    };
+});
+
 export default combineReducers({
     metrics,
     segments,
diff --git a/frontend/src/metabase/reference/Reference.css b/frontend/src/metabase/reference/Reference.css
index 812c2778f6baa2173f55c3b444bcb57d3cd4ee23..42975fa68eee68a584f6bbba71f762a162f08b68 100644
--- a/frontend/src/metabase/reference/Reference.css
+++ b/frontend/src/metabase/reference/Reference.css
@@ -1,4 +1,6 @@
 :root {
+    --title-color: #606E7B;
+    --subtitle-color: #AAB7C3;
     --icon-width: calc(48px + 1rem);
 }
 
@@ -16,6 +18,7 @@
     composes: text-dark text-paragraph text-centered mt3 from "style";
 }
 
+
 :local(.columnHeader) {
     composes: flex flex-full from "style";
     margin-left: var(--icon-width);
@@ -35,5 +38,157 @@
 }
 
 :local(.tableActualName) {
-    color: #AAB7C3;
+    color: var(--subtitle-color);
+}
+
+:local(.guideLeftPadded) {
+    composes: flex full justify-center from "style";
+}
+
+:local(.guideLeftPadded)::before {
+    /*FIXME: not sure how to share this with other components
+     because we can't use composes here apparently. any workarounds?*/
+    content: '';
+    display: block;
+    flex: 0.3;
+    max-width: 250px;
+    margin-right: 50px;
+}
+
+:local(.guideLeftPaddedBody) {
+    flex: 0.7;
+    max-width: 550px;
+}
+
+:local(.guideWrapper) {
+    margin-bottom: 50px;
+}
+
+:local(.guideTitle) {
+    composes: guideLeftPadded;
+    font-size: 24px;
+    margin-top: 50px;
+}
+
+:local(.guideTitleBody) {
+    composes: full text-dark text-bold from "style";
+    composes: guideLeftPaddedBody;
+}
+
+:local(.guideSeeAll) {
+    composes: guideLeftPadded;
+    font-size: 18px;
+}
+
+:local(.guideSeeAllBody) {
+    composes: flex full text-dark text-bold mt4 from "style";
+    composes: guideLeftPaddedBody;
+}
+
+:local(.guideSeeAllLink) {
+    composes: flex-full block no-decoration py1 border-top from "style";
+}
+
+:local(.guideContact) {
+    composes: mt4 from "style";
+    composes: guideLeftPadded;
+    margin-bottom: 100px;
+}
+
+:local(.guideContactBody) {
+    composes: full from "style";
+    composes: guideLeftPaddedBody;
+    font-size: 16px;
+}
+
+:local(.guideEditHeader) {
+    composes: full text-body my4 from "style";
+    max-width: 550px;
+    color: var(--dark-color);
+}
+
+:local(.guideEditHeaderTitle) {
+    composes: text-bold mb2 from "style";
+    font-size: 24px;
+}
+
+:local(.guideEditCards) {
+    composes: mt2 mb4 from "style";
+}
+
+:local(.guideEditCard) {
+    composes: input p4 from "style";
+}
+
+
+:local(.guideEditLabel) {
+    composes: block text-bold mb2 from "style";
+    font-size: 16px;
+    color: var(--title-color);
+}
+
+:local(.guideEditHeaderDescription) {
+    font-size: 16px;
+}
+
+:local(.guideEditTitle) {
+    composes: block text-body text-bold from "style";
+    color: var(--title-color);
+    font-size: 16px;
+    margin-top: 50px;
+}
+
+:local(.guideEditSubtitle) {
+    composes: text-body from "style";
+    color: var(--grey-2);
+    font-size: 16px;
+    max-width: 700px;
+}
+
+:local(.guideEditAddButton) {
+    composes: flex full my2 pl4 from "style";
+    padding-right: 3.5rem;
+}
+
+:local(.guideEditAddButton)::before {
+    content: '';
+    display: block;
+    flex: 250;
+    max-width: 250px;
+    margin-right: 50px;
+}
+
+:local(.guideEditAddButtonBody) {
+    flex: 550;
+    max-width: 550px;    
+}
+
+:local(.guideEditTextarea) {
+    composes: text-dark input p2 from "style";
+    resize: none;
+    font-size: 16px;
+    width: 100%;
+    max-width: 850px;
+    min-height: 100px;
+}
+
+:local(.guideEditContact) {
+    composes: flex from "style";
+}
+
+:local(.guideEditContactName) {
+    flex: 250;
+    max-width: 250px;
+    margin-right: 50px;
+}
+
+:local(.guideEditContactEmail) {
+    flex: 550;
+    max-width: 550px;
+}
+
+:local(.guideEditInput) {
+    composes: full text-dark input p2 from "style";
+    font-size: 16px;
+    display: block;
 }
diff --git a/frontend/src/metabase/components/Detail.css b/frontend/src/metabase/reference/components/Detail.css
similarity index 94%
rename from frontend/src/metabase/components/Detail.css
rename to frontend/src/metabase/reference/components/Detail.css
index 7aba4b3ffa0c824be020bfa3e650af63de4ac02c..2f87df61e2a3a8ac08a7fc8c8bd1c12fab9cb4ec 100644
--- a/frontend/src/metabase/components/Detail.css
+++ b/frontend/src/metabase/reference/components/Detail.css
@@ -27,6 +27,7 @@
 
 :local(.detailSubtitle) {
     composes: text-dark mt2 text-paragraph from "style";
+    white-space: pre-wrap;
 }
 
 :local(.detailSubtitleLight) {
@@ -34,7 +35,7 @@
     color: var(--subtitle-color);
 }
 
-:local(.detailTextArea) {
+:local(.detailTextarea) {
     composes: text-dark input p2 from "style";
     resize: none;
     font-size: 16px;
diff --git a/frontend/src/metabase/components/Detail.jsx b/frontend/src/metabase/reference/components/Detail.jsx
similarity index 87%
rename from frontend/src/metabase/components/Detail.jsx
rename to frontend/src/metabase/reference/components/Detail.jsx
index 9e9a6766fffac6473af49fb48bfa540774f67675..c6d76d55c70bd1ab5071e1f9cf371e00e069eca0 100644
--- a/frontend/src/metabase/components/Detail.jsx
+++ b/frontend/src/metabase/reference/components/Detail.jsx
@@ -18,9 +18,11 @@ const Detail = ({ name, description, placeholder, subtitleClass, url, icon, isEd
             <div className={cx(description ? S.detailSubtitle : S.detailSubtitleLight, { "mt1" : true })}>
                 { isEditing ?
                     <textarea
-                        className={S.detailTextArea}
+                        className={S.detailTextarea}
                         placeholder={placeholder}
                         {...field}
+                        //FIXME: use initialValues from redux forms instead of default value
+                        // to allow for reinitializing on cancel (see ReferenceGettingStartedGuide.jsx)
                         defaultValue={description}
                     /> :
                     <span className={subtitleClass}>{description || placeholder || 'No description yet'}</span>
diff --git a/frontend/src/metabase/reference/components/EditButton.css b/frontend/src/metabase/reference/components/EditButton.css
new file mode 100644
index 0000000000000000000000000000000000000000..41a46282c02ee031aa5e54dfd958ae44657c77c8
--- /dev/null
+++ b/frontend/src/metabase/reference/components/EditButton.css
@@ -0,0 +1,15 @@
+:local(.editButton) {
+    composes: flex align-center text-dark p0 mx1 from "style";
+    color: var(--primary-button-bg-color);
+    font-weight: normal;
+    font-size: 16px;
+}
+
+:local(.editButton):hover {
+    color: color(var(--primary-button-border-color) shade(10%));
+    transition: color .3s linear;
+}
+
+:local(.editButtonBody) {
+    composes: flex align-center relative from "style";
+}
\ No newline at end of file
diff --git a/frontend/src/metabase/reference/components/EditButton.jsx b/frontend/src/metabase/reference/components/EditButton.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..fe3a34779fcd078bd9b067f3beb973177fcdca79
--- /dev/null
+++ b/frontend/src/metabase/reference/components/EditButton.jsx
@@ -0,0 +1,29 @@
+import React, { Component, PropTypes } from "react";
+import cx from "classnames";
+import pure from "recompose/pure";
+
+import S from "./EditButton.css";
+
+import Icon from "metabase/components/Icon.jsx";
+
+const EditButton = ({
+    className,
+    startEditing
+}) =>
+    <button
+        className={cx("Button", "Button--borderless", S.editButton, className)}
+        type="button"
+        onClick={startEditing}
+    >
+        <div className={S.editButtonBody}>
+            <Icon name="pencil" size={16} />
+            <span className="ml1">Edit</span>
+        </div>
+    </button>
+
+EditButton.propTypes = {
+    className: PropTypes.string,
+    startEditing: PropTypes.func.isRequired
+};
+
+export default pure(EditButton);
diff --git a/frontend/src/metabase/reference/components/EditHeader.jsx b/frontend/src/metabase/reference/components/EditHeader.jsx
index 8c72546bcecdcbc261eedba55279b412f677c69b..116e82143a8300db3619a6d93b04d01bfbe5b422 100644
--- a/frontend/src/metabase/reference/components/EditHeader.jsx
+++ b/frontend/src/metabase/reference/components/EditHeader.jsx
@@ -9,6 +9,7 @@ import RevisionMessageModal from "metabase/reference/components/RevisionMessageM
 const EditHeader = ({
     hasRevisionHistory,
     endEditing,
+    reinitializeForm = () => undefined,
     submitting,
     onSubmit,
     revisionMessageFormField
@@ -44,15 +45,19 @@ const EditHeader = ({
             <button
                 type="button"
                 className={cx("Button", "Button--white", "Button--small", S.cancelButton)}
-                onClick={endEditing}
+                onClick={() => {
+                    endEditing();
+                    reinitializeForm();
+                }}
             >
                 CANCEL
             </button>
         </div>
     </div>;
 EditHeader.propTypes = {
-    hasRevisionHistory: PropTypes.bool.isRequired,
+    hasRevisionHistory: PropTypes.bool,
     endEditing: PropTypes.func.isRequired,
+    reinitializeForm: PropTypes.func,
     submitting: PropTypes.bool.isRequired,
     onSubmit: PropTypes.func,
     revisionMessageFormField: PropTypes.object
diff --git a/frontend/src/metabase/reference/components/FieldTypeDetail.jsx b/frontend/src/metabase/reference/components/FieldTypeDetail.jsx
index cf454dffcfeee48e42617ba0307d78ceb2da2d90..c0ec97151b3d4ca836681c246e8350090e6a1917 100644
--- a/frontend/src/metabase/reference/components/FieldTypeDetail.jsx
+++ b/frontend/src/metabase/reference/components/FieldTypeDetail.jsx
@@ -9,7 +9,7 @@ import { isFK } from "metabase/lib/types";
 
 import Select from "metabase/components/Select.jsx";
 
-import D from "metabase/components/Detail.css";
+import D from "metabase/reference/components/Detail.css";
 
 const FieldTypeDetail = ({
     field,
diff --git a/frontend/src/metabase/reference/components/FieldsToGroupBy.jsx b/frontend/src/metabase/reference/components/FieldsToGroupBy.jsx
index 8a7f409222f55db76ee0329a93f6efac787491af..e5b77572f10ff70486b11e751e53d45baf64bd48 100644
--- a/frontend/src/metabase/reference/components/FieldsToGroupBy.jsx
+++ b/frontend/src/metabase/reference/components/FieldsToGroupBy.jsx
@@ -3,7 +3,7 @@ import cx from "classnames";
 import pure from "recompose/pure";
 
 import S from "./UsefulQuestions.css";
-import D from "metabase/components/Detail.css";
+import D from "metabase/reference/components/Detail.css";
 import L from "metabase/components/List.css";
 
 import {
@@ -13,7 +13,8 @@ import {
 import FieldToGroupBy from "metabase/reference/components/FieldToGroupBy.jsx";
 
 const FieldsToGroupBy = ({
-    table,
+    fields,
+    databaseId,
     metric,
     title,
     onChangeLocation
@@ -24,8 +25,7 @@ const FieldsToGroupBy = ({
                 <span className={D.detailName}>{title}</span>
             </div>
             <div className={S.usefulQuestions}>
-                { table && table.fields_lookup &&
-                    Object.values(table.fields_lookup)
+                { fields && Object.values(fields)
                         .map((field, index, fields) =>
                             <FieldToGroupBy
                                 key={field.id}
@@ -34,14 +34,14 @@ const FieldsToGroupBy = ({
                                 field={field}
                                 metric={metric}
                                 onClick={() => onChangeLocation(getQuestionUrl({
-                                        dbId: table.db_id,
-                                        tableId: table.id,
+                                        dbId: databaseId,
+                                        tableId: field.table_id,
                                         fieldId: field.id,
                                         metricId: metric.id
                                     }))}
                                 secondaryOnClick={(event) => {
                                     event.stopPropagation();
-                                    onChangeLocation(`/reference/databases/${table.db_id}/tables/${table.id}/fields/${field.id}`);
+                                    onChangeLocation(`/reference/databases/${databaseId}/tables/${field.table_id}/fields/${field.id}`);
                                 }}
                             />
                         )
@@ -50,7 +50,8 @@ const FieldsToGroupBy = ({
         </div>
     </div>;
 FieldsToGroupBy.propTypes = {
-    table: PropTypes.object.isRequired,
+    fields: PropTypes.object.isRequired,
+    databaseId: PropTypes.number.isRequired,
     metric: PropTypes.object.isRequired,
     title: PropTypes.string.isRequired,
     onChangeLocation: PropTypes.func.isRequired
diff --git a/frontend/src/metabase/reference/components/GuideDetail.jsx b/frontend/src/metabase/reference/components/GuideDetail.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..8a944134cdc86555ef39df7fd899af554ecc9d27
--- /dev/null
+++ b/frontend/src/metabase/reference/components/GuideDetail.jsx
@@ -0,0 +1,140 @@
+import React, { Component, PropTypes } from "react";
+import { Link } from "react-router";
+import pure from "recompose/pure";
+import cx from "classnames";
+import Icon from "metabase/components/Icon"
+
+import {
+    getQuestionUrl,
+    typeToBgClass,
+    typeToLinkClass,
+} from "../utils";
+
+const GuideDetail = ({
+    entity = {},
+    tables,
+    type,
+    exploreLinks,
+    detailLabelClasses
+}) => {
+    const title = entity.display_name || entity.name;
+    const { caveats, points_of_interest } = entity;
+    const typeToLink = {
+        dashboard: `/dash/${entity.id}`,
+        metric: getQuestionUrl({
+            dbId: tables[entity.table_id] && tables[entity.table_id].db_id,
+            tableId: entity.table_id,
+            metricId: entity.id
+        }),
+        segment: getQuestionUrl({
+            dbId: tables[entity.table_id] && tables[entity.table_id].db_id,
+            tableId: entity.table_id,
+            segmentId: entity.id
+        }),
+        table: getQuestionUrl({
+            dbId: entity.db_id,
+            tableId: entity.id
+        })
+    };
+    const link = typeToLink[type];
+    const typeToLearnMoreLink = {
+        metric: `/reference/metrics/${entity.id}`,
+        segment: `/reference/segments/${entity.id}`,
+        table: `/reference/databases/${entity.db_id}/tables/${entity.id}`
+    };
+    const learnMoreLink = typeToLearnMoreLink[type];
+
+    const linkClass = typeToLinkClass[type]
+    const linkHoverClass = `${typeToLinkClass[type]}-hover`
+    const bgClass = typeToBgClass[type]
+    const hasLearnMore = type === 'metric' || type === 'segment' || type === 'table';
+    const interestingOrImportant = type === 'dashboard' ? 'important' : 'interesting';
+
+    return <div className="relative mt2 pb3">
+        <div className="flex align-center">
+            <div style={{
+                width: 40,
+                height: 40,
+                left: -60
+            }}
+            className={cx('absolute text-white flex align-center justify-center', bgClass)}
+            >
+                <Icon name={type === 'metric' ? 'ruler' : type} />
+            </div>
+            { title && <ItemTitle link={link} title={title} linkColorClass={linkClass} linkHoverClass={linkHoverClass} /> }
+        </div>
+        <div className="mt2">
+            <ContextHeading>
+                { `Why this ${type} is ${interestingOrImportant}` }
+            </ContextHeading>
+
+            <ContextContent empty={!points_of_interest}>
+                {points_of_interest || `Nothing ${interestingOrImportant} yet`}
+            </ContextContent>
+
+            <div className="mt2">
+                <ContextHeading>
+                    {`Things to be aware of about this ${type}`}
+                </ContextHeading>
+
+                <ContextContent empty={!caveats}>
+                    {caveats || 'Nothing to be aware of yet'}
+                </ContextContent>
+            </div>
+
+            { exploreLinks && exploreLinks.length > 0 && [
+                <div className="mt2">
+                    <ContextHeading key="detailLabel">Explore this metric</ContextHeading>,
+                    <div key="detailLinks">
+                        <Link className="text-brand inline-block mr2 link text-bold" to={link}>View this metric</Link>
+                        { exploreLinks.map(link =>
+                            <Link
+                                className="inline-block text-bold text-brand mr2 link"
+                                key={link.url}
+                                to={link.url}
+                            >
+                                {`By ${link.name}`}
+                            </Link>
+                        )}
+                    </div>
+                </div>
+            ]}
+            { hasLearnMore &&
+                <Link
+                    className={cx('block mt3 no-decoration text-underline-hover text-bold', linkClass)}
+                    to={learnMoreLink}
+                >
+                    Learn more
+                </Link>
+            }
+        </div>
+    </div>;
+};
+
+GuideDetail.propTypes = {
+    entity: PropTypes.object,
+    type: PropTypes.string,
+    exploreLinks: PropTypes.array
+};
+
+const ItemTitle = ({ title, link, linkColorClass, linkHoverClass }) =>
+    <h2>
+        <Link
+            className={ cx(linkColorClass, linkHoverClass) }
+            style={{ textDecoration: 'none' }}
+            to={ link }
+        >
+            { title }
+        </Link>
+    </h2>
+
+const ContextHeading = ({ children }) =>
+    <h3 className="mb1 text-grey-4">{ children }</h3>
+
+const ContextContent = ({ empty, children }) =>
+    <p className={cx('m0 text-paragraph text-measure', { 'text-grey-3': empty })}>
+        { children }
+    </p>
+
+
+export default pure(GuideDetail);
diff --git a/frontend/src/metabase/reference/components/GuideDetailEditor.css b/frontend/src/metabase/reference/components/GuideDetailEditor.css
new file mode 100644
index 0000000000000000000000000000000000000000..308f16906011cae13ab304f4e108ad74387e0cef
--- /dev/null
+++ b/frontend/src/metabase/reference/components/GuideDetailEditor.css
@@ -0,0 +1,16 @@
+:local(.guideDetailEditor):last-child {
+    margin-bottom: 0;
+}
+
+:local(.guideDetailEditorTextarea) {
+    composes: text-dark input p2 mb4 from "style";
+    resize: none;
+    font-size: 16px;
+    width: 100%;
+    min-height: 100px;
+    background-color: unset;
+}
+
+:local(.guideDetailEditorTextarea):last-child {
+    margin-bottom: 0;
+}
diff --git a/frontend/src/metabase/reference/components/GuideDetailEditor.jsx b/frontend/src/metabase/reference/components/GuideDetailEditor.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..86936f2993d7a1e1acf12815393293b07b416ab7
--- /dev/null
+++ b/frontend/src/metabase/reference/components/GuideDetailEditor.jsx
@@ -0,0 +1,223 @@
+import React, { Component, PropTypes } from "react";
+// FIXME: using pure seems to mess with redux form updates
+// import pure from "recompose/pure";
+import cx from "classnames";
+
+import S from "./GuideDetailEditor.css";
+
+import Select from "metabase/components/Select.jsx";
+import Icon from "metabase/components/Icon.jsx";
+import DataSelector from "metabase/query_builder/DataSelector.jsx";
+import Tooltip from "metabase/components/Tooltip.jsx";
+
+import { typeToBgClass } from "../utils.js";
+
+const GuideDetailEditor = ({
+    className,
+    type,
+    entities,
+    metadata = {},
+    selectedIds = [],
+    selectedIdTypePairs = [],
+    formField,
+    removeField,
+    editLabelClasses
+}) => {
+    const {
+        databases,
+        tables,
+        segments,
+        metrics,
+        fields,
+        metricImportantFields
+    } = metadata;
+
+    const bgClass = typeToBgClass[type];
+    const entityId = formField.id.value;
+    const disabled = formField.id.value === null || formField.id.value === undefined
+    const tableId = metrics && metrics[entityId] && metrics[entityId].table_id;
+    const tableFields = tables && tables[tableId] && tables[tableId].fields || [];
+    const fieldsByMetric = type === 'metric' ?
+        tableFields.map(fieldId => fields[fieldId]) :
+        [];
+
+    const selectClasses = 'input h3 px2 py1'
+
+    return <div className={cx('mb2 border-bottom pb4 text-measure', className)}>
+        <div className="relative mt2 flex align-center">
+            <div
+                style={{
+                    width: 40,
+                    height: 40,
+                    left: -60
+                }}
+                className={cx(
+                    'absolute text-white flex align-center justify-center',
+                    bgClass
+                )}
+            >
+                <Icon name={type === 'metric' ? 'ruler' : type} />
+            </div>
+            <div className="py2">
+                { entities ?
+                    <Select 
+                        className={selectClasses}
+                        value={entities[formField.id.value]}
+                        options={Object.values(entities)}
+                        disabledOptionIds={selectedIds}
+                        optionNameFn={option => option.display_name || option.name}
+                        onChange={(entity) => {
+                            //TODO: refactor into function
+                            formField.id.onChange(entity.id);
+                            formField.points_of_interest.onChange(entity.points_of_interest || '');
+                            formField.caveats.onChange(entity.caveats || '');
+                            if (type === 'metric') {
+                                formField.important_fields.onChange(metricImportantFields[entity.id] &&
+                                    metricImportantFields[entity.id]
+                                        .map(fieldId => fields[fieldId])
+                                );
+                            }
+                        }}
+                        placeholder={'Select...'}
+                    /> :
+                    <DataSelector
+                        className={cx(selectClasses, 'inline-block', 'rounded', 'text-bold')}
+                        triggerIconSize={12}
+                        includeTables={true}
+                        query={{
+                            query: {
+                                source_table: formField.type.value === 'table' &&
+                                    Number.parseInt(formField.id.value)
+                            },
+                            database: (
+                                formField.type.value === 'table' &&
+                                tables[formField.id.value] &&
+                                tables[formField.id.value].db_id
+                            ) || Number.parseInt(Object.keys(databases)[0]),
+                            segment: formField.type.value === 'segment' &&
+                                Number.parseInt(formField.id.value)
+                        }}
+                        databases={
+                            Object.values(databases)
+                                .map(database => ({
+                                    ...database, 
+                                    tables: database.tables.map(tableId => tables[tableId])
+                                }))
+                        }
+                        setDatabaseFn={() => null}
+                        tables={Object.values(tables)}
+                        disabledTableIds={selectedIdTypePairs
+                            .filter(idTypePair => idTypePair[1] === 'table')
+                            .map(idTypePair => idTypePair[0])
+                        }
+                        setSourceTableFn={(tableId) => {
+                            const table = tables[tableId]; 
+                            formField.id.onChange(table.id);
+                            formField.type.onChange('table');
+                            formField.points_of_interest.onChange(table.points_of_interest || '');
+                            formField.caveats.onChange(table.caveats || '');
+                        }}
+                        segments={Object.values(segments)}
+                        disabledSegmentIds={selectedIdTypePairs
+                            .filter(idTypePair => idTypePair[1] === 'segment')
+                            .map(idTypePair => idTypePair[0])
+                        }
+                        setSourceSegmentFn={(segmentId) => {
+                            const segment = segments[segmentId]; 
+                            formField.id.onChange(segment.id);
+                            formField.type.onChange('segment');
+                            formField.points_of_interest.onChange(segment.points_of_interest || '');
+                            formField.caveats.onChange(segment.caveats || '');
+                        }}
+                    />
+                }
+            </div>
+            <div className="ml-auto cursor-pointer text-grey-2">
+                <Tooltip tooltip="Remove item">
+                    <Icon
+                        name="close"
+                        width={16}
+                        height={16}
+                        onClick={removeField}
+                    />
+                </Tooltip>
+            </div>
+        </div>
+        <div className="mt2 text-measure">
+            <div className={cx('mb2', { 'disabled' : disabled })}>
+                <EditLabel>
+                    { type === 'dashboard' ?
+                            `Why is this dashboard the most important?` :
+                            `What is useful or interesting about this ${type}?` 
+                    }
+                </EditLabel>
+                <textarea 
+                    className={S.guideDetailEditorTextarea}
+                    placeholder="Write something helpful here"
+                    {...formField.points_of_interest}
+                    disabled={disabled}
+                />
+            </div>
+
+            <div className={cx('mb2', { 'disabled' : disabled })}>
+                <EditLabel>
+                    { type === 'dashboard' ?
+                            `Is there anything users of this dashboard should be aware of?` :
+                            `Anything users should be aware of about this ${type}?` 
+                    }
+                </EditLabel>           
+                <textarea 
+                    className={S.guideDetailEditorTextarea} 
+                    placeholder="Write something helpful here"
+                    {...formField.caveats}
+                    disabled={disabled}
+                />
+            </div>
+            { type === 'metric' && 
+                <div className={cx('mb2', { 'disabled' : disabled })}>
+                    <EditLabel key="metricFieldsLabel">
+                        Which 2-3 fields do you usually group this metric by?
+                    </EditLabel>
+                    <Select
+                        className={cx(selectClasses, 'inline-block')}
+                        key="metricFieldsSelect"
+                        triggerClasses={cx('px2', S.guideDetailEditorSelect)}
+                        options={fieldsByMetric} 
+                        optionNameFn={option => option.display_name || option.name}
+                        placeholder="Select..."
+                        values={formField.important_fields.value || []}
+                        disabledOptionIds={formField.important_fields.value && formField.important_fields.value.length === 3 ?
+                            fieldsByMetric
+                                .filter(field => !formField.important_fields.value.includes(field))
+                                .map(field => field.id) :
+                            []
+                        }
+                        onChange={(field) => {
+                            const importantFields = formField.important_fields.value || [];
+                            return importantFields.includes(field) ?
+                                formField.important_fields.onChange(importantFields.filter(importantField => importantField !== field)) :
+                                importantFields.length < 3 && formField.important_fields.onChange(importantFields.concat(field));
+                        }}
+                        disabled={formField.id.value === null || formField.id.value === undefined}
+                    />
+                </div>
+            }
+        </div>
+    </div>;
+};
+
+const EditLabel = ({ children } ) =>
+    <h3 className="mb1">{ children }</h3>
+
+GuideDetailEditor.propTypes = {
+    className: PropTypes.string,
+    type: PropTypes.string.isRequired,
+    entities: PropTypes.object,
+    metadata: PropTypes.object,
+    selectedIds: PropTypes.array,
+    selectedIdTypePairs: PropTypes.array,
+    formField: PropTypes.object.isRequired,
+    removeField: PropTypes.func.isRequired
+};
+
+export default GuideDetailEditor;
diff --git a/frontend/src/metabase/reference/components/GuideEditSection.css b/frontend/src/metabase/reference/components/GuideEditSection.css
new file mode 100644
index 0000000000000000000000000000000000000000..409bc25d2387c9c730c80f282a816948b8d78313
--- /dev/null
+++ b/frontend/src/metabase/reference/components/GuideEditSection.css
@@ -0,0 +1,21 @@
+:local(.guideEditSectionCollapsed) {
+    composes: flex flex-full align-center mt4 p3 input text-brand text-bold from "style";
+    font-size: 16px;
+}
+
+:local(.guideEditSectionDisabled) {
+    composes: text-grey-3 from "style";
+}
+
+:local(.guideEditSectionCollapsedIcon) {
+    composes: mr3 from "style";
+}
+
+:local(.guideEditSectionCollapsedTitle) {
+    composes: flex-full mr3 from "style";
+}
+
+:local(.guideEditSectionCollapsedLink) {
+    composes: text-brand no-decoration from "style";
+    font-size: 14px;
+}
\ No newline at end of file
diff --git a/frontend/src/metabase/reference/components/GuideEditSection.jsx b/frontend/src/metabase/reference/components/GuideEditSection.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..f8e416a928dd48be5191f6fa7068da770931c65e
--- /dev/null
+++ b/frontend/src/metabase/reference/components/GuideEditSection.jsx
@@ -0,0 +1,66 @@
+import React, { Component, PropTypes } from "react";
+import { Link } from "react-router";
+import pure from "recompose/pure";
+import cx from "classnames";
+
+import S from "./GuideEditSection.css";
+
+import Icon from "metabase/components/Icon.jsx";
+
+const GuideEditSection = ({
+    children,
+    isCollapsed,
+    isDisabled,
+    showLink,
+    collapsedIcon,
+    collapsedTitle,
+    linkMessage,
+    link,
+    action,
+    expand
+}) => isCollapsed ?
+    <div
+        className={cx(
+            'text-measure',
+            S.guideEditSectionCollapsed,
+            {
+                'cursor-pointer border-brand-hover': !isDisabled,
+                [S.guideEditSectionDisabled]: isDisabled
+            }
+        )}
+        onClick={!isDisabled && expand}
+    >
+        <Icon className={S.guideEditSectionCollapsedIcon} name={collapsedIcon} size={24} />
+        <span className={S.guideEditSectionCollapsedTitle}>{collapsedTitle}</span>
+        {(showLink || isDisabled) && (link ? (link.startsWith('http') ?
+                <a
+                    className={S.guideEditSectionCollapsedLink}
+                    href={link}
+                    target="_blank"
+                >
+                    {linkMessage}
+                </a> :
+                <Link
+                    className={S.guideEditSectionCollapsedLink}
+                    to={link}
+                >
+                    {linkMessage}
+                </Link>
+            ) :
+            action &&
+                <a
+                    className={S.guideEditSectionCollapsedLink}
+                    onClick={action}
+                >
+                    {linkMessage}
+                </a>
+        )}
+    </div> :
+    <div className={cx('my4', S.guideEditSection)}>
+        {children}
+    </div>;
+GuideEditSection.propTypes = {
+    isCollapsed: PropTypes.bool.isRequired
+};
+
+export default pure(GuideEditSection);
diff --git a/frontend/src/metabase/reference/components/GuideEmptyState.css b/frontend/src/metabase/reference/components/GuideEmptyState.css
new file mode 100644
index 0000000000000000000000000000000000000000..b0aa96a73a4333821594e3997cf8afc3a08029b0
--- /dev/null
+++ b/frontend/src/metabase/reference/components/GuideEmptyState.css
@@ -0,0 +1,25 @@
+:local(.guideEmpty) {
+    composes: flex full justify-center from "style";
+    padding-top: 75px;
+}
+
+:local(.guideEmptyWrapper) {
+    composes: text-centered from "style";
+    width: 550px;
+}
+
+:local(.guideEmptyBody) {
+    composes: flex justify-center align-center mb4 from "style";
+    flex-direction: column;
+}
+
+:local(.guideEmptyMessage) {
+    composes: text-dark text-centered mt3 from "style";
+    max-width: 450px;
+    font-size: 1.1em;
+    line-height: 1.457em;
+}
+
+:local(.guideEmptyAction) {
+    composes: pt4 border-top from "style";
+}
\ No newline at end of file
diff --git a/frontend/src/metabase/reference/components/GuideEmptyState.jsx b/frontend/src/metabase/reference/components/GuideEmptyState.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..7aa664448bfe0943ce0ee6601e16b4eb918ef5dd
--- /dev/null
+++ b/frontend/src/metabase/reference/components/GuideEmptyState.jsx
@@ -0,0 +1,31 @@
+import React, { Component, PropTypes } from "react";
+import pure from "recompose/pure";
+
+import S from "./GuideEmptyState.css";
+
+const GuideEmptyState = ({
+    isSuperuser,
+    startEditing
+}) =>
+    <div className={S.guideEmpty}>
+        <div className={S.guideEmptyWrapper}>
+            <div className={S.guideEmptyBody}>
+                <img className="mb4" src={`/app/img/lightbulb.png`} height="200px" alt="Lightbulb" srcSet={`/app/img/lightbulb@2x.png 2x`} />
+                <h1 className="text-bold text-dark">Understanding our data</h1>
+                <span className={S.guideEmptyMessage}>This guide lets you explore all the metrics, segments, and raw data that we currently have in Metabase. Select a section on the left to learn more about our data.</span>
+            </div>
+            { isSuperuser && 
+                <div className={S.guideEmptyAction}>
+                    <button className="Button Button--large Button--primary" onClick={startEditing}>Create a custom Getting Started guide</button>
+                </div>
+            }
+        </div>
+    </div>;
+GuideEmptyState.propTypes = {
+    isSuperuser: PropTypes.bool.isRequired,
+    startEditing: PropTypes.func.isRequired
+};
+
+export default pure(GuideEmptyState);
+
+
diff --git a/frontend/src/metabase/reference/components/GuideHeader.jsx b/frontend/src/metabase/reference/components/GuideHeader.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..28a37f070506960c1adeef68496bc3646248381f
--- /dev/null
+++ b/frontend/src/metabase/reference/components/GuideHeader.jsx
@@ -0,0 +1,29 @@
+import React, { Component, PropTypes } from "react";
+import pure from "recompose/pure";
+
+import EditButton from "metabase/reference/components/EditButton.jsx";
+
+const GuideHeader = ({
+    startEditing,
+    isSuperuser
+}) =>
+    <div>
+        <div className="wrapper wrapper--trim py4 my3">
+            <div className="flex align-center">
+                <h1 className="text-dark" style={{fontWeight: 700}}>Start here.</h1>
+                { isSuperuser &&
+                    <span className="ml-auto">
+                        <EditButton startEditing={startEditing}/>
+                    </span>
+                }
+            </div>
+            <p className="text-paragraph" style={{maxWidth: 620}}>This is the perfect place to start if you’re new to your company’s data, or if you just want to check in on what’s going on.</p>
+        </div>
+    </div>;
+
+GuideHeader.propTypes = {
+    startEditing: PropTypes.func.isRequired,
+    isSuperuser: PropTypes.bool
+};
+
+export default pure(GuideHeader);
diff --git a/frontend/src/metabase/reference/components/MetricImportantFieldsDetail.jsx b/frontend/src/metabase/reference/components/MetricImportantFieldsDetail.jsx
new file mode 100644
index 0000000000000000000000000000000000000000..1fbf5afb469053cacad2a40fade6fabefaa5e3cd
--- /dev/null
+++ b/frontend/src/metabase/reference/components/MetricImportantFieldsDetail.jsx
@@ -0,0 +1,70 @@
+import React, { Component, PropTypes } from "react";
+import cx from "classnames";
+import pure from "recompose/pure";
+
+import FieldsToGroupBy from "metabase/reference/components/FieldsToGroupBy.jsx";
+
+import Select from "metabase/components/Select.jsx";
+
+import D from "metabase/reference/components/Detail.css";
+
+const MetricImportantFieldsDetail = ({
+    fields,
+    metric,
+    table,
+    allFields,
+    isEditing,
+    onChangeLocation,
+    formField
+}) => isEditing ? 
+    <div className={cx(D.detail)}>
+        <div className={D.detailBody}>
+            <div className={D.detailTitle}>
+                <span className={D.detailName}>
+                    Which 2-3 fields do you usually group this metric by?
+                </span>
+            </div>
+            <div className={cx(D.detailSubtitle, { "mt1" : true })}>
+                <Select
+                    key="metricFieldsSelect"
+                    triggerClasses="input p1 block"
+                    options={table.fields.map(fieldId => allFields[fieldId])} 
+                    optionNameFn={option => option.display_name || option.name}
+                    placeholder="Select..."
+                    values={formField.value || []}
+                    disabledOptionIds={formField.value && formField.value.length === 3 ?
+                        table.fields
+                            .map(fieldId => allFields[fieldId])
+                            .filter(field => !formField.value.includes(field))
+                            .map(field => field.id) :
+                        []
+                    }
+                    onChange={(field) => {
+                        const importantFields = formField.value || [];
+                        return importantFields.includes(field) ?
+                            formField.onChange(importantFields.filter(importantField => importantField !== field)) :
+                            importantFields.length < 3 && formField.onChange(importantFields.concat(field));
+                    }}
+                />
+            </div>
+        </div>
+    </div> : 
+    fields ? 
+        <FieldsToGroupBy
+            fields={fields}
+            databaseId={table.db_id} 
+            metric={metric}
+            title={"Most useful fields to group this metric by"}
+            onChangeLocation={onChangeLocation}
+        /> :
+        null; 
+MetricImportantFieldsDetail.propTypes = {
+    fields: PropTypes.object,
+    metric: PropTypes.object.isRequired,
+    table: PropTypes.object.isRequired,
+    isEditing: PropTypes.bool.isRequired,
+    onChangeLocation: PropTypes.func.isRequired,
+    formField: PropTypes.object.isRequired
+};
+
+export default pure(MetricImportantFieldsDetail);
diff --git a/frontend/src/metabase/reference/components/ReferenceHeader.css b/frontend/src/metabase/reference/components/ReferenceHeader.css
index 05d27f0d2ad78b37b522a8f29c70816db142064c..8199cae6abc47e902e9731704a0ac3bb7e8838c0 100644
--- a/frontend/src/metabase/reference/components/ReferenceHeader.css
+++ b/frontend/src/metabase/reference/components/ReferenceHeader.css
@@ -4,7 +4,7 @@
 }
 
 :local(.headerBody) {
-    composes: flex flex-full border-bottom from "style";
+    composes: flex flex-full border-bottom text-dark text-bold from "style";
     overflow: hidden;
     align-items: center;
     border-color: #EDF5FB;
@@ -38,18 +38,6 @@
     transition: color .3s linear;
 }
 
-:local(.editButton) {
-    composes: text-dark p0 mx1 from "style";
-    color: var(--primary-button-bg-color);
-    font-weight: normal;
-    font-size: 16px;
-}
-
-:local(.editButton):hover {
-    color: color(var(--primary-button-border-color) shade(10%));
-    transition: color .3s linear;
-}
-
 :local(.headerSchema) {
     composes: text-grey-2 absolute from "style";
     left: var(--icon-width);
diff --git a/frontend/src/metabase/reference/components/ReferenceHeader.jsx b/frontend/src/metabase/reference/components/ReferenceHeader.jsx
index bc14089bfc99e472161645a65ab7ce71222dd17f..21a718a30e020e3748fb145455e567b326cf6a4e 100644
--- a/frontend/src/metabase/reference/components/ReferenceHeader.jsx
+++ b/frontend/src/metabase/reference/components/ReferenceHeader.jsx
@@ -5,10 +5,13 @@ import pure from "recompose/pure";
 
 import S from "./ReferenceHeader.css";
 import L from "metabase/components/List.css";
+import E from "metabase/reference/components/EditButton.css";
 
 import IconBorder from "metabase/components/IconBorder.jsx";
 import Icon from "metabase/components/Icon.jsx";
 import Ellipsified from "metabase/components/Ellipsified.jsx";
+import EditButton from "metabase/reference/components/EditButton.jsx";
+
 
 const ReferenceHeader = ({
     entity = {},
@@ -76,14 +79,14 @@ const ReferenceHeader = ({
                             }
                         </Ellipsified>,
                         section.headerLink &&
-                            <div key="2" className={cx("flex-full", L.headerButton)}>
+                            <div key="2" className={cx("flex-full", S.headerButton)}>
                                 <Link
                                     to={section.headerLink}
-                                    className={cx("Button", "Button--borderless", S.editButton)}
+                                    className={cx("Button", "Button--borderless", "ml3", E.editButton)}
                                     data-metabase-event={`Data Reference;Entity -> QB click;${section.type}`}
                                 >
                                     <div className="flex align-center relative">
-                                        <span className="mr1">See this {section.type}</span>
+                                        <span className="mr1 flex-no-shrink">See this {section.type}</span>
                                         <Icon name="chevronright" size={16} />
                                     </div>
                                 </Link>
@@ -91,17 +94,7 @@ const ReferenceHeader = ({
                     ]
                 }
                 { user && user.is_superuser && !isEditing &&
-                    <div className={L.headerButton}>
-                        <a
-                            onClick={startEditing}
-                            className={cx("Button", "Button--borderless", S.editButton)}
-                        >
-                            <div className="flex align-center relative">
-                                <Icon name="pencil" size={16} />
-                                <span className="ml1">Edit</span>
-                            </div>
-                        </a>
-                    </div>
+                    <EditButton className="ml1" startEditing={startEditing} />
                 }
             </div>
         </div>
diff --git a/frontend/src/metabase/reference/components/UsefulQuestions.jsx b/frontend/src/metabase/reference/components/UsefulQuestions.jsx
index 7e996cf40106d0ce9c25b34b9f66dcd70608259a..0c7e49a463a77860fca9fb1122de35f00f27b1b2 100644
--- a/frontend/src/metabase/reference/components/UsefulQuestions.jsx
+++ b/frontend/src/metabase/reference/components/UsefulQuestions.jsx
@@ -3,7 +3,7 @@ import cx from "classnames";
 import pure from "recompose/pure";
 
 import S from "./UsefulQuestions.css";
-import D from "metabase/components/Detail.css";
+import D from "metabase/reference/components/Detail.css";
 import L from "metabase/components/List.css";
 
 import QueryButton from "metabase/components/QueryButton.jsx";
diff --git a/frontend/src/metabase/reference/containers/ReferenceApp.jsx b/frontend/src/metabase/reference/containers/ReferenceApp.jsx
index b214c74d7432f1b44d739ea837e6552102f0a6ed..8152a108017d2a82d0fa8c23d2578703c8dc46ad 100644
--- a/frontend/src/metabase/reference/containers/ReferenceApp.jsx
+++ b/frontend/src/metabase/reference/containers/ReferenceApp.jsx
@@ -26,6 +26,10 @@ import {
     selectSection as fetchQuestions
 } from 'metabase/questions/questions';
 
+import {
+    fetchDashboards
+} from 'metabase/dashboard/dashboard';
+
 const mapStateToProps = (state, props) => ({
     sectionId: getSectionId(state, props),
     databaseId: getDatabaseId(state, props),
@@ -37,6 +41,7 @@ const mapStateToProps = (state, props) => ({
 
 const mapDispatchToProps = {
     fetchQuestions,
+    fetchDashboards,
     ...metadataActions,
     ...actions
 };
@@ -73,10 +78,16 @@ export default class ReferenceApp extends Component {
     render() {
         const {
             children,
+            section,
             sections,
             breadcrumbs,
             isEditing
         } = this.props;
+
+        if (section.sidebar === false) {
+            return children;
+        }
+
         return (
             <SidebarLayout
                 className="flex-full relative"
@@ -85,6 +96,6 @@ export default class ReferenceApp extends Component {
             >
                 {children}
             </SidebarLayout>
-        )
+        );
     }
 }
diff --git a/frontend/src/metabase/reference/containers/ReferenceEntity.jsx b/frontend/src/metabase/reference/containers/ReferenceEntity.jsx
index bf4622a03d5dd355e6f962ffd5f1c038f156658d..908a1fe84e316d6c6251da5e1620d491fc263912 100644
--- a/frontend/src/metabase/reference/containers/ReferenceEntity.jsx
+++ b/frontend/src/metabase/reference/containers/ReferenceEntity.jsx
@@ -8,15 +8,16 @@ import { push } from "react-router-redux";
 import S from "metabase/reference/Reference.css";
 
 import List from "metabase/components/List.jsx";
-import Detail from "metabase/components/Detail.jsx";
 import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
 
 import EditHeader from "metabase/reference/components/EditHeader.jsx";
 import ReferenceHeader from "metabase/reference/components/ReferenceHeader.jsx";
+import Detail from "metabase/reference/components/Detail.jsx";
 import FieldTypeDetail from "metabase/reference/components/FieldTypeDetail.jsx";
 import UsefulQuestions from "metabase/reference/components/UsefulQuestions.jsx";
 import FieldsToGroupBy from "metabase/reference/components/FieldsToGroupBy.jsx";
 import Formula from "metabase/reference/components/Formula.jsx";
+import MetricImportantFieldsDetail from "metabase/reference/components/MetricImportantFieldsDetail.jsx";
 
 import {
     tryUpdateData
@@ -26,6 +27,8 @@ import {
     getSection,
     getData,
     getTable,
+    getFields,
+    getGuide,
     getError,
     getLoading,
     getUser,
@@ -41,22 +44,39 @@ import {
 import * as metadataActions from 'metabase/redux/metadata';
 import * as actions from 'metabase/reference/reference';
 
-const mapStateToProps = (state, props) => ({
-    section: getSection(state, props),
-    entity: getData(state, props) || {},
-    table: getTable(state, props),
-    loading: getLoading(state, props),
-    // naming this 'error' will conflict with redux form
-    loadingError: getError(state, props),
-    user: getUser(state, props),
-    foreignKeys: getForeignKeys(state, props),
-    isEditing: getIsEditing(state, props),
-    hasSingleSchema: getHasSingleSchema(state, props),
-    hasQuestions: getHasQuestions(state, props),
-    hasDisplayName: getHasDisplayName(state, props),
-    isFormulaExpanded: getIsFormulaExpanded(state, props),
-    hasRevisionHistory: getHasRevisionHistory(state, props)
-});
+const mapStateToProps = (state, props) => {
+    const entity = getData(state, props) || {};
+    const guide = getGuide(state, props);
+    const fields = getFields(state, props);
+    
+    const initialValues = {
+        important_fields: guide && guide.metric_important_fields &&
+            guide.metric_important_fields[entity.id] &&
+            guide.metric_important_fields[entity.id]
+                .map(fieldId => fields[fieldId]) ||
+                []
+    };
+
+    return {
+        section: getSection(state, props),
+        entity,
+        table: getTable(state, props),
+        metadataFields: fields,
+        guide,
+        loading: getLoading(state, props),
+        // naming this 'error' will conflict with redux form
+        loadingError: getError(state, props),
+        user: getUser(state, props),
+        foreignKeys: getForeignKeys(state, props),
+        isEditing: getIsEditing(state, props),
+        hasSingleSchema: getHasSingleSchema(state, props),
+        hasQuestions: getHasQuestions(state, props),
+        hasDisplayName: getHasDisplayName(state, props),
+        isFormulaExpanded: getIsFormulaExpanded(state, props),
+        hasRevisionHistory: getHasRevisionHistory(state, props),
+        initialValues,
+    }
+};
 
 const mapDispatchToProps = {
     ...metadataActions,
@@ -72,7 +92,7 @@ const validate = (values, props) => props.hasRevisionHistory ?
 @connect(mapStateToProps, mapDispatchToProps)
 @reduxForm({
     form: 'details',
-    fields: ['name', 'display_name', 'description', 'revision_message', 'points_of_interest', 'caveats', 'how_is_this_calculated', 'special_type', 'fk_target_field_id'],
+    fields: ['name', 'display_name', 'description', 'revision_message', 'points_of_interest', 'caveats', 'how_is_this_calculated', 'special_type', 'fk_target_field_id', 'important_fields'],
     validate
 })
 export default class ReferenceEntity extends Component {
@@ -80,6 +100,8 @@ export default class ReferenceEntity extends Component {
         style: PropTypes.object.isRequired,
         entity: PropTypes.object.isRequired,
         table: PropTypes.object,
+        metadataFields: PropTypes.object,
+        guide: PropTypes.object,
         user: PropTypes.object.isRequired,
         foreignKeys: PropTypes.object,
         isEditing: PropTypes.bool,
@@ -108,11 +130,13 @@ export default class ReferenceEntity extends Component {
 
     render() {
         const {
-            fields: { name, display_name, description, revision_message, points_of_interest, caveats, how_is_this_calculated, special_type, fk_target_field_id },
+            fields: { name, display_name, description, revision_message, points_of_interest, caveats, how_is_this_calculated, special_type, fk_target_field_id, important_fields },
             style,
             section,
             entity,
             table,
+            metadataFields,
+            guide,
             loadingError,
             loading,
             user,
@@ -128,6 +152,7 @@ export default class ReferenceEntity extends Component {
             isFormulaExpanded,
             hasRevisionHistory,
             handleSubmit,
+            resetForm,
             submitting,
             onChangeLocation
         } = this.props;
@@ -145,6 +170,7 @@ export default class ReferenceEntity extends Component {
                         hasRevisionHistory={hasRevisionHistory}
                         onSubmit={onSubmit}
                         endEditing={endEditing}
+                        reinitializeForm={resetForm}
                         submitting={submitting}
                         revisionMessageFormField={revision_message}
                     />
@@ -255,12 +281,39 @@ export default class ReferenceEntity extends Component {
                                     <UsefulQuestions questions={section.questions} />
                                 </li>
                             }
+                            { section.type === 'metric' &&
+                                <li className="relative">
+                                    <MetricImportantFieldsDetail
+                                        fields={guide && guide.metric_important_fields[entity.id] &&
+                                            Object.values(guide.metric_important_fields[entity.id])
+                                                .map(fieldId => metadataFields[fieldId])
+                                                .reduce((map, field) => ({ ...map, [field.id]: field }), {})
+                                        }
+                                        table={table}
+                                        allFields={metadataFields}
+                                        metric={entity}
+                                        onChangeLocation={onChangeLocation}
+                                        isEditing={isEditing}
+                                        formField={important_fields}
+                                    />
+                                </li>
+                            }
                             { section.type === 'metric' && !isEditing &&
                                 <li className="relative">
                                     <FieldsToGroupBy
-                                        table={table}
+                                        fields={table.fields
+                                            .filter(fieldId => !guide || !guide.metric_important_fields[entity.id] ||
+                                                !guide.metric_important_fields[entity.id].includes(fieldId)
+                                            )
+                                            .map(fieldId => metadataFields[fieldId])
+                                            .reduce((map, field) => ({ ...map, [field.id]: field }), {})
+                                        }
+                                        databaseId={table.db_id} 
                                         metric={entity}
-                                        title={"Fields you can group this metric by"}
+                                        title={ guide && guide.metric_important_fields[entity.id] ?
+                                            "Other fields you can group this metric by" :
+                                            "Fields you can group this metric by"
+                                        }
                                         onChangeLocation={onChangeLocation}
                                     />
                                 </li>
diff --git a/frontend/src/metabase/reference/containers/ReferenceFieldsList.jsx b/frontend/src/metabase/reference/containers/ReferenceFieldsList.jsx
index b6a7eaa65705a4cdf63bbdaaf4850878f7e64228..1f665afdf358e709ae94e72134f7aea221f2cf1a 100644
--- a/frontend/src/metabase/reference/containers/ReferenceFieldsList.jsx
+++ b/frontend/src/metabase/reference/containers/ReferenceFieldsList.jsx
@@ -87,7 +87,8 @@ export default class ReferenceEntityList extends Component {
         section: PropTypes.object.isRequired,
         loading: PropTypes.bool,
         loadingError: PropTypes.object,
-        submitting: PropTypes.bool
+        submitting: PropTypes.bool,
+        resetForm: PropTypes.func
     };
 
     render() {
@@ -104,6 +105,7 @@ export default class ReferenceEntityList extends Component {
             hasRevisionHistory,
             startEditing,
             endEditing,
+            resetForm,
             handleSubmit,
             submitting
         } = this.props;
@@ -117,6 +119,7 @@ export default class ReferenceEntityList extends Component {
                 { isEditing &&
                     <EditHeader
                         hasRevisionHistory={hasRevisionHistory}
+                        reinitializeForm={resetForm}
                         endEditing={endEditing}
                         submitting={submitting}
                     />
diff --git a/frontend/src/metabase/reference/containers/ReferenceGettingStartedGuide.jsx b/frontend/src/metabase/reference/containers/ReferenceGettingStartedGuide.jsx
index 42d68f66c2d11b9838641784e70ff3b6ecbdb7ac..8e403c24d2c36ed76b38be359096a3294f712b4f 100644
--- a/frontend/src/metabase/reference/containers/ReferenceGettingStartedGuide.jsx
+++ b/frontend/src/metabase/reference/containers/ReferenceGettingStartedGuide.jsx
@@ -1,17 +1,594 @@
 /* eslint "react/prop-types": "warn" */
 import React, { Component, PropTypes } from "react";
+import { Link } from "react-router";
+import { connect } from 'react-redux';
+import { push } from 'react-router-redux';
+import { reduxForm } from "redux-form";
+import i from "icepick";
 
-import S from "metabase/reference/Reference.css";
+import {
+    getQuestionUrl
+} from '../utils';
 
-import { pure } from "recompose";
+import MetabaseAnalytics from "metabase/lib/analytics";
 
-const ReferenceGettingStartedGuide = () =>
-    <div className={S.guideEmpty}>
-        <div className={S.guideEmptyBody}>
-            <img className="mb4" src={`/app/img/lightbulb.png`} height="200px" alt="Lightbulb" srcSet={`/app/img/lightbulb@2x.png 2x`} />
-            <h1 className="text-bold text-dark">Understanding our data</h1>
-            <div className={S.guideEmptyMessage}>This guide lets you explore all the metrics, segments, and raw data that we currently have in Metabase. Select a section on the left to learn more about our data.</div>
-        </div>
-    </div>
+import LoadingAndErrorWrapper from "metabase/components/LoadingAndErrorWrapper.jsx";
+import CreateDashboardModal from 'metabase/components/CreateDashboardModal.jsx';
+import Modal from 'metabase/components/Modal.jsx';
 
-export default pure(ReferenceGettingStartedGuide);
+import EditHeader from "metabase/reference/components/EditHeader.jsx";
+import GuideEmptyState from "metabase/reference/components/GuideEmptyState.jsx";
+import GuideHeader from "metabase/reference/components/GuideHeader.jsx";
+import GuideEditSection from "metabase/reference/components/GuideEditSection.jsx";
+import GuideDetail from "metabase/reference/components/GuideDetail.jsx";
+import GuideDetailEditor from "metabase/reference/components/GuideDetailEditor.jsx";
+
+import * as metadataActions from 'metabase/redux/metadata';
+import * as actions from 'metabase/reference/reference';
+import { clearRequestState } from "metabase/redux/requests";
+import {
+    updateDashboard,
+    createDashboard
+} from 'metabase/dashboard/dashboard';
+
+import {
+    updateSetting
+} from 'metabase/admin/settings/settings';
+
+import S from "../components/GuideDetailEditor.css";
+
+import {
+    getGuide,
+    getUser,
+    getDashboards,
+    getMetrics,
+    getSegments,
+    getTables,
+    getFields,
+    getDatabases,
+    getLoading,
+    getError,
+    getIsEditing,
+    getIsDashboardModalOpen
+} from '../selectors';
+
+import {
+    isGuideEmpty,
+    tryUpdateGuide
+} from '../utils';
+
+const mapStateToProps = (state, props) => {
+    const guide = getGuide(state, props);
+    const dashboards = getDashboards(state, props);
+    const metrics = getMetrics(state, props);
+    const segments = getSegments(state, props);
+    const tables = getTables(state, props);
+    const fields = getFields(state, props);
+    const databases = getDatabases(state, props);
+
+    // redux-form populates fields with stale values after update
+    // if we dont specify nulls here
+    // could use a lot of refactoring
+    const initialValues = guide && {
+        things_to_know: guide.things_to_know || null,
+        contact: guide.contact || {name: null, email: null},
+        most_important_dashboard: guide.most_important_dashboard !== null ?
+            dashboards[guide.most_important_dashboard] :
+            {},
+        important_metrics: guide.important_metrics && guide.important_metrics.length > 0 ?
+            guide.important_metrics
+                .map(metricId => metrics[metricId] && i.assoc(metrics[metricId], 'important_fields', guide.metric_important_fields[metricId] && guide.metric_important_fields[metricId].map(fieldId => fields[fieldId]))) :
+            [],
+        important_segments_and_tables:
+            (guide.important_segments && guide.important_segments.length > 0) ||
+            (guide.important_tables && guide.important_tables.length > 0) ?
+                guide.important_segments
+                    .map(segmentId => segments[segmentId] && i.assoc(segments[segmentId], 'type', 'segment'))
+                    .concat(guide.important_tables
+                        .map(tableId => tables[tableId] && i.assoc(tables[tableId], 'type', 'table'))
+                    ) :
+                []
+    };
+
+    return {
+        guide,
+        user: getUser(state, props),
+        dashboards,
+        metrics,
+        segments,
+        tables,
+        databases,
+        // FIXME: avoids naming conflict, tried using the propNamespace option
+        // version but couldn't quite get it to work together with passing in
+        // dynamic initialValues
+        metadataFields: fields,
+        loading: getLoading(state, props),
+        // naming this 'error' will conflict with redux form
+        loadingError: getError(state, props),
+        isEditing: getIsEditing(state, props),
+        isDashboardModalOpen: getIsDashboardModalOpen(state, props),
+        // redux form doesn't pass this through to component
+        // need to use to reset form field arrays
+        initialValues: initialValues,
+        initialFormValues: initialValues
+    };
+};
+
+const mapDispatchToProps = {
+    push,
+    updateDashboard,
+    createDashboard,
+    updateSetting,
+    clearRequestState,
+    ...metadataActions,
+    ...actions
+};
+
+@connect(mapStateToProps, mapDispatchToProps)
+@reduxForm({
+    form: 'guide',
+    fields: [
+        'things_to_know',
+        'contact.name',
+        'contact.email',
+        'most_important_dashboard.id',
+        'most_important_dashboard.caveats',
+        'most_important_dashboard.points_of_interest',
+        'important_metrics[].id',
+        'important_metrics[].caveats',
+        'important_metrics[].points_of_interest',
+        'important_metrics[].important_fields',
+        'important_segments_and_tables[].id',
+        'important_segments_and_tables[].type',
+        'important_segments_and_tables[].caveats',
+        'important_segments_and_tables[].points_of_interest'
+    ]
+})
+export default class ReferenceGettingStartedGuide extends Component {
+    static propTypes = {
+        fields: PropTypes.object,
+        style: PropTypes.object,
+        guide: PropTypes.object,
+        user: PropTypes.object,
+        dashboards: PropTypes.object,
+        metrics: PropTypes.object,
+        segments: PropTypes.object,
+        tables: PropTypes.object,
+        databases: PropTypes.object,
+        metadataFields: PropTypes.object,
+        loadingError: PropTypes.any,
+        loading: PropTypes.bool,
+        isEditing: PropTypes.bool,
+        startEditing: PropTypes.func,
+        endEditing: PropTypes.func,
+        handleSubmit: PropTypes.func,
+        submitting: PropTypes.bool,
+        initialFormValues: PropTypes.object,
+        initializeForm: PropTypes.func,
+        createDashboard: PropTypes.func,
+        isDashboardModalOpen: PropTypes.bool,
+        showDashboardModal: PropTypes.func,
+        hideDashboardModal: PropTypes.func,
+        push: PropTypes.func
+    };
+
+    render() {
+        const {
+            fields: {
+                things_to_know,
+                contact,
+                most_important_dashboard,
+                important_metrics,
+                important_segments_and_tables
+            },
+            style,
+            guide,
+            user,
+            dashboards,
+            metrics,
+            segments,
+            tables,
+            databases,
+            metadataFields,
+            loadingError,
+            loading,
+            isEditing,
+            startEditing,
+            endEditing,
+            handleSubmit,
+            submitting,
+            initialFormValues,
+            initializeForm,
+            createDashboard,
+            isDashboardModalOpen,
+            showDashboardModal,
+            hideDashboardModal,
+            push
+        } = this.props;
+
+        const onSubmit = handleSubmit(async (fields) =>
+            await tryUpdateGuide(fields, this.props)
+        );
+
+        const getSelectedIds = fields => fields
+            .map(field => field.id.value)
+            .filter(id => id !== null);
+
+        const getSelectedIdTypePairs = fields => fields
+            .map(field => [field.id.value, field.type.value])
+            .filter(idTypePair => idTypePair[0] !== null);
+
+        return (
+            <form className="full relative py4" style={style} onSubmit={onSubmit}>
+                { isDashboardModalOpen &&
+                    <Modal>
+                        <CreateDashboardModal
+                            createDashboardFn={async (newDashboard) => {
+                                try {
+                                    const action = await createDashboard(newDashboard, true);
+                                    push(`/dash/${action.payload.id}`);
+                                }
+                                catch(error) {
+                                    console.error(error);
+                                }
+
+                                MetabaseAnalytics.trackEvent("Dashboard", "Create");
+                            }}
+                            closeFn={hideDashboardModal}
+                        />
+                    </Modal>
+                }
+                { isEditing &&
+                    <EditHeader
+                        endEditing={endEditing}
+                        // resetForm doesn't reset field arrays
+                        reinitializeForm={() => initializeForm(initialFormValues)}
+                        submitting={submitting}
+                    />
+                }
+                <LoadingAndErrorWrapper className="full" style={style} loading={!loadingError && loading} error={loadingError}>
+                { () => isEditing ?
+                    <div className="wrapper wrapper--trim">
+                        <div className="mt4 py2">
+                            <h1 className="my3 text-dark">
+                                Help new Metabase users find their way around.
+                            </h1>
+                            <p className="text-paragraph text-measure">
+                                The Getting Started guide highlights the dashboard,
+                                metrics, segments, and tables that matter most,
+                                and informs your users of important things they
+                                should know before digging into the data.
+                            </p>
+                        </div>
+
+                        <GuideEditSection
+                            isCollapsed={most_important_dashboard.id.value === undefined}
+                            isDisabled={!dashboards || Object.keys(dashboards).length === 0}
+                            collapsedTitle="Is there an important dashboard for your team?"
+                            collapsedIcon="dashboard"
+                            linkMessage="Create a dashboard now"
+                            action={showDashboardModal}
+                            expand={() => most_important_dashboard.id.onChange(null)}
+                        >
+                            <div>
+                                <SectionHeader>
+                                    What is your most important dashboard?
+                                </SectionHeader>
+                                <GuideDetailEditor
+                                    type="dashboard"
+                                    entities={dashboards}
+                                    selectedIds={[most_important_dashboard.id.value]}
+                                    formField={most_important_dashboard}
+                                    removeField={() => {
+                                        most_important_dashboard.id.onChange(null);
+                                        most_important_dashboard.points_of_interest.onChange('');
+                                        most_important_dashboard.caveats.onChange('');
+                                    }}
+                                />
+                            </div>
+                        </GuideEditSection>
+
+                        <GuideEditSection
+                            isCollapsed={important_metrics.length === 0}
+                            isDisabled={!metrics || Object.keys(metrics).length === 0}
+                            collapsedTitle="Do you have any commonly referenced metrics?"
+                            collapsedIcon="ruler"
+                            linkMessage="Learn how to define a metric"
+                            link="http://www.metabase.com/docs/latest/administration-guide/05-segments-and-metrics#creating-a-metric"
+                            expand={() => important_metrics.addField({id: null, caveats: null, points_of_interest: null, important_fields: null})}
+                        >
+                            <div className="my2">
+                                <SectionHeader>
+                                    What are your 3-5 most commonly referenced metrics?
+                                </SectionHeader>
+                                <div>
+                                    { important_metrics.map((metricField, index, metricFields) =>
+                                        <GuideDetailEditor
+                                            key={index}
+                                            type="metric"
+                                            metadata={{
+                                                tables,
+                                                metrics,
+                                                fields: metadataFields,
+                                                metricImportantFields: guide.metric_important_fields
+                                            }}
+                                            entities={metrics}
+                                            formField={metricField}
+                                            selectedIds={getSelectedIds(metricFields)}
+                                            removeField={() => {
+                                                if (metricFields.length > 1) {
+                                                    return metricFields.removeField(index);
+                                                }
+                                                metricField.id.onChange(null);
+                                                metricField.points_of_interest.onChange('');
+                                                metricField.caveats.onChange('');
+                                                metricField.important_fields.onChange(null);
+                                            }}
+                                        />
+                                    )}
+                                </div>
+                                { important_metrics.length < 5 &&
+                                    important_metrics.length < Object.keys(metrics).length &&
+                                        <button
+                                            className="Button Button--primary Button--large"
+                                            type="button"
+                                            onClick={() => important_metrics.addField({id: null, caveats: null, points_of_interest: null})}
+                                        >
+                                            Add another metric
+                                        </button>
+                                }
+                            </div>
+                        </GuideEditSection>
+
+                        <GuideEditSection
+                            isCollapsed={important_segments_and_tables.length === 0}
+                            isDisabled={(!segments || Object.keys(segments).length === 0) && (!tables || Object.keys(tables).length === 0)}
+                            showLink={!segments || Object.keys(segments).length === 0}
+                            collapsedTitle="Do you have any commonly referenced segments or tables?"
+                            collapsedIcon="table2"
+                            linkMessage="Learn how to create a segment"
+                            link="http://www.metabase.com/docs/latest/administration-guide/05-segments-and-metrics#creating-a-segment"
+                            expand={() => important_segments_and_tables.addField({id: null, type: null, caveats: null, points_of_interest: null})}
+                        >
+                            <div>
+                                <h2 className="text-measure text-dark">
+                                    What are 3-5 commonly referenced segments or tables
+                                    that would be useful for this audience?
+                                </h2>
+                                <div className="mb2">
+                                    { important_segments_and_tables.map((segmentOrTableField, index, segmentOrTableFields) =>
+                                        <GuideDetailEditor
+                                            key={index}
+                                            type="segment"
+                                            metadata={{
+                                                databases,
+                                                tables,
+                                                segments
+                                            }}
+                                            formField={segmentOrTableField}
+                                            selectedIdTypePairs={getSelectedIdTypePairs(segmentOrTableFields)}
+                                            removeField={() => {
+                                                if (segmentOrTableFields.length > 1) {
+                                                    return segmentOrTableFields.removeField(index);
+                                                }
+                                                segmentOrTableField.id.onChange(null);
+                                                segmentOrTableField.type.onChange(null);
+                                                segmentOrTableField.points_of_interest.onChange('');
+                                                segmentOrTableField.caveats.onChange('');
+                                            }}
+                                        />
+                                    )}
+                                </div>
+                                { important_segments_and_tables.length < 5 &&
+                                    important_segments_and_tables.length < Object.keys(tables).concat(Object.keys.segments).length &&
+                                        <button
+                                            className="Button Button--primary Button--large"
+                                            type="button"
+                                            onClick={() => important_segments_and_tables.addField({id: null, type: null, caveats: null, points_of_interest: null})}
+                                        >
+                                            Add another segment or table
+                                        </button>
+                                }
+                            </div>
+                        </GuideEditSection>
+
+                        <GuideEditSection
+                            isCollapsed={things_to_know.value === null}
+                            isDisabled={false}
+                            collapsedTitle="Is there anything your users should understand or know before they start accessing the data?"
+                            collapsedIcon="reference"
+                            expand={() => things_to_know.onChange('')}
+                        >
+                            <div className="text-measure">
+                                <SectionHeader>
+                                    What should a user of this data know before they start
+                                    accessing it?
+                                </SectionHeader>
+                                <textarea
+                                    className={S.guideDetailEditorTextarea}
+                                    placeholder="E.g., expectations around data privacy and use,
+                                        common pitfalls or misunderstandings, information about
+                                        data warehouse performance, legal notices, etc."
+                                    {...things_to_know}
+                                />
+                            </div>
+                        </GuideEditSection>
+
+                        <GuideEditSection
+                            isCollapsed={contact.name.value === null && contact.email.value === null}
+                            isDisabled={false}
+                            collapsedTitle="Is there someone your users could contact for help if they're confused about this guide?"
+                            collapsedIcon="mail"
+                            expand={() => {
+                                contact.name.onChange('');
+                                contact.email.onChange('');
+                            }}
+                        >
+                            <div>
+                                <SectionHeader>
+                                    Who should users contact for help if they're confused about this data?
+                                </SectionHeader>
+                                <div className="flex">
+                                    <div className="flex-full">
+                                        <h3 className="mb1">Name</h3>
+                                        <input
+                                            className="input text-paragraph"
+                                            placeholder="Julie McHelpfulson"
+                                            type="text"
+                                            {...contact.name}
+                                        />
+                                    </div>
+                                    <div className="flex-full">
+                                        <h3 className="mb1">Email address</h3>
+                                        <input
+                                            className="input text-paragraph"
+                                            placeholder="julie.mchelpfulson@acme.com"
+                                            type="text"
+                                            {...contact.email}
+                                        />
+                                    </div>
+                                </div>
+                            </div>
+                        </GuideEditSection>
+                    </div> :
+                    !guide || isGuideEmpty(guide) ?
+                        <GuideEmptyState
+                            isSuperuser={user && user.is_superuser}
+                            startEditing={startEditing}
+                        /> :
+                        <div>
+                            <GuideHeader
+                                startEditing={startEditing}
+                                isSuperuser={user && user.is_superuser}
+                            />
+                            <div className="wrapper wrapper--trim">
+                                { guide.most_important_dashboard !== null && [
+                                    <div className="my2">
+                                        <SectionHeader key={'dashboardTitle'}>
+                                            Our most important dashboard
+                                        </SectionHeader>
+                                        <GuideDetail
+                                            key={'dashboardDetail'}
+                                            type="dashboard"
+                                            entity={dashboards[guide.most_important_dashboard]}
+                                            tables={tables}
+                                        />
+                                    </div>
+                                ]}
+                                <div className="my4">
+                                    { guide.important_metrics && guide.important_metrics.length > 0 && [
+                                        <div className="my2">
+                                            <SectionHeader key={'metricsTitle'}>
+                                                Numbers that we pay attention to
+                                            </SectionHeader>
+                                            { guide.important_metrics.map((metricId) =>
+                                                <GuideDetail
+                                                    key={metricId}
+                                                    type="metric"
+                                                    entity={metrics[metricId]}
+                                                    tables={tables}
+                                                    exploreLinks={guide.metric_important_fields[metricId] &&
+                                                        guide.metric_important_fields[metricId]
+                                                            .map(fieldId => metadataFields[fieldId])
+                                                            .map(field => ({
+                                                                name: field.display_name || field.name,
+                                                                url: getQuestionUrl({
+                                                                    dbId: tables[field.table_id] && tables[field.table_id].db_id,
+                                                                    tableId: field.table_id,
+                                                                    fieldId: field.id,
+                                                                    metricId
+                                                                })
+                                                            }))
+                                                    }
+                                                />
+                                            )} ,
+                                            <div key={'metricsSeeAll'}>
+                                                <Link className="Button Button--primary" to={'/reference/metrics'}>
+                                                    See all metrics
+                                                </Link>
+                                            </div>
+                                        </div>
+                                    ]}
+                                </div>
+
+                                <div className="mt4">
+                                    { ((guide.important_segments && guide.important_segments.length > 0) ||
+                                        (guide.important_tables && guide.important_tables.length > 0)) && [
+                                        <div className="mt2">
+                                            <SectionHeader key={'segmentTitle'}>
+                                                Segments and tables
+                                            </SectionHeader>
+                                            { guide.important_segments.map((segmentId) =>
+                                                <GuideDetail
+                                                    key={segmentId}
+                                                    type="segment"
+                                                    entity={segments[segmentId]}
+                                                    tables={tables}
+                                                />
+                                            )}
+                                            { guide.important_tables.map((tableId) =>
+                                                <GuideDetail
+                                                    key={tableId}
+                                                    type="table"
+                                                    entity={tables[tableId]}
+                                                    tables={tables}
+                                                />
+                                            )}
+                                        </div>,
+                                        <div key={'segmentSeeAll'}>
+                                            <div>
+                                                <Link className="Button Button--purple mr2" to={'/reference/segments'}>
+                                                    See all segments
+                                                </Link>
+                                                <Link className="text-purple text-bold no-decoration text-underline-hover" to={'/reference/databases'}>
+                                                    See all tables
+                                                </Link>
+                                            </div>
+                                        </div>
+                                    ]}
+                                </div>
+
+                                <div className="mt4">
+                                    { guide.things_to_know && [
+                                        <SectionHeader key={'thingsToKnowTitle'}>
+                                            Other things to know about our data
+                                        </SectionHeader>,
+                                        <p className="text-paragraph text-measure" key={'thingsToKnowDetails'}>
+                                            { guide.things_to_know || `Nothing to know yet`}
+                                        </p>,
+                                        <Link className="link text-bold" to={'/reference/databases'} key={'thingsToKnowSeeAll'}>
+                                            Explore our data
+                                        </Link>
+                                    ]}
+                                </div>
+
+                                <div className="mt4">
+                                    { guide.contact && (guide.contact.name || guide.contact.email) && [
+                                        <SectionHeader key={'contactTitle'}>
+                                            Have questions?
+                                        </SectionHeader>,
+                                        <div className="mb4 pb4" key={'contactDetails'}>
+                                                { guide.contact.name &&
+                                                    <span className="text-dark mr3">
+                                                        {`Contact ${guide.contact.name}`}
+                                                    </span>
+                                                }
+                                                { guide.contact.email &&
+                                                    <a className="text-brand text-bold no-decoration" href={`mailto:${guide.contact.email}`}>
+                                                        {guide.contact.email}
+                                                    </a>
+                                                }
+                                        </div>
+                                    ]}
+                                </div>
+                            </div>
+                        </div>
+                }
+                </LoadingAndErrorWrapper>
+            </form>
+        );
+    }
+}
+
+const SectionHeader = ({ children }) => // eslint-disable-line react/prop-types
+    <h2 className="text-dark text-measure mb4">{children}</h2> 
diff --git a/frontend/src/metabase/reference/reference.js b/frontend/src/metabase/reference/reference.js
index 8bddeae54dc70c29560a74540083a2cdd43b945f..6b9ddf567ba2e9d897fae392fd74bafd9ec2c407 100644
--- a/frontend/src/metabase/reference/reference.js
+++ b/frontend/src/metabase/reference/reference.js
@@ -1,7 +1,38 @@
-import { handleActions, createAction } from 'metabase/lib/redux';
+import i from 'icepick';
+
+import { 
+    handleActions, 
+    createAction,
+    createThunkAction,
+    AngularResourceProxy,
+    cleanResource,
+    fetchData
+} from 'metabase/lib/redux';
+
 import MetabaseAnalytics from 'metabase/lib/analytics';
 
-import i from 'icepick';
+const GettingStartedApi = new AngularResourceProxy("GettingStarted", ["get"]);
+
+const FETCH_GUIDE = "metabase/reference/FETCH_GUIDE";
+export const fetchGuide = createThunkAction(FETCH_GUIDE, (reload = false) => {
+    return async (dispatch, getState) => {
+        const requestStatePath = ["reference", 'guide'];
+        const existingStatePath = requestStatePath;
+        const getData = async () => {
+            const guide = await GettingStartedApi.get();
+            return cleanResource(guide);
+        };
+
+        return await fetchData({
+            dispatch, 
+            getState, 
+            requestStatePath, 
+            existingStatePath, 
+            getData, 
+            reload
+        });
+    };
+});
 
 const SET_ERROR = "metabase/reference/SET_ERROR";
 export const setError = createAction(SET_ERROR);
@@ -31,13 +62,25 @@ export const expandFormula = createAction(EXPAND_FORMULA);
 const COLLAPSE_FORMULA = "metabase/reference/COLLAPSE_FORMULA";
 export const collapseFormula = createAction(COLLAPSE_FORMULA);
 
+//TODO: consider making an app-wide modal state reducer and related actions
+const SHOW_DASHBOARD_MODAL = "metabase/reference/SHOW_DASHBOARD_MODAL";
+export const showDashboardModal = createAction(SHOW_DASHBOARD_MODAL);
+
+const HIDE_DASHBOARD_MODAL = "metabase/reference/HIDE_DASHBOARD_MODAL";
+export const hideDashboardModal = createAction(HIDE_DASHBOARD_MODAL);
+
+
 const initialState = {
     error: null,
     isLoading: false,
     isEditing: false,
     isFormulaExpanded: false,
+    isDashboardModalOpen: false
 };
 export default handleActions({
+    [FETCH_GUIDE]: {
+        next: (state, { payload }) => i.assoc(state, 'guide', payload) 
+    },
     [SET_ERROR]: {
         throw: (state, { payload }) => i.assoc(state, 'error', payload)
     },
@@ -61,5 +104,11 @@ export default handleActions({
     },
     [COLLAPSE_FORMULA]: {
         next: (state) => i.assoc(state, 'isFormulaExpanded', false)
+    },
+    [SHOW_DASHBOARD_MODAL]: {
+        next: (state) => i.assoc(state, 'isDashboardModalOpen', true)
+    },
+    [HIDE_DASHBOARD_MODAL]: {
+        next: (state) => i.assoc(state, 'isDashboardModalOpen', false)
     }
 }, initialState);
diff --git a/frontend/src/metabase/reference/selectors.js b/frontend/src/metabase/reference/selectors.js
index 15fb4bcb9cccb3f3ed6f34c1f44828e73363756e..c27ceca7ff13db4170b98536b2876eb071b97e20 100644
--- a/frontend/src/metabase/reference/selectors.js
+++ b/frontend/src/metabase/reference/selectors.js
@@ -2,6 +2,10 @@ import { createSelector } from 'reselect';
 import i from "icepick";
 
 import Query, { AggregationClause } from 'metabase/lib/query';
+import {
+    resourceListToMap
+} from 'metabase/lib/redux';
+
 import {
     idsToObjectMap,
     buildBreadcrumbs,
@@ -14,13 +18,21 @@ import {
 //TODO: refactor to use different container components for each section
 // initialize section metadata in there
 // may not be worthwhile due to the extra boilerplate required
-// ideal solution is to pass metadata to each section through router
+// try using a higher-order component to reduce boilerplate?
 const referenceSections = {
     [`/reference/guide`]: {
         id: `/reference/guide`,
         name: "Understanding our data",
         breadcrumb: "Guide",
-        icon: "reference"
+        fetch: {
+            fetchGuide: [],
+            fetchDashboards: [],
+            fetchMetrics: [],
+            fetchSegments: [],
+            fetchDatabasesWithMetadata: []
+        },
+        icon: "reference",
+        sidebar: false
     },
     [`/reference/metrics`]: {
         id: `/reference/metrics`,
@@ -83,7 +95,11 @@ const getMetricSections = (metric, table, user) => metric ? {
         update: 'updateMetric',
         type: 'metric',
         breadcrumb: `${metric.name}`,
-        fetch: {fetchMetricTable: [metric.id]},
+        fetch: {
+            fetchMetricTable: [metric.id],
+            // currently the only way to fetch metrics important fields
+            fetchGuide: []
+        },
         get: 'getMetric',
         icon: "document",
         headerIcon: "ruler",
@@ -414,21 +430,21 @@ export const getUser = (state, props) => state.currentUser;
 export const getSectionId = (state, props) => props.location.pathname;
 
 export const getMetricId = (state, props) => Number.parseInt(props.params.metricId);
-const getMetrics = (state, props) => state.metadata.metrics;
+export const getMetrics = (state, props) => state.metadata.metrics;
 export const getMetric = createSelector(
     [getMetricId, getMetrics],
     (metricId, metrics) => metrics[metricId] || { id: metricId }
 );
 
 export const getSegmentId = (state, props) => Number.parseInt(props.params.segmentId);
-const getSegments = (state, props) => state.metadata.segments;
+export const getSegments = (state, props) => state.metadata.segments;
 export const getSegment = createSelector(
     [getSegmentId, getSegments],
     (segmentId, segments) => segments[segmentId] || { id: segmentId }
 );
 
 export const getDatabaseId = (state, props) => Number.parseInt(props.params.databaseId);
-const getDatabases = (state, props) => state.metadata.databases;
+export const getDatabases = (state, props) => state.metadata.databases;
 const getDatabase = createSelector(
     [getDatabaseId, getDatabases],
     (databaseId, databases) => databases[databaseId] || { id: databaseId }
@@ -459,7 +475,7 @@ export const getTable = createSelector(
 );
 
 export const getFieldId = (state, props) => Number.parseInt(props.params.fieldId);
-const getFields = (state, props) => state.metadata.fields;
+export const getFields = (state, props) => state.metadata.fields;
 const getFieldsByTable = createSelector(
     [getTable, getFields],
     (table, fields) => table && table.fields ? idsToObjectMap(table.fields, fields) : {}
@@ -659,4 +675,11 @@ export const getHasQuestions = createSelector(
 
 export const getIsEditing = (state, props) => state.reference.isEditing;
 
-export const getIsFormulaExpanded = (state, props) => state.reference.isFormulaExpanded;
\ No newline at end of file
+export const getIsFormulaExpanded = (state, props) => state.reference.isFormulaExpanded;
+
+export const getGuide = (state, props) => state.reference.guide;
+
+export const getDashboards = (state, props) => state.dashboard.dashboardListing &&
+    resourceListToMap(state.dashboard.dashboardListing);
+
+export const getIsDashboardModalOpen = (state, props) => state.reference.isDashboardModalOpen;
diff --git a/frontend/src/metabase/reference/utils.js b/frontend/src/metabase/reference/utils.js
index 9039aeea0fbe5ef40be88ef91acf6ed568dc7cba..392b7eb7755360e8f81488a593442c2f1b24df56 100644
--- a/frontend/src/metabase/reference/utils.js
+++ b/frontend/src/metabase/reference/utils.js
@@ -1,4 +1,5 @@
 import i from "icepick";
+import _ from "underscore";
 
 import { titleize, humanize } from "metabase/lib/formatting";
 import { startNewCard, serializeCardForUrl } from "metabase/lib/card";
@@ -6,11 +7,20 @@ import { isPK } from "metabase/lib/types";
 
 export const idsToObjectMap = (ids, objects) => ids
     .map(id => objects[id])
-    .reduce((map, object) => Object.assign({}, map, {[object.id]: object}), {});
+    .reduce((map, object) => ({ ...map, [object.id]: object }), {});
     // recursive freezing done by i.assoc here is too expensive
     // hangs browser for large databases
     // .reduce((map, object) => i.assoc(map, object.id, object), {});
 
+const filterUntouchedFields = (fields, entity = {}) => Object.keys(fields)
+    .filter(key => 
+        fields[key] !== undefined && 
+        entity[key] !== fields[key]
+    )
+    .reduce((map, key) => ({ ...map, [key]: fields[key] }), {});
+
+const isEmptyObject = (object) => Object.keys(object).length === 0;
+
 export const tryFetchData = async (props) => {
     const {
         section,
@@ -45,7 +55,9 @@ export const tryFetchData = async (props) => {
 export const tryUpdateData = async (fields, props) => {
     const {
         entity,
+        guide,
         section,
+        updateMetricImportantFields,
         startLoading,
         endLoading,
         resetForm,
@@ -53,18 +65,34 @@ export const tryUpdateData = async (fields, props) => {
         endEditing
     } = props;
 
-    const editedFields = Object.keys(fields)
-        .filter(key => fields[key] !== undefined)
-        .reduce((map, key) => i.assoc(map, key, fields[key]), {});
-    const newEntity = {...entity, ...editedFields};
     startLoading();
     try {
-        await props[section.update](newEntity);
+        const editedFields = filterUntouchedFields(fields, entity);
+        if (!isEmptyObject(editedFields)) {
+            const newEntity = {...entity, ...editedFields};
+            await props[section.update](newEntity);
+
+            if (section.type === 'metric' && fields.important_fields) {
+                const importantFieldIds = fields.important_fields.map(field => field.id);
+                const existingImportantFieldIds = guide.metric_important_fields && guide.metric_important_fields[entity.id];
+
+                const areFieldIdsIdentitical = existingImportantFieldIds && 
+                    existingImportantFieldIds.length === importantFieldIds.length &&
+                    existingImportantFieldIds.every(id => importantFieldIds.includes(id));
+                
+                console.log(areFieldIdsIdentitical);
+                if (!areFieldIdsIdentitical) {
+                    await updateMetricImportantFields(entity.id, importantFieldIds);
+                    tryFetchData(props);
+                }
+            }
+        }
     }
     catch(error) {
         setError(error);
         console.error(error);
     }
+
     resetForm();
     endLoading();
     endEditing();
@@ -77,35 +105,235 @@ export const tryUpdateFields = async (formFields, props) => {
         startLoading,
         endLoading,
         endEditing,
+        resetForm,
         setError
     } = props;
 
-    const updatedFields = Object.keys(formFields)
-        .map(fieldId => ({
-            field: entities[fieldId],
-            formField: Object.keys(formFields[fieldId])
-                .filter(key => formFields[fieldId][key] !== undefined)
-                .reduce((map, key) => i
-                    .assoc(map, key, formFields[fieldId][key]), {}
-                )
-        }))
-        .filter(({field, formField}) => Object
-            .keys(formField).length !== 0
-        )
-        .map(({field, formField}) => ({...field, ...formField}));
-
     startLoading();
     try {
+        const updatedFields = Object.keys(formFields)
+            .map(fieldId => ({
+                field: entities[fieldId],
+                formField: filterUntouchedFields(formFields[fieldId], entities[fieldId])
+            }))
+            .filter(({field, formField}) => !isEmptyObject(formField))
+            .map(({field, formField}) => ({...field, ...formField}));
+
         await Promise.all(updatedFields.map(updateField));
     }
     catch(error) {
         setError(error);
         console.error(error);
     }
+
+    resetForm();
     endLoading();
     endEditing();
 }
 
+export const tryUpdateGuide = async (formFields, props) => {
+    const {
+        guide,
+        dashboards,
+        metrics,
+        segments,
+        tables,
+        startLoading,
+        endLoading,
+        endEditing,
+        setError,
+        resetForm,
+        updateDashboard,
+        updateMetric,
+        updateSegment,
+        updateTable,
+        updateMetricImportantFields,
+        updateSetting,
+        fetchGuide,
+        clearRequestState
+    } = props;
+
+    startLoading();
+    try {
+        const updateNewEntities = ({
+            entities, 
+            formFields, 
+            updateEntity
+        }) => formFields.map(formField => {
+            if (!formField.id) {
+                return [];
+            }
+
+            const editedEntity = filterUntouchedFields(
+                i.assoc(formField, 'show_in_getting_started', true), 
+                entities[formField.id]
+            );
+
+            if (isEmptyObject(editedEntity)) {
+                return [];
+            }
+
+            const newEntity = entities[formField.id];
+            const updatedNewEntity = {
+                ...newEntity, 
+                ...editedEntity
+            };
+
+            const updatingNewEntity = updateEntity(updatedNewEntity);
+
+            return [updatingNewEntity];
+        });
+
+        const updateOldEntities = ({
+            newEntityIds, 
+            oldEntityIds, 
+            entities, 
+            updateEntity
+        }) => oldEntityIds
+            .filter(oldEntityId => !newEntityIds.includes(oldEntityId))
+            .map(oldEntityId => {
+                const oldEntity = entities[oldEntityId];
+
+                const updatedOldEntity = i.assoc(
+                    oldEntity,
+                    'show_in_getting_started',
+                    false
+                );
+
+                const updatingOldEntity = updateEntity(updatedOldEntity);
+                
+                return [updatingOldEntity];
+            });
+        //FIXME: necessary because revision_message is a mandatory field
+        // even though we don't actually keep track of changes to caveats/points_of_interest yet
+        const updateWithRevisionMessage = updateEntity => entity => updateEntity(i.assoc(
+            entity,
+            'revision_message', 
+            'Updated in Getting Started guide.'
+        ));
+
+        const updatingDashboards = updateNewEntities({
+                entities: dashboards,
+                formFields: [formFields.most_important_dashboard],
+                updateEntity: updateDashboard
+            })
+            .concat(updateOldEntities({
+                newEntityIds: formFields.most_important_dashboard ? 
+                    [formFields.most_important_dashboard.id] : [],
+                oldEntityIds: guide.most_important_dashboard ? 
+                    [guide.most_important_dashboard] :
+                    [],
+                entities: dashboards,
+                updateEntity: updateDashboard
+            }));
+
+        const updatingMetrics = updateNewEntities({
+                entities: metrics,
+                formFields: formFields.important_metrics,
+                updateEntity: updateWithRevisionMessage(updateMetric)
+            })
+            .concat(updateOldEntities({
+                newEntityIds: formFields.important_metrics
+                    .map(formField => formField.id),
+                oldEntityIds: guide.important_metrics,
+                entities: metrics,
+                updateEntity: updateWithRevisionMessage(updateMetric)
+            }));
+        
+        const updatingMetricImportantFields = formFields.important_metrics
+            .map(metricFormField => {
+                if (!metricFormField.id || !metricFormField.important_fields) {
+                    return [];
+                }
+                const importantFieldIds = metricFormField.important_fields
+                    .map(field => field.id);
+                const existingImportantFieldIds = guide.metric_important_fields[metricFormField.id];
+                
+                const areFieldIdsIdentitical = existingImportantFieldIds && 
+                    existingImportantFieldIds.length === importantFieldIds.length &&
+                    existingImportantFieldIds.every(id => importantFieldIds.includes(id));
+                if (areFieldIdsIdentitical) {
+                    return [];
+                }
+                
+                return [updateMetricImportantFields(metricFormField.id, importantFieldIds)];
+            });
+        
+        const segmentFields = formFields.important_segments_and_tables
+            .filter(field => field.type === 'segment');
+
+        const updatingSegments = updateNewEntities({
+                entities: segments,
+                formFields: segmentFields,
+                updateEntity: updateWithRevisionMessage(updateSegment)
+            })
+            .concat(updateOldEntities({
+                newEntityIds: segmentFields
+                    .map(formField => formField.id),
+                oldEntityIds: guide.important_segments,
+                entities: segments,
+                updateEntity: updateWithRevisionMessage(updateSegment)
+            }));
+
+        const tableFields = formFields.important_segments_and_tables
+            .filter(field => field.type === 'table');
+
+        const updatingTables = updateNewEntities({
+                entities: tables,
+                formFields: tableFields,
+                updateEntity: updateTable
+            })
+            .concat(updateOldEntities({
+                newEntityIds: tableFields
+                    .map(formField => formField.id),
+                oldEntityIds: guide.important_tables,
+                entities: tables,
+                updateEntity: updateTable
+            }));
+
+        const updatingThingsToKnow = guide.things_to_know !== formFields.things_to_know ?
+            [updateSetting({key: 'getting-started-things-to-know', value: formFields.things_to_know })] :
+            [];
+
+        const updatingContactName = guide.contact && formFields.contact &&
+            guide.contact.name !== formFields.contact.name ?
+                [updateSetting({key: 'getting-started-contact-name', value: formFields.contact.name })] :
+                [];
+        
+        const updatingContactEmail = guide.contact && formFields.contact &&
+            guide.contact.email !== formFields.contact.email ?
+                [updateSetting({key: 'getting-started-contact-email', value: formFields.contact.email })] :
+                [];
+
+        const updatingData = _.flatten([
+            updatingDashboards,
+            updatingMetrics,
+            updatingMetricImportantFields,
+            updatingSegments,
+            updatingTables,
+            updatingThingsToKnow,
+            updatingContactName,
+            updatingContactEmail
+        ]);
+
+        if (updatingData.length > 0) {
+            await Promise.all(updatingData);
+            
+            clearRequestState({statePath: ['reference', 'guide']});
+
+            await fetchGuide();
+        }
+    }
+    catch(error) {
+        setError(error);
+        console.error(error);
+    }
+
+    resetForm();
+    endLoading();
+    endEditing();
+};
+
 const getBreadcrumb = (section, index, sections) => index !== sections.length - 1 ?
     [section.breadcrumb, section.id] : [section.breadcrumb];
 
@@ -207,3 +435,33 @@ export const getQuestion = ({dbId, tableId, fieldId, metricId, segmentId, getCou
 };
 
 export const getQuestionUrl = getQuestionArgs => `/q#${serializeCardForUrl(getQuestion(getQuestionArgs))}`;
+
+export const isGuideEmpty = ({
+    things_to_know,
+    contact,
+    most_important_dashboard,
+    important_metrics,
+    important_segments,
+    important_tables
+} = {}) => things_to_know ? false :
+    contact && contact.name ? false :
+    contact && contact.email ? false :
+    most_important_dashboard ? false :
+    important_metrics && important_metrics.length !== 0 ? false :
+    important_segments && important_segments.length !== 0 ? false :
+    important_tables && important_tables.length !== 0 ? false : 
+    true;
+
+export const typeToLinkClass = {
+    dashboard: 'text-green',
+    metric: 'text-brand',
+    segment: 'text-purple',
+    table: 'text-purple'
+};
+
+export const typeToBgClass = {
+    dashboard: 'bg-green',
+    metric: 'bg-brand',
+    segment: 'bg-purple',
+    table: 'bg-purple'
+};
diff --git a/frontend/src/metabase/services.js b/frontend/src/metabase/services.js
index bf0a26557c01e5eeea180be4d975e8d954cc7ca3..7873b8873a7aa48e5e93981b6782bb04d6ebc4a1 100644
--- a/frontend/src/metabase/services.js
+++ b/frontend/src/metabase/services.js
@@ -436,6 +436,14 @@ CoreServices.factory('Metric', ['$resource', function($resource) {
             method: 'PUT',
             params: { metricId: '@id' }
         },
+        update_important_fields: {
+            url: '/api/metric/:metricId/important_fields',
+            method: 'PUT',
+            params: { 
+                metricId: '@metricId',
+                important_field_ids: '@important_field_ids'
+            }
+        },
         delete: {
             method: 'DELETE',
             params: { metricId: '@metricId' }
@@ -570,6 +578,15 @@ CoreServices.factory('Settings', ['$resource', function($resource) {
     });
 }]);
 
+CoreServices.factory('GettingStarted', ['$resource', function($resource) {
+    return $resource('/api/getting_started', {}, {
+        get: {
+            url: '/api/getting_started',
+            method: 'GET',
+        }
+    });
+}]);
+
 CoreServices.factory('Setup', ['$resource', function($resource) {
     return $resource('/api/setup/', {}, {
         create: {
diff --git a/frontend/test/unit/redux/metadata.spec.js b/frontend/test/unit/lib/redux.spec.js
similarity index 98%
rename from frontend/test/unit/redux/metadata.spec.js
rename to frontend/test/unit/lib/redux.spec.js
index 55d1cbdfcff9014995095d680a080373387f2624..723be7003d9532c4bbe7ab2465969fd5abac683e 100644
--- a/frontend/test/unit/redux/metadata.spec.js
+++ b/frontend/test/unit/lib/redux.spec.js
@@ -1,4 +1,7 @@
-import { fetchData, updateData } from 'metabase/redux/metadata';
+import { 
+    fetchData, 
+    updateData 
+} from 'metabase/lib/redux';
 
 describe("Metadata", () => {
     const getDefaultArgs = ({
diff --git a/src/metabase/api/dashboard.clj b/src/metabase/api/dashboard.clj
index 01eb43653beaf7648db8f584ea5e0006ec7713dc..e7140b9ee81f0aef611ca46cb7caed54488b12b6 100644
--- a/src/metabase/api/dashboard.clj
+++ b/src/metabase/api/dashboard.clj
@@ -45,7 +45,7 @@
 
 (defendpoint PUT "/:id"
   "Update a `Dashboard`."
-  [id :as {{:keys [description name parameters], :as dashboard} :body}]
+  [id :as {{:keys [description name parameters caveats points_of_interest show_in_getting_started], :as dashboard} :body}]
   {name       [Required NonEmptyString]
    parameters [ArrayOfMaps]}
   (write-check Dashboard id)
diff --git a/src/metabase/api/getting_started.clj b/src/metabase/api/getting_started.clj
index fa7238a0fa3493c21bbba397f114a159b976a4e5..f8078f1121beccf803b5569b568e68467c4db009 100644
--- a/src/metabase/api/getting_started.clj
+++ b/src/metabase/api/getting_started.clj
@@ -1,5 +1,6 @@
 (ns metabase.api.getting-started
   (:require [compojure.core :refer [GET]]
+            [medley.core :as m]
             [metabase.api.common :refer :all]
             [metabase.db :as db]
             [metabase.models.setting :refer [defsetting]]))
@@ -20,17 +21,12 @@
   {:things_to_know           (getting-started-things-to-know)
    :contact                  {:name  (getting-started-contact-name)
                               :email (getting-started-contact-email)}
-   :most_important_dashboard (db/select-one 'Dashboard :show_in_getting_started true)
-   ;; TODO - Need to hydrate the `MetricImportantFields` for this
-   :important_metrics        (db/select 'Metric :show_in_getting_started true, {:order-by [:name]})
-   ;; TODO - should these come back combined or separate?
-   :important_tables         (db/select 'Table :show_in_getting_started true, {:order-by [:name]})
-   :important_segments       (db/select 'Segment :show_in_getting_started true, {:order-by [:name]})})
-
-
-;; TODO - Endpoint for editing the settings above? Or just edit them the normal way via PUT /api/setting/:key ?
-;; TODO - Endpoint for setting most_important_dashboard (?) Or just have people set it the normal way via PUT /api/dashboard/:id ?
-;;        If we keep the existing endpoint it might make sense to clear `show_in_getting_started` for other Dashboards whenever this is set
-;; TODO - Endpoints for setting most important metrics / tables / segments ? Or just have people set them the normal way via PUT /api/.../:id ?
+   :most_important_dashboard (db/select-one-id 'Dashboard :show_in_getting_started true)
+   :important_metrics        (map :id (db/select ['Metric :id]  :show_in_getting_started true, {:order-by [:name]}))
+   :important_tables         (map :id (db/select ['Table :id]   :show_in_getting_started true, {:order-by [:name]}))
+   :important_segments       (map :id (db/select ['Segment :id] :show_in_getting_started true, {:order-by [:name]}))
+   ;; A map of metric_id -> sequence of important field_ids
+   :metric_important_fields  (m/map-vals (partial map :field_id)
+                                         (group-by :metric_id (db/select ['MetricImportantField :field_id :metric_id])))})
 
 (define-routes)
diff --git a/src/metabase/api/metric.clj b/src/metabase/api/metric.clj
index 50de91e5c80085ab903b67d0049e23fbeff25898..8bfac88f3f2b93290f3def84ea7881614149c97a 100644
--- a/src/metabase/api/metric.clj
+++ b/src/metabase/api/metric.clj
@@ -1,6 +1,7 @@
 (ns metabase.api.metric
   "/api/metric endpoints."
   (:require [clojure.data :as data]
+            [clojure.tools.logging :as log]
             [compojure.core :refer [defroutes GET PUT POST DELETE]]
             [metabase.api.common :refer :all]
             [metabase.db :as db]
@@ -36,21 +37,22 @@
 
 (defendpoint PUT "/:id"
   "Update a `Metric` with ID."
-  [id :as {{:keys [name description caveats points_of_interest how_is_this_calculated definition revision_message]} :body}]
+  [id :as {{:keys [name description caveats points_of_interest how_is_this_calculated show_in_getting_started definition revision_message]} :body}]
   {name             [Required NonEmptyString]
    revision_message [Required NonEmptyString]
    definition       [Required Dict]}
   (check-superuser)
   (check-404 (metric/exists? id))
   (metric/update-metric!
-    {:id                     id
-     :name                   name
-     :description            description
-     :caveats                caveats
-     :points_of_interest     points_of_interest
-     :how_is_this_calculated how_is_this_calculated
-     :definition             definition
-     :revision_message       revision_message}
+    {:id                      id
+     :name                    name
+     :description             description
+     :caveats                 caveats
+     :points_of_interest      points_of_interest
+     :how_is_this_calculated  how_is_this_calculated
+     :show_in_getting_started show_in_getting_started
+     :definition              definition
+     :revision_message        revision_message}
     *current-user-id*))
 
 (defendpoint PUT "/:id/important_fields"
@@ -62,8 +64,9 @@
   (check-404 (metric/exists? id))
   (check (<= (count important_field_ids) 3)
     [400 "A Metric can have a maximum of 3 important fields."])
-  (let [[fields-to-remove fields-to-add] (data/diff (set (db/select-field :field_id 'MetricImportantField :metric_id 1))
+  (let [[fields-to-remove fields-to-add] (data/diff (set (db/select-field :field_id 'MetricImportantField :metric_id id))
                                                     (set important_field_ids))]
+
     ;; delete old fields as needed
     (when (seq fields-to-remove)
       (db/delete! 'MetricImportantField {:metric_id id, :field_id [:in fields-to-remove]}))
diff --git a/src/metabase/api/segment.clj b/src/metabase/api/segment.clj
index 5493c222cf48e777da1f51a497fbfb3c2d8e5aa5..1d65841f802de7d11633f8bedd08400c69b97460 100644
--- a/src/metabase/api/segment.clj
+++ b/src/metabase/api/segment.clj
@@ -35,20 +35,21 @@
 
 (defendpoint PUT "/:id"
   "Update a `Segment` with ID."
-  [id :as {{:keys [name description caveats points_of_interest definition revision_message]} :body}]
+  [id :as {{:keys [name description caveats points_of_interest show_in_getting_started definition revision_message]} :body}]
   {name             [Required NonEmptyString]
    revision_message [Required NonEmptyString]
    definition       [Required Dict]}
   (check-superuser)
   (check-404 (segment/exists? id))
   (segment/update-segment!
-    {:id                 id
-     :name               name
-     :description        description
-     :caveats            caveats
-     :points_of_interest points_of_interest
-     :definition         definition
-     :revision_message   revision_message}
+    {:id                      id
+     :name                    name
+     :description             description
+     :caveats                 caveats
+     :points_of_interest      points_of_interest
+     :show_in_getting_started show_in_getting_started
+     :definition              definition
+     :revision_message        revision_message}
     *current-user-id*))
 
 
diff --git a/src/metabase/api/table.clj b/src/metabase/api/table.clj
index 56795215a27cc9d0d6f491e18e57dd338199d109..78aa357a31e5ec534c5389e70400860b6d8fd3f8 100644
--- a/src/metabase/api/table.clj
+++ b/src/metabase/api/table.clj
@@ -39,17 +39,18 @@
 
 (defendpoint PUT "/:id"
   "Update `Table` with ID."
-  [id :as {{:keys [display_name entity_type visibility_type description caveats points_of_interest]} :body}]
+  [id :as {{:keys [display_name entity_type visibility_type description caveats points_of_interest show_in_getting_started]} :body}]
   {display_name    NonEmptyString,
    entity_type     TableEntityType,
    visibility_type TableVisibilityType}
   (write-check Table id)
   (check-500 (db/update-non-nil-keys! Table id
-               :display_name       display_name
-               :caveats            caveats
-               :points_of_interest points_of_interest
-               :entity_type        entity_type
-               :description        description))
+               :display_name            display_name
+               :caveats                 caveats
+               :points_of_interest      points_of_interest
+               :show_in_getting_started show_in_getting_started
+               :entity_type             entity_type
+               :description             description))
   (check-500 (db/update! Table id, :visibility_type visibility_type))
   (Table id))
 
diff --git a/src/metabase/models/dashboard.clj b/src/metabase/models/dashboard.clj
index 909d90a971531afb1833b876b3f57929854e1236..a4c9cf21b80162d18fb2a6a8948775c909881912 100644
--- a/src/metabase/models/dashboard.clj
+++ b/src/metabase/models/dashboard.clj
@@ -55,15 +55,18 @@
 
 (defn update-dashboard!
   "Update a `Dashboard`"
-  [{:keys [id name description parameters], :as dashboard} user-id]
+  [{:keys [id name description parameters caveats points_of_interest show_in_getting_started], :as dashboard} user-id]
   {:pre [(map? dashboard)
          (integer? id)
          (u/maybe? u/sequence-of-maps? parameters)
          (integer? user-id)]}
   (db/update-non-nil-keys! Dashboard id
-    :description description
-    :name        name
-    :parameters  parameters)
+    :description             description
+    :name                    name
+    :parameters              parameters
+    :caveats                 caveats
+    :points_of_interest      points_of_interest
+    :show_in_getting_started show_in_getting_started)
   (u/prog1 (Dashboard id)
     (events/publish-event :dashboard-update (assoc <> :actor_id user-id))))
 
diff --git a/src/metabase/models/metric.clj b/src/metabase/models/metric.clj
index 920560402b1c76f016763fa4a70752bd27087ffa..7cfdc5f83d71ad8944b41307b5fcd8bdeaf30f5b 100644
--- a/src/metabase/models/metric.clj
+++ b/src/metabase/models/metric.clj
@@ -117,7 +117,7 @@
   "Update an existing `Metric`.
 
    Returns the updated `Metric` or throws an Exception."
-  [{:keys [id name description caveats points_of_interest how_is_this_calculated definition revision_message]} user-id]
+  [{:keys [id name description caveats points_of_interest how_is_this_calculated show_in_getting_started definition revision_message]} user-id]
   {:pre [(integer? id)
          (string? name)
          (map? definition)
@@ -125,12 +125,13 @@
          (string? revision_message)]}
   ;; update the metric itself
   (db/update! Metric id
-    :name                   name
-    :description            description
-    :caveats                caveats
-    :points_of_interest     points_of_interest
-    :how_is_this_calculated how_is_this_calculated
-    :definition             definition)
+    :name                    name
+    :description             description
+    :caveats                 caveats
+    :points_of_interest      points_of_interest
+    :how_is_this_calculated  how_is_this_calculated
+    :show_in_getting_started show_in_getting_started
+    :definition              definition)
   (u/prog1 (retrieve-metric id)
     (events/publish-event :metric-update (assoc <> :actor_id user-id, :revision_message revision_message))))
 
diff --git a/src/metabase/models/segment.clj b/src/metabase/models/segment.clj
index 4251c5506d605ec67dda7aebe6409813c3e92684..4c6a9c4335b393278ef3e2730dc290cb0209c5a8 100644
--- a/src/metabase/models/segment.clj
+++ b/src/metabase/models/segment.clj
@@ -99,7 +99,7 @@
   "Update an existing `Segment`.
 
    Returns the updated `Segment` or throws an Exception."
-  [{:keys [id name description caveats points_of_interest definition revision_message]} user-id]
+  [{:keys [id name description caveats points_of_interest show_in_getting_started definition revision_message]} user-id]
   {:pre [(integer? id)
          (string? name)
          (map? definition)
@@ -107,11 +107,12 @@
          (string? revision_message)]}
   ;; update the segment itself
   (db/update! Segment id
-    :name               name
-    :description        description
-    :caveats            caveats
-    :points_of_interest points_of_interest
-    :definition         definition)
+    :name                    name
+    :description             description
+    :caveats                 caveats
+    :points_of_interest      points_of_interest
+    :show_in_getting_started show_in_getting_started
+    :definition              definition)
   (u/prog1 (retrieve-segment id)
     (events/publish-event :segment-update (assoc <> :actor_id user-id, :revision_message revision_message))))