diff --git a/src/mol-model/structure/structure/carbohydrates/compute.ts b/src/mol-model/structure/structure/carbohydrates/compute.ts
index 729e7bb56c1b38207f8297e19a457212eec0cd27..d86ed125b4f6d796b02453c432a0017ebb9a89fc 100644
--- a/src/mol-model/structure/structure/carbohydrates/compute.ts
+++ b/src/mol-model/structure/structure/carbohydrates/compute.ts
@@ -262,8 +262,9 @@ export function computeCarbohydrates(structure: Structure): Carbohydrates {
 
     }
 
-    // get carbohydrate links induced by inter-unit bonds
-    // (e.g. for structures from the PDB archive __before__ carbohydrate remediation)
+    // get carbohydrate links induced by inter-unit bonds, that is
+    // terminal links plus inter monosaccharide links for structures from the
+    // PDB archive __before__ carbohydrate remediation
     for (let i = 0, il = structure.units.length; i < il; ++i) {
         const unit = structure.units[i]
         if (!Unit.isAtomic(unit)) continue
@@ -309,10 +310,10 @@ export function computeCarbohydrates(structure: Structure): Carbohydrates {
         })
     }
 
-    return { links, terminalLinks, elements, partialElements, ...buildLookups(elements, links) }
+    return { links, terminalLinks, elements, partialElements, ...buildLookups(elements, links, terminalLinks) }
 }
 
