void
SCFeedbackDirector::BuildWindow
(
    SCCircuitDocument* doc
)
{
    const SCCircuit* circuit = doc->GetCircuit();

    JArray<JCoordinate> heights(4);
    heights.AppendElement(kInitExprHeight);
    heights.AppendElement(kInitExprHeight);
    heights.AppendElement(kInitExprHeight);
    heights.AppendElement(kInitExprHeight);

    JArray<JCoordinate> minHeights(4);
    minHeights.AppendElement(kMinExprHeight);
    minHeights.AppendElement(kMinExprHeight);
    minHeights.AppendElement(kMinExprHeight);
    minHeights.AppendElement(kMinExprHeight);

// begin JXLayout

    JXWindow* window = new JXWindow(this, 360,520, "");
    assert( window != NULL );

    itsMainPartition =
        new JXVertPartition(heights, 0, minHeights, window,
                            JXWidget::kHElastic, JXWidget::kVElastic, 0,110, 365,415);
    assert( itsMainPartition != NULL );

    itsInputSource =
        new SCComponentMenu(circuit, SCACSourceFilter, "Input source:", window,
                            JXWidget::kFixedLeft, JXWidget::kFixedTop, 20,20, 150,30);
    assert( itsInputSource != NULL );

    itsDepSource =
        new SCComponentMenu(circuit, SCDepSourceFilter, "Dependent source:", window,
                            JXWidget::kFixedLeft, JXWidget::kFixedTop, 20,60, 150,30);
    assert( itsDepSource != NULL );

    itsEvalButton =
        new JXTextButton(JGetString("itsEvalButton::SCFeedbackDirector::JXLayout"), window,
                         JXWidget::kFixedRight, JXWidget::kFixedTop, 230,20, 80,20);
    assert( itsEvalButton != NULL );

    JXStaticText* layoutMessage =
        new JXStaticText(JGetString("layoutMessage::SCFeedbackDirector::JXLayout"), window,
                         JXWidget::kFixedRight, JXWidget::kFixedTop, 240,50, 110,60);
    assert( layoutMessage != NULL );

// end JXLayout

    const JCoordinate kMinWindowWidth = window->GetBoundsWidth();

    window->SetTitle("Feedback Theorem");
    window->SetMinSize(kMinWindowWidth, window->GetBoundsHeight());

    layoutMessage->SetText(
        "Output fn\nH0  |  Hinf\n T   |  Tn\nScratch area");

    itsInputSource->SetToPopupChoice(kJTrue);
    itsDepSource->SetToPopupChoice(kJTrue);

    ListenTo(itsEvalButton);

    // create sub-partitions

    const JCoordinate w =
        (itsMainPartition->GetBoundsWidth() - JPartition::kDragRegionSize)/2;
    JArray<JCoordinate> widths(2);
    widths.AppendElement(w);
    widths.AppendElement(w);

    const JCoordinate wMin = (kMinWindowWidth - JPartition::kDragRegionSize)/2;
    JArray<JCoordinate> minWidths(2);
    minWidths.AppendElement(wMin);
    minWidths.AppendElement(wMin);

    JXContainer* encl = itsMainPartition->GetCompartment(2);
    itsHPartition =
        new JXHorizPartition(widths, 0, minWidths, encl,
                             JXWidget::kHElastic, JXWidget::kVElastic,
                             0,0, encl->GetBoundsWidth(), encl->GetBoundsHeight());
    assert( itsHPartition != NULL );

    encl = itsMainPartition->GetCompartment(3);
    itsTPartition =
        new JXHorizPartition(widths, 0, minWidths, encl,
                             JXWidget::kHElastic, JXWidget::kVElastic,
                             0,0, encl->GetBoundsWidth(), encl->GetBoundsHeight());
    assert( itsTPartition != NULL );

    // create expressions

    SCExprEditorSet* exprSet =
        new SCExprEditorSet(doc, &itsOutputFn,
                            itsMainPartition->GetCompartment(1),
                            JXWidget::kHElastic, JXWidget::kVElastic,
                            0,0, 100,100);
    assert( exprSet != NULL );
    exprSet->FitToEnclosure();

    exprSet =
        new SCExprEditorSet(doc, itsOutputFn, &itsH0,
                            itsHPartition->GetCompartment(1),
                            JXWidget::kHElastic, JXWidget::kVElastic,
                            0,0, 100,100);
    assert( exprSet != NULL );
    exprSet->FitToEnclosure();

    exprSet =
        new SCExprEditorSet(doc, itsOutputFn, &itsHinf,
                            itsHPartition->GetCompartment(2),
                            JXWidget::kHElastic, JXWidget::kVElastic,
                            0,0, 100,100);
    assert( exprSet != NULL );
    exprSet->FitToEnclosure();

    exprSet =
        new SCExprEditorSet(doc, itsOutputFn, &itsT,
                            itsTPartition->GetCompartment(1),
                            JXWidget::kHElastic, JXWidget::kVElastic,
                            0,0, 100,100);
    assert( exprSet != NULL );
    exprSet->FitToEnclosure();

    exprSet =
        new SCExprEditorSet(doc, itsOutputFn, &itsTn,
                            itsTPartition->GetCompartment(2),
                            JXWidget::kHElastic, JXWidget::kVElastic,
                            0,0, 100,100);
    assert( exprSet != NULL );
    exprSet->FitToEnclosure();

    exprSet =
        new SCExprEditorSet(doc, itsOutputFn, &itsScratchFn,
                            itsMainPartition->GetCompartment(4),
                            JXWidget::kHElastic, JXWidget::kVElastic,
                            0,0, 100,100);
    assert( exprSet != NULL );
    exprSet->FitToEnclosure();

    // add our menu items

    JXTextMenu* menu = itsOutputFn->GetExtraMenu();

    menu->AppendItem(kBuildH0FormItemStr);
    itsBuildH0Index = menu->GetItemCount();

    menu->AppendItem(kBuildHinfFormItemStr);
    itsBuildHinfIndex = menu->GetItemCount();

    menu->ShowSeparatorAfter(itsBuildH0Index-1);
    ListenTo(menu);
}