bool WaterToAirComponent_Impl::removeFromAirLoopHVAC()
{
    if( auto t_oaSystem = airLoopHVACOutdoorAirSystem() ) {
        if( t_oaSystem->oaComponent(handle()) ) {
            return HVACComponent_Impl::removeFromLoop(t_oaSystem->outboardOANode().get(),
                    t_oaSystem.get(),
                    airInletPort(),
                    airOutletPort());
        } else if( t_oaSystem->reliefComponent(handle()) ) {
            return HVACComponent_Impl::removeFromLoop(t_oaSystem.get(),
                    t_oaSystem->outboardReliefNode().get(),
                    airInletPort(),
                    airOutletPort());
        }
    } else if( auto t_airLoop = airLoopHVAC() ) {
        if( t_airLoop->supplyComponent(handle()) ) {
            return HVACComponent_Impl::removeFromLoop(t_airLoop->supplyInletNode(),
                    t_airLoop->supplyOutletNode(),
                    airInletPort(),
                    airOutletPort());
        }
    }

    return false;
}
boost::optional<ModelObject> WaterToAirComponent_Impl::airInletModelObject()
{
    return connectedObject( airInletPort() );
}
bool WaterToAirComponent_Impl::removeFromAirLoopHVAC()
{
    Model _model = model();
    ModelObject thisObject = getObject<ModelObject>();

    if( boost::optional<AirLoopHVAC> airLoop = airLoopHVAC() )
    {
        if( airOutletModelObject().get() == airLoop->supplyOutletNodes().front() &&
                airInletModelObject().get() == airLoop->supplyInletNode() )
        {
            ModelObject sourceModelObject = airInletModelObject().get();
            unsigned sourcePort = connectedObjectPort( airInletPort() ).get();
            ModelObject targetModelObject = airOutletModelObject().get();
            unsigned targetPort = connectedObjectPort( airOutletPort() ).get();

            model().disconnect(thisObject,airOutletPort());
            model().disconnect(thisObject,airInletPort());

            _model.connect( sourceModelObject, sourcePort,
                            targetModelObject, targetPort );
            return true;
        }
        else if( airOutletModelObject().get() == airLoop->supplyOutletNodes().front() )
        {
            Node sourceModelObject = airInletModelObject()->optionalCast<Node>().get();
            ModelObject targetModelObject = airOutletModelObject().get();
            unsigned targetPort = connectedObjectPort( airOutletPort() ).get();
            ModelObject source2ModelObject = sourceModelObject.inletModelObject().get();
            unsigned source2Port = sourceModelObject.connectedObjectPort( sourceModelObject.inletPort() ).get();

            model().disconnect(thisObject,airOutletPort());
            model().disconnect(thisObject,airInletPort());

            _model.connect( source2ModelObject, source2Port,
                            targetModelObject, targetPort );

            sourceModelObject.remove();

            return true;
        }
        else
        {
            ModelObject sourceModelObject = airInletModelObject().get();
            unsigned sourcePort = connectedObjectPort( airInletPort() ).get();
            Node targetModelObject = airOutletModelObject()->optionalCast<Node>().get();
            ModelObject target2ModelObject = targetModelObject.outletModelObject().get();
            unsigned target2Port = targetModelObject.connectedObjectPort( targetModelObject.outletPort() ).get();

            model().disconnect(thisObject,airOutletPort());
            model().disconnect(thisObject,airInletPort());


            _model.connect( sourceModelObject, sourcePort,
                            target2ModelObject, target2Port );

            targetModelObject.remove();

            return true;
        }
    }

    return false;
}
bool WaterToAirComponent_Impl::addToNode(Node & node)
{
    Model _model = node.model();
    ModelObject thisModelObject = getObject<ModelObject>();
    boost::optional<AirLoopHVACOutdoorAirSystem> oaSystem = node.airLoopHVACOutdoorAirSystem();

    if( node.airLoopHVAC() && ! oaSystem )
    {
        AirLoopHVAC airLoop = node.airLoopHVAC().get();
        if( airLoop.demandComponent( node.handle() ) )
        {
            return false;
        }
        else
        {
            if( airLoopHVAC() )
            {
                removeFromAirLoopHVAC();
            }

            if( node == airLoop.supplyOutletNode() &&
                    node.inletModelObject().get() == airLoop.supplyInletNode() )
            {
                unsigned oldOutletPort = node.connectedObjectPort( node.inletPort() ).get();
                unsigned oldInletPort = node.inletPort();
                ModelObject oldSourceModelObject = node.connectedObject( node.inletPort() ).get();
                ModelObject oldTargetModelObject = node;

                _model.connect( oldSourceModelObject, oldOutletPort,
                                thisModelObject, airInletPort() );
                _model.connect( thisModelObject, airOutletPort(),
                                oldTargetModelObject, oldInletPort );
                return true;
            }
            if( node == airLoop.supplyInletNode() &&
                    node.outletModelObject().get() == airLoop.supplyOutletNode() )
            {
                unsigned oldOutletPort = node.outletPort();
                unsigned oldInletPort = node.connectedObjectPort( node.outletPort() ).get();
                ModelObject oldSourceModelObject = node;
                ModelObject oldTargetModelObject = node.outletModelObject().get();

                _model.connect( oldSourceModelObject, oldOutletPort,
                                thisModelObject, airInletPort() );
                _model.connect( thisModelObject, airOutletPort(),
                                oldTargetModelObject, oldInletPort );
                return true;
            }
            else if( node == airLoop.supplyOutletNode() )
            {
                unsigned oldOutletPort = node.connectedObjectPort( node.inletPort() ).get();
                unsigned oldInletPort = node.inletPort();
                ModelObject oldSourceModelObject = node.connectedObject( node.inletPort() ).get();
                ModelObject oldTargetModelObject = node;

                Node newNode( _model );
                _model.connect( oldSourceModelObject, oldOutletPort,
                                newNode, newNode.inletPort() );
                _model.connect( newNode, newNode.outletPort(),
                                thisModelObject, airInletPort() );
                _model.connect( thisModelObject, airOutletPort(),
                                oldTargetModelObject, oldInletPort );
                return true;
            }
            else
            {
                unsigned oldOutletPort = node.outletPort();
                unsigned oldInletPort = node.connectedObjectPort( node.outletPort() ).get();
                ModelObject oldSourceModelObject = node;
                ModelObject oldTargetModelObject = node.connectedObject( node.outletPort() ).get();

                Node newNode( _model );
                _model.connect( oldSourceModelObject, oldOutletPort,
                                thisModelObject, airInletPort() );
                _model.connect( thisModelObject, airOutletPort(),
                                newNode, newNode.inletPort() );
                _model.connect( newNode, newNode.outletPort(),
                                oldTargetModelObject, oldInletPort );
                return true;
            }
        }
    }
    else if( node.plantLoop() )
    {
        PlantLoop _plantLoop = node.plantLoop().get();
        if( ! _plantLoop.demandComponent( node.handle() ) )
        {
            return false;
        }
        else
        {
            if( plantLoop() )
            {
                removeFromPlantLoop();
            }

            if( node == _plantLoop.demandOutletNode() &&
                    node.inletModelObject().get() == _plantLoop.demandInletNode() )
            {
                unsigned oldOutletPort = node.connectedObjectPort( node.inletPort() ).get();
                unsigned oldInletPort = node.inletPort();
                ModelObject oldSourceModelObject = node.connectedObject( node.inletPort() ).get();
                ModelObject oldTargetModelObject = node;

                _model.connect( oldSourceModelObject, oldOutletPort,
                                thisModelObject, waterInletPort() );
                _model.connect( thisModelObject, waterOutletPort(),
                                oldTargetModelObject, oldInletPort );
                return true;
            }
            else if( node == _plantLoop.demandOutletNode() )
            {
                unsigned oldOutletPort = node.connectedObjectPort( node.inletPort() ).get();
                unsigned oldInletPort = node.inletPort();
                ModelObject oldSourceModelObject = node.connectedObject( node.inletPort() ).get();
                ModelObject oldTargetModelObject = node;

                Node newNode( _model );
                _model.connect( oldSourceModelObject, oldOutletPort,
                                newNode, newNode.inletPort() );
                _model.connect( newNode, newNode.outletPort(),
                                thisModelObject, waterInletPort() );
                _model.connect( thisModelObject, waterOutletPort(),
                                oldTargetModelObject, oldInletPort );
                return true;
            }
            else
            {
                unsigned oldOutletPort = node.outletPort();
                unsigned oldInletPort = node.connectedObjectPort( node.outletPort() ).get();
                ModelObject oldSourceModelObject = node;
                ModelObject oldTargetModelObject = node.connectedObject( node.outletPort() ).get();

                Node newNode( _model );
                _model.connect( oldSourceModelObject, oldOutletPort,
                                thisModelObject, waterInletPort() );
                _model.connect( thisModelObject, waterOutletPort(),
                                newNode, newNode.inletPort() );
                _model.connect( newNode, newNode.outletPort(),
                                oldTargetModelObject, oldInletPort );
                return true;
            }
        }
    }
    else
    {
        return false;
    }
}
bool WaterToAirComponent_Impl::addToNode(Node & node)
{
    auto _model = node.model();
    auto thisModelObject = getObject<ModelObject>();
    auto t_airLoop = node.airLoopHVAC();
    auto t_plantLoop = node.plantLoop();
    auto t_oaSystem = node.airLoopHVACOutdoorAirSystem();

    boost::optional<unsigned> componentInletPort;
    boost::optional<unsigned> componentOutletPort;

    boost::optional<HVACComponent> systemStartComponent;
    boost::optional<HVACComponent> systemEndComponent;

    if( node.getImpl<Node_Impl>()->isConnected(thisModelObject) ) return false;

    if( t_airLoop && ! t_oaSystem )
    {
        if( t_airLoop->demandComponent( node.handle() ) ) return false;

        systemStartComponent = t_airLoop->supplyInletNode();
        auto nodes = t_airLoop->supplyOutletNodes();
        OS_ASSERT( ! nodes.empty() );
        if( (nodes.size() == 2u) && (! t_airLoop->supplyComponents(node,nodes[1]).empty()) ) {
            systemEndComponent = nodes[1];
        } else {
            systemEndComponent = nodes[0];
        }
        OS_ASSERT(systemEndComponent);
        componentInletPort = airInletPort();
        componentOutletPort = airOutletPort();

        removeFromAirLoopHVAC();
    } else if( t_oaSystem ) {
        if( t_oaSystem->oaComponent(node.handle()) ) {
            systemStartComponent = t_oaSystem->outboardOANode();
            systemEndComponent = t_oaSystem.get();
            componentInletPort = airInletPort();
            componentOutletPort = airOutletPort();
        } else if( t_oaSystem->reliefComponent(node.handle()) ) {
            systemStartComponent = t_oaSystem.get();
            systemEndComponent = t_oaSystem->outboardReliefNode();
            componentInletPort = airInletPort();
            componentOutletPort = airOutletPort();
        }
        removeFromAirLoopHVAC();
    } else if( t_plantLoop ) {
        if( ! t_plantLoop->demandComponent( node.handle() ) ) return false;

        systemStartComponent = t_plantLoop->demandInletNode();
        systemEndComponent = t_plantLoop->demandOutletNode();
        componentInletPort = waterInletPort();
        componentOutletPort = waterOutletPort();

        removeFromPlantLoop();
    }

    if( systemStartComponent && systemEndComponent && componentOutletPort && componentInletPort ) {
        return HVACComponent_Impl::addToNode(node,systemStartComponent.get(),systemEndComponent.get(),componentInletPort.get(),componentOutletPort.get());
    } else {
        return false;
    }
}