-function buildLookups (elements: CarbohydrateElement[], links: CarbohydrateLink[]) {
+function buildLookups (elements: CarbohydrateElement[], links: CarbohydrateLink[], terminalLinks: CarbohydrateTerminalLink[]) {
     // element lookup
 
     function elementKey(unit: Unit, anomericCarbon: ElementIndex) {
@@ -347,6 +348,27 @@ function buildLookups (elements: CarbohydrateElement[], links: CarbohydrateLink[
         return linkMap.get(linkKey(unitA, anomericCarbonA, unitB, anomericCarbonB))
     }
 
+    // terminal link lookup
+
+    function terminalLinkKey(unitA: Unit, elementA: ElementIndex, unitB: Unit, elementB: ElementIndex) {
+        return `${unitA.id}|${elementA}|${unitB.id}|${elementB}`
+    }
+
+    const terminalLinkMap = new Map<string, number>()
+    for (let i = 0, il = terminalLinks.length; i < il; ++i) {
+        const { fromCarbohydrate, carbohydrateIndex, elementUnit, elementIndex } = terminalLinks[i]
+        const { unit, anomericCarbon } = elements[carbohydrateIndex]
+        if (fromCarbohydrate) {
+            terminalLinkMap.set(terminalLinkKey(unit, anomericCarbon, elementUnit, elementUnit.elements[elementIndex]), i)
+        } else {
+            terminalLinkMap.set(terminalLinkKey(elementUnit, elementUnit.elements[elementIndex], unit, anomericCarbon), i)
+        }
+    }
+
+    function getTerminalLinkIndex(unitA: Unit, elementA: ElementIndex, unitB: Unit, elementB: ElementIndex) {
+        return terminalLinkMap.get(terminalLinkKey(unitA, elementA, unitB, elementB))
+    }
+
     // anomeric carbon lookup
 
     function anomericCarbonKey(unit: Unit, residueIndex: ResidueIndex) {
@@ -364,5 +386,5 @@ function buildLookups (elements: CarbohydrateElement[], links: CarbohydrateLink[
         return anomericCarbonMap.get(anomericCarbonKey(unit, residueIndex))
     }
 
-    return { getElementIndex, getLinkIndex, getAnomericCarbon }
+    return { getElementIndex, getLinkIndex, getTerminalLinkIndex, getAnomericCarbon }
 }
\ No newline at end of file
diff --git a/src/mol-model/structure/structure/carbohydrates/data.ts b/src/mol-model/structure/structure/carbohydrates/data.ts
index 0a8d383755bac79c9ffde4be7de61a4b8f331cf0..7743bd0ba2ab580cd9a5226c07bd0678253953af 100644
--- a/src/mol-model/structure/structure/carbohydrates/data.ts
+++ b/src/mol-model/structure/structure/carbohydrates/data.ts
@@ -8,6 +8,7 @@ import Unit from '../unit';
 import { Vec3 } from 'mol-math/linear-algebra';
 import { ResidueIndex, ElementIndex } from '../../model';
 import { SaccharideComponent } from './constants';
+import StructureElement from '../element';
 
 export interface CarbohydrateLink {
     readonly carbohydrateIndexA: number
@@ -16,7 +17,7 @@ export interface CarbohydrateLink {
 
 export interface CarbohydrateTerminalLink {
     readonly carbohydrateIndex: number
-    readonly elementIndex: number
+    readonly elementIndex: StructureElement.UnitIndex
     readonly elementUnit: Unit
     /** specifies direction of the link */
     readonly fromCarbohydrate: boolean
@@ -31,7 +32,7 @@ export interface CarbohydrateElement {
     readonly ringAltId: string,
 }
 
-// partial carbohydrate with no ring present
+/** partial carbohydrate with no ring present */
 export interface PartialCarbohydrateElement {
     readonly unit: Unit.Atomic,
     readonly residueIndex: ResidueIndex,
@@ -45,5 +46,6 @@ export interface Carbohydrates {
     partialElements: ReadonlyArray<PartialCarbohydrateElement>
     getElementIndex: (unit: Unit, anomericCarbon: ElementIndex) => number | undefined
     getLinkIndex: (unitA: Unit, anomericCarbonA: ElementIndex, unitB: Unit, anomericCarbonB: ElementIndex) => number | undefined
+    getTerminalLinkIndex: (unitA: Unit, elementA: ElementIndex, unitB: Unit, elementB: ElementIndex) => number | undefined
     getAnomericCarbon: (unit: Unit, residueIndex: ResidueIndex) => ElementIndex | undefined
 }
\ No newline at end of file
diff --git a/src/mol-repr/structure/representation/carbohydrate.ts b/src/mol-repr/structure/representation/carbohydrate.ts
index 82660da3fb1f0eba58ad787a8843cca7684450bb..ac2e0d87bd53066ddf807ea3b39c2c2f73c3cc2f 100644
--- a/src/mol-repr/structure/representation/carbohydrate.ts
+++ b/src/mol-repr/structure/representation/carbohydrate.ts
@@ -6,6 +6,7 @@
 
 import { CarbohydrateSymbolVisual, CarbohydrateSymbolParams } from '../visual/carbohydrate-symbol-mesh';
 import { CarbohydrateLinkVisual, CarbohydrateLinkParams } from '../visual/carbohydrate-link-cylinder';
+import { CarbohydrateTerminalLinkParams, CarbohydrateTerminalLinkVisual } from '../visual/carbohydrate-terminal-link-cylinder';
 import { ParamDefinition as PD } from 'mol-util/param-definition';
 import { ComplexRepresentation } from '../complex-representation';
 import { StructureRepresentation, StructureRepresentationProvider } from '../representation';
@@ -17,6 +18,7 @@ import { BuiltInColorThemeOptions, getBuiltInColorThemeParams } from 'mol-theme/
 const CarbohydrateVisuals = {
     'carbohydrate-symbol': (getParams: RepresentationParamsGetter<Structure, CarbohydrateSymbolParams>) => ComplexRepresentation('Carbohydrate symbol mesh', getParams, CarbohydrateSymbolVisual),
     'carbohydrate-link': (getParams: RepresentationParamsGetter<Structure, CarbohydrateLinkParams>) => ComplexRepresentation('Carbohydrate link cylinder', getParams, CarbohydrateLinkVisual),
+    'carbohydrate-terminal-link': (getParams: RepresentationParamsGetter<Structure, CarbohydrateTerminalLinkParams>) => ComplexRepresentation('Carbohydrate terminal link cylinder', getParams, CarbohydrateTerminalLinkVisual),
 }
 type CarbohydrateVisualName = keyof typeof CarbohydrateVisuals
 const CarbohydrateVisualOptions = Object.keys(CarbohydrateVisuals).map(name => [name, name] as [CarbohydrateVisualName, string])
@@ -24,8 +26,9 @@ const CarbohydrateVisualOptions = Object.keys(CarbohydrateVisuals).map(name => [
 export const CarbohydrateParams = {
     ...CarbohydrateSymbolParams,
     ...CarbohydrateLinkParams,
+    ...CarbohydrateTerminalLinkParams,
     colorTheme: PD.Mapped('carbohydrate-symbol', BuiltInColorThemeOptions, getBuiltInColorThemeParams),
-    visuals: PD.MultiSelect<CarbohydrateVisualName>(['carbohydrate-symbol', 'carbohydrate-link'], CarbohydrateVisualOptions),
+    visuals: PD.MultiSelect<CarbohydrateVisualName>(['carbohydrate-symbol', 'carbohydrate-link', 'carbohydrate-terminal-link'], CarbohydrateVisualOptions),
 }
 PD.getDefaultValues(CarbohydrateParams).colorTheme.name
 export type CarbohydrateParams = typeof CarbohydrateParams
diff --git a/src/mol-repr/structure/visual/carbohydrate-link-cylinder.ts b/src/mol-repr/structure/visual/carbohydrate-link-cylinder.ts
index e58322f57d5b6f1eb90db7832db26dbe61007433..05d5a04b0d66afd2c4bf649fb66826835538fe13 100644
--- a/src/mol-repr/structure/visual/carbohydrate-link-cylinder.ts
+++ b/src/mol-repr/structure/visual/carbohydrate-link-cylinder.ts
@@ -7,7 +7,7 @@
 import { Structure, Link, StructureElement } from 'mol-model/structure';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { Vec3 } from 'mol-math/linear-algebra';
-import { createLinkCylinderMesh, LinkCylinderProps, LinkCylinderParams } from './util/link';
+import { createLinkCylinderMesh, LinkCylinderParams } from './util/link';
 import { OrderedSet, Interval } from 'mol-data/int';
 import { ComplexMeshVisual, ComplexVisual } from '../complex-visual';
 import { LinkType } from 'mol-model/structure/model/types';
@@ -21,22 +21,10 @@ import { VisualUpdateState } from '../../util';
 import { VisualContext } from 'mol-repr/representation';
 import { Theme } from 'mol-theme/theme';
 
-// TODO create seperate visual
-// for (let i = 0, il = carbohydrates.terminalLinks.length; i < il; ++i) {
-//     const tl = carbohydrates.terminalLinks[i]
-//     const center = carbohydrates.elements[tl.carbohydrateIndex].geometry.center
-//     tl.elementUnit.conformation.position(tl.elementUnit.elements[tl.elementIndex], p)
-//     if (tl.fromCarbohydrate) {
-//         builder.addCylinder(center, p, 0.5, linkParams)
-//     } else {
-//         builder.addCylinder(p, center, 0.5, linkParams)
-//     }
-// }
-
-const radiusFactor = 0.3
-
-async function createCarbohydrateLinkCylinderMesh(ctx: VisualContext, structure: Structure, theme: Theme, props: LinkCylinderProps, mesh?: Mesh) {
+async function createCarbohydrateLinkCylinderMesh(ctx: VisualContext, structure: Structure, theme: Theme, props: PD.Values<CarbohydrateLinkParams>, mesh?: Mesh) {
     const { links, elements } = structure.carbohydrates
+    const { linkSizeFactor } = props
+
     const location = StructureElement.create()
 
     const builderProps = {
@@ -53,7 +41,7 @@ async function createCarbohydrateLinkCylinderMesh(ctx: VisualContext, structure:
             const l = links[edgeIndex]
             location.unit = elements[l.carbohydrateIndexA].unit
             location.element = elements[l.carbohydrateIndexA].anomericCarbon
-            return theme.size.size(location) * radiusFactor
+            return theme.size.size(location) * linkSizeFactor
         }
     }
 
@@ -64,6 +52,7 @@ export const CarbohydrateLinkParams = {
     ...UnitsMeshParams,
     ...LinkCylinderParams,
     detail: PD.Numeric(0, { min: 0, max: 3, step: 1 }),
+    linkSizeFactor: PD.Numeric(0.3, { min: 0, max: 3, step: 0.01 }),
 }
 export type CarbohydrateLinkParams = typeof CarbohydrateLinkParams
 
diff --git a/src/mol-repr/structure/visual/carbohydrate-symbol-mesh.ts b/src/mol-repr/structure/visual/carbohydrate-symbol-mesh.ts
index 440d6e834e948a8b2ae6de8cdf85855686316368..7a5acbf598fc3d6b1241632712d95c97ee30358e 100644
--- a/src/mol-repr/structure/visual/carbohydrate-symbol-mesh.ts
+++ b/src/mol-repr/structure/visual/carbohydrate-symbol-mesh.ts
@@ -30,8 +30,7 @@ const t = Mat4.identity()
 const sVec = Vec3.zero()
 const pd = Vec3.zero()
 
-const sideFactor = 1.75 * 2 * 0.806; // 0.806 == Math.cos(Math.PI / 4)
-const radiusFactor = 1.75
+const SideFactor = 2 * 0.806; // 0.806 == Math.cos(Math.PI / 4)
 
 const box = Box()
 const perforatedBox = PerforatedBox()
@@ -47,7 +46,7 @@ const hexagonalPrism = HexagonalPrism()
 async function createCarbohydrateSymbolMesh(ctx: VisualContext, structure: Structure, theme: Theme, props: PD.Values<CarbohydrateSymbolParams>, mesh?: Mesh) {
     const builder = MeshBuilder.create(256, 128, mesh)
 
-    const { detail } = props
+    const { detail, sizeFactor } = props
 
     const carbohydrates = structure.carbohydrates
     const n = carbohydrates.elements.length
@@ -60,8 +59,8 @@ async function createCarbohydrateSymbolMesh(ctx: VisualContext, structure: Struc
         l.unit = c.unit
         l.element = c.unit.elements[c.anomericCarbon]
         const size = theme.size.size(l)
-        const radius = size * radiusFactor
-        const side = size * sideFactor
+        const radius = size * sizeFactor
+        const side = size * sizeFactor * SideFactor
 
         const { center, normal, direction } = c.geometry
         Vec3.add(pd, center, direction)
@@ -148,6 +147,7 @@ async function createCarbohydrateSymbolMesh(ctx: VisualContext, structure: Struc
 export const CarbohydrateSymbolParams = {
     ...ComplexMeshParams,
     detail: PD.Numeric(0, { min: 0, max: 3, step: 1 }),
+    sizeFactor: PD.Numeric(1.75, { min: 0, max: 10, step: 0.01 }),
 }
 export type CarbohydrateSymbolParams = typeof CarbohydrateSymbolParams
 
diff --git a/src/mol-repr/structure/visual/carbohydrate-terminal-link-cylinder.ts b/src/mol-repr/structure/visual/carbohydrate-terminal-link-cylinder.ts
new file mode 100644
index 0000000000000000000000000000000000000000..7d594fd788a192d1fa5fb1df4e2ec6f2bff9ca65
--- /dev/null
+++ b/src/mol-repr/structure/visual/carbohydrate-terminal-link-cylinder.ts
@@ -0,0 +1,147 @@
+/**
+ * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
+ *
+ * @author Alexander Rose <alexander.rose@weirdbyte.de>
+ */
+
+import { Structure, Link, StructureElement } from 'mol-model/structure';
+import { Loci, EmptyLoci } from 'mol-model/loci';
+import { Vec3 } from 'mol-math/linear-algebra';
+import { createLinkCylinderMesh, LinkCylinderParams } from './util/link';
+import { OrderedSet, Interval } from 'mol-data/int';
+import { ComplexMeshVisual, ComplexVisual } from '../complex-visual';
+import { LinkType } from 'mol-model/structure/model/types';
+import { BitFlags } from 'mol-util';
+import { UnitsMeshParams } from '../units-visual';
+import { ParamDefinition as PD } from 'mol-util/param-definition';
+import { Mesh } from 'mol-geo/geometry/mesh/mesh';
+import { LocationIterator } from 'mol-geo/util/location-iterator';
+import { PickingId } from 'mol-geo/geometry/picking';
+import { VisualUpdateState } from '../../util';
+import { VisualContext } from 'mol-repr/representation';
+import { Theme } from 'mol-theme/theme';
+
+async function createCarbohydrateTerminalLinkCylinderMesh(ctx: VisualContext, structure: Structure, theme: Theme, props: PD.Values<CarbohydrateTerminalLinkParams>, mesh?: Mesh) {
+    const { terminalLinks, elements } = structure.carbohydrates
+    const { linkSizeFactor } = props
+
+    const location = StructureElement.create()
+
+    const builderProps = {
+        linkCount: terminalLinks.length,
+        referencePosition: (edgeIndex: number) => null,
+        position: (posA: Vec3, posB: Vec3, edgeIndex: number) => {
+            const l = terminalLinks[edgeIndex]
+            if (l.fromCarbohydrate) {
+                Vec3.copy(posA, elements[l.carbohydrateIndex].geometry.center)
+                l.elementUnit.conformation.position(l.elementIndex, posB)
+            } else {
+                l.elementUnit.conformation.position(l.elementIndex, posA)
+                Vec3.copy(posB, elements[l.carbohydrateIndex].geometry.center)
+            }
+        },
+        order: (edgeIndex: number) => 1,
+        flags: (edgeIndex: number) => BitFlags.create(LinkType.Flag.None),
+        radius: (edgeIndex: number) => {
+            const l = terminalLinks[edgeIndex]
+            if (l.fromCarbohydrate) {
+                location.unit = elements[l.carbohydrateIndex].unit
+                location.element = elements[l.carbohydrateIndex].anomericCarbon
+            } else {
+                location.unit = l.elementUnit
+                location.element = l.elementUnit.elements[l.elementIndex]
+            }
+            return theme.size.size(location) * linkSizeFactor
+        }
+    }
+
+    return createLinkCylinderMesh(ctx, builderProps, props, mesh)
+}
+
+export const CarbohydrateTerminalLinkParams = {
+    ...UnitsMeshParams,
+    ...LinkCylinderParams,
+    detail: PD.Numeric(0, { min: 0, max: 3, step: 1 }),
+    linkSizeFactor: PD.Numeric(0.3, { min: 0, max: 3, step: 0.01 }),
+}
+export type CarbohydrateTerminalLinkParams = typeof CarbohydrateTerminalLinkParams
+
+export function CarbohydrateTerminalLinkVisual(): ComplexVisual<CarbohydrateTerminalLinkParams> {
+    return ComplexMeshVisual<CarbohydrateTerminalLinkParams>({
+        defaultProps: PD.getDefaultValues(CarbohydrateTerminalLinkParams),
+        createGeometry: createCarbohydrateTerminalLinkCylinderMesh,
+        createLocationIterator: CarbohydrateTerminalLinkIterator,
+        getLoci: getTerminalLinkLoci,
+        mark: markTerminalLink,
+        setUpdateState: (state: VisualUpdateState, newProps: PD.Values<CarbohydrateTerminalLinkParams>, currentProps: PD.Values<CarbohydrateTerminalLinkParams>) => {
+            state.createGeometry = newProps.radialSegments !== currentProps.radialSegments
+        }
+    })
+}
+
+function CarbohydrateTerminalLinkIterator(structure: Structure): LocationIterator {
+    const { elements, terminalLinks } = structure.carbohydrates
+    const groupCount = terminalLinks.length
+    const instanceCount = 1
+    const location = Link.Location()
+    const getLocation = (groupIndex: number) => {
+        const terminalLink = terminalLinks[groupIndex]
+        const carb = elements[terminalLink.carbohydrateIndex]
+        const indexCarb = OrderedSet.indexOf(carb.unit.elements, carb.anomericCarbon)
+        if (terminalLink.fromCarbohydrate) {
+            location.aUnit = carb.unit
+            location.aIndex = indexCarb as StructureElement.UnitIndex
+            location.bUnit = terminalLink.elementUnit
+            location.bIndex = terminalLink.elementIndex
+        } else {
+            location.aUnit = terminalLink.elementUnit
+            location.aIndex = terminalLink.elementIndex
+            location.bUnit = carb.unit
+            location.bIndex = indexCarb as StructureElement.UnitIndex
+        }
+        return location
+    }
+    return LocationIterator(groupCount, instanceCount, getLocation, true)
+}
+
+function getTerminalLinkLoci(pickingId: PickingId, structure: Structure, id: number) {
+    const { objectId, groupId } = pickingId
+    if (id === objectId) {
+        const { terminalLinks, elements } = structure.carbohydrates
+        const l = terminalLinks[groupId]
+        const carb = elements[l.carbohydrateIndex]
+        const carbIndex = OrderedSet.indexOf(carb.unit.elements, carb.anomericCarbon)
+
+        if (l.fromCarbohydrate) {
+            return Link.Loci(structure, [
+                Link.Location(
+                    carb.unit, carbIndex as StructureElement.UnitIndex,
+                    l.elementUnit, l.elementIndex
+                )
+            ])
+        } else {
+            return Link.Loci(structure, [
+                Link.Location(
+                    l.elementUnit, l.elementIndex,
+                    carb.unit, carbIndex as StructureElement.UnitIndex
+                )
+            ])
+        }
+    }
+    return EmptyLoci
+}
+
+function markTerminalLink(loci: Loci, structure: Structure, apply: (interval: Interval) => boolean) {
+    const { getTerminalLinkIndex } = structure.carbohydrates
+
+    let changed = false
+    if (Link.isLoci(loci)) {
+        for (const l of loci.links) {
+            const idx = getTerminalLinkIndex(l.aUnit, l.aUnit.elements[l.aIndex], l.bUnit, l.bUnit.elements[l.bIndex])
+            if (idx !== undefined) {
+                if (apply(Interval.ofSingleton(idx))) changed = true
+            }
+        }
+    }
+    return changed
+}
\ No newline at end of file
diff --git a/src/mol-repr/structure/visual/inter-unit-link-cylinder.ts b/src/mol-repr/structure/visual/inter-unit-link-cylinder.ts
index 31e82c69c78b9f1e5bad8b5022b02b3a2f7e7e8c..f85233d3541260ded2037f1c37c814e17e00be24 100644
--- a/src/mol-repr/structure/visual/inter-unit-link-cylinder.ts
+++ b/src/mol-repr/structure/visual/inter-unit-link-cylinder.ts
@@ -7,7 +7,7 @@
 import { Link, Structure, StructureElement } from 'mol-model/structure';
 import { ComplexVisual } from '../representation';
 import { VisualUpdateState } from '../../util';
-import { LinkCylinderProps, createLinkCylinderMesh, LinkIterator, LinkCylinderParams } from './util/link';
+import { createLinkCylinderMesh, LinkIterator, LinkCylinderParams } from './util/link';
 import { Vec3 } from 'mol-math/linear-algebra';
 import { Loci, EmptyLoci } from 'mol-model/loci';
 import { ComplexMeshVisual, ComplexMeshParams } from '../complex-visual';
@@ -19,9 +19,10 @@ import { PickingId } from 'mol-geo/geometry/picking';
 import { VisualContext } from 'mol-repr/representation';
 import { Theme } from 'mol-theme/theme';
 
-async function createInterUnitLinkCylinderMesh(ctx: VisualContext, structure: Structure, theme: Theme, props: LinkCylinderProps, mesh?: Mesh) {
+async function createInterUnitLinkCylinderMesh(ctx: VisualContext, structure: Structure, theme: Theme, props: PD.Values<InterUnitLinkParams>, mesh?: Mesh) {
     const links = structure.links
     const { bondCount, bonds } = links
+    const { sizeFactor } = props
 
     if (!bondCount) return Mesh.createEmpty(mesh)
 
@@ -42,7 +43,7 @@ async function createInterUnitLinkCylinderMesh(ctx: VisualContext, structure: St
             const b = bonds[edgeIndex]
             location.unit = b.unitA
             location.element = b.unitA.elements[b.indexA]
-            return theme.size.size(location)
+            return theme.size.size(location) * sizeFactor
         }
     }
 
@@ -52,6 +53,7 @@ async function createInterUnitLinkCylinderMesh(ctx: VisualContext, structure: St
 export const InterUnitLinkParams = {
     ...ComplexMeshParams,
     ...LinkCylinderParams,
+    sizeFactor: PD.Numeric(0.2, { min: 0, max: 10, step: 0.01 }),
 }
 export type InterUnitLinkParams = typeof InterUnitLinkParams